汽車之家App詳細(xì)介紹、汽車之家app下載安裝

    首頁 > 汽車 > 車市行情 > 正文

    汽車之家App詳細(xì)介紹、汽車之家app下載安裝

    1.前言

    早期之家在C端產(chǎn)品的即時(shí)通信功能是直接使用第三方商業(yè)軟件服務(wù)(SaaS),功能擴(kuò)展性上存在很大制約,某些定制化業(yè)務(wù)需求很難實(shí)現(xiàn),考慮到后續(xù)業(yè)務(wù)發(fā)展需要、數(shù)據(jù)安全、內(nèi)容實(shí)時(shí)審核及性能、自主可控高可用架構(gòu)等因素,決定自主開發(fā)IM即時(shí)通信平臺(tái)并逐步迭代替換。

    2.網(wǎng)絡(luò)通信框架及協(xié)議

    2.1

    網(wǎng)絡(luò)通信框架

    網(wǎng)絡(luò)通信系統(tǒng)通常可以選擇原生NIO庫或者第三方網(wǎng)絡(luò)框架進(jìn)行開發(fā),原生NIO的類庫API比較底層基礎(chǔ),缺少對(duì)常用操作的封裝,例如粘包、解碼、重連等,開發(fā)工作量和維護(hù)成本會(huì)比較高,需要關(guān)注很多底層的東西。我們選擇了目前非常熱門的網(wǎng)絡(luò)框架Netty進(jìn)行開發(fā),Netty功能強(qiáng)大開發(fā)門檻較低,預(yù)置了多種主流協(xié)議編解碼功能,成熟、穩(wěn)定,且修復(fù)了大量已經(jīng)發(fā)現(xiàn)的JDK NIO BUG。

    ? Netty具備如下優(yōu)點(diǎn):

    1.入門簡(jiǎn)單,文檔齊全,無其他依賴,只依賴 JDK 就夠了;

    2.使用簡(jiǎn)單,預(yù)置了多種編解碼功能,支持多種主流協(xié)議,對(duì)大量常用操作進(jìn)行了封裝,減少開發(fā)周期;

    3.高性能,高吞吐,低延遲,資源消耗少;

    4.靈活的線程模型,支持阻塞和非阻塞的I/O 模型;

    5.代碼質(zhì)量高,目前主流版本基本沒有 Bug;

    6.社區(qū)活躍,版本迭代周期短,發(fā)現(xiàn)的BUG可以被及時(shí)修復(fù),同時(shí),更多的新功能會(huì)加入;

    7.經(jīng)歷了大規(guī)模的商業(yè)應(yīng)用考驗(yàn),穩(wěn)定性得到驗(yàn)證。

    2.2

    通信協(xié)議

    TCP是個(gè)“流”協(xié)議,就是沒有界限的一串?dāng)?shù)據(jù),數(shù)據(jù)傳輸時(shí)可能會(huì)存多包或半包傳輸?shù)那闆r,原因如下:

    1. 應(yīng)用程序?qū)懭胱止?jié)大小于套接口發(fā)送緩沖區(qū)大小;

    2. 進(jìn)行 MSS 大小的 TCP 分段;

    3. 以太網(wǎng)幀的 payload 大于 MTU 進(jìn)行 IP 分片

    ? 解決策略

    1. 消息定長,例如每個(gè)報(bào)文大小固定200字節(jié),如果不夠,空位補(bǔ)空格。

    2. 用回車符進(jìn)行分割,例如FTP協(xié)議。

    3. 約定特殊字符作為消息結(jié)束標(biāo)記。

    4. 將消息分為消息頭和消息體,消息頭中包含表示消息總長度(或消息體長度)

    5. 更復(fù)雜的應(yīng)用層協(xié)議。

    按約定的方式編解碼保證數(shù)據(jù)完整性,就是通信協(xié)議。將消息分為消息頭和消息體是最常見的協(xié)議設(shè)計(jì)方式(定長消息頭,可變長度消息體),如下圖:

    汽車之家App詳細(xì)介紹、汽車之家app下載安裝

    ? 消息頭

    固定長度字節(jié)來標(biāo)記消息類型,及消息體字節(jié)長度。

    ?消息體

    可以使用文本、XML、JSON、Protobuf等擴(kuò)展性好的數(shù)據(jù)格式,盡量考慮以下幾點(diǎn):

    1. 精簡(jiǎn)消息體大小,不要有冗余數(shù)據(jù),減少網(wǎng)絡(luò)帶寬占用(尤其是大量用戶發(fā)消息群聊場(chǎng)景下),提高傳輸效率

    2. 數(shù)據(jù)安全性(例如加密傳輸)

    3. 編碼效率及可擴(kuò)展性

    ? 除了自己設(shè)計(jì)實(shí)現(xiàn)通信協(xié)議,還可以直接使用現(xiàn)成的設(shè)計(jì)好的公開協(xié)議,如目前比較流行的websocket協(xié)議,相對(duì)于私有協(xié)議有以下優(yōu)點(diǎn):

    1. 瀏覽器直接支持,方便web端接入

    2. 降低接入成本,websocket是公開協(xié)議,接入時(shí)不需要在協(xié)議規(guī)范上耗費(fèi)太多的溝通時(shí)間。

    3. 很多框架包括Netty都自帶實(shí)現(xiàn)了websocket協(xié)議解碼器。

    3.架構(gòu)設(shè)計(jì)

    客戶端:用戶收發(fā)消息終端

    接入層:為客戶端連接、收發(fā)消息、關(guān)系建立提供入口

    數(shù)據(jù)層:負(fù)責(zé)各類業(yè)務(wù)邏輯數(shù)據(jù)及消息數(shù)據(jù)緩存或持久化存儲(chǔ),及消息指令的分發(fā)渠道。

    3.1

    消息設(shè)置

    聊天場(chǎng)景常見的消息類型通常有:文本、圖片、表情、語音,視頻。我們把消息分為消息類型,及消息內(nèi)容兩部分,客戶端通過識(shí)別消息類型去解析消息內(nèi)容并展示,像圖片視頻等消息,并不需要通過消息即時(shí)傳遞其內(nèi)容,而是先將圖片或視頻上傳到文件服務(wù)器,消息中只需要把uri帶過去,并且?guī)蟗ase64編碼的縮略圖即可,如下示例:

    msgType:msg_image

    msgContent: { user: { id:1,name:xxx,portrait:xxxx }, content: "縮略小圖base64編碼",url:"大圖地址", extra: "" }

    消息下發(fā)流程如下圖:

    如圖,整體思路是將上行消息通過webapi寫入消息隊(duì)列,socket服務(wù)器通過消息隊(duì)列或離線消息庫進(jìn)行增量消息分發(fā)同步。

    socket服務(wù)承載連接著所有在線用戶,發(fā)生部署上線將會(huì)導(dǎo)致所有在線用戶斷開重連,瞬間大量增加其它服務(wù)器的連接壓力,且對(duì)部分用戶行為可能會(huì)有短暫的影響,上行消息通過webAPI實(shí)現(xiàn),統(tǒng)一了消息入口,方便各類渠道消息的接入,并且使得socket服務(wù)的職責(zé)變得簡(jiǎn)單單一,僅用于保持連接和推送消息,上行消息業(yè)務(wù)邏輯頻繁變動(dòng)時(shí)僅需要重新部署webAPI,對(duì)用戶基本無感知。

    還有一些建議是,對(duì)消息進(jìn)行合并,壓縮能極大提升消息推送吞吐能力,減少帶寬占用,經(jīng)測(cè)試十條以上消息壓縮率能達(dá)到80%左右;細(xì)分消息隊(duì)列,按不同維度拆分消息隊(duì)列可以分散壓力防止某類消息高峰期對(duì)其它業(yè)務(wù)消息造成延遲推送,保證其它消息的時(shí)效性,比如可以按場(chǎng)景用戶消息,系統(tǒng)指令等各自使用獨(dú)立的消息隊(duì)列。

    3.2

    消息擴(kuò)散

    消息擴(kuò)散分發(fā)是im設(shè)計(jì)的重點(diǎn),尤其是一對(duì)多的場(chǎng)景,如群聊。簡(jiǎn)單的說就是每條消息需要擴(kuò)散給群里所有人收到,通常有兩種方式,讀擴(kuò)散,寫擴(kuò)散。什么是讀擴(kuò)散?什么是寫擴(kuò)散?

    ? 讀擴(kuò)散:

    描述:每條消息只存一份,群組所有成員讀取這一份數(shù)據(jù)。

    優(yōu)點(diǎn):節(jié)省存儲(chǔ)空間,無寫入壓力。

    缺點(diǎn):

    1. 獲取離線增量消息邏輯復(fù)雜,需要根據(jù)用戶所有會(huì)話關(guān)系去遍歷獲取,且并未知道會(huì)話是否有增量消息,會(huì)造成大量無效空讀,效率極慢。

    2. 針對(duì)消息做單個(gè)用戶個(gè)性化操作時(shí)設(shè)計(jì)會(huì)變的麻煩,比如其中一個(gè)用戶刪除消息,已讀回執(zhí)等操作時(shí),不能去影響其它用戶的視角。

    ? 寫擴(kuò)散:

    描述:每個(gè)用戶有獨(dú)立的消息列表,每條消息給所有消息關(guān)聯(lián)人同步一份副本。

    優(yōu)點(diǎn):讀取邏輯簡(jiǎn)單,效率極快,通過用戶自身消息列表一次性獲取所有離線增量消息即可,用戶個(gè)性化操作實(shí)現(xiàn)簡(jiǎn)單,不會(huì)影響其它用戶的視角。

    缺點(diǎn):存儲(chǔ)空間增加,寫入壓力較大。

    兩種方案如圖所示:

    對(duì)比兩種消息擴(kuò)散方案優(yōu)缺點(diǎn)都比較明確,同時(shí)也都面臨無法接受的極端情況,比如讀擴(kuò)散,如果某用戶擁有巨量會(huì)話,那他每次上線時(shí)讀取消息就是災(zāi)難,再如寫擴(kuò)散,如遇到萬人群,每條消息都會(huì)產(chǎn)生一萬分副本,作為設(shè)計(jì)者必須根據(jù)實(shí)際情況從邏輯上去結(jié)合兩種方案來平衡讀寫壓力。

    消息寫擴(kuò)散按需延遲擴(kuò)散,我們通過登陸時(shí)間把用戶分類活躍和非活躍,只對(duì)活躍用戶進(jìn)行即時(shí)寫擴(kuò)散,非活躍用戶在上線時(shí)做一次補(bǔ)償同步操作,這樣能有效分散消息寫入壓力,還能對(duì)減少僵尸賬號(hào)進(jìn)行無意義消息副本同步。

    3.3

    IMSDK架構(gòu)構(gòu)圖

    IMSDK架構(gòu)按模塊分工可以分為中間件層、核心層、協(xié)議層。

    ?中間件層

    負(fù)責(zé)請(qǐng)求連接時(shí)需要的Token,以及對(duì)Token的緩存、Token過期更新等邏輯。當(dāng)App啟動(dòng)之后平臺(tái)層會(huì)設(shè)置用戶信息到中間件,中間件根據(jù)設(shè)置的用戶信息判斷本地是否緩存該用戶的Token,如果有則直接用該Token進(jìn)行連接;如果沒有則會(huì)請(qǐng)求接口獲取Token。獲取到之后使用獲取到的Token進(jìn)行連接,連接成功之后將該Token本地緩存,方便下次使用。如果連接過程中服務(wù)器端返回Token過期的錯(cuò)誤,客戶端會(huì)刪除掉本地緩存的Token,并重新請(qǐng)求Token進(jìn)行再次連接。

    ?核心層

    包含連接模塊、監(jiān)聽模塊、API封裝模塊、日志模塊、本地?cái)?shù)據(jù)庫模塊。連接模塊負(fù)責(zé)Socket的連接、保活、斷線重連、斷開、收發(fā)消息等操作,連接模塊每隔50秒發(fā)送一次ping來保活,連接模塊重連機(jī)制是2秒、4秒、8秒、16秒等2的n次方逐漸增加,當(dāng)重試次數(shù)到10次后會(huì)認(rèn)為當(dāng)前網(wǎng)絡(luò)有問題,不再重試,等待監(jiān)聽網(wǎng)絡(luò)變化或者前后臺(tái)切換之后再次重試;監(jiān)聽模塊當(dāng)收到會(huì)話變更、消息變更、連接狀態(tài)變更時(shí)將變更內(nèi)容通知到所有注冊(cè)監(jiān)聽的業(yè)務(wù)層,業(yè)務(wù)層根據(jù)收到的通知做出相應(yīng)處理。

    API封裝模塊提供一些SDK基礎(chǔ)功能的API到業(yè)務(wù)層,例如發(fā)送消息、撤回消息、刪除消息、獲取會(huì)話未讀數(shù)、會(huì)話草稿等等,業(yè)務(wù)層調(diào)用提供的API完成相關(guān)功能。日志模塊提供日志采集的API,將每一條日志順序的記錄到日志文件中。日志模塊還負(fù)責(zé)日志文件的創(chuàng)建、刪除、保存與上傳工作。本地?cái)?shù)據(jù)庫模塊負(fù)責(zé)數(shù)據(jù)庫相關(guān)的工作,當(dāng)上層設(shè)置用戶信息時(shí),數(shù)據(jù)庫模塊會(huì)打開相應(yīng)的數(shù)據(jù)庫,如果沒有則會(huì)新建。數(shù)據(jù)庫模塊負(fù)責(zé)會(huì)話表和消息表的創(chuàng)建,負(fù)責(zé)會(huì)話和消息的增、刪、改、查。數(shù)據(jù)庫模塊執(zhí)行操作時(shí)會(huì)增加一些必要的邏輯到其中,例如,在插入消息時(shí)需要更新會(huì)話的未讀數(shù)、會(huì)話的最后一條消息;在刪除消息時(shí)需要更新會(huì)話的未讀數(shù)、會(huì)話的最后一條消息;在消息已讀功能中需要修改會(huì)話的未讀數(shù)等等。

    ?協(xié)議層

    主要負(fù)責(zé)跟服務(wù)端通訊內(nèi)容的編解碼工作,包括消息的編解碼、會(huì)話的編解碼、命令的編解碼等工作,協(xié)議層將收到的數(shù)據(jù)進(jìn)行解析,區(qū)分出諸如收到新消息、刪除消息、撤回消息、增加會(huì)話、刪除會(huì)話、會(huì)話更新等行為,同時(shí)將收到的數(shù)據(jù)解碼成消息或者會(huì)話Model傳遞到上層,通知到業(yè)務(wù)層。

    3.4

    連接流程圖

    App需要同App Server進(jìn)行數(shù)據(jù)交互,獲取IM連接需要的Token數(shù)據(jù),并且App Server負(fù)責(zé)維護(hù)業(yè)務(wù)數(shù)據(jù),如用戶數(shù)據(jù)、會(huì)話數(shù)據(jù)、好友關(guān)系等;

    App通過Token數(shù)據(jù)與IM Server進(jìn)行連接,建立數(shù)據(jù)通道實(shí)現(xiàn)消息的實(shí)時(shí)接收與推送功能;

    IM Server維護(hù)App的連接狀態(tài),在接收實(shí)時(shí)消息時(shí)判斷用戶是否在線,將消息轉(zhuǎn)發(fā)給目標(biāo)設(shè)備或保存為離線消息;

    ?會(huì)話及氣泡:

    在面對(duì)特殊用戶會(huì)話較多時(shí)每次從服務(wù)拉取會(huì)話信息時(shí)將面臨較大壓力,我們采用本地和服務(wù)端結(jié)合方案實(shí)現(xiàn),本地緩存一份會(huì)話,接收消息對(duì)會(huì)話氣泡進(jìn)行疊加,本地會(huì)話設(shè)置發(fā)生變更如免打擾,隱藏會(huì)話,已讀消息等,上報(bào)給服務(wù)端,服務(wù)端在發(fā)生好友關(guān)系或加入群組等操作時(shí)產(chǎn)生會(huì)話,或會(huì)話信息變更時(shí)也會(huì)對(duì)本地進(jìn)行同步,服務(wù)器和本地之間會(huì)話同步包括連接時(shí)同步、實(shí)時(shí)同步、主動(dòng)同步。

    連接時(shí)同步:用戶每次連接時(shí)會(huì)向服務(wù)器傳遞會(huì)話唯一標(biāo)識(shí),服務(wù)端通過用戶傳遞的標(biāo)識(shí)進(jìn)行邏輯判斷并向用戶推送會(huì)話數(shù)據(jù),包括全部會(huì)話和增量會(huì)話,SDK接收到會(huì)話數(shù)據(jù)后進(jìn)行本地的新增、修改、刪除操作,并通知給UI層,本地會(huì)話“標(biāo)識(shí)”由服務(wù)端每次同步會(huì)話時(shí)提供。

    實(shí)時(shí)同步:本地會(huì)話修改會(huì)通知給服務(wù)端,服務(wù)端接收到會(huì)話信息變更時(shí),會(huì)即時(shí)通過IM推送給SDK,其中包括新增、修改、刪除會(huì)話的操作,SDK接收到會(huì)話數(shù)據(jù)后進(jìn)行本地的新增、修改、刪除操作,并通知給UI層。

    主動(dòng)同步:客戶端接收到不存在的會(huì)話消息時(shí),會(huì)主動(dòng)向服務(wù)器獲取此會(huì)話信息進(jìn)行本地保存并通知UI層。

    會(huì)話設(shè)計(jì)圖:

    會(huì)話部分字段:

    單聊:兩個(gè)用戶之間進(jìn)行一對(duì)一的聊天,聊天消息可以持久化保存至本地進(jìn)行查看。

    群組:兩個(gè)或兩個(gè)以上的用戶在同一個(gè)會(huì)話中進(jìn)行聊天,發(fā)送的消息會(huì)被群組所有成員接收并可以持久化保存至本地進(jìn)行查看。

    公眾號(hào):企業(yè)或官方通過系統(tǒng)賬號(hào)向單個(gè)或多個(gè)賬號(hào)推送消息,消息可以持久化保存至本地進(jìn)行查看。

    聊天室:一個(gè)或多個(gè)用戶在同一個(gè)會(huì)話中進(jìn)行聊天,發(fā)送的消息會(huì)被推送至當(dāng)前聊天室中所有用戶,用戶接收端消息不會(huì)保存本地。

    本地記錄每次會(huì)話同步時(shí)間,連接時(shí)服務(wù)端根據(jù)本地上報(bào)最后更新時(shí)間對(duì)比,增量同步變動(dòng)過的會(huì)話記錄,保證本地會(huì)話與服務(wù)器端保持一致。之家的會(huì)話列表體現(xiàn)在個(gè)人主頁的消息部分,如下:

    4.服務(wù)器優(yōu)化

    我們系統(tǒng)的設(shè)計(jì)要求是單機(jī)百萬連接支持、下行消息QPS一百萬。由于一個(gè)連接會(huì)占用一個(gè)文件描述符,首先就要對(duì)系統(tǒng)的文件描述符上限做調(diào)整,讓服務(wù)器能夠支持百萬級(jí)連接的建立;

    # /etc/security/limits.conf

    * soft nporc 1500000

    * hard nporc 1500000

    * soft nofile 1500000

    * hard nofile 1500000

    # /etc/sysctl.conf

    fs.nr_open = 3000000

    fs.file-max = 3000000

    我們使用Nginx作為七層負(fù)載,并且開啟了TLS保障數(shù)據(jù)的傳輸安全。當(dāng)Nginx層作為客戶端在與后端應(yīng)用服務(wù)器建立連接的時(shí)候,會(huì)遇到本地端口瓶頸,可以依據(jù)TCP四元組規(guī)則,增加后端應(yīng)用服務(wù)器的監(jiān)聽端口,來實(shí)現(xiàn)本地端口的復(fù)用,從而突破本地端口資源的限制;

    在實(shí)際壓測(cè)過車中,客戶端接收消息的毛刺問題比較嚴(yán)重,經(jīng)排查發(fā)現(xiàn)nginx服務(wù)器有丟包,并且CPU的使用非常不均衡,特別是軟中斷,只集中在少數(shù)CPU上。為解決以上問題前,先了解下網(wǎng)卡收包流程以及相關(guān)的一些概念。

    網(wǎng)卡收到數(shù)據(jù)幀后,將數(shù)據(jù)幀以DMA的方式拷貝到內(nèi)存的Ring Buffer中,該步驟不需要CPU的參與。當(dāng)拷貝完成后,網(wǎng)卡便會(huì)觸發(fā)一個(gè)網(wǎng)卡硬件中斷,CPU必須立即響應(yīng)硬件中斷,CPU根據(jù)中斷類型,在中斷注冊(cè)表中查找對(duì)應(yīng)的中斷處理程序,然后調(diào)用網(wǎng)卡注冊(cè)的中斷處理程序(網(wǎng)卡驅(qū)動(dòng)),此后網(wǎng)卡驅(qū)動(dòng)程序觸發(fā)一個(gè)軟中斷,自此硬件中斷返回,硬中斷不會(huì)做過多事情,它只負(fù)責(zé)通知驅(qū)動(dòng)有數(shù)據(jù)到達(dá),具體的操作由軟中斷過程來處理。

    DMA是Direct Memory Access,直接存儲(chǔ)器訪問。在DMA出現(xiàn)之前,CPU與外設(shè)之間的數(shù)據(jù)傳送方式有程序傳送方式、中斷傳送方式。CPU是通過系統(tǒng)總線與其他部件連接并進(jìn)行數(shù)據(jù)傳輸,DMA就是指外部設(shè)備不通過CPU而直接與系統(tǒng)內(nèi)存交換數(shù)據(jù)的接口技術(shù)。

    Ring Buffer網(wǎng)卡環(huán)形緩沖區(qū),如果該緩沖區(qū)被占滿,新到來的數(shù)據(jù)包將會(huì)被丟棄,從而導(dǎo)致丟包。把該緩沖區(qū)由原來的512調(diào)整到2048后,丟包問題得以解決,方法如下:

    查看當(dāng)前Buffer

    ethtool -g em1

    Ring parameters for em1:

    Pre-set maximums:

    RX: 4096

    RX Mini: 0

    RX Jumbo: 0

    TX: 4096

    Current hardware settings:

    RX: 4096

    RX Mini: 0

    RX Jumbo: 0

    TX: 4096

    ethtool -G em1 rx 2048

    ethtool -G em1 tx 2048

    修改

    ethtool -G em1 rx 4096

    ethtool -G em1 tx 4096

    4.1

    設(shè)置網(wǎng)卡隊(duì)列

    對(duì)于CPU軟中斷不均衡,與網(wǎng)卡的設(shè)置與CPU的親和力綁定有直接關(guān)系,借用網(wǎng)絡(luò)一張圖先了解下RSS多隊(duì)列網(wǎng)卡,如下:

    當(dāng)網(wǎng)卡收到報(bào)文時(shí),通過Hash包頭的SIP、SPort、DIP、DPort四元組信息,將數(shù)據(jù)投遞到相應(yīng)的網(wǎng)卡隊(duì)列,同時(shí)會(huì)觸發(fā)該隊(duì)列綁定的中斷,通知CPU進(jìn)一步處理;由此可知CPU使用不均衡,無非就是兩個(gè)原因,隊(duì)列收到的數(shù)據(jù)包不均衡或者CPU與網(wǎng)卡隊(duì)列綁定不合理導(dǎo)致;

    # 設(shè)定網(wǎng)卡隊(duì)列

    ethtool -L em1 combined 16

    4.2

    網(wǎng)卡中斷號(hào)

    Interrupt Request,簡(jiǎn)稱IRQ,中斷就是由硬件或軟件所發(fā)送的中斷請(qǐng)求信號(hào)。系統(tǒng)上的每個(gè)硬件設(shè)備都會(huì)被分配一個(gè) IRQ 號(hào),通過這個(gè)唯一的 IRQ 號(hào)就能區(qū)是來自哪個(gè)硬件了。開啟了多隊(duì)列的網(wǎng)卡,每個(gè)隊(duì)列都會(huì)有唯一的中斷號(hào)。

    # 查看網(wǎng)卡隊(duì)列中斷號(hào)

    cat /proc/interrupts |grep em1 |awk '{print $1 $NF}'

    4.3

    CPU親和力綁定

    把每個(gè)網(wǎng)卡隊(duì)列與CPU一一綁定,均衡CPU的使用

    # CPU綁定

    echo /proc/irq/107/smp_affinity_list 0

    echo /proc/irq/108/smp_affinity_list 1

    中斷號(hào)為107的隊(duì)列綁定0號(hào)CPU,中斷號(hào)為108的隊(duì)列綁定1號(hào)CPU,依此類推,每個(gè)網(wǎng)卡隊(duì)列都需要綁定到不同的CPU核上,這樣我們就完成了網(wǎng)卡隊(duì)列的設(shè)置以及與CPU的綁定。

    這里還有個(gè)問題是,CPU不緊要處理網(wǎng)路數(shù)據(jù),還要處理Nginx應(yīng)用,這個(gè)時(shí)候CPU資源的分配要根據(jù)具體的壓測(cè)情況進(jìn)行調(diào)整;

    4.4

    Intel Flow Director

    上面提到投遞到網(wǎng)卡隊(duì)列的數(shù)據(jù)包是均衡的,如何能做到均衡呢?有個(gè)辦法是使用Intel以太網(wǎng)FD( Flow Director)技術(shù),自定義數(shù)據(jù)包投遞規(guī)則,應(yīng)用監(jiān)聽多個(gè)端口,不同目標(biāo)端口的數(shù)據(jù)包按制定的規(guī)則投遞到相應(yīng)的網(wǎng)卡隊(duì)列,從而達(dá)到均衡數(shù)據(jù)包的目的,進(jìn)而均衡CPU的使用;

    # 數(shù)據(jù)投遞規(guī)則 根據(jù)目的端口把數(shù)據(jù)投遞到不同隊(duì)列

    ethtool --features em1 ntuple on

    ethtool --config-ntuple em1 flow-type tcp4 dst-port 9500 action 0 loc 1

    ethtool --config-ntuple em1 flow-type tcp4 dst-port 9501 action 1 loc 2

    至此網(wǎng)卡丟包以及CPU使用率不均衡的問題得到解決,基本就是解決了客戶端接收數(shù)據(jù)毛刺的問題;

    4.5

    其他優(yōu)化

    對(duì)部分需要更高時(shí)時(shí)性及穩(wěn)定的用戶,如客服、商家號(hào)等,可以增加專用服務(wù)器來應(yīng)對(duì),專用服務(wù)器通常接入量較小,連接和消息推送都會(huì)更穩(wěn)定快速。

    增加備用域名(不同cdn),在連接失敗重試過程中使用可有效減少外部網(wǎng)絡(luò)波動(dòng)帶來的影響,使系統(tǒng)更加穩(wěn)定可靠。我們之前有一次線上故障,使用的第三方的即時(shí)通訊服務(wù),

    當(dāng)時(shí)該服務(wù)商的一個(gè)關(guān)鍵域名被誤封,導(dǎo)致整個(gè)即時(shí)通訊服務(wù)不可用,由于處理過程復(fù)雜,故障持續(xù)了半天的時(shí)間才得以恢復(fù)。基于此,我們自研的時(shí)候,把這部分設(shè)計(jì)了進(jìn)去。

    為提高連接效率及服務(wù)器連接壓力SDK增加了token緩存機(jī)制,IM連接成功后,會(huì)將token進(jìn)行本地緩存,當(dāng)設(shè)備再次觸發(fā)連接時(shí),會(huì)優(yōu)先檢查本地是否存在token,如存在立刻使用緩存數(shù)據(jù)進(jìn)行連接,若不存在或過期會(huì)向服務(wù)器獲取新token數(shù)據(jù)進(jìn)行連接,連接成功后將新Token緩存本地。

    SDK具備自動(dòng)重連機(jī)制,在整個(gè)應(yīng)用全局只需要調(diào)用一次連接即可,連接異常斷開后會(huì)啟動(dòng)重連機(jī)制進(jìn)行多次重連,在這之后如果仍沒有連接成功,還會(huì)在當(dāng)檢測(cè)到設(shè)備網(wǎng)絡(luò)狀態(tài)變化時(shí)再次進(jìn)行重連。

    心跳保活,為了保持客戶端和服務(wù)端的實(shí)時(shí)雙向通信,需要確保客戶端和服務(wù)端之間的TCP通道保持連接不斷開,IM連接成功后,SDK每間隔50秒會(huì)向服務(wù)器發(fā)送一個(gè)ping包,服務(wù)器接收到ping包后立即響應(yīng)一個(gè)pong包,如果服務(wù)在120秒內(nèi)檢查沒有收到過ping包會(huì)立即斷開此連接,釋放資源。SDK在檢測(cè)斷開后會(huì)自動(dòng)觸發(fā)重連機(jī)制。

    發(fā)送方->接收方:ping

    接收放->發(fā)送方:pong

    5.總結(jié)

    本文內(nèi)容介紹了之家IM即時(shí)通信平臺(tái)部分設(shè)計(jì)策略,借此機(jī)會(huì)總結(jié)設(shè)計(jì)方案及技術(shù)實(shí)踐,與大家一起學(xué)習(xí)提升。目前該項(xiàng)目在之家已經(jīng)落地兩年有余,接入十幾條業(yè)務(wù)線,包含單聊、群聊、聊天室、公眾號(hào)、通用信令服務(wù)等場(chǎng)景,日均服務(wù)三端用戶在千萬級(jí),為之家三端產(chǎn)品提供全雙工消息總線基礎(chǔ)設(shè)施支撐;目前一些個(gè)性化產(chǎn)品需求以及相關(guān)運(yùn)營平臺(tái)仍在不斷完善中,如果你對(duì)此很有興趣,歡迎加入我們。

    作者簡(jiǎn)介

    林道輝

    ■ C端及中臺(tái)產(chǎn)研中心-看選技術(shù)團(tuán)隊(duì)

    2012年加入汽車之家,目前主要負(fù)責(zé)參與熱聊業(yè)務(wù)及之家im通信平臺(tái)架構(gòu)及研發(fā)工作。

    來源:微信公眾號(hào):之家技術(shù)

    出處:https://mp.weixin.qq.com/s/kMGEpE_piFbeWTm9YxWVRA

    熱點(diǎn)圖片

    備案號(hào):贛ICP備2022005379號(hào)
    華網(wǎng)(http://www.www489tv.com) 版權(quán)所有未經(jīng)同意不得復(fù)制或鏡像

    QQ:51985809郵箱:51985809@qq.com

    主站蜘蛛池模板: 欧美大尺度电影| 友田真希息与子中文字幕 | 久久免费视频网站| 又大又硬又爽又粗又快的视频免费| 欧洲一级毛片免费| 国产av午夜精品一区二区入口| 一区二区三区中文字幕| 黄网在线观看免费| 性做久久久久免费观看| 亚洲精品国产肉丝袜久久| 91啦视频在线| 怡红院免费手机在线观看| 亚洲AV无码国产精品色| 美女和男生一起差差差| 国产高清免费观看| 久久亚洲精品国产亚洲老地址| 精品一区二区三区在线视频 | 精品人妻av无码一区二区三区| 国产美女一级做a爱视频| 久久精品国产亚洲7777| 看**一级**多毛片| 国产欧美久久久精品影院| 一级毛片在线完整观看| 欧美人与动欧交视频| 四虎精品1515hh| 84pao强力打造| 无码人妻丰满熟妇区五十路百度| 亚洲视频在线观看网站| 黄色aaa大片| 国产精品电影在线| 中文字幕亚洲欧美日韩不卡| 欧美日韩亚洲国产无线码| 国产一级一级一级成人毛片| 99久高清在线观看视频| 日韩毛片在线免费观看| 北条麻妃一区二区三区av高清 | 91成人在线免费视频| 日本不卡高字幕在线2019| 亚洲精品国精品久久99热| 精品欧美一区二区三区在线观看| 国产精品天堂avav在线|