공유 학습 시스템 메시지 큐 (b)는 왜 우리는 메시지 큐가 필요합니까?

메시지 큐는 가장 오래된 미들웨어 중 하나, 거기에서 시스템 간의 통신을 요구하기 시작했다, 그것은 자연적으로 메시지 큐를 생성합니다. 그러나 메시지 큐에 대한 정확한 정의는 쉽지 않았다. 우리는 메시지 큐의 주요 기능은 메시지를 보내고받을 것을 알고 있지만, 그 역할은 너무 간단한 응용 프로그램 사이의 통신 문제를 해결하지 않는 것입니다.

우리는 메시지 큐의 역할을 설명하는 예를 제공합니다. 초콜릿 워크샵의 Xiaoyuan 보스 있다며 맛 초콜릿을 제조하는 세 가지 단계를 필요 우선 코코아 콩, 코코아 분말, 코코아 분말 후 가열 첨가 설탕 초콜릿 시럽, 초콜릿 시럽 될 마지막 금형에 붓고, 다진 견과류를 뿌려, 냉각 후 초콜릿이 완료됩니다.

각각 코코아 가루의 물통을 갈아 후 처음은, 코코아 노동자들은 초콜렛 주류 처리 노동자 손이 버킷에 전송 한 후 다시 처리 코코아 가루의 배럴에서 올 것이다. 의 Xiaoyuan 곧 사실, 노동자 반제품을 운반하지 않아도 것을 발견, 그래서 컨베이어 벨트에 코코아 가루의 좋은 연삭, 당신은 다음 처리에 갈 수있는 각각의 프로세스 사이 그는 한 컨베이어 벨트, 연마 노동자의 세트를 추가 코코아 가루 배럴. 컨베이어 하류 공정과 "통신"문제를 해결한다.

컨베이어 벨트에 선 후 생산 효율성을 개선하지뿐만 아니라 새로운 문제를 제공합니다 : 각 프로세스는 동일한 생산 속도가 아닙니다. 코코아 가루의 배럴 노동자 코코아 가루의 수에 일하게 될 수도 보냈 초콜릿 가게에서받을 수있는 시간이 없다. 노동자는 반제품의 시간을 배치하는 컨베이어 벨트의 다른 단계를 조정하고 다운 스트림 처리 속도 밟지 경우 컨베이어 벨트에 반제품의 사례는 접수되지 않음을 보장하기 위해 서로 기다려야합니다 업스트림 및 다운 스트림 노동자 사이에 발생한다.

이 문제를 해결하기 위해, 노동자, 세미 제품의 시간이 완성 된 벨트에 던져 질 수있는 사용 가능한 업스트림 다운 스트림 노동자 기다릴 필요가 없습니다 있도록 반제품 창고의 임시 이전을 갖추고 하류 밴드의 Xiaoyuan 각각받을 수 없습니다 물품이 일시적으로 창고에 저장되어있는 노동자는 항상 다운 스트림 취할 수 있습니다. 컨베이어의 "커뮤니케이션"과정 "캐시"의 역할을 사실에 창고를 갖추고 있습니다.

 

교통 문제를 해결하기 반제품 컨베이어 벨트, 다운 스트림 생산 속도의 불일치 문제를 해결하기 위해, 반제품 창고의 번호를 무대 수의 Xiaoyuan는 무의식적으로 메시지 큐의 초콜릿 공장 버전을 구현했습니다.

사용 메시지 큐에 적합한 어떤 문제를 해결하기 위해?

다음으로 우리가 사용하는 메시지 큐 문제를 해결하는 데 적합 매일 개발에 대해 이야기.

1. 비동기식 처리

인터뷰에서 대부분의 프로그래머는, 내가 물었다 또는 고전을 요구하지만, 질문에 대한 표준 응답이하지 말았어야 : 어떻게 스파이크 시스템을 설계하는 방법은? 이 문제는 백 버전에 적절한 대답을 할 수 있지만, 대부분의 답변은 메시지 큐에서 분리 될 수 없다.

스파이크 시스템은 핵심 문제를 해결하기 위해 필요로 대규모 요청의 짧은 시간 처리에 가능한 한 많이, 제한된 서버 리소스를 사용하는 방법입니다. 우리는 스파이크 요청을 처리하는 등의 단계가 많이 포함 된 것을 알고있다 :

  • 위험 관리;
  • 인벤토리 잠금;
  • 주문을 생성;
  • SMS 알림;
  • 업데이트 통계.

어떤 최적화 경우, 정상적인 프로세스 흐름은 다음 차례는이 다섯 개 가지 프로세스를 요구하고, APP에 결과를 반환에서 응용 프로그램은, 게이트웨이에 요청을 보냅니다.

이러한 다섯 단계, 성공적인 스파이크를 결정하는 능력에 대해서는 사실 만 리스크 관리 및 재고은이 두 단계를 잠급니다. 리스크 관리 및 서버에 잠겨 완전한 목록을 통해 사용자의 요청 스파이크, 당신은 요청의 스파이크를 처리하지 않아도 주문, SMS 알림 및 업데이트 통계와 다른 단계를 생성 이후를 들어, 사용자에게 결과를 스파이크 반환 할 수있는 한 완료.

단계 (2)의 선단부가,이 판정 스파이크 요청 결과가 즉시 응답하여 사용자에게 리턴 될 수 있도록 서비스가 완료되면, 요청 된 데이터는 비동기 메시지 큐에 의해 연속 동작을 위해, 메시지 큐에 배치된다.

2 단계뿐만 아니라, 빠른 응답 및 스파이크 동안 5 단계에서 감소 스파이크 요청 처리, 우리는 요청 스파이크를 처리하기 위해 서버 자원의 많은 양을 넣을 수 있습니다. 나중에 처리 단계의 스파이크 자원의 종료 후, 처리 서버 요청 추가 스파이크의 한정된 자원을 최대한 활용.

이 시나리오에서, 메시지 큐는 비동기 처리 서비스를 구현하는 데 사용됩니다, 볼 수 있습니다. 이것의 장점은 다음과 같습니다

  • 빠른 결과를 반환 할 수 있습니다;
  • 전체 시스템 성능을 향상시킬 자연적인 단계들 사이의 동시성을 달성하기 위해, 대기를 감소시킨다.

2. 흐름 제어

계속 우리의 스파이크 시스템, 우리는 비동기 메시지 큐는 몇 가지 작업을 실현 사용하고 있지만, 우리는 문제에 직면하는 방법 너무 많은 요청이 우리의 스파이크 시스템을 압도 피하기 위해?

강력한 프로그램을 설계하는 것은 자신을 보호 할 수있는 능력을 가지고, 즉, 그것은 질량의 요청에 따라해야하지만, 또한 요청을 처리 할 수만큼 자신의 능력에, 요청을 처리하기를 거부하고 자신의 정상적인 작동을 보장 할 수 없습니다. 불행하게도, 현실에서, 많은 프로그램이 그래서 "강력한"가 아니라 직접 사용자 요청에 오류가 반환을 거부하는 것은 매우 좋은 경험이 아니다.

따라서, 우리는 보호 된 백엔드 서비스에 충분히 강력한 아키텍처를 설계 할 필요가있다. 우리의 디자인 아이디어는 메시지의 사용이 차단 게이트웨이와 백엔드 서비스, 백엔드 서비스의 목적을 달성하기 위해 제어 및 보호 흐름 큐입니다.

메시지 대기열을 첨가 한 후, 전체 공정은 스파이크된다 :

  1. 게이트웨이 요청하는 요청 메시지 큐에 상기 요청을 수신 한 후;
  2. 백엔드 서비스 획득 요청 요청 큐 앱에서 메시지, 완벽한 스파이크 이후의 과정, 그리고 결과를 반환합니다.

스파이크는 게이트웨이 짧은 스파이크 요구의 다수의 메시지 큐에서 최대 용량 및 소비에있어서, 백엔드 서비스를 백엔드 스파이크 서비스에 직접적으로 영향을 미치지 않지만, 메시지 큐에 축적 될 때 시작하면 요청을 처리합니다.

타임 아웃 요구가 직접 폐기 될 수있다, APP는 스파이크 치료 실패에 대한 응답이 타임 아웃하지 않는다. 운영 및 유지 보수 인력은 시스템의 나머지 부분을 변경하지 않고, 서비스의 시간 스파이크 수평 확장에 인스턴스의 수를 증가시킬 수있다.

이 디자인의 장점은 다음과 같습니다 : 자동의 "부하 이동"의 역할, 하류의 처리 능력의 흐름을 조정합니다. 그러나이 또한 비용 :

  • 지연이 길어질수록 전체 응답의 결과로, 체인의 시스템 호출 링크를 높입니다.
  • 다운 스트림 시스템은 비동기 메시지의 호출에 동기화해야합니다, 시스템의 복잡성을 증가시킨다.

약간의 트래픽 제어를 할 수있는 더 쉬운 방법이 없다고? 우리는 프로세싱 파워 스파이크 서비스를 추정 할 수 있다면, 당신은 더 쉽게, 메시지 큐와 토큰 버킷을 달성 흐름 제어 할 수 있습니다.

원리 토큰 버킷 트래픽 제어는 다음과 같습니다 만 더 토큰 버킷이없는 경우 토큰 버킷에 토큰의 고정 수, 서비스의 규정은 요청을 처리하기 전에 토큰 버킷을 시작 토큰을 마련해야하는 시간 단위 당 지불 토큰 요청이 거부됩니다. 이 시간 단위가, 교통 제어 역할을 지급 토큰의 수를 초과하지 않는 요청을 처리 할 수 ​​있도록합니다.

 

방법은 매우 간단하고 원래 호출 체인만큼 APP 게이트웨이에게 토큰 로직을 획득하기위한 요청을 처리의 증가를 파괴하지 않는다.

토큰 버킷은 단순히 고정 용량 메시지 큐 플러스 달성하는 "토큰 생성기"를 사용할 수있다 : 상기 추정 된 처리 능력에 따른 토큰 생성 균일 생산 및 토큰이 토큰 큐에 넣어 (큐가 가득 토큰은 토큰이 토큰을 소비하는 게이트웨이 큐에 요청에 따라)을 폐기, 서비스를받을 수있는 토큰은 인수 토큰이 실패 스파이크에 직접 반환보다 작은 경우, 백엔드 스파이크 전화를 계속합니다.

이러한 일반적 흐름 제어 설계 방법 두 가지를 사용하여 메시지 큐에 사용되는, 당신은 합리적으로 각각의 장점과 단점 및 다른 애플리케이션 시나리오에 따라 선택 될 수있다.

3. 서비스 디커플링

消息队列的另外一个作用,就是实现系统应用之间的解耦。再举一个电商的例子来说明解耦的作用和必要性。

我们知道订单是电商系统中比较核心的数据,当一个新订单创建时:

  1. 支付系统需要发起支付流程;
  2. 风控系统需要审核订单的合法性;
  3. 客服系统需要给用户发短信告知用户;
  4. 经营分析系统需要更新统计数据;
  5. ……

这些订单下游的系统都需要实时获得订单数据。随着业务不断发展,这些订单下游系统不断的增加,不断变化,并且每个系统可能只需要订单数据的一个子集,负责订单服务的开发团队不得不花费很大的精力,应对不断增加变化的下游系统,不停地修改调试订单系统与这些下游系统的接口。任何一个下游系统接口变更,都需要订单模块重新进行一次上线,对于一个电商的核心服务来说,这几乎是不可接受的。

所有的电商都选择用消息队列来解决类似的系统耦合过于紧密的问题。引入消息队列后,订单服务在订单变化时发送一条消息到消息队列的一个主题 Order 中,所有下游系统都订阅主题 Order,这样每个下游系统都可以获得一份实时完整的订单数据。

无论增加、减少下游系统或是下游系统需求如何变化,订单服务都无需做任何更改,实现了订单服务与下游服务的解耦。

 

小结

以上就是消息队列最常被使用的三种场景:异步处理、流量控制和服务解耦。当然,消息队列的适用范围不仅仅局限于这些场景,还有包括:

  • 作为发布 / 订阅系统实现一个微服务级系统间的观察者模式;
  • 连接流计算任务和数据;
  • 用于将消息广播给大量接收者。

简单的说,我们在单体应用里面需要用队列解决的问题,在分布式系统中大多都可以用消息队列来解决。

同时我们也要认识到,消息队列也有它自身的一些问题和局限性,包括:

  • 引入消息队列带来的延迟问题;
  • 增加了系统的复杂度;
  • 可能产生数据不一致的问题。

所以我们说没有最好的架构,只有最适合的架构,根据目标业务的特点和自身条件选择合适的架构,才是体现一个架构师功力的地方。

思考题

在你工作或学习涉及到的系统中,哪些问题可以通过引入消息队列来解决?对于系统中已经使用消息队列,可以对应到这一讲中提到的哪个场景?如果没有可以对应的场景,那这个消息队列在系统中起到的是什么作用?解决了什么问题?是否又带来了什么新的问题?欢迎在留言区写下你的想法。

추천

출처www.cnblogs.com/wt645631686/p/11408452.html