Jack Jiang

我的最新工程MobileIMSDK:http://git.oschina.net/jackjiang/MobileIMSDK
posts - 142, comments - 13, trackbacks - 0, articles - 0

置頂隨筆

     摘要: 本文的上篇我們討論了在線實時消息的投遞,如果接收方用戶B不在線,系統是如何保證離線消息的可達性的呢?這就是本文要討論的問題。  閱讀全文

posted @ 2016-11-18 14:39 Jack Jiang 閱讀(2673) | 評論 (0)編輯 收藏

     摘要: 雖然C10K問題已被妥善解決,但對于即時通訊應用(或其它網絡編程方面)的開發者而言,研究C10K問題仍然價值巨大,因為技術的發展都是有規律和線索可循的,了解C10K問題及其解決思路,通過舉一反三,或許可以為你以后面對類似問題提供更多可借鑒的思想和解決問題的實踐思路。而這,也正是撰寫本文的目的所在。  閱讀全文

posted @ 2016-10-21 16:02 Jack Jiang 閱讀(2376) | 評論 (0)編輯 收藏

     摘要: 本文將以新手的視角引導你閱讀相關文章,以便為從零開發一個移動端IM做好方方面面的知識準備:包括但不限于網絡編程基礎、通信協議的選型、IM的架構設計等等。  閱讀全文

posted @ 2016-08-29 17:42 Jack Jiang 閱讀(2923) | 評論 (0)編輯 收藏

     摘要: 本文將簡要介紹TeamTalk開源的過去和現在,為打算研究和采用TeamTalk的同行提供一定程度的參考。  閱讀全文

posted @ 2016-08-09 17:25 Jack Jiang 閱讀(2458) | 評論 (0)編輯 收藏

     摘要: 本文基于作者的實踐以及相關資料的整理,總結了自已對Android進程和Service保活的理解,希望能為你的應用開發帶來啟發。  閱讀全文

posted @ 2016-08-02 22:43 Jack Jiang 閱讀(2174) | 評論 (0)編輯 收藏

     摘要: 本文將介紹如何在現有的技術基礎上選擇合適的方案開發一個“服務器推”(Comet技術)的應用,最優的方案還是取決于應用需求的本身。相對于傳統的 Web 應用, 開發 Comet 應用具有一定的挑戰性。  閱讀全文

posted @ 2016-07-28 11:07 Jack Jiang 閱讀(1318) | 評論 (0)編輯 收藏

     摘要: 本文對服務器推送技術(SSE)進行了詳細的介紹,包含瀏覽器端和服務器端的相應實現細節,為在實踐中使用該技術提供了指南  閱讀全文

posted @ 2016-07-22 18:03 Jack Jiang 閱讀(972) | 評論 (0)編輯 收藏

     摘要: Web端即時通訊技術因受限于瀏覽器的設計限制,一直以來實現起來并不容易,主流的Web端即時通訊方案大致有4種:傳統Ajax短輪詢、Comet技術、WebSocket技術、SSE(Server-sent Events)。本文將簡要介紹這4種技術的原理,并指出各自的異同點、優缺點等。  閱讀全文

posted @ 2016-07-15 15:08 Jack Jiang 閱讀(1487) | 評論 (2)編輯 收藏

     摘要: Web端的IM應用,由于瀏覽器的兼容性以及其固有的“客戶端請求服務器處理并響應”的通信模型,造成了要在瀏覽器中實現一個兼容性較好的IM應用,其通信過程必然是諸多技術的組合,本文的目的就是要詳細探討這些技術并分析其原理和過程。   閱讀全文

posted @ 2016-07-12 15:59 Jack Jiang 閱讀(5179) | 評論 (0)編輯 收藏

     摘要: 文演示的是一個Android客戶端程序,通過UDP協議與兩個典型的NIO框架服務端(分別用MINA2和Netty4來實現),實現跨平臺雙向通信的完整Demo。  閱讀全文

posted @ 2016-06-30 16:57 Jack Jiang 閱讀(558) | 評論 (0)編輯 收藏

     摘要: 本文將演示一個iOS客戶端程序,通過UDP協議與兩個典型的NIO框架服務端(將分別用MINA2和Netty4來實現),實現跨平臺雙向通信的完整Demo。  閱讀全文

posted @ 2016-06-28 22:11 Jack Jiang 閱讀(1152) | 評論 (0)編輯 收藏

     摘要: 本文是《NIO框架入門》系列文章中的第2篇,將演示的是一個基于MINA2的UDP服務端和一個標準UDP客戶端(Java實現)雙向通信的完整例子。  閱讀全文

posted @ 2016-06-24 14:38 Jack Jiang 閱讀(537) | 評論 (0)編輯 收藏

     摘要: 本文將演示的是一個基于Netty4的UDP服務端和一個標準UDP客戶端(Java實現)雙向通信的完整例子。實際上,Netty4的UDP例子非常難找,官方的代碼演示里只有一個簡單的UDP廣播例子,不足以用于演示Netty4的UDP通信最佳實踐。  閱讀全文

posted @ 2016-06-20 14:48 Jack Jiang 閱讀(1124) | 評論 (0)編輯 收藏

     摘要: MobileIMSDK是一套專為移動端開發的原創即時通訊框架:超輕量級、高度提煉,lib包50KB以內;完全基于UDP協議實現;客戶端支持iOS、Android、標準Java平臺;可應用于跨設備、跨網絡的聊天APP、企業OA、消息推送等各種場景。  閱讀全文

posted @ 2015-12-14 15:18 Jack Jiang 閱讀(2573) | 評論 (0)編輯 收藏

     摘要: MobileIMSDK是專為移動端開發的原創即時通訊開源框架:超輕量級、高度提煉,lib包50KB以內;完全基于UDP協議實現;客戶端支持iOS、Android、標準Java平臺;可應用于跨設備、跨網絡的聊天APP、企業OA、消息推送等各種場景。  閱讀全文

posted @ 2015-12-01 16:06 Jack Jiang 閱讀(3053) | 評論 (2)編輯 收藏

2019年9月19日

     摘要: 本文來自融云技術團隊原創分享,原文發布于“融云全球互聯網通信云”公眾號,原題《如何實現分布式場景下唯一 ID 生成?》,即時通訊網收錄時有部分改動。1、引言對于IM應用來說,消息ID(或稱序列號)是個看似不起眼,但非常重要的東西之一。消息ID的使用貫穿了IM技術邏輯的方方面面,比如:1)聊天消息的順序保證;2)聊天消息QoS送達保證機制時的去重;3)特定聊天消息的精確查找和...  閱讀全文

posted @ 2019-09-19 17:40 Jack Jiang 閱讀(6) | 評論 (0)編輯 收藏

2019年9月17日

     摘要: 本文來自融云技術團隊原創分享,原文發布于“ 融云全球互聯網通信云”公眾號,原題《IM 即時通訊之鏈路保活》,即時通訊網收錄時有部分改動。1、引言眾所周知,IM 即時通訊是一項對即時性要求非常高的技術,而保障消息即時到達的首要條件就是鏈路存活。那么在復雜的網絡環境和國內安卓手機被深度定制化的條件下,如何保障鏈路存活呢?本文詳解了融云安卓端IM產品在基于 TCP 協議實現鏈路保...  閱讀全文

posted @ 2019-09-17 11:15 Jack Jiang 閱讀(14) | 評論 (0)編輯 收藏

2019年9月9日

     摘要: 本文原作者:selfboot,博客地址:selfboot.cn,Github地址:github.com/selfboot,感謝原作者的技術分享。1、引言對于 DNS(Domain Name System) 大家肯定不陌生,不就是用來將一個網站的域名轉換為對應的IP嗎。當我們發現可以上QQ但不能瀏覽網頁時,我們會想到可能是域名服務器掛掉了;當我們用別人提供的hosts文件瀏覽到一...  閱讀全文

posted @ 2019-09-09 15:41 Jack Jiang 閱讀(23) | 評論 (0)編輯 收藏

2019年9月5日

本文來自知乎官方技術團隊的“知乎技術專欄”,感謝原作者faceair的無私分享。

1、引言

實時的響應總是讓人興奮的,就如你在微信里看到對方正在輸入,如你在王者峽谷里一呼百應,如你們在直播彈幕里不約而同的 666,它們的背后都離不開長連接技術的加持。

每個互聯網公司里幾乎都有一套長連接系統,它們被應用在消息提醒、即時通訊、推送、直播彈幕、游戲、共享定位、股票行情等等場景。而當公司發展到一定規模,業務場景變得更復雜后,更有可能是多個業務都需要同時使用長連接系統。

業務間分開設計長連接會導致研發和維護成本陡增、浪費基礎設施、增加客戶端耗電、無法復用已有經驗等等問題。共享長連接系統又需要協調好不同系統間的認證、鑒權、數據隔離、協議拓展、消息送達保證等等需求,迭代過程中協議需要向前兼容,同時因為不同業務的長連接匯聚到一個系統導致容量管理的難度也會增大。

經過了一年多的開發和演進,經過我們服務面向內和外的數個 App、接入十幾個需求和形態各異的長連接業務、數百萬設備同時在線、突發大規模消息發送等等場景的錘煉,我們提煉出一個長連接系統網關的通用解決方案,解決了多業務共用長連接時遇到的種種問題。

知乎長連接網關致力于業務數據解耦、消息高效分發、解決容量問題,同時提供一定程度的消息可靠性保證。

(本文同步發布于:http://www.52im.net/thread-2737-1-1.html

2、相關文章

3、我們怎么設計通訊協議?

3.1 業務解耦

支撐多業務的長連接網關實際上是同時對接多客戶端和多業務后端的,是多對多的關系,他們之間只使用一條長連接通訊。

 

這種多對多的系統在設計時要避免強耦合。業務方邏輯也是會動態調整的,如果將業務的協議和邏輯與網關實現耦合會導致所有的業務都會互相牽連,協議升級和維護都會異常困難。

所以我們嘗試使用經典的發布訂閱模型來解耦長連接網關跟客戶端與業務后端,它們之間只需要約定 Topic 即可自由互相發布訂閱消息。傳輸的消息是純二進制數據,網關也無需關心業務方的具體協議規范和序列化方式。



3.2 權限控制

我們使用發布訂閱解耦了網關與業務方的實現,我們仍然需要控制客戶端對 Topic 的發布訂閱的權限,避免有意或無意的數據污染或越權訪問。

假如講師正在知乎 Live 的 165218 頻道開講,當客戶端進入房間嘗試訂閱 165218 頻道的 Topic 時就需要知乎 Live 的后端判斷當前用戶是否已經付費。這種情況下的權限實際上是很靈活的,當用戶付費以后就能訂閱,否則就不能訂閱。權限的狀態只有知乎 Live 業務后端知曉,網關無法獨立作出判斷。

所以我們在 ACL 規則中設計了基于回調的鑒權機制,可以配置 Live 相關 Topic 的訂閱和發布動作都通過 HTTP 回調給 Live 的后端服務判斷。



同時根據我們對內部業務的觀察,大部分場景下業務需要的只是一個當前用戶的私有 Topic 用來接收服務端下發的通知或消息,這種情況下如果讓業務都設計回調接口來判斷權限會很繁瑣。

所以我們在 ACL 規則中設計了 Topic 模板變量來降低業務方的接入成本,我們給業務方配置允許訂閱的 Topic 中包含連接的用戶名變量標識,表示只允許用戶訂閱或發送消息到自己的 Topic。



此時網關可以在不跟業務方通信的情況下,獨立快速判斷客戶端是否有權限訂閱或往 Topic 發送消息。

3.3 消息可靠性保證


網關作為消息傳輸的樞紐,同時對接業務后端和客戶端,在轉發消息時需要保證消息在傳輸過程的可靠性。

TCP 只能保證了傳輸過程中的順序和可靠性,但遇到 TCP 狀態異常、客戶端接收邏輯異常或發生了 Crash 等等情況時,傳輸中的消息就會發生丟失。

為了保證下發或上行的消息被對端正常處理,我們實現了回執和重傳的功能。重要業務的消息在客戶端收到并正確處理后需要發送回執,而網關內暫時保存客戶端未收取的消息,網關會判斷客戶端的接收情況并嘗試再次發送,直到正確收到了客戶端的消息回執。



而面對服務端業務的大流量場景,服務端發給網關的每條消息都發送回執的方式效率較低,我們也提供了基于消息隊列的接收和發送方式,后面介紹發布訂閱實現時再詳細闡述。

在設計通訊協議時我們參考了 MQTT 規范(詳見《掃盲貼:認識MQTT通信協議》),拓展了認證和鑒權設計,完成了業務消息的隔離與解耦,保證了一定程度的傳輸可靠性。同時保持了與 MQTT 協議一定程度上兼容,這樣便于我們直接使用 MQTT 的各端客戶端實現,降低業務方接入成本。

4、我們怎么設計系統架構?

在設計項目整體架構時,我們優先考慮的是:

  • 1)可靠性;
  • 2)水平擴展能力;
  • 3)依賴組件成熟度;
  • 4)簡單才值得信賴。


為了保證可靠性,我們沒有考慮像傳統長連接系統那樣將內部數據存儲、計算、消息路由等等組件全部集中到一個大的分布式系統中維護,這樣增大系統實現和維護的復雜度。我們嘗試將這幾部分的組件獨立出來,將存儲、消息路由交給專業的系統完成,讓每個組件的功能盡量單一且清晰。

同時我們也需要快速地水平擴展能力。互聯網場景下各種營銷活動都可能導致連接數陡增,同時發布訂閱模型系統中下發消息數會隨著 Topic 的訂閱者的個數線性增長,此時網關暫存的客戶端未接收消息的存儲壓力也倍增。將各個組件拆開后減少了進程內部狀態,我們就可以將服務部署到容器中,利用容器來完成快速而且幾乎無限制的水平擴展。

最終設計的系統架構如下圖:
 

系統主要由四個主要組件組成:

  • 1)接入層使用 OpenResty 實現,負責連接負載均衡和會話保持;
  • 2)長連接 Broker,部署在容器中,負責協議解析、認證與鑒權、會話、發布訂閱等邏輯;
  • 3)Redis 存儲,持久化會話數據;
  • 4)Kafka 消息隊列,分發消息給 Broker 或業務方。


其中 Kafka 和 Redis 都是業界廣泛使用的基礎組件,它們在知乎都已平臺化和容器化 (詳見:《Redis at Zhihu》、《知乎基于 Kubernetes 的 Kafka 平臺的設計和實現》),它們也都能完成分鐘級快速擴容。

5、我們如何構建長連接網關?

5.1 接入層

OpenResty 是業界使用非常廣泛的支持 Lua 的 Nginx 拓展方案,靈活性、穩定性和性能都非常優異,我們在接入層的方案選型上也考慮使用 OpenResty。

接入層是最靠近用戶的一側,在這一層需要完成兩件事:

  • 1)負載均衡,保證各長連接 Broker 實例上連接數相對均衡;
  • 2)會話保持,單個客戶端每次連接到同一個 Broker,用來提供消息傳輸可靠性保證。


負載均衡其實有很多算法都能完成,不管是隨機還是各種 Hash 算法都能比較好地實現,麻煩一些的是會話保持。

常見的四層負載均衡策略是根據連接來源 IP 進行一致性 Hash,在節點數不變的情況下這樣能保證每次都 Hash 到同一個 Broker 中,甚至在節點數稍微改變時也能大概率找到之前連接的節點。

之前我們也使用過來源 IP Hash 的策略,主要有兩個缺點:

  • 1)分布不夠均勻,部分來源 IP 是大型局域網 NAT 出口,上面的連接數多,導致 Broker 上連接數不均衡;
  • 2)不能準確標識客戶端,當移動客戶端掉線切換網絡就可能無法連接回剛才的 Broker 了。


所以我們考慮七層的負載均衡,根據客戶端的唯一標識來進行一致性 Hash,這樣隨機性更好,同時也能保證在網絡切換后也能正確路由。常規的方法是需要完整解析通訊協議,然后按協議的包進行轉發,這樣實現的成本很高,而且增加了協議解析出錯的風險。

最后我們選擇利用 Nginx 的 preread 機制實現七層負載均衡,對后面長連接 Broker 的實現的侵入性小,而且接入層的資源開銷也小。

Nginx 在接受連接時可以指定預讀取連接的數據到 preread buffer 中,我們通過解析 preread buffer 中的客戶端發送的第一個報文提取客戶端標識,再使用這個客戶端標識進行一致性 Hash 就拿到了固定的 Broker。

5.2 發布與訂閱

我們引入了業界廣泛使用的消息隊列 Kafka 來作為內部消息傳輸的樞紐。

前面提到了一些這么使用的原因:

  • 1)減少長連接 Broker 內部狀態,讓 Broker 可以無壓力擴容;
  • 2)知乎內部已平臺化,支持水平擴展。


還有一些原因是:

  • 1)使用消息隊列削峰,避免突發性的上行或下行消息壓垮系統;
  • 2)業務系統中大量使用 Kafka 傳輸數據,降低與業務方對接成本。


其中利用消息隊列削峰好理解,下面我們看一下怎么利用 Kafka 與業務方更好地完成對接。

5.3 發布

連接 Broker 會根據路由配置將消息發布到 Kafka Topic,同時也會根據訂閱配置去消費 Kafka 將消息下發給訂閱客戶端。

路由規則和訂閱規則是分別配置的,那么可能會出現四種情況。

情況一:消息路由到 Kafka Topic,但不消費,適合數據上報的場景,如下圖所示。



情況二:消息路由到 Kafka Topic,也被消費,普通的即時通訊場景,如下圖所示。



情況三:直接從 Kafka Topic 消費并下發,用于純下發消息的場景,如下圖所示。



情況四:消息路由到一個 Topic,然后從另一個 Topic 消費,用于消息需要過濾或者預處理的場景,如下圖所示。



這套路由策略的設計靈活性非常高,可以解決幾乎所有的場景的消息路由需求。同時因為發布訂閱基于 Kafka,可以保證在處理大規模數據時的消息可靠性。

5.4 訂閱

當長連接 Broker 從 Kafka Topic 中消費出消息后會查找本地的訂閱關系,然后將消息分發到客戶端會話。

我們最開始直接使用 HashMap 存儲客戶端的訂閱關系。當客戶端訂閱一個 Topic 時我們就將客戶端的會話對象放入以 Topic 為 Key 的訂閱 Map 中,當反查消息的訂閱關系時直接用 Topic 從 Map 上取值就行。

因為這個訂閱關系是共享對象,當訂閱和取消訂閱發生時就會有連接嘗試操作這個共享對象。為了避免并發寫我們給 HashMap 加了鎖,但這個全局鎖的沖突非常嚴重,嚴重影響性能。

最終我們通過分片細化了鎖的粒度,分散了鎖的沖突。

本地同時創建數百個 HashMap,當需要在某個 Key 上存取數據前通過 Hash 和取模找到其中一個 HashMap 然后進行操作,這樣將全局鎖分散到了數百個 HashMap 中,大大降低了操作沖突,也提升了整體的性能。

5.5 會話持久化

當消息被分發給會話 Session 對象后,由 Session 來控制消息的下發。

Session 會判斷消息是否是重要 Topic 消息, 是的話將消息標記 QoS 等級為 1,同時將消息存儲到 Redis 的未接收消息隊列,并將消息下發給客戶端。等到客戶端對消息的 ACK 后,再將未確認隊列中的消息刪除。

有一些業界方案是在內存中維護了一個列表,在擴容或縮容時這部分數據沒法跟著遷移。也有部分業界方案是在長連接集群中維護了一個分布式內存存儲,這樣實現起來復雜度也會變高。

我們將未確認消息隊列放到了外部持久化存儲中,保證了單個 Broker 宕機后,客戶端重新上線連接到其他 Broker 也能恢復 Session 數據,減少了擴容和縮容的負擔。

5.6 滑動窗口

在發送消息時,每條 QoS 1 的消息需要被經過傳輸、客戶端處理、回傳 ACK 才能確認下發完成,路徑耗時較長。如果消息量較大,每條消息都等待這么長的確認才能下發下一條,下發通道帶寬不能被充分利用。

為了保證發送的效率,我們參考 TCP 的滑動窗口設計了并行發送的機制(詳見:《通俗易懂-深入理解TCP協議(下):RTT、滑動窗口、擁塞處理》)。我們設置一定的閾值為發送的滑動窗口,表示通道上可以同時有這么多條消息正在傳輸和被等待確認。



我們應用層設計的滑動窗口跟 TCP 的滑動窗口實際上還有些差異。

TCP 的滑動窗口內的 IP 報文無法保證順序到達,而我們的通訊是基于 TCP 的所以我們的滑動窗口內的業務消息是順序的,只有在連接狀態異常、客戶端邏輯異常等情況下才可能導致部分窗口內的消息亂序。

因為 TCP 協議保證了消息的接收順序,所以正常的發送過程中不需要針對單條消息進行重試,只有在客戶端重新連接后才對窗口內的未確認消息重新發送。消息的接收端同時會保留窗口大小的緩沖區用來消息去重,保證業務方接收到的消息不會重復。

我們基于 TCP 構建的滑動窗口保證了消息的順序性同時也極大提升傳輸的吞吐量。

6、寫在最后

知乎長連接網關由基礎架構組 (Infra) 開發和維護,主要貢獻者是@faceair@安江澤 。

基礎架構組負責知乎的流量入口和內部基礎設施建設,對外我們奮斗在直面海量流量的的第一戰線,對內我們為所有的業務提供堅如磐石的基礎設施,用戶的每一次訪問、每一個請求、內網的每一次調用都與我們的系統息息相關。

附錄:更多網絡編程相關資料

[1] 網絡編程基礎資料:
TCP/IP詳解 - 第11章·UDP:用戶數據報協議
TCP/IP詳解 - 第17章·TCP:傳輸控制協議
TCP/IP詳解 - 第18章·TCP連接的建立與終止
TCP/IP詳解 - 第21章·TCP的超時與重傳
技術往事:改變世界的TCP/IP協議(珍貴多圖、手機慎點)
通俗易懂-深入理解TCP協議(上):理論基礎
通俗易懂-深入理解TCP協議(下):RTT、滑動窗口、擁塞處理
理論經典:TCP協議的3次握手與4次揮手過程詳解
理論聯系實際:Wireshark抓包分析TCP 3次握手、4次揮手過程
計算機網絡通訊協議關系圖(中文珍藏版)
UDP中一個包的大小最大能多大?
P2P技術詳解(一):NAT詳解——詳細原理、P2P簡介
P2P技術詳解(二):P2P中的NAT穿越(打洞)方案詳解
P2P技術詳解(三):P2P技術之STUN、TURN、ICE詳解
通俗易懂:快速理解P2P技術中的NAT穿透原理
高性能網絡編程(一):單臺服務器并發TCP連接數到底可以有多少
高性能網絡編程(二):上一個10年,著名的C10K并發連接問題
高性能網絡編程(三):下一個10年,是時候考慮C10M并發問題了
高性能網絡編程(四):從C10K到C10M高性能網絡應用的理論探索
高性能網絡編程(五):一文讀懂高性能網絡編程中的I/O模型
高性能網絡編程(六):一文讀懂高性能網絡編程中的線程模型
不為人知的網絡編程(一):淺析TCP協議中的疑難雜癥(上篇)
不為人知的網絡編程(二):淺析TCP協議中的疑難雜癥(下篇)
不為人知的網絡編程(三):關閉TCP連接時為什么會TIME_WAIT、CLOSE_WAIT
不為人知的網絡編程(四):深入研究分析TCP的異常關閉
不為人知的網絡編程(五):UDP的連接性和負載均衡
不為人知的網絡編程(六):深入地理解UDP協議并用好它
不為人知的網絡編程(七):如何讓不可靠的UDP變的可靠?
不為人知的網絡編程(八):從數據傳輸層深度解密HTTP
網絡編程懶人入門(一):快速理解網絡通信協議(上篇)
網絡編程懶人入門(二):快速理解網絡通信協議(下篇)
網絡編程懶人入門(三):快速理解TCP協議一篇就夠
網絡編程懶人入門(四):快速理解TCP和UDP的差異
網絡編程懶人入門(五):快速理解為什么說UDP有時比TCP更有優勢
網絡編程懶人入門(六):史上最通俗的集線器、交換機、路由器功能原理入門
網絡編程懶人入門(七):深入淺出,全面理解HTTP協議
網絡編程懶人入門(八):手把手教你寫基于TCP的Socket長連接
網絡編程懶人入門(九):通俗講解,有了IP地址,為何還要用MAC地址?
技術掃盲:新一代基于UDP的低延時網絡傳輸層協議——QUIC詳解
讓互聯網更快:新一代QUIC協議在騰訊的技術實踐分享
現代移動端網絡短連接的優化手段總結:請求速度、弱網適應、安全保障
聊聊iOS中網絡編程長連接的那些事
移動端IM開發者必讀(一):通俗易懂,理解移動網絡的“弱”和“慢”
移動端IM開發者必讀(二):史上最全移動弱網絡優化方法總結
IPv6技術詳解:基本概念、應用現狀、技術實踐(上篇)
IPv6技術詳解:基本概念、應用現狀、技術實踐(下篇)
從HTTP/0.9到HTTP/2:一文讀懂HTTP協議的歷史演變和設計思路
腦殘式網絡編程入門(一):跟著動畫來學TCP三次握手和四次揮手
腦殘式網絡編程入門(二):我們在讀寫Socket時,究竟在讀寫什么?
腦殘式網絡編程入門(三):HTTP協議必知必會的一些知識
腦殘式網絡編程入門(四):快速理解HTTP/2的服務器推送(Server Push)
腦殘式網絡編程入門(五):每天都在用的Ping命令,它到底是什么?
腦殘式網絡編程入門(六):什么是公網IP和內網IP?NAT轉換又是什么鬼?
以網游服務端的網絡接入層設計為例,理解實時通信的技術挑戰
邁向高階:優秀Android程序員必知必會的網絡基礎
全面了解移動端DNS域名劫持等雜癥:技術原理、問題根源、解決方案等
美圖App的移動端DNS優化實踐:HTTPS請求耗時減小近半
Android程序員必知必會的網絡通信傳輸層協議——UDP和TCP
IM開發者的零基礎通信技術入門(一):通信交換技術的百年發展史(上)
IM開發者的零基礎通信技術入門(二):通信交換技術的百年發展史(下)
IM開發者的零基礎通信技術入門(三):國人通信方式的百年變遷
IM開發者的零基礎通信技術入門(四):手機的演進,史上最全移動終端發展史
IM開發者的零基礎通信技術入門(五):1G到5G,30年移動通信技術演進史
IM開發者的零基礎通信技術入門(六):移動終端的接頭人——“基站”技術
IM開發者的零基礎通信技術入門(七):移動終端的千里馬——“電磁波”
IM開發者的零基礎通信技術入門(八):零基礎,史上最強“天線”原理掃盲
IM開發者的零基礎通信技術入門(九):無線通信網絡的中樞——“核心網”
IM開發者的零基礎通信技術入門(十):零基礎,史上最強5G技術掃盲
IM開發者的零基礎通信技術入門(十一):為什么WiFi信號差?一文即懂!
IM開發者的零基礎通信技術入門(十二):上網卡頓?網絡掉線?一文即懂!
IM開發者的零基礎通信技術入門(十三):為什么手機信號差?一文即懂!
IM開發者的零基礎通信技術入門(十四):高鐵上無線上網有多難?一文即懂!
IM開發者的零基礎通信技術入門(十五):理解定位技術,一篇就夠
百度APP移動端網絡深度優化實踐分享(一):DNS優化篇
百度APP移動端網絡深度優化實踐分享(二):網絡連接優化篇
百度APP移動端網絡深度優化實踐分享(三):移動端弱網優化篇
技術大牛陳碩的分享:由淺入深,網絡編程學習經驗干貨總結
可能會搞砸你的面試:你知道一個TCP連接上能發起多少個HTTP請求嗎?
知乎技術分享:知乎千萬級并發的高性能長連接網關技術實踐
>> 更多同類文章 ……

[2] NIO異步網絡編程資料:
Java新一代網絡編程模型AIO原理及Linux系統AIO介紹
有關“為何選擇Netty”的11個疑問及解答
開源NIO框架八卦——到底是先有MINA還是先有Netty?
選Netty還是Mina:深入研究與對比(一)
選Netty還是Mina:深入研究與對比(二)
NIO框架入門(一):服務端基于Netty4的UDP雙向通信Demo演示
NIO框架入門(二):服務端基于MINA2的UDP雙向通信Demo演示
NIO框架入門(三):iOS與MINA2、Netty4的跨平臺UDP雙向通信實戰
NIO框架入門(四):Android與MINA2、Netty4的跨平臺UDP雙向通信實戰
Netty 4.x學習(一):ByteBuf詳解
Netty 4.x學習(二):Channel和Pipeline詳解
Netty 4.x學習(三):線程模型詳解
Apache Mina框架高級篇(一):IoFilter詳解
Apache Mina框架高級篇(二):IoHandler詳解
MINA2 線程原理總結(含簡單測試實例)
Apache MINA2.0 開發指南(中文版)[附件下載]
MINA、Netty的源代碼(在線閱讀版)已整理發布
解決MINA數據傳輸中TCP的粘包、缺包問題(有源碼)
解決Mina中多個同類型Filter實例共存的問題
實踐總結:Netty3.x升級Netty4.x遇到的那些坑(線程篇)
實踐總結:Netty3.x VS Netty4.x的線程模型
詳解Netty的安全性:原理介紹、代碼演示(上篇)
詳解Netty的安全性:原理介紹、代碼演示(下篇)
詳解Netty的優雅退出機制和原理
NIO框架詳解:Netty的高性能之道
Twitter:如何使用Netty 4來減少JVM的GC開銷(譯文)
絕對干貨:基于Netty實現海量接入的推送服務技術要點
Netty干貨分享:京東京麥的生產級TCP網關技術實踐總結
新手入門:目前為止最透徹的的Netty高性能原理和框架架構解析
寫給初學者:Java高性能NIO框架Netty的學習方法和進階策略
少啰嗦!一分鐘帶你讀懂Java的NIO和經典IO的區別
史上最強Java NIO入門:擔心從入門到放棄的,請讀這篇!
手把手教你用Netty實現網絡通信程序的心跳機制、斷線重連機制
>> 更多同類文章 …

(本文同步發布于:http://www.52im.net/thread-2737-1-1.html

posted @ 2019-09-05 12:04 Jack Jiang 閱讀(17) | 評論 (0)編輯 收藏

2019年9月2日

     摘要: 本文原作者: Wizey,作者博客:http://wenshixin.gitee.io,即時通訊網收錄時有改動,感謝原作者的無私分享。1、引言典型的Web端即時通訊技術應用場景,主要有以下兩種形式:1)作為完整的即時通訊產品進行應用:比如獨立的Web端IM產品;2)作為某個更大系統中的一部分進行應用:比如客服系統(相當于工單系統里嵌入IM技術啦)。對于第一種場景,為了更好的劃分功能邏輯,一個完整的...  閱讀全文

posted @ 2019-09-02 15:40 Jack Jiang 閱讀(121) | 評論 (0)編輯 收藏

2019年8月22日

     摘要: 本文原文由作者“司徒正美”發布于公眾號“前端你別鬧”,即時通訊網收錄時有改動,感謝原作者的分享。1、引言1990 年,第一個Web瀏覽器的誕生;1991 年,WWW誕生,這標志著前端技術的開始。在這將近20年的前端發展史中,我們經歷了從最早的純靜態頁面,到JavaScript跨時代的誕生;從PC端到移動端;從依賴后端到前端可自由打包開發;從早期的網景...  閱讀全文

posted @ 2019-08-22 18:05 Jack Jiang 閱讀(40) | 評論 (0)編輯 收藏

2019年8月14日

本文來自網易云信團隊的技術分享,原創發表于網易云信公眾號,原文鏈接:mp.weixin.qq.com/s/LT2dASI7QVpcOVxDAsMeVg,收錄時有改動。

1、引言

在不了解IM技術的人眼里,群聊是再平常不過的功能而已,萬人群聊?應該也不難實現吧?!

確實,從前端功能界面上來看,群聊無非就是個循環向群員發送消息的一對多聊天消息分發模式而已,難在何處?

真實的情況是,群聊是IM系統中的高難度技術點之一。難在哪?難在服務端!從某種角度上說,群聊功能的架構設計和技術實現的品質,可以代表這款IM軟件的技術水平。

群聊從后臺的技術實現上說,至少有以下難點:

1)如何高效地進行大量群員消息的分發?

2)如何高效地管理群員的在線狀態?

3)如何高效地讀取群員的在線狀態?

4)集群系統中,如何高效地保證群員消息的準確送達?

5)群聊消息該擴散寫還是擴散讀?

6)如何保證大量群聊消息分發的情況下不影響單聊消息體驗?

7)如何應對大群突發事件下的性能負載?

.... ....

目前,市面上主流的IM產品中,微信群是500人上限,QQ群是3000人上限(3000人群是按年付費升級,很貴,不是為一般用戶準備的)。一方面,從產品的定義上群成員數量不應過多,另一方面,技術成本也是個不可回避的因素。萬人群這種超大規模群的技術難度,更是難已想象。

本文內容是網易云信團隊為了響應萬人群聊功能需求,在設計實現萬人群聊技術方案中總結的技術實踐,借此機會分享給各IM開發者同行。

(本文同步發布于:http://www.52im.net/thread-2707-1-1.html

學習交流:

- 即時通訊/推送技術開發交流5群:215477170[推薦]

- 移動端IM開發入門文章:《新手入門一篇就夠:從零開發移動端IM

2、概述

隨著移動互聯網的發展,即時通訊服務被廣泛應用到各個行業,客戶業務快速發展,傳統百人或千人上限的群聊已經無法滿足很多業務發展需求,因此網易云信IM推出萬人群服務。

萬人群場景需要解決以下問題:

1)消息需要按1:9999的比例進行轉發投遞,按常規消息處理流程將產生大量的子任務,對系統吞吐量的要求極高;

2)在微服務系統架構下,如果不采用一些優化方案,服務以及存儲(DB、緩存等)之間的QPS和網絡流量將非常高;

3)以群為單位的緩存(如群成員列表)內存存儲開銷較大(假設一個成員200Byte,萬人群約2MB);

4)群成員登錄后需要同步群離線消息,智能手機上App前后臺切換產生的較多登錄同步消息協議,因此需要優化消息同步方案。

為了解決以上問題,萬人群技術方案采用了“聚合+分層/組+增量”的設計思路:

3、萬人群消息的處理流程

1)按群維護在線群成員信息,主要包含兩部分(可以理解為兩個緩存集合):

a. 群成員在線信息:即用戶在線狀態變化(上線、下線)時,更新相應群的在線狀態信息(即動態維護群有哪些成員在線);

b. 成員IM長連接信息:即用戶新登錄時,更新用戶的Link信息(即登錄所在Link的地址信息,消息轉發時根據Link地址路由消息)。

2)IM Server收到群消息后,按群ID將消息路由到“群消息服務”模塊;

3)群消息模塊檢查并預處理消息內容,然后通過“群成員在線狀態”服務獲取在線成員,完成消息轉發的基礎工作。為了減少群消息模塊和群在線成員服務之間的網絡流量,采用了“本地緩存+增量同步”的緩存策略,即本地緩存記錄最后更新版本號和時間戳,每次同步群在線成員前先檢查緩存版本號是否有變更,若有則按最后更新時間增量同步;

4)通過“群成員在線服務”獲取在線群成員的Link鏈接信息,按Link分組路由消息(分組路由的原因:同一Link上的全部群成員只需要路由一條消息即可)。同樣為了減少網絡開銷,成員Link信息也采用“本地緩存+增量同步”的方案;

5)群消息采用“漫游+歷史”的存儲方案,漫游的消息存儲在分布式緩存中,歷史消息異步寫入HBase。用戶登錄后可以通過漫游快速的獲取到最新消息,并可以通過拉取歷史查看更早的消息。

4、萬人群方案本地緩存增量同步策略

拋開群在線狀態管理邏輯,群成員在線狀態服務可以簡單理解為分布式集中緩存。

增量同步技術方案如下:

如上圖所示:

1)數據緩存是一個集合,其包含了多個緩存數據項,每一個數據項帶有最后更新時間信息;另外緩存還有一個嚴格遞增的版本號;

2)緩存數據變更(新增、修改、刪除)后,需要增加版本號;

3)本地線程通過緩存管理讀取數據時,管理服務先檢查本地版本號和分布式緩存中的版本號是否一致,若不一致則按本地最新時間戳增量同步新數據項,并更新本地的版本號和最后更新時間(為了避免分布式集中緩存中并發寫入導致的增量時間戳不可靠問題,增量更新時可以將本地記錄的最后更新時間戳向前推移,比如減少20ms);

4)為避免本地多線程并發讀取相同數據項導致并發更新本地緩存的問題,可以按緩存數據合并更新請求,即解決并發問題還可以減少網絡開銷;

5)緩存數據由大量數據項構成,為了避免單個緩存數據太大,可以將數據項中的屬性業務場景精簡(冷熱分離),低頻次讀寫的屬性額外緩存。

5、萬人群水平擴容方案

萬人群采用大量本地緩存的方案解決消息處理性能和網絡流量的問題,因此本地存儲空間成了方案的瓶頸點。因此我們設計了分組路由的技術方案。

消息按群ID和路由策略定向路由到指定分組(集群)上處理,分組由多個計算節點組成,因此方案上可以做到分組內和分組間的水平擴縮容。

6、作為“云”服務,網易云信是如何實現萬人群所需的計算資源的?

由于萬人群對計算和存儲資源消耗比較高,在實施和運維方案上也有一定的特殊性,為了保證業務的可靠性和穩定性,網易云信是將萬人大群的能力,僅提供給專屬的云客戶(普通公有云客戶是無法使用的)。

之所以能從軟硬件基礎設施上為萬人群提供保障,網易云信的IM專有云必須具備以下資源能力:

1)需要專屬的獨立計算資源:保持計算資源獨立,且資源冗余度比公有云高,且需要保證不會受到公有云上其他客戶業務的影響;

2)需要專屬的獨立運維服務:從而根據客戶業務場景制定最佳的業務監控、彈性擴容、故障遷移等運維方案。

總之,萬人群聊的實現,過硬的技術方案設計和技術實現只是一方面,基礎計算設施資源和運維能力也是不可或缺。

所以,從今以后,不要隨隨便便就喊萬人群聊,甚至十萬人群聊,這不是想實現就能實現的哦!

附錄:更多群聊相關技術文章

快速裂變:見證微信強大后臺架構從0到1的演進歷程(一)
如何保證IM實時消息的“時序性”與“一致性”?
IM單聊和群聊中的在線狀態同步應該用“推”還是“拉”?
IM群聊消息如此復雜,如何保證不丟不重?
微信后臺團隊:微信后臺異步消息隊列的優化升級實踐分享
移動端IM中大規模群消息的推送如何保證效率、實時性?
現代IM系統中聊天消息的同步和存儲方案探討
關于IM即時通訊群聊消息的亂序問題討論
IM群聊消息的已讀回執功能該怎么實現?
IM群聊消息究竟是存1份(即擴散讀)還是存多份(即擴散寫)?
一套高可用、易伸縮、高并發的IM群聊、單聊架構方案設計實踐
[技術腦洞] 如果把14億中國人拉到一個微信群里技術上能實現嗎?
IM群聊機制,除了循環去發消息還有什么方式?如何優化?
網易云信技術分享:IM中的萬人群聊技術方案實踐總結
>> 更多同類文章 ……

(本文同步發布于:http://www.52im.net/thread-2707-1-1.html

posted @ 2019-08-14 10:07 Jack Jiang 閱讀(19) | 評論 (0)編輯 收藏

2019年8月8日

     摘要: 本文原文由作者“張小方”原創發布于“高性能服務器開發”微信公眾號,原題《心跳包機制設計詳解》,即時通訊網收錄時有改動。1、引言一般來說,沒有真正動手做過網絡通信應用的開發者,很難想象即時通訊應用中的心跳機制的作用。但不可否認,作為即時通訊應用,心跳機制是其網絡通信技術底層中非常重要的一環,有沒有心跳機制、心跳機制的算法實現好壞,都將直接影響即時通訊應...  閱讀全文

posted @ 2019-08-08 12:01 Jack Jiang 閱讀(33) | 評論 (0)編輯 收藏

2019年8月2日

     摘要: 本文由原作者松若章原創發布,作者主頁:zhihu.com/people/hrsonion/posts,感謝原作者的無私分享。1、引言一道經典的面試題是:從 URL 在瀏覽器被被輸入到頁面展現的過程中發生了什么?大多數回答都是說請求響應之后 DOM 怎么被構建,被繪制出來。但是你有沒有想過,收到的 HTML 如果包含幾十個圖片標簽,這些圖片是以什么方式、什么順序、建立了多少連接、使用什么協議被下載下...  閱讀全文

posted @ 2019-08-02 09:55 Jack Jiang 閱讀(54) | 評論 (0)編輯 收藏

2019年7月29日

     摘要: 本文由百度技術團隊“蔡銳”原創發表于“百度App技術”公眾號,原題為《百度App網絡深度優化系列《三》弱網優化》,感謝原作者的無私分享。一、前言網絡優化解決的核心問題有三個,第一是安全問題,我們在《百度APP移動端網絡深度優化實踐分享(一):DNS優化篇》進行了詳細的講解。第二是速度問題,我們在《百度APP移動端網絡深度優化實踐分享(二):網絡連接優...  閱讀全文

posted @ 2019-07-29 10:29 Jack Jiang 閱讀(27) | 評論 (0)編輯 收藏

Jack Jiang的 Mail: [email protected], 聯系QQ: 413980957, 微信: hellojackjiang
云南11选5软件