강사님, MSA의 장애 격리에 대해 강의를 듣다가 궁금한 점이 생겨 질문드립니다. 제가 이해하기로는 모놀리식은 하나의 애플리케이션 안에 여러 도메인/서비스가 함께 구성되어 있고, MSA는 각 도메인별로 서비스를 분리하여 구성하는 것으로 알고 있습니다. 강의에서 MSA의 장점 중 하나로 장애 격리를 말씀해 주셨는데, 실제로는 한 서비스의 장애가 해당 서비스를 의존하고 있는 다른 서비스로 전파될 수도 있지 않을까 하는 생각이 들었습니다. 예를 들어 여러 서비스에서 회원 정보나 회원 상태를 검증하기 위해 회원 서비스에 요청을 보내야 하고, 회원 서비스의 검증 결과가 정상이어야만 해당 서비스를 이용할 수 있는 구조라고 가정하겠습니다. 이 경우 회원 서비스에 장애가 발생하면 회원 서비스에 의존하고 있는 여러 서비스에서도 요청 처리가 불가능해지기 때문에, 결국 장애가 다른 서비스로 전파되는 것처럼 보입니다. 그래서 제가 생각한 것은 MSA의 장애 격리가 '장애가 다른 서비스로 전혀 전파되지 않는다'는 의미보다는, 모놀리식에 비해 장애가 발생했을 때 영향을 받는 범위를 제한할 수 있다는 의미에 더 가깝지 않을까? 하는 것입니다. 예를 들어 모놀리식에서는 하나의 애플리케이션에 장애가 발생하면 전체 기능에 영향을 줄 수 있지만, MSA에서는 특정 서비스의 장애가 해당 서비스 및 이를 직접적으로 의존하는 서비스 정도로 영향 범위를 제한할 수 있다는 의미인지 궁금합니다. 그리고 실제 MSA 환경에서는 이러한 장애 전파를 막기 위해 Circuit Breaker, Timeout, Retry, Fallback, 비동기 메시징 등의 방법을 사용해서 장애 격리 수준을 높이는 것으로 이해하고 있는데, 제가 이해한 방향이 맞는지도 궁금합니다. 결국 MSA에서 말하는 장애 격리의 핵심이 '완전한 장애 격리'라기보다는 '장애 영향 범위를 줄이고 장애 전파를 제어할 수 있다'는 점에 있다고 이해하면 될까요?
안녕하세요 강사님 강의 잘 듣고 있습니다. 섹션 9에서 강의대로 docker에 rabbitmq를 올린 뒤 configservice를 실행했는데 오류가 발생합니다. org.springframework.amqp.rabbit.listener.BlockingQueueConsumer$DeclarationException: Failed to declare queue(s):[springCloudBus.anonymous.PswTKgDeT12hTiCFa33hLw] at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.attemptPassiveDeclarations(BlockingQueueConsumer.java:772) ~[spring-rabbit-3.2.5.jar:3.2.5] at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.passiveDeclarations(BlockingQueueConsumer.java:649) ~[spring-rabbit-3.2.5.jar:3.2.5] at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.start(BlockingQueueConsumer.java:636) ~[spring-rabbit-3.2.5.jar:3.2.5] at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.initialize(SimpleMessageListenerContainer.java:1482) ~[spring-rabbit-3.2.5.jar:3.2.5] at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$ AsyncMessageProcessingConsumer.run (SimpleMessageListenerContainer.java:1322) ~[spring-rabbit-3.2.5.jar:3.2.5] at java.base/ java.lang.Thread.run (Thread.java:1447) ~[na:na] Caused by: java.io .IOException: null at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:140) ~[amqp-client-5.25.0.jar:5.25.0] at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:136) ~[amqp-client-5.25.0.jar:5.25.0] at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:158) ~[amqp-client-5.25.0.jar:5.25.0] at com.rabbitmq.client.impl.ChannelN.queueDeclarePassive(ChannelN.java:1033) ~[amqp-client-5.25.0.jar:5.25.0] at com.rabbitmq.client.impl.ChannelN.queueDeclarePassive(ChannelN.java:47) ~[amqp-client-5.25.0.jar:5.25.0] at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:565) ~[na:na] at org.springframework.amqp.rabbit.connection.CachingConnectionFactory$CachedChannelInvocationHandler.invoke(CachingConnectionFactory.java:1201) ~[spring-rabbit-3.2.5.jar:3.2.5] at jdk.proxy2/jdk.proxy2.$Proxy140.queueDeclarePassive(Unknown Source) ~[na:na] at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.attemptPassiveDeclarations(BlockingQueueConsumer.java:750) ~[spring-rabbit-3.2.5.jar:3.2.5] ... 5 common frames omitted Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no queue 'springCloudBus.anonymous.PswTKgDeT12hTiCFa33hLw' in vhost '/', class-id=50, method-id=10) at com.rabbitmq.utility.ValueOrException.getValue(ValueOrException.java:66) ~[amqp-client-5.25.0.jar:5.25.0] at com.rabbitmq.utility.BlockingValueOrException.uninterruptibleGetValue(BlockingValueOrException.java:36) ~[amqp-client-5.25.0.jar:5.25.0] at com.rabbitmq.client.impl.AMQChannel$BlockingRpcContinuation.getReply(AMQChannel.java:552) ~[amqp-client-5.25.0.jar:5.25.0] at com.rabbitmq.client.impl.AMQChannel.privateRpc(AMQChannel.java:316) ~[amqp-client-5.25.0.jar:5.25.0] at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:152) ~[amqp-client-5.25.0.jar:5.25.0] ... 12 common frames omitted Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no queue 'springCloudBus.anonymous.PswTKgDeT12hTiCFa33hLw' in vhost '/', class-id=50, method-id=10) at com.rabbitmq.client.impl.ChannelN.asyncShutdown(ChannelN.java:528) ~[amqp-client-5.25.0.jar:5.25.0] at com.rabbitmq.client.impl.ChannelN.processAsync(ChannelN.java:349) ~[amqp-client-5.25.0.jar:5.25.0] at com.rabbitmq.client.impl.AMQChannel.handleCompleteInboundCommand(AMQChannel.java:193) ~[amqp-client-5.25.0.jar:5.25.0] at com.rabbitmq.client.impl.AMQChannel.handleFrame(AMQChannel.java:125) ~[amqp-client-5.25.0.jar:5.25.0] at com.rabbitmq.client.impl.AMQConnection.readFrame(AMQConnection.java:761) ~[amqp-client-5.25.0.jar:5.25.0] at com.rabbitmq.client.impl.AMQConnection.access$400(AMQConnection.java:48) ~[amqp-client-5.25.0.jar:5.25.0] at com.rabbitmq.client.impl.AMQConnection$ MainLoop.run (AMQConnection.java:688) ~[amqp-client-5.25.0.jar:5.25.0] ... 1 common frames omitted 깃허브의 프로젝트를 그대로 가져오고 어떻게 해도 해결이 안되네요ㅠㅠ 도움 부탁드립니다..
retryCount가 전역에서 작동하는것이 좀 수상하네요. 각 메세지의 retryCount를 세어야 할 것 같은데 저렇게 두면 혹시 메세지들이 들어오면 숫자가 마구 이랬다 저랬다 할 가능성은 없나요? 이를테면 메세지 두세개가 들어왔는데 첫번째는 실패 두번째 메세지 실패 세번째 성공 이런 경우 첫번째 메세지가 성공할때까지 sync하게 작동하여 완전 처리될때까지 두번째 메세지는 아예 실행되지 않는것인가요? 아니면 평행하게 동시에 실행되는거라 저 코드가 좀 잘못된 건가요?
안녕하세요, step 4에 fanout 브로드캐스팅으로 구현한 이유가 궁금해서 질문드립니다. 다른 질문을 찾아보니 아래와 같이 답변을 주셨습니다. "정리하면 Fanout은 모든 큐에 메시지를 브로드캐스트하지만 WebSocket을 이용해 특정 뉴스 타입만 선택적으로 구독할 수 있습니다. (서로 독립적으로 동작합니다) 따라서 Pub/Sub의 성격을 이용해서 브로드 캐스트를 하는 것은 Direct나 Topic 보다 Fanout이 적합하고, 전체 브로드캐스트가 필요하지 않은 Pub/Sub의 일부 제한이 필요한 경우는 WebSocket과 STOMP를 통해서 필터링 .. 여기서 저는 왜 step4에서 Pub/Sub의 성격을 이용해서 브로드캐스팅하는지 이해가 안됩니다. 어차피 WebSocket에서 필터링할 것이라면 왜 비효율적으로 브로드캐스팅하는건가요? fanout보다 topic Exchange가 적합하지 않나요? 어차피 브로드캐스팅하고 모든 큐에 넣을 것이라면, javaQueue, vueQueue, springQueue로 구분할 필요가 있나요? pub/sub 모델은 아니지만, 하나의 newQueue로 관리하고 simpMessagingTemplate의 destination을 구분하는 것은 어떤가요?
안녕하세요. 설정 시 String 으로 작성 된게 눈에 걸려서 확인해봤는데, Spring AMQP 2.X 에서는 다른 방법이 있어서 내용 공유 드립니다... 다른 수강생분들도 참고용으로 q&a로 남겼습니다.. 감사합니다... @Bean public Queue orderQueue() { return QueueBuilder.durable(ORDER_COMPLETED_QUEUE) .deadLetterExchange(DLX) // Available since Spring AMQP 2.x .deadLetterRoutingKey(DLQ) // Available since Spring AMQP 2.x // .withArgument("x-dead-letter-exchange", DLX) // Spring AMQP 1.x compatible // .withArgument("x-dead-letter-routing-key", DLQ) // Spring AMQP 1.x compatible .ttl(5000) .build(); }
api gateway 에서 jwt 검증을 해서 분기를 시키는데, 세션-쿠키 방식일때도 api-gateway에서 처리 하나요 ? 만약 세션-쿠키 방식일 때,user-service 에서 인증 처리한다고 하면, order 서비스에서 인증이 필요한 경우, user-service로 http 통신으로 인증을 확인하나요 ?
섹션 19 부분은 예전에 강의하셨을 때 쓰신 스프링부트 2점대 버전을 3점대 버전으로 업그레이드하는 강의인가요? 최신 강의 기준 업데이트 하신 3점대 버전으로 강의를 듣고 있는데 섹션 19에서 강의가 정확히 어떤 강의인지 궁금합니다. 만약 2점대 버전을 3점대 버전으로 업그레이드 하는 강의라면, 섹션 19에서 분산 트레이싱, swagger, kubernates 부분만 들어도 되는걸까요?
안녕하세요. 11:18분쯤 전체 사용자 조회할 때 강의에서 오류가 나지 않아서 여쭈어봅니다.. apigateway 에서는 yml파일을 바라보는 파일이 ecommerce 이고, user-service에서는 user-service yml파일을 바라보고 있는데 두 개의 secret key 값이 다른데 오류가 안나는 게 정상인가요..? 코드 바뀐 부분을 영상에서 말씀을 안해주셔서 매번 이 강의 깃허브랑, yml 파일들이 들어가있는 깃허브를 확인하면서 진행하는데 깃허브 업데이트가 안된건지 .. 궁금합니다.. 제가 임의로 ecommerce secret key값을 application.yml 파일과 동일하게 하니 오류는 해결되었는데.. 강사님 영상 보면서 할 때 오류가 나지 않아야 한다면 제가 잘못 한건지 궁금해요.. https://github.com/joneconsulting/new-toy-msa/blob/ch10-1/apigateway-service/src/main/resources/bootstrap.yml https://github.com/joneconsulting/spring-cloud-config/blob/master/ecommerce.yml
코드를 한줄 한줄 같이 치면서 학습을 하는데요, 강사님께서도 코드 한줄 한줄 같이 치신다고 하셨으나 이번 , 다음 강의에서는 yml, controller, service, vo등 모든 것이 작성이 되어있더라고요. 따로 설명 하는 부분 없이 바로 서버 실행 하시는 거 보고 당황했습니다. 코드를 직접 쳐가면서 학습을 하고 싶은데 그러지 못한거 같아 아쉽고, 어디 까지 깃허브에서 코드를 가져와서 사용해야 하나 궁금합니다.