互聯(lián)網(wǎng)/程序員/技術/資料共享?
來自:網(wǎng)絡,侵刪
1.背景
公司在做一個社交項目,音視頻技術是使用的第三方技術,直播間開播,進出房間,以及推送相關功能需要自己完成開發(fā),因而需要自己搭建長連接服務器。于是在技術選型上,為了保證服務高并發(fā)性能,以及長連接性能,在本身就是微服務架構上,采用了SpringBoot + Netty實現(xiàn)了長連接服務搭建,關于SpringBoot和Netty框架相關,本文不是重點,本文重點在于Netty集群搭建實現(xiàn)消息轉(zhuǎn)發(fā)功能。2.技術選項&實現(xiàn)
2.1 關于Netty長連接
Netty是一個非常優(yōu)秀的NIO異步事件驅(qū)動框架,在JDK NIO的基礎上,封裝并拓展包裝,使得NIO的API簡單易用,很多框架底層也應用了(比如Dubbo),Netty是可以做為一個長連接服務的,使用ws協(xié)議,可以構建一個高性能的長連接服務器,據(jù)說單機就能支持1萬左右的連接。熟悉Netty或NIO的都了解,其底層數(shù)據(jù)傳輸時通過一個網(wǎng)絡連接Channel,對于單機Netty來說,Channel都連接在同一臺服務器上,Channel之間的通信可以直接根據(jù)綁定的用戶信息進行獲取并轉(zhuǎn)發(fā)。但是對于Netty集群來說,每個客戶端的連接可能在不同的服務器上,這樣在Channel互相通信時,需要判斷是否在當前節(jié)點,并實現(xiàn)消息的轉(zhuǎn)發(fā)。2.2 技術選項
實現(xiàn)消息轉(zhuǎn)發(fā),有多種技術框架可以實現(xiàn),比如ZK,MQ,Redis等,由于當前項目已經(jīng)搭建了自己的MQ和Redis服務,因此考慮成本,目前只在MQ和Redis中選擇。如上文,Netty集群搭建后,Channel收到消息后,需要判斷目標用戶的Channel是否在本節(jié)點,如果不在,就需要做消息轉(zhuǎn)發(fā),轉(zhuǎn)發(fā)到目標節(jié)點上,并將消息寫到Channel中。因而MQ的廣播機制和Redis的發(fā)布訂閱就可以實現(xiàn)功能。- MQ:專門做消息隊列的,可靠性高,但重量級,異步,不能保證實時。
- Redis:較輕量級,低延遲,高并發(fā),低可靠性。
兩者在項目均在使用,考慮到直播消息更加保證時效性,故而選擇Redis發(fā)布訂閱功能,相對而言集成較為簡單。2.3 實現(xiàn)架構圖
①服務啟動時,向Redis注冊自己的節(jié)點信息,并指定監(jiān)聽頻道。②客戶端連接Netty Server成功后,并在Redis緩存中綁定用戶加入的節(jié)點,以便后續(xù)信息轉(zhuǎn)發(fā),將信息轉(zhuǎn)發(fā)到指定的頻道。③在Channel轉(zhuǎn)發(fā)時,判斷如果當前用戶在本節(jié)點,就直接轉(zhuǎn)發(fā),如果不在,從Redis獲取到注冊的節(jié)點信息,并將消息發(fā)布到指定的頻道節(jié)點。3.代碼實現(xiàn)
綁定當前節(jié)點,服務啟動并監(jiān)聽指定的頻道,指定Listener。訂閱節(jié)點生成器 本機 ip + 服務端口監(jiān)聽器實現(xiàn),監(jiān)聽的頻道收到消息,處理并發(fā)送到對應Channel4.總結
①通過應用Redis發(fā)布訂閱,Netty Server多個集群,追加多節(jié)點時,新增節(jié)點會自動注冊監(jiān)聽對于的頻道,消息轉(zhuǎn)發(fā)時也會自動投遞到新注冊的節(jié)點頻道上,可擴展性強。②當前Redis 5中有很多新增的高級特性,筆者也在慢慢學習中,可應用到項目業(yè)務場景中也比較多。推薦閱讀:
Mybatis-Plus官方發(fā)布分庫分表神器,一個依賴輕松搞定!
SpringBoot+RabbitMQ 死信隊列
互聯(lián)網(wǎng)初中高級大廠面試題(9個G)內(nèi)容包含Java基礎、JavaWeb、MySQL性能優(yōu)化、JVM、鎖、百萬并發(fā)、消息隊列、高性能緩存、反射、Spring全家桶原理、微服務、Zookeeper......等技術棧!
?戳閱讀原文領??!? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??朕已閱?