本文由轉轉王棕生分享,原題“IM系列(一):轉轉IM系統架構探秘”,下文進行了排版和內容優化。
1、引言
轉轉是二手電商平臺,在這個平臺上,人人可以是買家,人人也可以是賣家。轉轉從最初的信息模式升級為一個閉環的交易模式,IM打通了買家與賣家之間的通道。本文描述了轉轉IM為整個平臺提供的支撐能力,給出了系統的整體架構設計,分析了系統架構的特性。
2、系列文章
本文是系列文章中的第1篇,本系列文章的大綱如下:
3、本文作者
王棕生:轉轉架構平臺部高級研發工程師,負責IM系統、推送系統和分布式存儲系統。
4、系統能力定義
轉轉IM需要提供如下的支撐能力:
1)有的用戶習慣使用APP、有的用戶習慣免安裝的小程序;還有的用戶習慣于在“58同城”APP上搜索二手;所以IM需要支持APP、小程序、M端等各種終端類型,以及由轉轉平臺衍生出的其他垂類APP。
2)IM是轉轉平臺中的一個獨立系統,需要向平臺中的其他系統(如客服系統、風控系統)提供“聯系人”和“私信”等IM能力。
3)在轉轉平臺的各種運營活動中,需要借助于IM通道將商品消息、訂單消息、交易消息及活動通知等實時的發送給用戶。
總之:IM為轉轉平臺提供一個可靠和穩定的通道,為用戶與用戶之間、業務系統與用戶之間、平臺與用戶之間打造一個可以即時通訊的環境。
5、系統架構概覽
轉轉IM系統架構設計如下圖所示,自上而下包括四層:用戶層、入口層、邏輯層和原子存儲層。
轉轉IM系統架構設計圖:
6、系統架構之“用戶層”
用戶層是IM服務的調用者,用戶層支撐各類業務應用,包括APP、小程序、M端、平臺運營類業務系統和ZZRPC。
APP基于TCP協議與IM服務端進行消息傳輸,小程序和M端則是通過HTTP協議。
ZZRPC是轉轉平臺使用Java語言自研的RPC框架,而轉轉IM系統是使用C++語言進行研發的,所以IM需要通過適配支持ZZRPC服務的相互調用。
7、系統架構之“入口層”
入口層是IM系統的入口網關,包括:
- 1)Entry
- 2)Http-Entry
- 3)轉轉自研的分布式消息中間件ZZMQ;
- 4)IMUI。
Entry:負責維護與APP之間的TCP連接,把APP發送的業務請求包向后直接轉發到邏輯層進行處理。Entry邏輯較為簡單,不參與具體的業務處理,這樣設計的原因是為了避免Entry因業務改造升級進行模塊重啟,而丟失與APP之間的TCP連接,影響大量用戶。
Http-Entry:是HTTP版的Entry實現,Http-Entry負責維護的是與小程序和M端之間通過HTTP協議模擬的“長連接”。
HTTP“長連接”的實現原理是:小程序發送http_request到Http-Entry,Http-Entry會hold住連接不返回、不釋放;當產生了該用戶的私信數據時或hold住連接超過一定時間(如15秒)時,Http-Entry則返回http_response到小程序;小程序收到http_response時需要立即再次發送http_request到Http-Entry......。
ZZMQ:是轉轉自研的分布式消息隊列,接收平臺各個運營類業務系統生產的系統消息、廣播消息和推送類消息,然后由IM邏輯模塊進行消費處理。ZZMQ解耦了平臺業務系統和IM系統。
IMUI:用于IM系統適配ZZRPC的調用;IMUI作為ZZRPC服務的提供者,接收ZZRPC客戶端的請求后,按照IM系統的內部協議格式同步訪問邏輯層,再將邏輯層的操作結果按ZZRPC協議進行封裝,然后返回到ZZRPC的客戶端。
8、系統架構之“邏輯層”
邏輯層包括Logic和Extlogic兩個模塊組件:
- 1)Logic負責實現IM系統核心的和輕量級的業務邏輯,如用戶登錄、獲取未讀數、發送私信等;
- 2)非核心的和重量級的業務由Extlogic進行實現;
- 3)Logic和Extlogic兩個邏輯模塊通過ZZMQ進行解耦。
例如:在私信邏輯處理流程中,Logic接收私信和用戶在線時的私信推送,而對于離線私信Logic則會通過ZZMQ通知Extlogic進行離線消息的召回邏輯處理。
9、系統架構之“原子存儲層”
IM需要持久化存儲的數據包括私信消息、系統消息和聯系人等。
這些數據通過傳統的關系型數據庫MySQL和NewSQL數據庫TiDB進行保存:
- 1)TiDB是分布式數據庫,具有天然的彈性擴容特性;
- 2)MySQL通過通用的分庫分表策略來應對存儲和查詢負載。
Das接收邏輯層對持久化數據的讀寫請求,將請求放入本地隊列中,然后按順序對數據庫進行同步讀寫操作。
ZZRedis是轉轉自研的分布式緩存系統,負責對用戶的在線信息進行緩存。
Jtransit與IMUI類似,用于適配ZZRPC服務;Jtransit作為ZZRPC服務的調用,接收邏輯層的請求后,按照ZZRPC協議格式訪問平臺其他系統提供的服務,獲取數據后封裝成IM系統的協議數據返回到邏輯層。
10、架構特性1:伸縮性
對轉轉IM系統架構設計,從伸縮性、高可用、可靠性、可擴展性和高性能分別進行分析。
當轉轉并發訪問的用戶量不斷增加,IM系統資源緊張時,需要通過增加機器進行水平彈性擴容,主要是通過服務管理平臺控制中心進行實施的。入口層、邏輯層和原子層服務之間相互調用的關系如下表所示。
Entry和Http-Entry會作為調用方調用Logic的服務,Logic和Extlogic會作為調用方調用Das的服務和Entry與Http-Entry的服務,這些服務之間的關系通過控制中心進行管理。
首先:
- 1)服務方組件與控制中心建立TCP長連接,將服務內容包括本實例ip、端口、服務接口等等注冊到控制中心;
- 2)調用方組件與控制中心建立TCP長連接,從控制中心輪詢服務列表;
- 3)服務方組件增加機器彈性擴容時,新的實例會注冊到控制中心,進而被調用方實時拉取到。
另外:
- 1)App通過域名連接Entry時會首先訪問TGW,由TGW轉發請求到Entry,所以增加Entry實例時需要在TGW進行注冊;
- 2)小程序到Http-Entry的HTTP請求都是由Nginx進行中轉,所以增加Http-Entry機器需要在Nginx上進行配置;
- 3)Extlogic作為ZZMQ的消費者,可以自由增加實例。
存儲層擴容:
- 1)數據庫MySQL通過分庫和分表的方式進行擴容;
- 2)分布式數據庫TiDB以及分布式緩存ZZRedis;
- 3)還有分布式消息隊列ZZMQ自身具有天然的彈性伸縮特性。
11、架構特性2:高可用
1)入口層高可用:入口層Entry和Http-Entry的可用性分別由TGW和Nginx進行探活和遷移。
2)Logic高可用:Logic的可用性由入口層實例進行控制;為了保證同一用戶消息的順序性,Entry和Http-Entry會將同一個用戶的請求通過哈希算法打到相同的Logic實例;若一索引號為x的Logic實例掛掉以后,Entry和Http-Entry會在重試后將請求打到索引號為(x+p)%n的Logic實例上(n為Logic實例數目,p的取值區間為[1,n) );注意p的取值不能固定,否則很容易將瞬時流量打到固定的Logic實例,引起雪崩效應。
3)Extlogic高可用:Extlogic負責消費消息隊列ZZMQ中的消息,掛掉任意一個實例后,不影響業務的正常處理。
4)Das高可用:Das的高可用由Logic和Extlogic進行控制,原理與Logic高可用一致,在掛掉任意一個Das實例后,Logic和Extlogic會將請求打到索引號為(x+p)%n的Das實例上。
5)存儲層高可用:MySQL通過一主兩備模式保證其高可用,在主庫掛掉以后,其中的一個備庫變為主庫繼續對Das提供服務;分布式數據庫TiDB、分布式緩存ZZRedis,分布式消息隊列ZZMQ自身具有天然的高可用特性。
12、架構特性3:可靠性
程序的正確處理保證系統的可靠性,影響IM系統可靠性的因素主要是瞬時高峰導致的邏輯層Logic實例的系統資源被用光和原子層Das對數據庫的訪問超時。
1)Logic可靠性:邏輯層實例的系統資源被用光發生在業務的相互影響;例如瞬時大量用戶登錄IM系統時,Logic大部分或全部線程被調度用于處理用戶登錄業務,而沒有足夠的資源去處理私信等業務。提高Logic可靠性的方案,可以根據微服務思想對Logic按功能職責進行拆分,如拆分成Login_Logic、Msg_Logic、Contact_Logic等。
2)Das可靠性:對數據庫的訪問超時發生在數據庫負載較高時,例如推送千萬級廣播系統消息時,會有大量的更新操作落到數據庫上,此時數據庫響應較慢或超時;因為Das對數據庫的操作是同步的,所以會造成Das內部隊列請求的堆積,其他業務請求也會被堆積而導致超時。提高Das可靠性的方案,可以根據業務類型在Das內部分別創建不同的請求隊列,從而避免業務的相互影響。
13、架構特性4:可擴展性和高性能
1)可擴展性:轉轉IM系統架構的可擴展性體現在邏輯層,邏輯層Logic和Extlogic通過消息隊列ZZMQ進行解耦,定制類的功能需求在Extlogic中進行實現,避免對核心業務Logic的影響。
ZZMQ除了解耦Logic和Extlogic外,還對平臺的業務系統和IM系統進行解耦。
2)高性能:分析IM系統架構,入口層和邏輯層主要是計算模塊,原子存儲層主要是IO模塊,系統的性能瓶頸集中在數據庫端。提升性能方案有:通過增強機器配置、增加機器、研究和新的存儲方式,如用戶聯系人可以通過KList引擎進行存儲。
14、本文小結
轉轉IM為用戶與用戶之間、客服與用戶之間、平臺與用戶之間打造了一個高效和可靠的通訊通道。
按微服務私信和分層模式對IM系統架構進行分布式設計,架構中每個組件模塊的功能職責明確。
具體的功能職責如下:
- 1)Entry負責維護TCP連接;
- 2)Http-Entry負責維護HTTP連接;
- 3)Logic負責處理核心的輕量級業務,Logic要求服務穩定;
- 4)Extlogic負責處理非核心的重量級業務,Extlogic要求服務可擴展;
- 5)Das負責對數據庫進行讀寫訪問;
- 6)IMUI和Jtransit負責對平臺的RPC框架ZZRPC進行適配;
- 7)MySQL、TiDB和ZZRedis負責持久化和緩存數據;
- 8)ZZMQ負責對平臺的業務系統和IM系統,以及Logic和Extlogic之間進行解耦。
轉轉IM的系統架構具有伸縮性、高可用、可靠性、功能擴展性和高性能。
15、參考資料
[1] 淺談IM系統的架構設計
[2] 簡述移動端IM開發的那些坑:架構設計、通信協議和客戶端
[3] 一套海量在線用戶的移動端IM架構設計實踐分享(含詳細圖文)
[4] 一套原創分布式即時通訊(IM)系統理論架構方案
[5] 從零到卓越:京東客服即時通訊系統的技術架構演進歷程
[6] 蘑菇街即時通訊/IM服務器開發之架構選擇
[7] 現代IM系統中聊天消息的同步和存儲方案探討
[8] 一套高可用、易伸縮、高并發的IM群聊、單聊架構方案設計實踐
[9] 馬蜂窩旅游網的IM系統架構演進之路
[10] 瓜子IM智能客服系統的數據架構設計(整理自現場演講,有配套PPT)
[11] 阿里釘釘技術分享:企業級IM王者——釘釘在后端架構上的過人之處
[12] 一套億級用戶的IM架構技術干貨(上篇):整體架構、服務拆分等
[13] 從新手到專家:如何設計一套億級消息量的分布式IM系統
[14] 閑魚億級IM消息系統的架構演進之路
[15] 基于實踐:一套百萬消息量小規模IM系統技術要點總結
[16] 一套十萬級TPS的IM綜合消息系統的架構實踐與思考
[17] vivo直播系統中IM消息模塊的架構實踐
[18] 一套分布式IM即時通訊系統的技術選型和架構設計
[19] 微信團隊分享:來看看微信十年前的IM消息收發架構,你做到了嗎
[20] 攜程技術分享:億級流量的辦公IM及開放平臺技術實踐
(本文已同步發布于:http://www.52im.net/thread-4764-1-1.html)