過去的十五年,我們怎樣做 IM?

語言: CN / TW / HK

世界變了,即使同樣的場景和需求,在每個時代使用的技術做的事情都可能完全不一樣。

雖然使用者需求越來越高,人力成本越來越高,研發一個行業水準的系統也越來越難。但要不要從頭自建,依然受到很多因素的影響。

閱讀本文,瞭解過去十五年裡,IM 軟體研發走過的三個階段,瞭解系統選型背後的思考,瞭解新一代雲原生 IM。

就在前幾天,飛信要關停了,訊息傳出,很多人感慨說「又一滴時代的眼淚」,言語唏噓。

飛信誕生於 2007 年,迄今已經運營了 15 年。由於出現時恰逢國內網際網路建設初期,網路速率較低且資費昂貴,大部分即時通訊軟體事實上還只能作為半留言式工具,這讓與簡訊結合的飛信在訊息投遞方面的即時性無人能及,順理成章地迎來了爆發式的增長。

只不過這種優勢並沒有保持多久,隨著網路建設和資費下調,紅利很快就開始消退,並最終在移動網際網路崛起後徹底失去了機會。

巧的是,筆者也是從 2007 年開始做 IM,算來也有十五年。因此除了跟其他使用者一樣感慨外,也會有行業從業者的不同角度和觀點。特別是最近幾年一直做 IM 雲服務 ,看過數以萬計的 APP,這種情況也是見怪不怪。

除此之外,其實我還會經常遇到的一個問題是:

IM 不就是聊天嗎,技術發展這麼多年應該成熟了吧,還有什麼可做的呢?

所以今天我們不談產品,來談一個技術問題,我們怎樣實現一個即時通訊系統(IM)。

過去的十五年裡,即時通訊(IM)技術大致經歷了三個階段。

第一階段:軟體和高併發服務

網路剛剛興起的時代,開發一個軟體系統要從買電腦租伺服器機架開始。由於沒有云服務和現成的SDK 技術,工作會往往從開源的協議和軟體開始。

這也是屬於 PC 網際網路的時代,網路雖然不快但相對穩定,擴充套件性和互操作性相對重要,也因此釋出於 2000 年的 XMPP 協議逐漸成為標準。

在這個以研發軟體為主的時期,網際網路使用者開始增長,越來越多的服務開始遇到大量使用者帶來的併發挑戰。後端技術也隨之不斷髮展,從解決 C10K 問題(承載一萬併發)到 C100K、C1000K,與之相關的執行緒池、IO 模型優化等技術成為重點。

為了解決併發連線,大多數伺服器都要確保切換 epoll,因為在 IO 多路複用的問題上,epoll 要比 select 要高效。而當用戶數超過了單機容量,就要進行會話的分片管理,你要用一致性雜湊這樣的技術,確保在部分節點宕機情況下整體服務的可用性。

顯而易見,這個階段軟體複用率很低,每一個需要 IM 的業務基本都要從頭構建自己的系統,都要自行解決這些技術難題,導致開發週期漫長且低效。現在看來簡直如刀耕火種般原始,但當時確實是常態,能夠從開源軟體開始構建已經是高階開發做的事情了。

這種情況一直持續到後來的移動網際網路時期,直到雲的出現。

第二階段:移動網際網路和雲

2009 年中國正式釋出 3G 牌照,標誌著中國進入 3G 時代,而同年蘋果釋出了 iPhone 3GS 手機,開發生態也逐步完善,為隨後到來的移動移動網際網路爆發做好了鋪墊。

3G 網路的成熟,為手機上網提供了便利,也為業務帶來了新的挑戰。因為手機終端的移動特性,導致使用者在網路切換過程中會頻繁斷網重登入,以 XMPP 協議為代表的 IM 系統會因此耗費相當大的網路流量以及電量,而且還會丟失訊息。

這個時期的 IM 系統,重點開始解決在行動網路下訊息可靠投遞的問題,以及省電省流量設計,很多公司開始使用二進位制資料結構來實現自己的協議。

這個問題首先被微信解決了,這就是後來大家經常提的增量同步 XSync 協議。這種設計思想一般說是從郵箱協議啟發而來,比如微軟的 ActiveSYNC,但用在 IM 場景算是一個創新。

除了二進位制包更小有效負荷更高外,比起傳統的 XMPP 協議,開發者還會重點解決兩個問題。

一個是訊息投遞確認機制改為顯式 ACK。即把原來 XMPP 以訊息離開服務端為投遞成功,改為客戶端收到訊息後回覆 ACK,服務端收到 ACK 才認為投遞成功,失敗的投遞會觸發重試,這樣保證了訊息投遞的可靠性。

另一個是離線訊息的儲存與獲取。原來 XMPP 協議有單獨的離線儲存設計,使用者登入後會自動下發,而線上訊息則是直接投遞。前面提到,這兩種情況下都會遇到的是,訊息投遞後如果網路切換或者不穩定,訊息就會丟失。在新的顯式 ACK 設計下,線上投遞和離線投遞合二為一,統一簡化了處理。

也是部分因為這樣的設計,部分因為使用者體驗,移動網際網路後,大家不再強調線上和離線的狀態,而是宣稱永遠線上。畢竟一個進了電梯斷網的使用者,下一秒就會上線,而手機一直帶在身邊,只要聯網訊息就會被取走。線上狀態這個原來 IM 系統裡最大的負擔特性被捨棄了。

說到這裡,你可能會覺得,移動網際網路就是技術棧變了,好像要做的事情比之前還要多,因為協議甚至都沒有現成的開源的方案可以用了。

事實並非如此,因為雲的時代也到了。

大量移動 App 的爆發,帶來了標準化模組化 SDK 的需求,因此為開發者服務的雲服務應運而生。2014 年開始,市場上開始出現即時通訊雲服務,為企業和開發者提供 IM SDK 和API 服務,我們是其中之一。

由於存在大量的機會和競爭,對於每一個移動網際網路企業來講,時間和人才變得更加寶貴。機會稍縱即逝,你要在最短的時間裡跑通業務,便不可能在每個系統中都投入人力,整合 SDK 是最經濟也是最明智的決策。

研發的專業化比如帶來分工分化。因此,也就是從這個時期開始,研發 IM 功能的開發人員產生了分化。

一個群體是普通 App 開發者。他們的工作不再是解決 IM 系統的實現問題,而是開始整合現成的服務,使用標準的 API,將重心放在自己的業務上。

另一個群體是雲服務提供方。他們開始研究客戶端跨平臺(iOS、安卓、Web 等)技術,解決更大規模的分散式系統問題,提供更高可用性的服務。當然在這之前,他們也要首先解決多租戶問題,即大量應用使用同一個雲服務,又有足夠的隔離保證資料不會通不會亂。

隨後對 IM 系統的更大挑戰到來。2015 年,網際網路直播開始流行,萬人群甚至無上限聊天室等極端場景被提了出來,要知道在此之前,一般的群都是千人規模,微信群規模限制更是長期在 500 人左右。

如果要做萬人群,甚至是無上限聊天室,訊息的分發模型必須進行改造。因為每個使用者傳送訊息預設都會被擴散到所有人,因此即使是萬人群,每人發一條訊息,系統就要承載一億條的峰值壓力,更別提百萬人聊天室了。之前有個知乎提問說「把 14 億中國人都拉到一個群裡,技術上能實現嗎」,算是一個很有意思的例子。

因此,服務實現時首先要將分發分批打散,分散到多臺佇列以及處理機上。這其中的每一步,都涉及一個更為基本的操作,即獲取群成員列表,這樣的壓力下使得儲存必須進入記憶體而且要分片才能解決。

客戶端自然也存在群成員展示問題,毫無疑問這個列表也需要分片獲取。然後你會發現,即使伺服器能夠下發成功,一個手機也無法同時處理一萬條訊息。因此,在無上限聊天室場景下,服務端在訊息分發開始就需要區分訊息優先順序並實現訊息丟棄策略。

這個階段是雲服務逐漸滲透的過程,因此我們還是會看到一些企業沒有上雲,這便是第三類開發者。

他們思考了自己的業務,發現業務有相對穩定的使用者數,不會有使用者突然爆發的情況,也沒有極端的群聊需求,但同時,他們出於政策要求或者安全考慮,不放心聊天資料上雲,因此他們還是會從頭構建自己的 IM 系統。如前面所提,這種情況下,一般他們的 TCO 成本會遠高於公有云,因為需要投入額外人力和獨立的伺服器,同時,他們在 IM 系統研發上投入以及服務質量也會跟專業的 IM 雲服務有不少差距。

第三階段:雲原生

在雲服務階段,我們提到了三類開發者。其實在很長時間內,我們作為第二類雲服務開發者,是相信未來大部分服務都是要上雲的,即使不是全部的話。

然而隨著越來越多場景的出現,這個觀點也在逐漸改變。前面說的資料安全要求是一個原因,跟它類似的是網路安全要求。在某些業務裡,IM 聊天要求內網通訊,或在特定專網內,這就使得租用一個公共的雲服務變得不可行。

同時從雲服務的角度看,雲服務模式成立的基礎在於規模效應,即通過統一服務提高資源使用效率,以低於客戶自建服務成本的價格收取租用費,然後通過大量客戶來獲得利潤。也就是說,每一個公有云服務的執行,需要有足夠量的客戶支撐。反之則不然。

也因此我們發現,在某些發展中國家或地區,當移動開發者和企業數量不足的時候,公有云服務實際上無法做到有效覆蓋,使得在這些地區的開發者只能選擇非雲的當地 IDC 和技術服務。

在無法使用公有云服務的場景下,某些有足夠預算的企業可以通過購買雲廠商的私有部署來繼續將自己的開發人員鎖定在一類開發者中。這便是 IM 私有云的場景。

在過去,私有云的交付一直處在兩個極端。系統整合商一般有自己的過時的相對陳舊的 IM 軟體(由於客戶群相同,我們暫且也稱其為私有云)。它們分層抽象不足,效能差,業務靈活性不足,然而他們設計簡單,交付工作量反而可控;與此同時,雲廠商雖然有設計優秀的 SDK 和 API 服務,然而服務卻也因承載大規模高併發而進行了各種拆分,導致私有部署複雜,交付困難,也因此定價昂貴。

這種情況一直持續到雲原生技術的成熟。2015 年,隨著 Kubernetes v1.0 釋出, Cloud Native Computing Foundation(CNCF) 成立,並在隨後幾年逐漸成為容器編排的主流工具。各大雲服務廠商也逐漸開始使用雲原生技術來重構自己的服務,IM 服務也不例外。

藉助於雲原生技術,雲服務廠商可以統一私有云和公有云的技術棧,在私有云或者自建伺服器上進行服務部署不再是一件複雜的事情,交付實施成本得以大幅降低。

當然,要實現雲原生,要解決兩個重要的技術問題,也是技術難題。

首先是多雲架構,也是前面提到的,必須統一公有云私有云介面、技術棧和管理控制檯。做到這一點,不僅需要統一每一層的介面定義,更難的是,IM 系統多叢集技術。在過去的網際網路後端技術裡,多叢集技術,有時候會在異地多活或者單元化設計提到,是多數業務都不會涉及的工程難題。雪上加霜的是,多雲架構下,多叢集進一步被放大成了大量叢集,且叢集之間的網路環境是不穩定的公網鏈路。

但我們也都知道,最優的設計必然來源於對業務的深層理解。我們要實現的是 IM 系統的多叢集,而不是某個通用服務的多叢集。因此這裡首先可以利用的業務特點是訊息投遞的一致性要求。並不是一般網際網路服務的的最終一致性,而是訊息傳送的因果一致性。也就是說,IM 訊息的有序,可以主要限定在某一對通話的人,傳送者的訊息要保證在回覆者的訊息前面顯示即可。

因此要實現作為多叢集資料核心服務的 ID 生成器,我們可以通過預先劃分而不是中心服務的方式進行設計,典型的設計可參照 Snowflake 或 Ticktock,核心思想是將八個位元組的 Long 型整數看成 64 位位元,約定特定位數的意義。這樣就可以保證全系統跨地域生成的時候,ID 唯一且在時間上粗略有序。

第二個問題是自動化安裝部署與 License 控制,在這個基礎上如果有定製需求,再進一步完善版本管理和製品管理,這裡也是用到雲原生技術的地方。

通過容器技術,實現內建服務的持續整合和交付 CI/CD,實際上是製品的版本管理。其次藉助 K8S 等編排工具,將所有服務以及模板整合成一個整體,進而將部署實施的過程變為在目標主機上安裝 K8S 並拉取映象啟動服務。這樣,就可以做到私有云的部署安裝以及配置在極短的時間內完成。

順便提一句, 這個時間在我們實際業務中的基準是十分鐘。 超過了這個數量級的時間一般還是通過擠壓運維操作時間來實現的,但要達到這個時間,有人蔘與的方式是不太可行的。

需要注意的是,這裡面還有個前置條件是配置的服務化,這是很多系統實現時會忽略的地方。只有將配置服務化,所有的配置項可以從一個服務獲取,而不是配置檔案裡讀取,才能更好地支援動態更改與配置,也才能方便的通過編排工具來管理。

所以在這個階段,雲服務廠商將可以同時提供專業設計的 SDK 和低成本的私有云,根據現有的市場定價來看,雲原生 IM 私有云的價格可以將成本降低兩個數量級,即之前價格的百分之一,這樣的價格下,客戶使用 IM 的成本也會極大降低。

也因此根據我們的預測,這個階段將會是第三類開發者,即不上雲而堅持自建 IM 的開發者大量減少的階段。

後記

在本質上,我是相信大多數軟體技術都經歷了類似的發展。只不過由於我個人經驗所限,就以即時通訊(IM)技術為例。如果可以拋磚引玉,對各位所從事業務的軟體開發或服務能有個啟發,也算是一件開心的事。

2011 年,Marc Andreessen 在華爾街日報上發表文章說,軟體正在吞噬世界。過去幾年,雲服務廠商一直想讓客戶在雲和軟體中選擇,傳統軟體廠商則絞盡腦汁勸說客戶不要上雲,兩者你來我往,勢均力敵。

現在到了雲原生時代,雲服務終於又變回軟體,客戶也不再需要在「不上雲」和「好產品」之間猶豫徘徊了,系統整合商和雲服務廠商之間新的競爭和合作模式也開始逐漸形成。

因此,這必將也是一場軟體交付的變革,讓我們拭目以待吧。

關於「藍鶯 IM」

藍鶯IM 是由美信拓撲團隊釋出的新一代雲原生 IM,專業 IM SDK,私有云也可按月付費。未來還會逐步開放這套雲原生框架,成為所有 IM 相關應用的雲原生通訊底座,讓應用直接一步變成雲原生服務,也可以重新變成快速分發和交付軟體。

想了解更多關於藍鶯 IM 或者雲原生服務設計的內容,可以繼續閱讀關於藍鶯 IM 的那些兒事:《 未來在非洲,每兩臺智慧手機就有一臺使用藍鶯IM技術 》。

藍朋友計劃的最新情報

我們正在以藍鶯 IM 開源專案為基礎,打造一個專業的即時通訊技術社群,這便是我們的「藍朋友計劃」。此計劃將會邀請社群技術專家一起,共同分享關於即時通訊(IM)技術相關內容,歡迎持續關注,也歡迎自薦或推薦。

另外,微博關注 @藍鶯 IM,參與文章轉發,有機會獲得「藍鶯 IM 禮盒」哦~

作者介紹

一樂,本名梁宇鵬,藍鶯 IM 創始人,TGO 鯤鵬會(北京)成員。原環信首席架構師、雲通訊事業部總經理,也曾任新浪微博通訊技術專家,負責過微博聊天系統設計與研發,也負責當時微博平臺研發的架構委員會。從開始使用 XMPP 協議,在工作中進行相關開源軟體的研發,包括 C 語言的 Jabberd2、Erlang 的 EJabberd、Java 的 Openfire,到移動網際網路後自己設計通訊協議並實現,已經做了 10 餘年 IM,其中兩款產品服務達到千萬級同時線上。

原文連結: http://docs.lanyingim.com/articles/Industry-development/how-we-build-an-instant-messging-system-in-the-past-fifteen-years.html