강의에서 STOMP 동작 간 /app, /topic 요청을 동시에 보낸다고 하셨는데 그럼 app 경로 발행된 메세지는 broker를 통해서 topic 경로로 전달이 되고 맨 처음에 동시에 보낸 topic 요청도 broker를 통해서 전달이 되어서 broker에서 구독하고 있는 사용자들에게 메세지를 보내준다고 이해하면 되는 것일까요? /topic으로 2번 가는 것 처럼 느껴져서 약간의 혼동이 있었습니다!
안녕하세요, 강의에서는 메시지 브로커용으로 redis를 사용하셨는데, redis 외에도 rabbitmq나 카프카 같은 것들도 사용되는 것으로 알고있습니다. 그 중에서 특별히 redis를 사용한 이유가 있는지 궁금합니다. 그리고 무중단 배포 시 스프링 내장 브로커를 사용하면 서버 재실행 시 구독 정보가 초기화되기에 메시지 브로커를 도입하려고 하는데 이때는 셋 중에 어떤 것을 사용하면 좋을지 궁금합니다.
안녕하세요. JWT를 생성하는 코드(JwtTokenProvider.java의 createToken)에서는 Claims 객체를 먼저 생성하고 claims.setSubject() 로 설정한 후, 이 claims를 builder에 전달하는 방식을 사용하고 계신데요. Builder에도 setSubject() 메서드가 있는데, Claims 객체에서 먼저 설정하신 이유가 궁금합니다. 혹시 custom claim인 role 을 함께 추가하기 위해서 Claims 객체를 먼저 생성하여 사용하신 건가요? 아니면 다른 이유가 있으신지 궁금합니다.
현재 인터셉터에서는 토큰을 검증만 하고 있는데, "토큰 검증 후에 인증 객체를 SecurityContextHolder에 저장 해야 하지 않나?" 라는 생각이 들었습니다. 이 부분은 강의에서 굳이 필요하지 않아서 만들지 않으신 걸까요? 아니면 " 인증 객체를 SecurityContextHolder에 저장하는 부분 은 이 인터셉터의 의도와는 맞지 않다"라고 볼 수 있을까요? 추가로 인증 객체를 SecurityContextHolder에 저장했을 때 와 accessor.setUser(principal) 를 수행했을 때의 장점과 이를 활용해 추가로 구현해볼 수 있는 기능들에는 어떤 것들이 있을지 궁금합니다.
안녕하세요 강사님 좋은 강의 잘 듣고 있습니다 강의에서 말씀하신 그레이스풀 셧다운과 데몬스레드의 관계까 제가 이해한 의미와 조금 달라서 여쭤봅니다. 저는 그레이스풀 셧다운을 진행 중인 작업을 마무리하고 안전하게 종료하는 것으로 이해하고 있는데 데몬 스레드는 JVM 종료 시 작업이 중간에 끊길 수도 있다고 알고 있습니다. 그래서 “레디스 이벤트 처리 과정이 백그라운드에서 알아서 들어가기 때문에 데몬 스레드를 사용하면 자연스럽게 그레이스풀 셧다운이 된다”라는 설명에서 레디스의 백그라운드 이벤트 처리 방식과 데몬 스레드 사용이 어떤 식으로 연결되는지를 조금 더 구체적으로 알고 싶습니다. 또, 메시지를 소비하는 도중에 애플리케이션이 종료된다면 메시지 손실 가능성은 없는지도 궁금합니다. 그리고 실무 환경에서도 보통 이런 방식(데몬 스레드 기반)으로 Redis Pub/Sub 리스너를 구성하는지 아니면 다른 종료 처리 방식을 더 선호하는지도 알고 싶습니다. 좋은 강의 잘 듣고있습니다! 감사합니다.
학습중 궁금한 것은 언제든 문의 하세요. 질문을 최대한 자세히 남겨주시면 반드시 답변 드리도록 하겠습니다. 추가로 알고 싶은 내용도 요청해주시면 강의 자료를 업데이트 해서 제공할 예정입니다. application.yml spring: application: name: HelloMessageQueue rabbitmq: host: localhost port: 5672 username: admin password: admin server: port: 8080 docker-compose.yml services: rabbitmq: image: rabbitmq:3-management container_name: mq ports: - "5672:5672" - "15672:15672" environment: RABBITMQ_ERLANG_COOKIE: rabbitmqCookie RABBITMQ_DEFAULT_USER: admin RABBITMQ_DEFAULT_PASS: admin 이렇게 해서 실행하면 2025-08-08T11:17:15.145+09:00 ERROR 11684 --- [HelloMessageQueue] [ restartedMain] o.s.boot.SpringApplication : Application run failed org.springframework.context.ApplicationContextException: Failed to start bean 'container' at org.springframework.context.support .DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:408) ~[spring-context-6.2.9.jar:6.2.9] at org.springframework.context.support .DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:394) ~[spring-context-6.2.9.jar:6.2.9] at org.springframework.context.support .DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:586) ~[spring-context-6.2.9.jar:6.2.9] at java.base/java.lang.Iterable.forEach(Iterable.java:75) ~[na:na] at org.springframework.context.support .DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:364) ~[spring-context-6.2.9.jar:6.2.9] at org.springframework.context.support .DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:310) ~[spring-context-6.2.9.jar:6.2.9] at org.springframework.context.support .AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:1006) ~[spring-context-6.2.9.jar:6.2.9] at org.springframework.context.support .AbstractApplicationContext.refresh(AbstractApplicationContext.java:630) ~[spring-context-6.2.9.jar:6.2.9] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.5.4.jar:3.5.4] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752) ~[spring-boot-3.5.4.jar:3.5.4] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439) ~[spring-boot-3.5.4.jar:3.5.4] at org.springframework.boot.SpringApplication.run (SpringApplication.java:318) ~[spring-boot-3.5.4.jar:3.5.4] at org.springframework.boot.SpringApplication.run (SpringApplication.java:1361) ~[spring-boot-3.5.4.jar:3.5.4] at org.springframework.boot.SpringApplication.run (SpringApplication.java:1350) ~[spring-boot-3.5.4.jar:3.5.4] at com.study .rabbitmq.RabbitmqApplication.main(RabbitmqApplication.java:10) ~[main/:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na] at org.springframework.boot.devtools.restart.RestartLauncher.run (RestartLauncher.java:50) ~[spring-boot-devtools-3.5.4.jar:3.5.4] Caused by: org.springframework.amqp.AmqpIllegalStateException: Fatal exception on listener startup at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.waitForConsumersToStart(SimpleMessageListenerContainer.java:643) ~[spring-rabbit-3.2.6.jar:3.2.6] at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doStart(SimpleMessageListenerContainer.java:603) ~[spring-rabbit-3.2.6.jar:3.2.6] at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.start(AbstractMessageListenerContainer.java:1417) ~[spring-rabbit-3.2.6.jar:3.2.6] at org.springframework.context.support .DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:405) ~[spring-context-6.2.9.jar:6.2.9] ... 19 common frames omitted Caused by: org.springframework.amqp.rabbit.listener.exception.FatalListenerStartupException: Authentication failure at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.start(BlockingQueueConsumer.java:631) ~[spring-rabbit-3.2.6.jar:3.2.6] at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.initialize(SimpleMessageListenerContainer.java:1482) ~[spring-rabbit-3.2.6.jar:3.2.6] at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$ AsyncMessageProcessingConsumer.run (SimpleMessageListenerContainer.java:1322) ~[spring-rabbit-3.2.6.jar:3.2.6] at java.base/ java.lang.Thread.run (Thread.java:842) ~[na:na] Caused by: org.springframework.amqp.AmqpAuthenticationException: com.rabbitmq.client.AuthenticationFailureException: ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN. For details see the broker logfile. at org.springframework.amqp.rabbit.support .RabbitExceptionTranslator.convertRabbitAccessException(RabbitExceptionTranslator.java:64) ~[spring-rabbit-3.2.6.jar:3.2.6] at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:632) ~[spring-rabbit-3.2.6.jar:3.2.6] at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.createConnection(CachingConnectionFactory.java:726) ~[spring-rabbit-3.2.6.jar:3.2.6] at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils.createConnection(ConnectionFactoryUtils.java:257) ~[spring-rabbit-3.2.6.jar:3.2.6] at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils$RabbitResourceFactory.createConnection(ConnectionFactoryUtils.java:345) ~[spring-rabbit-3.2.6.jar:3.2.6] at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils.doGetTransactionalResourceHolder(ConnectionFactoryUtils.java:140) ~[spring-rabbit-3.2.6.jar:3.2.6] at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils.getTransactionalResourceHolder(ConnectionFactoryUtils.java:102) ~[spring-rabbit-3.2.6.jar:3.2.6] at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils.getTransactionalResourceHolder(ConnectionFactoryUtils.java:85) ~[spring-rabbit-3.2.6.jar:3.2.6] at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.start(BlockingQueueConsumer.java:625) ~[spring-rabbit-3.2.6.jar:3.2.6] ... 3 common frames omitted Caused by: com.rabbitmq.client.AuthenticationFailureException: ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN. For details see the broker logfile. at com.rabbitmq.client.impl.AMQConnection.start(AMQConnection.java:395) ~[amqp-client-5.25.0.jar:5.25.0] at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1251) ~[amqp-client-5.25.0.jar:5.25.0] at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1198) ~[amqp-client-5.25.0.jar:5.25.0] at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.connectAddresses(AbstractConnectionFactory.java:678) ~[spring-rabbit-3.2.6.jar:3.2.6] at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.connect(AbstractConnectionFactory.java:647) ~[spring-rabbit-3.2.6.jar:3.2.6] at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:593) ~[spring-rabbit-3.2.6.jar:3.2.6] ... 10 common frames omitted 이 에러가 발생합니다 계정도 있는데 인증이 안되는 이유를 모르겠습니다
안녕하세요. 이번에 강의 수강을 시작하였습니다. 급하게 앱 프로젝트에서 채팅 서비스 구현을 맡게 되어서 강의를 수강하게 되었는데요, 지금 이 강의는 웹에서 채팅을 구현하는데, 앱에서 구현하게된다고 해도 백엔드 부분은 동일한건가요? 차이점이 있다면 알려주시면 감사하겠습니다
안녕하세요. 트랜잭션 메시징에 대해 궁금한 것이 생겨 질문드립니다. 트랜잭션 메시징은 데이터베이스 작업과 메시지 발행 작업을 원자적으로 수행하여 데이터의 일관성을 보장하는 것으로 알고 있습니다. 강의 내용 중 '트랜잭션 메시징의 한계'에서 분산 트랜잭션을 완벽하게 보장하지는 않는다고 하셔서 이를 DB의 트랜잭션과 메시지 전송의 트랜잭션이 서로 독립적으로 작동한다고 이해했습니다. 그럼 RabbitMQ에서 트랜잭션 메시징을 지원한다고 할 수 있나요?