Jack Jiang

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

          關(guān)于MobileIMSDK

          MobileIMSDK 是一套專門為移動(dòng)端開(kāi)發(fā)的開(kāi)源IM即時(shí)通訊框架,超輕量級(jí)、高度提煉,一套API優(yōu)雅支持UDP 、TCP 、WebSocket 三種協(xié)議,支持iOS、Android、H5、標(biāo)準(zhǔn)Java平臺(tái),服務(wù)端基于Netty編寫(xiě)。

          工程開(kāi)源地址是:

          關(guān)于RainbowChat

          ► 詳細(xì)產(chǎn)品介紹:http://www.52im.net/thread-19-1-1.html
          ► 版本更新記錄:http://www.52im.net/thread-1217-1-1.html
          ► 全部運(yùn)行截圖:Android端iOS端
          ► 在線體驗(yàn)下載:專業(yè)版(TCP協(xié)議)專業(yè)版(UDP協(xié)議)      (關(guān)于 iOS 端,請(qǐng):點(diǎn)此查看

           

          RainbowChat是一套基于開(kāi)源IM聊天框架 MobileIMSDK 的產(chǎn)品級(jí)移動(dòng)端IM系統(tǒng)。RainbowChat源于真實(shí)運(yùn)營(yíng)的產(chǎn)品,解決了大量的屏幕適配、細(xì)節(jié)優(yōu)化、機(jī)器兼容問(wèn)題(可自行下載體驗(yàn):專業(yè)版下載安裝)。

          * RainbowChat可能是市面上提供im即時(shí)通訊聊天源碼的,唯一一款同時(shí)支持TCP、UDP兩種通信協(xié)議的IM產(chǎn)品(通信層基于開(kāi)源IM聊天框架  MobileIMSDK 實(shí)現(xiàn))。

          v8.2 版更新內(nèi)容

          此版更新內(nèi)容更多歷史更新日志):

          (1)Android端主要更新內(nèi)容新增“掃一掃”等功能及優(yōu)化!】:

          • 1)[bug]解決了客戶端被踢掉后,再次登陸時(shí)提示socket錯(cuò)誤的問(wèn)題;
          • 2)[優(yōu)化]優(yōu)化了掃碼加群界面中,群頭像加載失敗時(shí)的默認(rèn)顯示樣式;
          • 3)[優(yōu)化]優(yōu)化了切換賬號(hào)和被踢時(shí)跳轉(zhuǎn)到登陸界面的切換性能;
          • 4)[優(yōu)化]重構(gòu)了主要類代碼,更方便集成;
          • 5)[新增]搜索功能(支持好友、群聊、聊天記錄搜索(與微信邏輯一樣));
          • 6)[新增]“聊信信息”界面中新增“查找聊天記錄”功能;
          • 7)[新增]“群聊信息”界面中新增“查找聊天記錄”、“清空聊天記錄”功能。

          (2)服務(wù)端主要更新內(nèi)容:

          • 1)[優(yōu)化][服務(wù)端]升級(jí)了MobileIMSDK至v6.2beta(改動(dòng)了onUserLoginout方法參數(shù));
          • 2)[優(yōu)化][服務(wù)端]解決了log4j2的兩個(gè)jar包沖突導(dǎo)致在linux下不能正常輸出log的問(wèn)題.

          此版主要新增功能運(yùn)行截圖更多截圖點(diǎn)此查看):

          posted @ 2022-06-25 22:37 Jack Jiang 閱讀(111) | 評(píng)論 (0)編輯 收藏

               摘要: 本文由字節(jié)跳動(dòng)技術(shù)團(tuán)隊(duì)開(kāi)發(fā)工程師王浩分享,即時(shí)通訊網(wǎng)收錄時(shí)有較多修訂。1、引言對(duì)于移動(dòng)互聯(lián)網(wǎng)時(shí)代的用戶來(lái)說(shuō),短視頻應(yīng)用再也不是看看視頻就完事,尤其抖音這種頭部應(yīng)用,已經(jīng)是除了傳統(tǒng)IM即時(shí)通訊軟件以外的新型社交產(chǎn)品了。對(duì)于中國(guó)人一年一度最重的節(jié)日——春節(jié)來(lái)說(shuō),紅包是必不可少的節(jié)日特定社交元素,而抖音自然不會(huì)被錯(cuò)過(guò)。在2022年的春節(jié)活動(dòng)期間,抖音將視頻和春節(jié)紅包相結(jié)合,用戶可...  閱讀全文

          posted @ 2022-06-20 17:12 Jack Jiang 閱讀(189) | 評(píng)論 (0)編輯 收藏

          本文由B站微服務(wù)技術(shù)團(tuán)隊(duì)資深開(kāi)發(fā)工程師周佳輝原創(chuàng)分享。

          1、引言

          如果你在 2015 年就使用 B 站,那么你一定不會(huì)忘記那一年 B 站工作日選擇性崩潰,周末必然性崩潰的一段時(shí)間。

          也是那一年 B 站投稿量激增,訪問(wèn)量隨之成倍上升,而過(guò)去的 PHP 全家桶也開(kāi)始逐漸展露出頹勢(shì),運(yùn)維難、監(jiān)控難、排查故障難、調(diào)用路徑深不見(jiàn)底。

          也就是在這一年,B 站開(kāi)始正式用 Go 重構(gòu) B 站,從此B站的API網(wǎng)關(guān)技術(shù)子開(kāi)始了從0到1的持續(xù)演進(jìn)。。。

          * 補(bǔ)充說(shuō)明:本次 API 網(wǎng)關(guān)演進(jìn)也以開(kāi)源形式進(jìn)行了開(kāi)發(fā),源碼詳見(jiàn)本文“12、本文源碼”。

          PS:本文分享的API網(wǎng)關(guān)涉及到的主要是HTTP短連接,雖然跟長(zhǎng)連接技術(shù)有些差異,但從架構(gòu)設(shè)計(jì)思路和實(shí)踐上是一脈相承的,所以也就收錄到了本《長(zhǎng)連接網(wǎng)關(guān)技術(shù)專題》系列文章中。

          學(xué)習(xí)交流:

          - 移動(dòng)端IM開(kāi)發(fā)入門文章:《新手入門一篇就夠:從零開(kāi)發(fā)移動(dòng)端IM

          - 開(kāi)源IM框架源碼:https://github.com/JackJiang2011/MobileIMSDK備用地址點(diǎn)此

          本文已同步發(fā)布于:http://www.52im.net/thread-3941-1-1.html

          2、關(guān)于作者

          周佳輝:嗶哩嗶哩資深開(kāi)發(fā)工程師。始終以簡(jiǎn)單為核心的技術(shù)設(shè)計(jì)理念,追求極致簡(jiǎn)單有效的后端架構(gòu)。

          2017 年加入 B 站,先后從事賬號(hào)、網(wǎng)關(guān)、基礎(chǔ)庫(kù)等開(kāi)發(fā)工作。編碼 C/V 技能傳授者,技術(shù)文檔背誦者。開(kāi)源社區(qū)愛(ài)好者,安全技術(shù)愛(ài)好者,云計(jì)算行業(yè)活躍用戶,網(wǎng)絡(luò)工程熟練工。史詩(shī)級(jí) bug 生產(chǎn)者,熟練掌握 bug 產(chǎn)生的各類場(chǎng)景。

          3、專題目錄

          本文是專題系列文章的第8篇,總目錄如下:

          4、正式用Go重構(gòu)B站

          鑒于引言中所列舉的各種技術(shù)問(wèn)題,也是在2015年,財(cái)隊(duì)開(kāi)始正式用 Go 重構(gòu) B 站。

          B站第一個(gè) Go 項(xiàng)目——bilizone,由冠冠老師(郝冠偉)花了一個(gè)周末時(shí)間編碼完成。

          commit 4ccb1497ca6d94cec0ea1b2555dd1859e6f4f223

          Author: felixhao <g******[url=mailto:1@gmail.com]1@gmail.com[/url]>

          Date:   Wed Jul 1 18:55:00 2015 +0800

              project init

          commit 6e338bc0ee638621e01918adb183747cf2a9e567

          Author: 郝冠偉 <h*******@bilibili.com>

          Date:   Wed Jul 1 11:21:18 2015 +0800

              readme

          ▲ 郝冠偉:?jiǎn)袅▎袅ㄖ髡炯夹g(shù)中心架構(gòu)師

          bilizone 其實(shí)還是一個(gè)大而全的應(yīng)用,bilizone 在當(dāng)時(shí)重構(gòu)的主要意義是將誰(shuí)也理不清的 PHP 邏輯梳理成了一個(gè)比較標(biāo)準(zhǔn)的 Go 應(yīng)用。

          bilizone 在當(dāng)時(shí)最大的意義就是為用戶終端提供了基本穩(wěn)定的數(shù)據(jù)結(jié)構(gòu)、相對(duì)可靠的接口和比較有效的監(jiān)控。

          但因 bilizone 依舊是一個(gè)單體應(yīng)用,所以它依舊繼承了單體應(yīng)用所具有的缺點(diǎn):

          • 1)代碼復(fù)雜度高:方法被濫用、超時(shí)設(shè)置混亂、牽一發(fā)而動(dòng)全身;
          • 2)一掛全掛:最常見(jiàn)的比如,超時(shí)設(shè)置不合理、goroutine 大量堆積、雪崩;
          • 3)測(cè)試及維護(hù)成本高:小改動(dòng)都需要測(cè)試所有 case,運(yùn)維發(fā)布膽戰(zhàn)心驚。

          所以此時(shí)B站的崩潰頻率雖然已經(jīng)有所降低,但一炸全炸的問(wèn)題依舊是一個(gè)心腹大患。

          5、基于微服務(wù)的B站架構(gòu)初具雛形

          鑒于bilizone所面臨的單體應(yīng)用技術(shù)缺點(diǎn),接下來(lái)的一次重構(gòu),讓B站基于微服務(wù)的全局架構(gòu)面貌就將初具雛形。

          為了實(shí)現(xiàn)微服務(wù)模式下的 bilibili,我們將一個(gè) bilizone 應(yīng)用拆分成多個(gè)獨(dú)立業(yè)務(wù)應(yīng)用,如賬號(hào)、稿件、廣告等等,這些業(yè)務(wù)通過(guò) SLB 直接對(duì)外提供 API。

          當(dāng)時(shí)的調(diào)用模式如下圖所示:

          但是隨著功能拆分后,我們對(duì)外暴露了一批微服務(wù),但是因?yàn)槿狈y(tǒng)一的出口而面臨了不少困難。

          這些困難主要是:

          • 1)客戶端與微服務(wù)直接通信,強(qiáng)耦合;
          • 2)需要多次請(qǐng)求,客戶端聚合數(shù)據(jù),工作量巨大,延遲高;
          • 3)協(xié)議不利于統(tǒng)一,各個(gè)部門間有差異,反而需要通過(guò)客戶端來(lái)兼容;
          • 4)面向“端”的 API 適配,耦合到了內(nèi)部服務(wù);
          • 5)多終端兼容邏輯復(fù)雜,每個(gè)服務(wù)都需要處理;
          • 6)統(tǒng)一邏輯無(wú)法收斂,比如安全認(rèn)證、限流。

          6、基于BFF模式的微服務(wù)架構(gòu)

          基于上節(jié)的初階微服務(wù)架構(gòu)帶來(lái)的技術(shù)問(wèn)題,以及我們想要將對(duì)端的處理進(jìn)行內(nèi)聚的想法,我們自然的而然的就想到在客戶端與后端服務(wù)之間加一個(gè) app-interface 的組件,這就是接下來(lái)的 BFF(Backend for Frontend)模式。

          app-interface 的工作模式如下圖所示:

          有了這個(gè) BFF 之后,我們可以在該服務(wù)內(nèi)進(jìn)行大量的數(shù)據(jù)聚合,按照業(yè)務(wù)場(chǎng)景來(lái)設(shè)計(jì)粗粒度的 API。

          這樣,后續(xù)服務(wù)的演進(jìn)也帶來(lái)了很多優(yōu)勢(shì):

          • 1)輕量交互:協(xié)議精簡(jiǎn)、聚合;
          • 2)差異服務(wù):數(shù)據(jù)裁剪以及聚合、針對(duì)終端定制化 API;
          • 3)動(dòng)態(tài)升級(jí):原有系統(tǒng)兼容升級(jí),更新服務(wù)而非協(xié)議;
          • 4)溝通效率提升:協(xié)作模式演進(jìn)為移動(dòng)業(yè)務(wù)和網(wǎng)關(guān)小組。

          BFF 可以認(rèn)為是一種適配服務(wù),將后端的微服務(wù)為客戶端的需要進(jìn)行適配(主要包括聚合裁剪和格式適配等邏輯),向終端設(shè)備暴露友好和統(tǒng)一的 API,方便無(wú)線設(shè)備接入訪問(wèn)后端服務(wù),在其中可能還伴隨有埋點(diǎn)、日志、統(tǒng)計(jì)等需求。

          然而,這個(gè)時(shí)期的 BFF 還有一個(gè)致命的一個(gè)問(wèn)題是——整個(gè) app-interface 屬于 single point of failure,嚴(yán)重代碼缺陷或者流量洪峰可能引發(fā)集群宕機(jī)所有接口不可用。

          7、基于多套BFF模式的微服務(wù)架構(gòu)

          針對(duì)上節(jié)中BFF模式下架構(gòu)的技術(shù)問(wèn)題,于是我們?cè)谏鲜龌A(chǔ)上進(jìn)一步迭代,將 app-interface 進(jìn)行業(yè)務(wù)拆分。

          進(jìn)而多套 BFF 的模式橫空出世:

          由此模式開(kāi)始,基本確定了 B 站微服務(wù)接口的對(duì)接模式,這套模式也隨之在全公司內(nèi)推廣開(kāi)來(lái)。

          8、垂直BFF模式時(shí)代(2016年至2019年)

          接上節(jié),當(dāng) B 站網(wǎng)關(guān)的架構(gòu)發(fā)展為多套垂直 BFF 之后,開(kāi)發(fā)團(tuán)隊(duì)圍繞該模式平穩(wěn)迭代了相當(dāng)長(zhǎng)的一段時(shí)間。

          而后隨著B(niǎo)站業(yè)務(wù)的發(fā)展,團(tuán)隊(duì)人員的擴(kuò)充和幾次組織架構(gòu)調(diào)整,此時(shí)開(kāi)始出現(xiàn)直播、電商等獨(dú)立業(yè)務(wù),這些業(yè)務(wù)的發(fā)展我們之后再細(xì)說(shuō)。

          而在這些調(diào)整之后,有一個(gè)團(tuán)隊(duì)的職責(zé)越來(lái)越清晰:主站網(wǎng)關(guān)組。

          主站網(wǎng)關(guān)組的主要職責(zé)就是維護(hù)上述各類功能的 BFF 網(wǎng)關(guān),此時(shí) bilibili 的主要流量入口為粉板 App。這里可以簡(jiǎn)單細(xì)說(shuō)一下粉板 App 上的所有業(yè)務(wù)組成。

          主站業(yè)務(wù):

          • 1)網(wǎng)關(guān)組維護(hù)的 BFF,如推薦、稿件播放頁(yè)等;
          • 2)業(yè)務(wù)層自行維護(hù)的 BFF,如評(píng)論、彈幕、賬號(hào)等。

          獨(dú)立業(yè)務(wù):

          • 1)電商服務(wù);
          • 2)直播服務(wù);
          • 3)動(dòng)態(tài)服務(wù)。

          主站業(yè)務(wù)的 BFF 其實(shí)被分為兩類:

          • 1)一類是由網(wǎng)關(guān)組負(fù)責(zé)的 BFF;
          • 2)另一類是業(yè)務(wù)自行維護(hù)的 BFF。

          而這兩類 BFF 的技術(shù)棧其實(shí)基本一致,基本功能職責(zé)也相差不多。如此劃分的原因是讓網(wǎng)關(guān)組可以更專注于迭代客戶端特性功能,免去理解部分獨(dú)立業(yè)務(wù)場(chǎng)景的接口,如登陸頁(yè)應(yīng)該讓對(duì)安全更專業(yè)賬號(hào)的同學(xué)自行維護(hù)。

          在這里我們也可以簡(jiǎn)述一下,一個(gè)新需求應(yīng)該如何決定參與的 BFF :

          • 1)如果這個(gè)功能能由業(yè)務(wù)層的業(yè)務(wù) BFF 獨(dú)立完成,則網(wǎng)關(guān)組不需介入;
          • 2)如果該功能是一個(gè)客戶端特性需求,如推薦流等復(fù)合型業(yè)務(wù),需要對(duì)接公司大量部門時(shí),則由網(wǎng)關(guān)同學(xué)參與開(kāi)發(fā) BFF。

          當(dāng)時(shí)主站技術(shù)部的后端同學(xué)遵循以上兩個(gè)規(guī)則,基本能夠滿足業(yè)務(wù)的快速開(kāi)發(fā)和迭代。

          我把這段時(shí)間稱為垂直 BFF 時(shí)代,因?yàn)榛局髡久總€(gè)業(yè)務(wù)或多或少都有各種形式的網(wǎng)關(guān)存在,大家通過(guò)這個(gè)網(wǎng)關(guān)向外提供接口,該網(wǎng)關(guān)和 SLB 進(jìn)行直接交互。

          9、基于業(yè)務(wù)的統(tǒng)一API網(wǎng)關(guān)架構(gòu)

          接上節(jié),我們?cè)賮?lái)談一談幾項(xiàng)重要的業(yè)務(wù):電商、直播和動(dòng)態(tài)。

          電商和直播其實(shí)并不是同一時(shí)期衍生的,直播在主站 PHP 時(shí)期就誕生了,而電商相對(duì)更晚一些。

          當(dāng)時(shí)直播的技術(shù)棧組成有 C++、PHP、Go,其中早期大部分業(yè)務(wù)邏輯由 PHP 和 C++ 實(shí)現(xiàn),稍晚一些也開(kāi)始逐步試用主站的 Go 實(shí)現(xiàn)部分業(yè)務(wù)邏輯。其中 PHP 負(fù)責(zé)對(duì)終端提供接口,C++ 主要實(shí)現(xiàn)核心業(yè)務(wù)功能。因此我們可以簡(jiǎn)單理解為直播使用由 PHP 編寫(xiě)的 BFF 網(wǎng)關(guān)。

          動(dòng)態(tài)團(tuán)隊(duì)其實(shí)派生自直播團(tuán)隊(duì),因此技術(shù)棧和直播當(dāng)時(shí)基本一致,這里可以簡(jiǎn)單省略。

          而眾所周知,大部分電商團(tuán)隊(duì)的技術(shù)棧都是 Java 和 Spring 或 Dubbo。

          因這幾個(gè)業(yè)務(wù)實(shí)現(xiàn)上幾乎沒(méi)有相似的地方,且大家對(duì) gRPC 協(xié)議逐漸地認(rèn)同,因此技術(shù)棧上大家基本沒(méi)有大一統(tǒng)的想法,互相能調(diào)通即可。

          而隨著 B 站團(tuán)隊(duì)進(jìn)一步的壯大、流量持續(xù)的增長(zhǎng),進(jìn)而經(jīng)歷了諸多線上故障、事故分析之后,大家慢慢發(fā)現(xiàn)了這套架構(gòu)下的各種問(wèn)題。

          這些問(wèn)題主要是:

          • 1)單個(gè)復(fù)雜模塊也會(huì)導(dǎo)致后續(xù)業(yè)務(wù)集成的高難度,根據(jù)康威法則,復(fù)雜聚合型 BFF 和多團(tuán)隊(duì)之間就出現(xiàn)不匹配問(wèn)題,團(tuán)隊(duì)之間溝通協(xié)調(diào)成本高,交付效率低下;
          • 2)很多跨橫切面邏輯,比如安全認(rèn)證,日志監(jiān)控,限流熔斷等。隨著時(shí)間的推移,功能的迭代,代碼變得越來(lái)越復(fù)雜,技術(shù)債越堆越多。

          此時(shí):我們可能還需要一個(gè)能協(xié)調(diào)橫跨切面的組件,將路由、認(rèn)證、限流、安全等組件全部上提,能夠統(tǒng)一更新發(fā)布,把業(yè)務(wù)集成度高的 BFF 層和通用功能服務(wù)層進(jìn)行分層,進(jìn)而大家開(kāi)始引入基于業(yè)務(wù)的“統(tǒng)一API網(wǎng)關(guān)”架構(gòu)(如下圖所示)。

          在新的架構(gòu)中:統(tǒng)一網(wǎng)關(guān)承擔(dān)了重要的角色,它是解耦拆分和后續(xù)升級(jí)遷移的利器。

          在統(tǒng)一網(wǎng)關(guān)的配合下:單塊 BFF 實(shí)現(xiàn)了解耦拆分,各業(yè)務(wù)線團(tuán)隊(duì)可以獨(dú)立開(kāi)發(fā)和交付各自的微服務(wù),研發(fā)效率大大提升。

          另外:把跨橫切面邏輯從 BFF 剝離到網(wǎng)關(guān)上去以后,BFF 的開(kāi)發(fā)人員可以更加專注業(yè)務(wù)邏輯交付,實(shí)現(xiàn)了架構(gòu)上的關(guān)注分離(Separation of Concerns)。

          10、從基于業(yè)務(wù)的多網(wǎng)關(guān)到全局統(tǒng)一網(wǎng)關(guān)(2022年至今)

          在這兩三年的時(shí)間里,各個(gè)業(yè)務(wù)團(tuán)隊(duì)或多或少都有自己業(yè)務(wù)網(wǎng)關(guān)組建獨(dú)立的維護(hù)團(tuán)隊(duì),也為網(wǎng)關(guān)的功能作出過(guò)相當(dāng)多的投入。

          但隨著 B 站業(yè)務(wù)的發(fā)展,公司級(jí)中間件功能的不斷更替演進(jìn),如果將對(duì)接各個(gè)中間件的工作在每個(gè)網(wǎng)關(guān)上都實(shí)現(xiàn)一次的話帶來(lái)的人力投入和溝通成本會(huì)相當(dāng)巨大,且實(shí)現(xiàn)標(biāo)準(zhǔn)不統(tǒng)一、運(yùn)營(yíng)方式不統(tǒng)一無(wú)法起到 API 網(wǎng)關(guān)所帶來(lái)的最佳收益。

          因此微服務(wù)團(tuán)隊(duì)開(kāi)發(fā)了一款 B 站內(nèi)部意義上的標(biāo)準(zhǔn) API 網(wǎng)關(guān)(全局統(tǒng)一API網(wǎng)關(guān)),該 API 網(wǎng)關(guān)匯集以往各型網(wǎng)關(guān)中流量治理的優(yōu)秀經(jīng)驗(yàn),對(duì)相關(guān)功能做出完善設(shè)計(jì)改進(jìn)。

          該 API 網(wǎng)關(guān)的目前的主要功能除了常規(guī)的限流、熔斷、降級(jí)、染色外,還會(huì)基于這些基礎(chǔ)功能和公司各類中間件的基礎(chǔ)上,提供各種額外能力。

          這些額外進(jìn)階型AP 質(zhì)量治理的相關(guān)功能主要是:

          • 1)全鏈路灰度;
          • 2)流量采樣分析、回放;
          • 3)流量安全控制;
          • ...

          業(yè)務(wù)團(tuán)隊(duì)在接入 API 網(wǎng)關(guān)后都可以一并獲得這些功能,為業(yè)務(wù)的迅速迭代做出力所能及的保障。

          11、不僅僅是 API 網(wǎng)關(guān)

          在開(kāi)發(fā) API 網(wǎng)關(guān)的同時(shí),我們也會(huì)更進(jìn)一步關(guān)注業(yè)務(wù)團(tuán)隊(duì)開(kāi)發(fā)、對(duì)接 API 時(shí)的體驗(yàn),我們將以網(wǎng)關(guān)作為統(tǒng)一標(biāo)準(zhǔn) API 規(guī)范的起點(diǎn),為業(yè)務(wù)團(tuán)隊(duì)提供更有效的 API 開(kāi)發(fā)生態(tài)。

          這些API 開(kāi)發(fā)生態(tài)可能是:

          • 1)規(guī)劃 API 業(yè)務(wù)域,簡(jiǎn)化 SRE 運(yùn)維;
          • 2)標(biāo)準(zhǔn) API 元信息平臺(tái);
          • 3)精確的 API 文檔和調(diào)試工具;
          • 4)類型安全的 API 集成 SDK;
          • 5)API 兼容性保障服務(wù)。

          API 網(wǎng)關(guān)是我們 API 治理生態(tài)中的一個(gè)標(biāo)志性里程碑,我們希望在 API 網(wǎng)關(guān)的開(kāi)發(fā)中能夠多多傾聽(tīng)大家的意見(jiàn),希望能有更多的聲音來(lái)幫助我們理清思路。

          本次 API 網(wǎng)關(guān)演進(jìn)也以開(kāi)源形式進(jìn)行了開(kāi)發(fā),在這里歡迎大家指導(dǎo)(本次源碼詳見(jiàn)本文“12、本文源碼)。

          12、本文源碼

          主地址:https://github.com/go-kratos/gateway

          備地址:https://github.com/52im/gateway

          或從原文鏈接中下載附件:http://www.52im.net/thread-3941-1-1.html

          13、參考資料

          [1] 喜馬拉雅自研億級(jí)API網(wǎng)關(guān)技術(shù)實(shí)踐

          [2] 手淘億級(jí)移動(dòng)端接入層網(wǎng)關(guān)的技術(shù)演進(jìn)之路

          [3] 從100到1000萬(wàn)高并發(fā)的架構(gòu)演進(jìn)之路

          [4] 一文讀懂大型分布式系統(tǒng)設(shè)計(jì)的方方面面

          [5] 零基礎(chǔ)理解大型分布式架構(gòu)的演進(jìn)歷史、技術(shù)原理、最佳實(shí)踐

          本文已同步發(fā)布于:http://www.52im.net/thread-3941-1-1.html

          posted @ 2022-06-14 11:56 Jack Jiang 閱讀(155) | 評(píng)論 (0)編輯 收藏

          本文引用了文章“月活 12.8 億的微信是如何防止崩潰的?”和論文“Overload Control for Scaling WeChat Microservices”的內(nèi)容,有大量改動(dòng)、優(yōu)化和修訂。

          1、引言

          微信是一款國(guó)民級(jí)的即時(shí)通訊IM應(yīng)用,月活用戶早就超過(guò)10億,而且經(jīng)常過(guò)年過(guò)節(jié)會(huì)遇到聊天消息量暴增的情況,服務(wù)是很容易出現(xiàn)過(guò)載的,但事實(shí)是微信的后臺(tái)服務(wù)一直比較穩(wěn)定,那么他們是怎么做到的呢?

          本文以微信發(fā)表的論文《Overload Control for Scaling Wechat Microservices》 為基礎(chǔ)(論文PDF原文下載見(jiàn)文末附件),分享了微信基于大規(guī)模微服務(wù)架構(gòu)的后臺(tái)過(guò)載管控和保護(hù)策略,以及微信根據(jù)IM業(yè)務(wù)特點(diǎn)的一些獨(dú)特的架構(gòu)設(shè)計(jì)做法,其中很多方法很有借鑒意義,值得一讀。

           (本文已同步發(fā)布于:http://www.52im.net/thread-3930-1-1.html

          2、微信所面臨的并發(fā)壓力

          截止論文《Overload Control for Scaling Wechat Microservices》發(fā)表前,微信后端有超過(guò)3000多個(gè)服務(wù)(包括即時(shí)聊天、社交關(guān)系、移動(dòng)支付和第三方授權(quán)等),占用20000多臺(tái)機(jī)器(隨著微信的廣泛普及,這些數(shù)字仍在不斷增加)。

          面向前端請(qǐng)求的入口服務(wù)每天需要處理10億到100億級(jí)別的請(qǐng)求,而每個(gè)這樣的請(qǐng)求還會(huì)觸發(fā)更多內(nèi)部的關(guān)聯(lián)服務(wù),從整體來(lái)看,微信后端需要每秒處理數(shù)億個(gè)請(qǐng)求。

          隨著微信的不斷發(fā)展,這些服務(wù)子系統(tǒng)一直在快速進(jìn)行更新迭代。以2018 年的3月到5月為例,在短短的兩個(gè)月時(shí)間里,微信的各服務(wù)子系統(tǒng)平均每天發(fā)生近千次的變更,運(yùn)維壓力可想而之。

          另外:微信每天請(qǐng)求量的分布很不平均,高峰期請(qǐng)求量能達(dá)到平時(shí)的3倍。而在特殊日子里(比如過(guò)年的時(shí)候),高峰期的流量能飆升到平時(shí)的10倍。有時(shí)朋友圈里有什么刷屏的活動(dòng),流量肯定也會(huì)突增。由此可見(jiàn),微信后端系統(tǒng)的并發(fā)壓力相當(dāng)之大。

          而且:微信后端的這些服務(wù)所處的環(huán)境也是不斷變化的,包括硬件故障、代碼bug、系統(tǒng)變更等,都會(huì)導(dǎo)致服務(wù)可承受的容量動(dòng)態(tài)變化。

          3、微信的后端服務(wù)架構(gòu)

          微信后端采用的也是微服務(wù)架構(gòu)。說(shuō)是微服務(wù),其實(shí)我理解就是采用統(tǒng)一的 RPC 框架搭建的一個(gè)個(gè)獨(dú)立的服務(wù),服務(wù)之間互相調(diào)用,實(shí)現(xiàn)各種各樣的功能,這也是現(xiàn)代服務(wù)的基本架構(gòu)。畢竟誰(shuí)也不希望看到我朋友圈崩了,導(dǎo)致跟我聊天也不行了,這也是微信的典型好處。

          微信后端的微服務(wù)架構(gòu)一般分為3層:

          如上圖所示,這3層服務(wù)分別是:

          • 1)“入口跳板”服務(wù)(接收外部請(qǐng)求的前端服務(wù));
          • 2)“共享跳板”服務(wù)(中間層協(xié)調(diào)服務(wù));
          • 3)“基礎(chǔ)服務(wù)”(不再向其他服務(wù)發(fā)出請(qǐng)求的服務(wù),也就是充當(dāng)請(qǐng)求的接收器)。

          微信后端的大多數(shù)服務(wù)屬于“共享跳板”服務(wù),“入口跳板”服務(wù)比如登錄、發(fā)送聊天消息、支付服務(wù)等。“基礎(chǔ)服務(wù)”也就是日常最好理解的這些信息數(shù)據(jù)接口類,比如賬戶數(shù)據(jù)、個(gè)人信息、好友/聯(lián)系人信息等。

          按照微信后端服務(wù)的請(qǐng)求量(每日在十億到百億之間),入口協(xié)議觸發(fā)對(duì)“共享跳板”服務(wù)和“基礎(chǔ)服務(wù)”更多的請(qǐng)求,核心服務(wù)每秒要處理上億次的請(qǐng)求,也就是顯而易見(jiàn)的了。

          4、什么是過(guò)載保護(hù)

          1)什么是服務(wù)過(guò)載?

          服務(wù)過(guò)載就是服務(wù)的請(qǐng)求量超過(guò)服務(wù)所能承受的最大值,從而導(dǎo)致服務(wù)器負(fù)載過(guò)高,響應(yīng)延遲加大。

          用戶側(cè)表現(xiàn)就是無(wú)法加載或者加載緩慢,這會(huì)引起用戶進(jìn)一步的重試,服務(wù)一直在處理過(guò)去的無(wú)效請(qǐng)求,導(dǎo)致有效請(qǐng)求跌 0,甚至導(dǎo)致整個(gè)系統(tǒng)產(chǎn)生雪崩。

          2)為什么會(huì)發(fā)生服務(wù)過(guò)載?

          互聯(lián)網(wǎng)天生就會(huì)有突發(fā)流量、秒殺、搶購(gòu)、突發(fā)大事件、節(jié)日甚至惡意攻擊等,都會(huì)造成服務(wù)承受平時(shí)數(shù)倍的壓力,比如微博經(jīng)常出現(xiàn)某明星官宣結(jié)婚或者離婚導(dǎo)致服務(wù)器崩潰的場(chǎng)景,這就是服務(wù)過(guò)載。

          3)過(guò)載保護(hù)的好處

          過(guò)載保護(hù)主要是為了提升用戶體驗(yàn),保障服務(wù)質(zhì)量,在發(fā)生突發(fā)流量時(shí)仍然能夠提供一部分服務(wù)能力,而不是整個(gè)系統(tǒng)癱瘓。

          系統(tǒng)癱瘓就意味著用戶流失、口碑變差、夫妻吵架,甚至威脅生命安全(假如騰訊文檔崩潰,這個(gè)文檔正好用于救災(zāi))。

          而微信團(tuán)隊(duì)在面對(duì)這種量級(jí)的高并發(fā)請(qǐng)求挑戰(zhàn),做法是精細(xì)化的服務(wù)過(guò)載控制。我們繼續(xù)往下學(xué)習(xí)。

          5、微信面臨的過(guò)載控制技術(shù)挑戰(zhàn)

          過(guò)載控制對(duì)于大規(guī)模在線應(yīng)用程序來(lái)說(shuō)至關(guān)重要,這些應(yīng)用程序需要在不可預(yù)測(cè)的負(fù)載激增的情況下實(shí)現(xiàn) 24×7 服務(wù)可用性。

          傳統(tǒng)的過(guò)載控制機(jī)制是為具有少量服務(wù)組件、相對(duì)狹窄的“前門”和普通依賴關(guān)系的系統(tǒng)而設(shè)計(jì)的。

          而微信這種現(xiàn)代即時(shí)通訊im應(yīng)用的全時(shí)在線服務(wù)特性,在架構(gòu)和依賴性方面正變得越來(lái)越復(fù)雜,遠(yuǎn)遠(yuǎn)超出了傳統(tǒng)過(guò)載控制的設(shè)計(jì)目標(biāo)。

          這些技術(shù)痛點(diǎn)包括:

          • 1)由于發(fā)送到微信后端的服務(wù)請(qǐng)求沒(méi)有單一的入口點(diǎn),因此傳統(tǒng)的全局入口點(diǎn)(網(wǎng)關(guān))集中負(fù)載監(jiān)控方法并不適用;
          • 2)特定請(qǐng)求的服務(wù)調(diào)用圖可能依賴于特定于請(qǐng)求的數(shù)據(jù)和服務(wù)參數(shù),即使對(duì)于相同類型的請(qǐng)求也是如此(因此,當(dāng)特定服務(wù)出現(xiàn)過(guò)載時(shí),很難確定應(yīng)該限制哪些類型的請(qǐng)求以緩解這種情況);
          • 3)過(guò)多的請(qǐng)求中止浪費(fèi)了計(jì)算資源,并由于高延遲而影響了用戶體驗(yàn);
          • 4)由于服務(wù)的調(diào)用鏈極其復(fù)雜,而且在不斷演化,導(dǎo)致有效的跨服務(wù)協(xié)調(diào)的維護(hù)成本和系統(tǒng)開(kāi)銷過(guò)高。

          由于一個(gè)服務(wù)可能會(huì)向它所依賴的服務(wù)發(fā)出多個(gè)請(qǐng)求,并且還可能向多個(gè)后端服務(wù)發(fā)出請(qǐng)求,因此我們必須特別注意過(guò)載控制。我們使用一個(gè)專門的術(shù)語(yǔ),叫作“后續(xù)過(guò)載”,用于描述調(diào)用多個(gè)過(guò)載服務(wù)或多次調(diào)用單個(gè)過(guò)載服務(wù)的情況。

          “后續(xù)過(guò)載”給有效的過(guò)載控制帶來(lái)了挑戰(zhàn)。當(dāng)服務(wù)過(guò)載時(shí)隨機(jī)執(zhí)行減載可以讓系統(tǒng)維持飽和的吞吐量,但后續(xù)過(guò)載可能會(huì)超預(yù)期大大降低系統(tǒng)吞吐量 …

          即:在大規(guī)模微服務(wù)場(chǎng)景下,過(guò)載會(huì)變得比較復(fù)雜,如果是單體服務(wù),一個(gè)事件只用一個(gè)請(qǐng)求,但微服務(wù)下,一個(gè)事件可能要請(qǐng)求很多的服務(wù),任何一個(gè)服務(wù)過(guò)載失敗,就會(huì)造成其他的請(qǐng)求都是無(wú)效的。如下圖所示。

           比如:在一個(gè)轉(zhuǎn)賬服務(wù)下,需要查詢分別兩者的卡號(hào), 再查詢 A 時(shí)成功了,但查詢 B 失敗,對(duì)于查卡號(hào)這個(gè)事件就算失敗了。比如查詢成功率只有 50%, 那對(duì)于查詢兩者卡號(hào)這個(gè)成功率只有 50% * 50% = 25% 了, 一個(gè)事件調(diào)用的服務(wù)次數(shù)越多,那成功率就會(huì)越低。

          6、微信的過(guò)載控制機(jī)制

          微信的微服務(wù)過(guò)載控制機(jī)制叫“DAGOR”(因?yàn)槲⑿虐阉姆?wù)間關(guān)系模型叫“directed acyclic graph ”,簡(jiǎn)稱DAG)。

          顯然這種微服務(wù)底層的機(jī)制必須是和具體的業(yè)務(wù)實(shí)現(xiàn)無(wú)關(guān)的。DAGOR還必須是去中心化的,否則的話在微信這么大且分布不均的流量下,過(guò)載控制很難做到實(shí)時(shí)和準(zhǔn)確。同時(shí)也無(wú)法適應(yīng)微服務(wù)快速的功能迭代發(fā)布(平均每天要發(fā)生近1000次的微服務(wù)上下線)。

          此外,DAGOR還需要解決一個(gè)問(wèn)題:服務(wù)調(diào)用鏈很長(zhǎng),如果底層服務(wù)因?yàn)檫^(guò)載保護(hù)丟棄了請(qǐng)求,上層服務(wù)耗費(fèi)的資源全浪費(fèi)了,而且很影響用戶體驗(yàn)(想想進(jìn)度條走到99%告訴你失敗了)。所以過(guò)載控制機(jī)制在各服務(wù)之間必須有協(xié)同作用,有時(shí)候需要考慮整個(gè)調(diào)用鏈的情況。

          首先我們來(lái)看怎么檢測(cè)到服務(wù)過(guò)載。

          7、微信如何判斷過(guò)載

          通常判斷過(guò)載可以使用吞吐量、延遲、CPU 使用率、丟包率、待處理請(qǐng)求數(shù)、請(qǐng)求處理事件等等。

          微信使用在請(qǐng)求在隊(duì)列中的平均等待時(shí)間作為判斷標(biāo)準(zhǔn)。平均等待時(shí)間就是從請(qǐng)求到達(dá),到開(kāi)始處理的時(shí)間。

          為啥不使用響應(yīng)時(shí)間?因?yàn)轫憫?yīng)時(shí)間是跟服務(wù)相關(guān)的,很多微服務(wù)是鏈?zhǔn)秸{(diào)用,響應(yīng)時(shí)間是不可控的,也是無(wú)法標(biāo)準(zhǔn)化的,很難作為一個(gè)統(tǒng)一的判斷依據(jù)。

          那為什么也不使用 CPU 負(fù)載作為判斷標(biāo)準(zhǔn)呢? 因?yàn)?CPU 負(fù)載高不代表服務(wù)過(guò)載,因?yàn)橐粋€(gè)服務(wù)請(qǐng)求處理及時(shí),CPU 處于高位反而是比較良好的表現(xiàn)。實(shí)際上 CPU 負(fù)載高,監(jiān)控服務(wù)是會(huì)告警出來(lái),但是并不會(huì)直接進(jìn)入過(guò)載處理流程。

          騰訊微服務(wù)默認(rèn)的超時(shí)時(shí)間是 500ms,通過(guò)計(jì)算每秒或每 2000 個(gè)請(qǐng)求的平均等待時(shí)間是否超過(guò) 20ms,判斷是否過(guò)載,這個(gè) 20ms 是根據(jù)微信后臺(tái) 5 年摸索出來(lái)的門檻值。

          采用平均等待時(shí)間還有一個(gè)好處是:獨(dú)立于服務(wù),可以應(yīng)用于任何場(chǎng)景,而不用關(guān)聯(lián)于業(yè)務(wù),可以直接在框架上進(jìn)行改造。

          當(dāng)平均等待時(shí)間大于 20ms 時(shí),以一定的降速因子過(guò)濾調(diào)部分請(qǐng)求,如果判斷平均等待時(shí)間小于 20ms,則以一定的速率提升通過(guò)率,一般采用快降慢升的策略,防止大的服務(wù)波動(dòng),整個(gè)策略相當(dāng)于一個(gè)負(fù)反饋電路。

           

          8、微信的過(guò)載控制策略

          微信后臺(tái)一旦檢測(cè)到服務(wù)過(guò)載,就需要按照一定的過(guò)載保戶策略對(duì)請(qǐng)求進(jìn)行過(guò)濾控制,來(lái)決定哪些請(qǐng)求能被過(guò)載服務(wù)處理,哪些是需要丟棄的。

          前面我們分析過(guò),對(duì)于鏈?zhǔn)秸{(diào)用的微服務(wù)場(chǎng)景,隨機(jī)丟棄請(qǐng)求會(huì)導(dǎo)致整體服務(wù)的成功率很低。所以請(qǐng)求是按照優(yōu)先級(jí)進(jìn)行控制的,優(yōu)先級(jí)低的請(qǐng)求會(huì)優(yōu)先丟棄。

          那么從哪些維度來(lái)進(jìn)行優(yōu)化級(jí)的分級(jí)呢?

          8.1 基于業(yè)務(wù)的優(yōu)先級(jí)控制

          對(duì)于微信來(lái)說(shuō),不同的業(yè)務(wù)場(chǎng)景優(yōu)先級(jí)是不同的, 比如:

          • 1)登錄場(chǎng)景是最重要的業(yè)務(wù)(不能登錄一切都白瞎);
          • 2)支付消息比普通im聊天消息優(yōu)先級(jí)高(因?yàn)橛脩魧?duì)金錢是更敏感的);
          • 3)普通消息又比朋友圈消息優(yōu)先級(jí)高(必竟微信的本質(zhì)還是im聊天)。

          所以在微信內(nèi)是天然存在業(yè)務(wù)優(yōu)先級(jí)的。

          微信的做法是,預(yù)先定義好所有業(yè)務(wù)的優(yōu)先級(jí)并保存在一個(gè)Hash Table里:

          沒(méi)有定義的業(yè)務(wù),默認(rèn)是最低優(yōu)先級(jí)。

          業(yè)務(wù)優(yōu)先級(jí)在各個(gè)業(yè)務(wù)的入口服務(wù)(Entry Services)中找到請(qǐng)求元信息里。由于一個(gè)請(qǐng)求成功與否依賴其下游服務(wù)所有的后續(xù)請(qǐng)求,所以下游服務(wù)的所有后續(xù)請(qǐng)求也會(huì)帶上相同的業(yè)務(wù)優(yōu)先級(jí)。當(dāng)服務(wù)過(guò)載時(shí),會(huì)處理優(yōu)先級(jí)更高的請(qǐng)求,丟棄優(yōu)先級(jí)低的請(qǐng)求。

          然而,只用業(yè)務(wù)優(yōu)先級(jí)決定是否丟棄請(qǐng)求,容易造成系統(tǒng)顛簸,比如:

          • 1)支付請(qǐng)求突然上漲導(dǎo)致過(guò)載,消息請(qǐng)求被丟棄;
          • 2)丟棄消息請(qǐng)求后,系統(tǒng)負(fù)載降低了,又開(kāi)始處理消息請(qǐng)求;
          • 3)然而,處理消息請(qǐng)求又導(dǎo)致服務(wù)過(guò)載,又會(huì)在下一個(gè)窗口拋棄消息請(qǐng)求。

          這樣反復(fù)調(diào)整服務(wù)請(qǐng)求管制,整體體驗(yàn)非常不好。所以微信需要更精細(xì)化的服務(wù)請(qǐng)求管制。

          PS:微信嘗試過(guò)提供API讓服務(wù)提供方自己修改業(yè)務(wù)優(yōu)先級(jí),后來(lái)在實(shí)踐中發(fā)現(xiàn)這種做法在不同的團(tuán)隊(duì)中極難管理,且對(duì)于過(guò)載控制容易出錯(cuò),最終放棄了。

          8.2 基于用戶的優(yōu)先級(jí)控制

          很明顯,正如上節(jié)內(nèi)容所述,只基于業(yè)務(wù)優(yōu)先級(jí)的控制是不夠的:

          • 1)首先不可能因?yàn)樨?fù)載高,丟棄或允許通過(guò)一整個(gè)業(yè)務(wù)的請(qǐng)求,因?yàn)槊總€(gè)業(yè)務(wù)的請(qǐng)求量很大,那一定會(huì)造成負(fù)載的大幅波動(dòng);
          • 2)另外如果在業(yè)務(wù)中隨機(jī)丟棄請(qǐng)求,在過(guò)載情況下還是會(huì)導(dǎo)致整體成功率很低。

          為了解決這個(gè)問(wèn)題,微信引入用戶優(yōu)先級(jí)。

          微信在每個(gè)業(yè)務(wù)優(yōu)先級(jí)內(nèi)按用戶ID計(jì)算出的128個(gè)優(yōu)先級(jí):

          首先用戶優(yōu)先級(jí)也不應(yīng)該相同,對(duì)于普通人來(lái)說(shuō)通過(guò) hash 用戶唯一 ID計(jì)算用戶優(yōu)先級(jí)(這個(gè)hash函數(shù)每小時(shí)變一次,讓所有用戶都有機(jī)會(huì)在相對(duì)較長(zhǎng)的時(shí)間內(nèi)享受到高優(yōu)先級(jí),保證“公平”)。跟業(yè)務(wù)優(yōu)先級(jí)一樣,單個(gè)用戶的訪問(wèn)鏈條上的優(yōu)先級(jí)總是一致的。

          這里有個(gè)疑問(wèn):為啥不采用會(huì)話 ID 計(jì)算優(yōu)先級(jí)呢?

          從理論上來(lái)說(shuō)采用會(huì)話 ID 和用戶 ID 效果是一樣的,但是采用會(huì)話 ID 在用戶重新登錄時(shí)刷新,這個(gè)時(shí)候可能用戶的優(yōu)先級(jí)可能變了。在過(guò)載的情況下,他可能因?yàn)樘岣吡藘?yōu)先級(jí)就恢復(fù)了。

          這樣用戶會(huì)養(yǎng)成壞習(xí)慣,在服務(wù)有問(wèn)題時(shí)就會(huì)重新登錄,這樣無(wú)疑進(jìn)一步加劇了服務(wù)的過(guò)載情況。

          于是,因?yàn)橐肓擞脩魞?yōu)先級(jí),那就和業(yè)務(wù)優(yōu)先級(jí)組成了一個(gè)二維控制平面。根據(jù)負(fù)載情況,決定這臺(tái)服務(wù)器的準(zhǔn)入優(yōu)先級(jí)(B,U),當(dāng)過(guò)來(lái)的請(qǐng)求業(yè)務(wù)優(yōu)先級(jí)大于 B,或者業(yè)務(wù)優(yōu)先級(jí)等于 B,但用戶優(yōu)先級(jí)高于 U 時(shí),則通過(guò),否則決絕。

          下圖就是這個(gè)“優(yōu)先級(jí)(B,U)”控制邏輯(我們會(huì)在后面再具體討論):

          8.3 自適應(yīng)優(yōu)先級(jí)調(diào)整

          在大規(guī)模微服務(wù)場(chǎng)景下,服務(wù)器的負(fù)載變化是非常頻繁的。所以服務(wù)器的準(zhǔn)入優(yōu)先級(jí)是需要?jiǎng)討B(tài)變化的,微信分了幾十個(gè)業(yè)務(wù)優(yōu)先級(jí),每個(gè)業(yè)務(wù)優(yōu)先級(jí)下有 128 個(gè)用戶優(yōu)先級(jí),所以總的優(yōu)先級(jí)是幾千個(gè)。

          如何根據(jù)負(fù)載情況調(diào)整優(yōu)先級(jí)呢?

          最簡(jiǎn)單的方式是從右到左遍歷:每調(diào)整一次判斷下負(fù)載情況。這個(gè)時(shí)間復(fù)雜度是 O(n), 就算使用二分法,時(shí)間復(fù)雜度也為 O(logn),在數(shù)千個(gè)優(yōu)先級(jí)下,可能需要數(shù)十次調(diào)整才能確定一個(gè)合適的優(yōu)先級(jí),每次調(diào)整好再統(tǒng)計(jì)優(yōu)先級(jí),可能幾十秒都過(guò)去了,這個(gè)方法無(wú)疑是非常低效的。

          微信提出了一種基于直方圖統(tǒng)計(jì)的方法快速調(diào)整準(zhǔn)入優(yōu)先級(jí):服務(wù)器上維護(hù)者目前準(zhǔn)入優(yōu)先級(jí)下,過(guò)去一個(gè)周期的(1s 或 2000 次請(qǐng)求)每個(gè)優(yōu)先級(jí)的請(qǐng)求量。當(dāng)過(guò)載時(shí),通過(guò)消減下一個(gè)周期的請(qǐng)求量來(lái)減輕負(fù)載。假設(shè)上一個(gè)周期所有優(yōu)先級(jí)的通過(guò)的請(qǐng)求總和是 N,下一個(gè)周期的請(qǐng)求量要減少 N*a,怎么去減少呢?每提升一個(gè)優(yōu)先級(jí)就減少一定的請(qǐng)求量,一直提升到 減少的數(shù)目大于目標(biāo)量,恢復(fù)負(fù)載使用相反的方法,只不是系數(shù)為 b ,比 a 小,也是為了快降慢升。根據(jù)經(jīng)驗(yàn)值 a 為 5%,b 為 1%。

          為了進(jìn)一步減輕過(guò)載機(jī)器的壓力,能不能在下游過(guò)載的情況下不把請(qǐng)求發(fā)到下游呢?否則下游還是要接受請(qǐng)求、解包、丟棄請(qǐng)求,白白的浪費(fèi)帶寬,也加重了下游的負(fù)載。

          為了實(shí)現(xiàn)這個(gè)能力:在每次請(qǐng)求下游服務(wù)時(shí),下游把當(dāng)前服務(wù)的準(zhǔn)入優(yōu)先級(jí)返回給上游,上游維護(hù)下游服務(wù)的準(zhǔn)入優(yōu)先級(jí),如果發(fā)現(xiàn)請(qǐng)求優(yōu)先級(jí)達(dá)不到下游服務(wù)的準(zhǔn)入門檻,直接丟棄,而不再請(qǐng)求下游,進(jìn)一步減輕下游的壓力。

          9、實(shí)驗(yàn)數(shù)據(jù)

          微信的這套服務(wù)過(guò)載控制策略(即DAGOR)在微信的生產(chǎn)環(huán)境已經(jīng)運(yùn)作多年,這是對(duì)它的設(shè)計(jì)可行性的最好證明。

          但并沒(méi)有為學(xué)術(shù)論文提供必要的圖表,所以微信同時(shí)進(jìn)行了一組模擬實(shí)驗(yàn)。

          下面的圖表突出顯示了基于排隊(duì)時(shí)間而非響應(yīng)時(shí)間的過(guò)載控制的好處。在發(fā)生后續(xù)過(guò)載的情況下,這些好處最為明顯(圖右)。

          10、小結(jié)一下

          微信的整個(gè)過(guò)載控制邏輯流程如下圖所示:

          針對(duì)上面這張圖,我們來(lái)解讀一下:

          • 1)當(dāng)用戶從微信發(fā)起請(qǐng)求,請(qǐng)求被路由到接入層服務(wù),分配統(tǒng)一的業(yè)務(wù)和用戶優(yōu)先級(jí),所有到下游的字請(qǐng)求都繼承相同的優(yōu)先級(jí);
          • 2)根據(jù)業(yè)務(wù)邏輯調(diào)用 1 個(gè)或多個(gè)下游服務(wù),當(dāng)服務(wù)收到請(qǐng)求,首先根據(jù)自身服務(wù)準(zhǔn)入優(yōu)先級(jí)判斷請(qǐng)求是接受還是丟棄(服務(wù)本身根據(jù)負(fù)載情況周期性的調(diào)整準(zhǔn)入優(yōu)先級(jí));
          • 3)當(dāng)服務(wù)需要再向下游發(fā)起請(qǐng)求時(shí),判斷本地記錄的下游服務(wù)準(zhǔn)入優(yōu)先級(jí)(如果小于則丟棄,如果沒(méi)有記錄或優(yōu)先級(jí)大于記錄則向下游發(fā)起請(qǐng)求);
          • 4)下游服務(wù)返回上游服務(wù)需要的信息,并且在信息中攜帶自身準(zhǔn)入優(yōu)先級(jí);
          • 5)上游接受到返回后解析信息,并更新本地記錄的下游服務(wù)準(zhǔn)入優(yōu)先級(jí)。

          微信的整個(gè)過(guò)載控制策略有以下三個(gè)特點(diǎn):

          • 1)業(yè)務(wù)無(wú)關(guān)的:使用請(qǐng)求等待時(shí)間而不是響應(yīng)時(shí)間,制定用戶和業(yè)務(wù)優(yōu)先級(jí),這些都與業(yè)務(wù)本身無(wú)關(guān);
          • 2)高效且公平: 請(qǐng)求鏈條的優(yōu)先級(jí)是一致的,并且會(huì)定時(shí)改變 hash 函數(shù)調(diào)整用戶優(yōu)先級(jí),過(guò)載情況下,不會(huì)總是影響固定的用戶;
          • 3)獨(dú)立控制和聯(lián)合控制結(jié)合:準(zhǔn)入優(yōu)先級(jí)取決于獨(dú)立的服務(wù),但又可以聯(lián)合下游服務(wù)的情況,優(yōu)化服務(wù)過(guò)載時(shí)的表現(xiàn)。

          11、寫(xiě)在最后

          微信團(tuán)隊(duì)的分享只提到過(guò)載控制,但我相信服務(wù)調(diào)用方應(yīng)該還有一些其他機(jī)制,能夠解決不是因?yàn)橄掠畏?wù)過(guò)載,而是因?yàn)榫W(wǎng)絡(luò)抖動(dòng)導(dǎo)致的請(qǐng)求超時(shí)問(wèn)題。

          微信的這套微服務(wù)過(guò)載控制機(jī)制(即DAGOR)提供的服務(wù)無(wú)關(guān)、去中心化、高效和公平等特性很好地在微信后端跑了很多年。

          最后,微信團(tuán)隊(duì)還分享了他們?cè)O(shè)計(jì)和運(yùn)維DAGOR寶貴經(jīng)驗(yàn):

          • 1)大規(guī)模微服務(wù)架構(gòu)中的過(guò)載控制必須在每個(gè)服務(wù)中實(shí)現(xiàn)分散和自治;
          • 2)過(guò)載控制應(yīng)該要考慮到各種反饋機(jī)制(例如 DAGOR 的協(xié)作準(zhǔn)入控制),而不是僅僅依賴于開(kāi)環(huán)啟發(fā)式;
          • 3)應(yīng)該通過(guò)分析實(shí)際工作負(fù)載來(lái)了解過(guò)載控制設(shè)計(jì)。

          12、參考資料

          [1] Overload Control for Scaling WeChat Microservices

          [2] 羅神解讀“Overload Control for Scaling WeChat Microservices”

          [3] 2W臺(tái)服務(wù)器、每秒數(shù)億請(qǐng)求,微信如何不“失控”?

          [4] DAGOR:微信微服務(wù)過(guò)載控制系統(tǒng)

          [5] 月活 12.8 億的微信是如何防止崩潰的?

          [6] 微信朋友圈千億訪問(wèn)量背后的技術(shù)挑戰(zhàn)和實(shí)踐總結(jié)

          [7] QQ 18年:解密8億月活的QQ后臺(tái)服務(wù)接口隔離技術(shù)

          [8] 微信后臺(tái)基于時(shí)間序的海量數(shù)據(jù)冷熱分級(jí)架構(gòu)設(shè)計(jì)實(shí)踐

          [9] 架構(gòu)之道:3個(gè)程序員成就微信朋友圈日均10億發(fā)布量[有視頻]

          [10] 快速裂變:見(jiàn)證微信強(qiáng)大后臺(tái)架構(gòu)從0到1的演進(jìn)歷程(一)

          [11] 一份微信后臺(tái)技術(shù)架構(gòu)的總結(jié)性筆記

          13、論文原文

          論文PDF請(qǐng)下載此附件:

          因無(wú)法上傳附件,請(qǐng)從此鏈接:http://www.52im.net/thread-3930-1-1.html文末的“參考資料”附件中下載

          論文PDF全部?jī)?nèi)容概覽:

          本文已同步發(fā)布于:http://www.52im.net/thread-3930-1-1.html

          posted @ 2022-06-06 16:31 Jack Jiang 閱讀(648) | 評(píng)論 (0)編輯 收藏

          本文由蘑菇街前端開(kāi)發(fā)工程師“三體”分享,原題“蘑菇街云端直播探索——啟航篇”,有修訂。

          1、引言

          隨著移動(dòng)網(wǎng)絡(luò)網(wǎng)速的提升與資費(fèi)的降低,視頻直播作為一個(gè)新的娛樂(lè)方式已經(jīng)被越來(lái)越多的用戶逐漸接受。特別是最近這幾年,視頻直播已經(jīng)不僅僅被運(yùn)用在傳統(tǒng)的秀場(chǎng)、游戲類板塊,更是作為電商的一種新模式得到迅速成長(zhǎng)。

          本文將通過(guò)介紹實(shí)時(shí)視頻直播技術(shù)體系,包括常用的推拉流架構(gòu)、傳輸協(xié)議等,讓你對(duì)現(xiàn)今主流的視頻直播技術(shù)有一個(gè)基本的認(rèn)知。

          學(xué)習(xí)交流:

          - 移動(dòng)端IM開(kāi)發(fā)入門文章:《新手入門一篇就夠:從零開(kāi)發(fā)移動(dòng)端IM

          - 開(kāi)源IM框架源碼:https://github.com/JackJiang2011/MobileIMSDK備用地址點(diǎn)此

          本文已同步發(fā)布于:http://www.52im.net/thread-3922-1-1.html

          2、蘑菇街的直播架構(gòu)概覽

          目前蘑菇街直播推拉流主流程依賴于某云直播的服務(wù)。

          云直播提供的推流方式有兩種:

          • 1)一是通過(guò)集成SDK的方式進(jìn)行推流(用于手機(jī)端開(kāi)播);
          • 2)另一種是通過(guò)RTMP協(xié)議向遠(yuǎn)端服務(wù)器進(jìn)行推流(用于PC開(kāi)播端或?qū)I(yè)控臺(tái)設(shè)備開(kāi)播)。

          除去推拉流,該云平臺(tái)也提供了云通信(IM即時(shí)通訊能力)和直播錄制等云服務(wù),組成了一套直播所需要的基礎(chǔ)服務(wù)。

          3、推拉流架構(gòu)1:廠商SDK推拉流

          如上題所示,這一種推拉流架構(gòu)方式需要依賴騰訊這類廠商提供的手機(jī)互動(dòng)直播SDK,通過(guò)在主播端APP和用戶端APP都集成SDK,使得主播端和用戶端都擁有推拉流的功能。

          這種推拉流架構(gòu)的邏輯原理是這樣的:

          • 1)主播端和用戶端分別與云直播的互動(dòng)直播后臺(tái)建立長(zhǎng)連接;
          • 2)主播端通過(guò)UDT私有協(xié)議向互動(dòng)直播后臺(tái)推送音視頻流;
          • 3)互動(dòng)直播后臺(tái)接收到音視頻流后做轉(zhuǎn)發(fā),直接下發(fā)給與之建立連接的用戶端。

          這種推拉流方式有幾點(diǎn)優(yōu)勢(shì):

          • 1)只需要在客戶端中集成SDK:通過(guò)手機(jī)就可以開(kāi)播,對(duì)于主播開(kāi)播的要求比較低,適合直播業(yè)務(wù)快速鋪開(kāi);
          • 2)互動(dòng)直播后臺(tái)僅做轉(zhuǎn)發(fā):沒(méi)有轉(zhuǎn)碼,上傳CDN等額外操作,整體延遲比較低;
          • 3)主播端和用戶端都可以作為音視頻上傳的發(fā)起方:適合連麥、視頻會(huì)話等場(chǎng)景。

          4、推拉流架構(gòu)2:旁路推流

          之前介紹了通過(guò)手機(jī)SDK推拉流的直播方式,看起來(lái)在手機(jī)客戶端中觀看直播的場(chǎng)景已經(jīng)解決了。

          那么問(wèn)題來(lái)了:如果我想要在H5、小程序等其他場(chǎng)景下觀看直播,沒(méi)有辦法接入SDK,需要怎么處理呢?

          這個(gè)時(shí)候需要引入一個(gè)新的概念——旁路推流。

          旁路推流指的是:通過(guò)協(xié)議轉(zhuǎn)換將音視頻流對(duì)接到標(biāo)準(zhǔn)的直播 CDN 系統(tǒng)上。

          目前云直播開(kāi)啟旁路推流后,會(huì)通過(guò)互動(dòng)直播后臺(tái)將音視頻流推送到云直播后臺(tái),云直播后臺(tái)負(fù)責(zé)將收到音視頻流轉(zhuǎn)碼成通用的協(xié)議格式并且推送到CDN,這樣H5、小程序等端就可以通過(guò)CDN拉取到通用格式的音視頻流進(jìn)行播放了。

          目前蘑菇街直播旁路開(kāi)啟的協(xié)議類型有HLS、FLV、RTMP三種,已經(jīng)可以覆蓋到所有的播放場(chǎng)景,在后續(xù)章節(jié)會(huì)對(duì)這幾種協(xié)議做詳細(xì)的介紹。

          5、推拉流架構(gòu)3:RTMP推流

          隨著直播業(yè)務(wù)發(fā)展,一些主播逐漸不滿足于手機(jī)開(kāi)播的效果,并且電商直播需要高保真地將商品展示在屏幕上,需要通過(guò)更加高清專業(yè)的設(shè)備進(jìn)行直播,RTMP推流技術(shù)應(yīng)運(yùn)而生。

          我們通過(guò)使用OBS等流媒體錄影程序,對(duì)專業(yè)設(shè)備錄制的多路流進(jìn)行合并,并且將音視頻流上傳到指定的推流地址。由于OBS推流使用了RTMP協(xié)議,因此我們稱這一種推流類型為RTMP推流。

          我們首先在云直播后臺(tái)申請(qǐng)到推流地址和秘鑰,將推流地址和秘鑰配置到OBS軟件當(dāng)中,調(diào)整推流各項(xiàng)參數(shù),點(diǎn)擊推流以后,OBS就會(huì)通過(guò)RTMP協(xié)議向?qū)?yīng)的推流地址推送音視頻流。

          這一種推流方式和SDK推流的不同之處在于音視頻流是直接被推送到了云直播后臺(tái)進(jìn)行轉(zhuǎn)碼和上傳CDN的,沒(méi)有直接將直播流轉(zhuǎn)推到用戶端的下行方式,因此相比SDK推流延遲會(huì)長(zhǎng)一些。

          總結(jié)下來(lái)RTMP推流的優(yōu)勢(shì)和劣勢(shì)比較明顯。

          優(yōu)勢(shì)主要是:

          • 1)可以接入專業(yè)的直播攝像頭、麥克風(fēng),直播的整體效果明顯優(yōu)于手機(jī)開(kāi)播;
          • 2)OBS已經(jīng)有比較多成熟的插件,比如目前蘑菇街主播常用YY助手做一些美顏的處理,并且OBS本身已經(jīng)支持濾鏡、綠幕、多路視頻合成等功能,功能比手機(jī)端強(qiáng)大。

          劣勢(shì)主要是:

          • 1)OBS本身配置比較復(fù)雜,需要專業(yè)設(shè)備支持,對(duì)主播的要求明顯更高,通常需要一個(gè)固定的場(chǎng)地進(jìn)行直播;
          • 2)RTMP需要云端轉(zhuǎn)碼,并且本地上傳時(shí)也會(huì)在OBS中配置GOP和緩沖,延時(shí)相對(duì)較長(zhǎng)。

          6、高可用架構(gòu)方案:云互備

          業(yè)務(wù)發(fā)展到一定階段后,我們對(duì)于業(yè)務(wù)的穩(wěn)定性也會(huì)有更高的要求,比如當(dāng)云服務(wù)商服務(wù)出現(xiàn)問(wèn)題時(shí),我們沒(méi)有備用方案就會(huì)出現(xiàn)業(yè)務(wù)一直等待服務(wù)商修復(fù)進(jìn)度的問(wèn)題。

          因此云互備方案就出現(xiàn)了:云互備指的是直播業(yè)務(wù)同時(shí)對(duì)接多家云服務(wù)商,當(dāng)一家云服務(wù)商出現(xiàn)問(wèn)題時(shí),快速切換到其他服務(wù)商的服務(wù)節(jié)點(diǎn),保證業(yè)務(wù)不受影響。

          直播業(yè)務(wù)中經(jīng)常遇到服務(wù)商的CDN節(jié)點(diǎn)下行速度較慢,或者是CDN節(jié)點(diǎn)存儲(chǔ)的直播流有問(wèn)題,此類問(wèn)題有地域性,很難排查,因此目前做的互備云方案,主要是備份CDN節(jié)點(diǎn)。

          目前蘑菇街整體的推流流程已經(jīng)依賴了原有云平臺(tái)的服務(wù),因此我們通過(guò)在云直播后臺(tái)中轉(zhuǎn)推一路流到備份云平臺(tái)上,備份云在接收到了直播流后會(huì)對(duì)流轉(zhuǎn)碼并且上傳到備份云自身的CDN系統(tǒng)當(dāng)中。一旦主平臺(tái)CDN節(jié)點(diǎn)出現(xiàn)問(wèn)題,我們可以將下發(fā)的拉流地址替換成備份云拉流地址,這樣就可以保證業(yè)務(wù)快速修復(fù)并且觀眾無(wú)感知。

          7、視頻直播數(shù)據(jù)流解封裝原理

          介紹流協(xié)議之前,先要介紹我們從云端拿到一份數(shù)據(jù),要經(jīng)過(guò)幾個(gè)步驟才能解析出最終需要的音視頻數(shù)據(jù)。

          如上圖所示,總體來(lái)說(shuō),從獲取到數(shù)據(jù)到最終將音視頻播放出來(lái)要經(jīng)歷四個(gè)步驟。

          第一步:解協(xié)議。

          協(xié)議封裝的時(shí)候通常會(huì)攜帶一些頭部描述信息或者信令數(shù)據(jù),這一部分?jǐn)?shù)據(jù)對(duì)我們音視頻播放沒(méi)有作用,因此我們需要從中提取出具體的音視頻封裝格式數(shù)據(jù),我們?cè)谥辈ブ谐S玫膮f(xié)議有HTTP和RTMP兩種。

          第二步:解封裝。

          獲取到封裝格式數(shù)據(jù)以后需要進(jìn)行解封裝操作,從中分別提取音頻壓縮流數(shù)據(jù)和視頻壓縮流數(shù)據(jù),封裝格式數(shù)據(jù)我們平時(shí)經(jīng)常見(jiàn)到的如MP4、AVI,在直播中我們接觸比較多的封裝格式有TS、FLV。

          第三步:解碼音視頻。

          到這里我們已經(jīng)獲取了音視頻的壓縮編碼數(shù)據(jù)。

          我們?nèi)粘=?jīng)常聽(tīng)到的視頻壓縮編碼數(shù)據(jù)有H.26X系列和MPEG系列等,音頻編碼格式有我們熟悉的MP3、ACC等。

          之所以我們能見(jiàn)到如此多的編碼格式,是因?yàn)楦鞣N組織都提出了自己的編碼標(biāo)準(zhǔn),并且會(huì)相繼推出一些新的議案,但是由于推廣和收費(fèi)問(wèn)題,目前主流的編碼格式也并不多。

          獲取壓縮數(shù)據(jù)以后接下來(lái)需要將音視頻壓縮數(shù)據(jù)解碼,獲取非壓縮的顏色數(shù)據(jù)和非壓縮的音頻抽樣數(shù)據(jù)。顏色數(shù)據(jù)有我們平時(shí)熟知的RGB,不過(guò)在視頻的中常用的顏色數(shù)據(jù)格式是YUV,指的是通過(guò)明亮度、色調(diào)、飽和度確定一個(gè)像素點(diǎn)的色值。音頻抽樣數(shù)據(jù)通常使用的有PCM。

          第四步:音視頻同步播放。

          最后我們需要比對(duì)音視頻的時(shí)間軸,將音視頻解碼后的數(shù)據(jù)交給顯卡聲卡同步播放。

          PS:如果你對(duì)上述流程還不太理解,建議進(jìn)一步閱讀以下系列文章:

          1. 移動(dòng)端實(shí)時(shí)音視頻直播技術(shù)詳解(一):開(kāi)篇
          2. 移動(dòng)端實(shí)時(shí)音視頻直播技術(shù)詳解(二):采集
          3. 移動(dòng)端實(shí)時(shí)音視頻直播技術(shù)詳解(三):處理
          4. 移動(dòng)端實(shí)時(shí)音視頻直播技術(shù)詳解(四):編碼和封裝
          5. 移動(dòng)端實(shí)時(shí)音視頻直播技術(shù)詳解(五):推流和傳輸
          6. 移動(dòng)端實(shí)時(shí)音視頻直播技術(shù)詳解(六):延遲優(yōu)化

          另外:有關(guān)音視頻編解碼技術(shù)的文章,也可以詳細(xì)學(xué)習(xí)以下文章:

          1. 視頻編解碼之:《理論概述》、《數(shù)字視頻介紹》、《編碼基礎(chǔ)》、《預(yù)測(cè)技術(shù)介紹
          2. 認(rèn)識(shí)主流視頻編碼技術(shù)H.264
          3. 如何開(kāi)始音頻編解碼技術(shù)的學(xué)習(xí)
          4. 音頻基礎(chǔ)及編碼原理入門
          5. 常見(jiàn)的實(shí)時(shí)語(yǔ)音通訊編碼標(biāo)準(zhǔn)
          6. 實(shí)時(shí)視頻編碼H.264的特點(diǎn)與優(yōu)勢(shì)》、《視頻編碼H.264、VP8的前世今生
          7. 詳解音頻編解碼的原理、演進(jìn)和應(yīng)用選型》、《零基礎(chǔ),史上最通俗視頻編碼技術(shù)入門

          8、視頻直播傳輸協(xié)議1:HLS

          首先介紹一下HLS協(xié)議。HLS是HTTP Live Streaming的簡(jiǎn)寫(xiě),是由蘋果公司提出的流媒體網(wǎng)絡(luò)傳輸協(xié)議。

          從名字可以明顯看出:這一套協(xié)議是基于HTTP協(xié)議傳輸?shù)摹?/p>

          說(shuō)到HLS協(xié)議:首先需要了解這一種協(xié)議是以視頻切片的形式分段播放的,協(xié)議中使用的切片視頻格式是TS,也就是我們前文提到的封裝格式。

          在我們獲取TS文件之前:協(xié)議首先要求請(qǐng)求一個(gè)M3U8格式的文件,M3U8是一個(gè)描述索引文件,它以一定的格式描述了TS地址的指向,我們根據(jù)M3U8文件中描述的內(nèi)容,就可以獲取每一段TS文件的CDN地址,通過(guò)加載TS地址分段播放就可以組合出一整段完整的視頻。

          使用HLS協(xié)議播放視頻時(shí):首先會(huì)請(qǐng)求一個(gè)M3U8文件,如果是點(diǎn)播只需要在初始化時(shí)獲取一次就可以拿到所有的TS切片指向,但如果是直播的話就需要不停地輪詢M3U8文件,獲取新的TS切片。

          獲取到M3U8后:我們可以看一下里面的內(nèi)容。首先開(kāi)頭是一些通用描述信息,比如第一個(gè)分片序列號(hào)、片段最大時(shí)長(zhǎng)和總時(shí)長(zhǎng)等,接下來(lái)就是具體TS對(duì)應(yīng)的地址列表。如果是直播,那么每次請(qǐng)求M3U8文件里面的TS列表都會(huì)隨著最新的直播切片更新,從而達(dá)到直播流播放的效果。

          HLS這種切片播放的格式在點(diǎn)播播放時(shí)是比較適用的,一些大的視頻網(wǎng)站也都有用這一種協(xié)議作為播放方案。

          首先:切片播放的特性特別適用于點(diǎn)播播放中視頻清晰度、多語(yǔ)種的熱切換。比如我們播放一個(gè)視頻,起初選擇的是標(biāo)清視頻播放,當(dāng)我們看了一半覺(jué)得不夠清晰,需要換成超清的,這時(shí)候只需要將標(biāo)清的M3U8文件替換成超清的M3U8文件,當(dāng)我們播放到下一個(gè)TS節(jié)點(diǎn)時(shí),視頻就會(huì)自動(dòng)替換成超清的TS文件,不需要對(duì)視頻做重新初始化。

          其次:切片播放的形式也可以比較容易地在視頻中插入廣告等內(nèi)容。

          在直播場(chǎng)景下,HLS也是一個(gè)比較常用的協(xié)議,他最大的優(yōu)勢(shì)是蘋果大佬的加持,對(duì)這一套協(xié)議推廣的比較好,特別是移動(dòng)端。將M3U8文件地址喂給video就可以直接播放,PC端用MSE解碼后大部分瀏覽器也都能夠支持。但是由于其分片加載的特性,直播的延遲相對(duì)較長(zhǎng)。比如我們一個(gè)M3U8有5個(gè)TS文件,每個(gè)TS文件播放時(shí)長(zhǎng)是2秒,那么一個(gè)M3U8文件的播放時(shí)長(zhǎng)就是10秒,也就是說(shuō)這個(gè)M3U8播放的直播進(jìn)度至少是10秒之前的,這對(duì)于直播場(chǎng)景來(lái)說(shuō)是一個(gè)比較大的弊端。

          HLS中用到的TS封裝格式,視頻編碼格式是通常是H.264或MPEG-4,音頻編碼格式為AAC或MP3。

          一個(gè)ts由多個(gè)定長(zhǎng)的packtet組成,通常是188個(gè)字節(jié),每個(gè)packtet有head和payload組成,head中包含一些標(biāo)識(shí)符、錯(cuò)誤信息、包位置等基礎(chǔ)信息。payload可以簡(jiǎn)單理解為音視頻信息,但實(shí)際上下層還有還有兩層封裝,將封裝解碼后可以獲取到音視頻流的編碼數(shù)據(jù)。

          9、視頻直播傳輸協(xié)議2:HTTP-FLV

          HTTP-FLV協(xié)議,從名字上就可以明顯看出是通過(guò)HTTP協(xié)議來(lái)傳輸FLV封裝格式的一種協(xié)議。

          FLV是Flash Video的簡(jiǎn)寫(xiě),是一種文件體積小,適合在網(wǎng)絡(luò)上傳輸?shù)姆獍绞健lV的視頻編碼格式通常是H.264,音頻編碼是ACC或MP3。

          HTTP-FLV在直播中是通過(guò)走HTTP長(zhǎng)連接的方式,通過(guò)分塊傳輸向請(qǐng)求端傳遞FLV封包數(shù)據(jù)。

          在直播中,我們通過(guò)HTTP-FLV協(xié)議的拉流地址可以拉取到一段chunked數(shù)據(jù)。

          打開(kāi)文件后可以讀取到16進(jìn)制的文件流,通過(guò)和FLV包結(jié)構(gòu)對(duì)比,可以發(fā)現(xiàn)這些數(shù)據(jù)就是我們需要的FLV數(shù)據(jù)。

          首先開(kāi)頭是頭部信息:464C56轉(zhuǎn)換ASCII碼后是FLV三個(gè)字符,01指的是版本號(hào),05轉(zhuǎn)換為2進(jìn)制后第6位和第8位分別代表是否存在音頻和視頻,09代表頭部長(zhǎng)度占了幾個(gè)字節(jié)。

          后續(xù)就是正式的音視頻數(shù)據(jù):是通過(guò)一個(gè)個(gè)的FLV TAG進(jìn)行封裝,每一個(gè)TAG也有頭部信息,標(biāo)注這個(gè)TAG是音頻信息、視頻信息還是腳本信息。我們通過(guò)解析TAG就可以分別提取音視頻的壓縮編碼信息。

          FLV這一種格式在video中并不是原生支持的,我們要播放這一種格式的封包格式需要通過(guò)MSE對(duì)影視片的壓縮編碼信息進(jìn)行解碼,因此需要瀏覽器能夠支持MSE這一API。由于HTTP-FLV的傳輸是通過(guò)長(zhǎng)連接傳輸文件流的形式,需要瀏覽器支持Stream IO或者fetch,對(duì)于瀏覽器的兼容性要求會(huì)比較高。

          FLV在延遲問(wèn)題上相比切片播放的HLS會(huì)好很多,目前看來(lái)FLV的延遲主要是受編碼時(shí)設(shè)置的GOP長(zhǎng)度的影響。

          這邊簡(jiǎn)單介紹一下GOP:在H.264視頻編碼的過(guò)程中,會(huì)生成三種幀類型:I幀、B幀和P幀。I幀就是我們通常說(shuō)的關(guān)鍵幀,關(guān)鍵幀內(nèi)包括了完整的幀內(nèi)信息,可以直接作為其他幀的參考幀。B幀和P幀為了將數(shù)據(jù)壓縮得更小,需要由其他幀推斷出幀內(nèi)的信息。因此兩個(gè)I幀之間的時(shí)長(zhǎng)也可以被視作最小的視頻播放片段時(shí)長(zhǎng)。從視頻推送的穩(wěn)定性考慮,我們也要求主播將關(guān)鍵幀間隔設(shè)置為定長(zhǎng),通常是1-3秒,因此除去其他因素,我們的直播在播放時(shí)也會(huì)產(chǎn)生1-3秒的延時(shí)。

          10、視頻直播傳輸協(xié)議3:RTMP

          RTMP協(xié)議實(shí)際可以與HTTP-FLV協(xié)議歸做同一種類型。

          他們的封包格式都是FlV,但HTTP-FLV使用的傳輸協(xié)議是HTTP,RTMP拉流使用RTMP作為傳輸協(xié)議。

          RTMP是Adobe公司基于TCP做的一套實(shí)時(shí)消息傳輸協(xié)議,經(jīng)常與Flash播放器匹配使用。

          RTMP協(xié)議的優(yōu)缺點(diǎn)非常明顯。

          RTMP協(xié)議的優(yōu)點(diǎn)主要是:

          • 1)首先和HTTP-FLV一樣,延遲比較低;
          • 2)其次它的穩(wěn)定性非常好,適合長(zhǎng)時(shí)間播放(由于播放時(shí)借用了Flash player強(qiáng)大的功能,即使開(kāi)多路流同時(shí)播放也能保證頁(yè)面不出現(xiàn)卡頓,很適合監(jiān)控等場(chǎng)景)。

          但是Flash player目前在web端屬于墻倒眾人推的境地,主流瀏覽器漸漸都表示不再支持Flash player插件,在MAC上使用能夠立刻將電腦變成燒烤用的鐵板,資源消耗很大。在移動(dòng)端H5基本屬于完全不支持的狀態(tài),兼容性是它最大的問(wèn)題。

          11、視頻直播傳輸協(xié)議4:MPEG-DASH

          MPEG-DASH這一協(xié)議屬于新興勢(shì)力,和HLS一樣,都是通過(guò)切片視頻的方式進(jìn)行播放。

          他產(chǎn)生的背景是早期各大公司都自己搞自己的一套協(xié)議。比如蘋果搞了HLS、微軟搞了 MSS、Adobe還搞了HDS,這樣使用者需要在多套協(xié)議封裝的兼容問(wèn)題上痛苦不堪。

          于是大佬們湊到一起,將之前各個(gè)公司的流媒體協(xié)議方案做了一個(gè)整合,搞了一個(gè)新的協(xié)議。

          由于同為切片視頻播放的協(xié)議,DASH優(yōu)劣勢(shì)和HLS類似,可以支持切片之間多視頻碼率、多音軌的切換,比較適合點(diǎn)播業(yè)務(wù),在直播中還是會(huì)有延時(shí)較長(zhǎng)的問(wèn)題。

          12、如何選擇最優(yōu)的視頻直播傳輸協(xié)議

          視頻直播協(xié)議選擇非常關(guān)鍵的兩點(diǎn),在前文都已經(jīng)有提到了,即低延時(shí)和更優(yōu)的兼容性。

          首先從延時(shí)角度考慮:不考慮云端轉(zhuǎn)碼以及上下行的消耗,HLS和MPEG-DASH通過(guò)將切片時(shí)長(zhǎng)減短,延時(shí)在10秒左右;RTMP和FLV理論上延時(shí)相當(dāng),在2-3秒。因此在延時(shí)方面HLS ≈ DASH > RTMP ≈ FLV。

          從兼容性角度考慮:HLS > FLV > RTMP,DASH由于一些項(xiàng)目歷史原因,并且定位和HLS重復(fù)了,暫時(shí)沒(méi)有對(duì)其兼容性做一個(gè)詳盡的測(cè)試,被推出了選擇的考慮范圍。

          綜上所述:我們可以通過(guò)動(dòng)態(tài)判斷環(huán)境的方式,選擇當(dāng)前環(huán)境下可用的最低延遲的協(xié)議。大致的策略就是優(yōu)先使用HTTP-FLV,使用HLS作為兜底,在一些特殊需求場(chǎng)景下通過(guò)手動(dòng)配置的方式切換為RTMP。

          對(duì)于HLS和HTTP-FLV:我們可以直接使用 hls.js 和 flv.js 做做解碼播放,這兩個(gè)庫(kù)內(nèi)部都是通過(guò)MSE做的解碼。首先根據(jù)視頻封裝格式提取出對(duì)應(yīng)的音視頻chunk數(shù)據(jù),在MediaSource中分別對(duì)音頻和視頻創(chuàng)建SourceBuffer,將音視頻的編碼數(shù)據(jù)喂給SourceBuffer后SourceBuffer內(nèi)部會(huì)處理完剩下的解碼和音視頻對(duì)齊工作,最后MediaSource將Video標(biāo)簽中的src替換成MediaSource 對(duì)象進(jìn)行播放。

          在判斷播放環(huán)境時(shí)我們可以參照flv.js內(nèi)部的判斷方式,通過(guò)調(diào)用MSE判斷方法和模擬請(qǐng)求的方式判斷MSE和StreamIO是否可用:

          // 判斷MediaSource是否被瀏覽器支持,H.264視頻編碼和Acc音頻編碼是否能夠被支持解碼

          window.MediaSource && window.MediaSource.isTypeSupported('video/mp4; codecs="avc1.42E01E,mp4a.40.2"');

          如果FLV播放不被支持的情況下:需要降級(jí)到HLS,這時(shí)候需要判斷瀏覽器環(huán)境是否在移動(dòng)端,移動(dòng)端通常不需要 hls.js 通過(guò)MSE解碼的方式進(jìn)行播放,直接將M3U8的地址交給video的src即可。如果是PC端則判斷MSE是否可用,如果可用就使用hls.js解碼播放。

          這些判讀可以在自己的邏輯里提前判斷后去拉取對(duì)應(yīng)解碼庫(kù)的CDN,而不是等待三方庫(kù)加載完成后使用三方庫(kù)內(nèi)部的方法判斷,這樣在選擇解碼庫(kù)時(shí)就可以不把所有的庫(kù)都拉下來(lái),提高加載速度。

          13、同層播放如何解決

          電商直播需要觀眾操作和互動(dòng)的部分比起傳統(tǒng)的直播更加多,因此產(chǎn)品設(shè)計(jì)的時(shí)候很多的功能模塊會(huì)懸浮在直播視頻上方減少占用的空間。這個(gè)時(shí)候就會(huì)遇到一個(gè)移動(dòng)端播放器的老大難問(wèn)題——同層播放。

          同層播放問(wèn)題:是指在移動(dòng)端H5頁(yè)面中,一些瀏覽器內(nèi)核為了提升用戶體驗(yàn),將video標(biāo)簽被劫持替換為native播放器,導(dǎo)致其他元素?zé)o法覆蓋于播放器之上。

          比如我們想要在直播間播放器上方增加聊天窗口,將聊天窗口通過(guò)絕對(duì)定位提升z-index置于播放器上方,在PC中測(cè)試完全正常。但在移動(dòng)端的一些瀏覽器中,video被替換成了native播放器,native的元素層級(jí)高于我們的普通元素,導(dǎo)致聊天窗口實(shí)際顯示的時(shí)候在播放器下方。

          要解決這個(gè)問(wèn)題,首先要分多個(gè)場(chǎng)景。

          首先在iOS系統(tǒng)中:正常情況下video標(biāo)簽會(huì)自動(dòng)被全屏播放,但iOS10以上已經(jīng)原生提供了video的同層屬性,我們?cè)趘ideo標(biāo)簽上增加playsinline/webkit-playsinline可以解決iOS系統(tǒng)中大部分瀏覽器的同層問(wèn)題,剩下的低系統(tǒng)版本的瀏覽器以及一些APP內(nèi)的webview容器(譬如微博),用上面提的屬性并不管用,調(diào)用三方庫(kù)iphone-inline-video可以解決大部分剩余問(wèn)題。

          在Android端:大部分騰訊系的APP內(nèi)置的webview容器用的都是X5內(nèi)核,X5內(nèi)核會(huì)將video替換成原生定制的播放器已便于增強(qiáng)一些功能。X5也提供了一套同層的方案(該方案官方文檔鏈接已無(wú)法打開(kāi)),給video標(biāo)簽寫(xiě)入X5同層屬性也可以在X5內(nèi)核中實(shí)現(xiàn)內(nèi)聯(lián)播放。不過(guò)X5的同層屬性在各個(gè)X5版本中表現(xiàn)都不太一樣(比如低版本X5中需要使用X5全屏播放模式才能保證MSE播放的視頻同層生效),需要注意區(qū)分版本。

          在蘑菇街App中,目前集成的X5內(nèi)核版本比較老,在使用MSE的情況下會(huì)導(dǎo)致X5同層參數(shù)不生效。但如果集成新版本的X5內(nèi)核,需要對(duì)大量的線上頁(yè)面做回歸測(cè)試,成本比較高,因此提供了一套折中的解決方案。通過(guò)在頁(yè)面URL中增加一個(gè)開(kāi)關(guān)參數(shù),容器讀取到參數(shù)以后會(huì)將X5內(nèi)核降級(jí)為系統(tǒng)原生的瀏覽器內(nèi)核,這樣可以在解決瀏覽器視頻同層問(wèn)題的同時(shí)也將內(nèi)核變動(dòng)的影響范圍控制在單個(gè)頁(yè)面當(dāng)中。

          14、相關(guān)文章

          [1] 移動(dòng)端實(shí)時(shí)音視頻直播技術(shù)詳解(四):編碼和封裝

          [2] 移動(dòng)端實(shí)時(shí)音視頻直播技術(shù)詳解(五):推流和傳輸

          [3] 實(shí)現(xiàn)延遲低于500毫秒的1080P實(shí)時(shí)音視頻直播的實(shí)踐分享

          [4] 淺談開(kāi)發(fā)實(shí)時(shí)視頻直播平臺(tái)的技術(shù)要點(diǎn)

          [5] 直播系統(tǒng)聊天技術(shù)(七):直播間海量聊天消息的架構(gòu)設(shè)計(jì)難點(diǎn)實(shí)踐

          [6] 從0到1:萬(wàn)人在線的實(shí)時(shí)音視頻直播技術(shù)實(shí)踐分享(視頻+PPT) [附件下載]

          [7] 實(shí)時(shí)視頻編碼H.264的特點(diǎn)與優(yōu)勢(shì)

          [8] 視頻編碼H.264、VP8的前世今生

          [9] 零基礎(chǔ),史上最通俗視頻編碼技術(shù)入門

          [10] 視頻編解碼之編碼基礎(chǔ)

          [11] 零基礎(chǔ)入門:實(shí)時(shí)音視頻技術(shù)基礎(chǔ)知識(shí)全面盤點(diǎn)

          [12] 實(shí)時(shí)音視頻面視必備:快速掌握11個(gè)視頻技術(shù)相關(guān)的基礎(chǔ)概念

          [13] 寫(xiě)給小白的實(shí)時(shí)音視頻技術(shù)入門提綱

          本文已同步發(fā)布于:http://www.52im.net/thread-3922-1-1.html

          posted @ 2022-05-31 15:26 Jack Jiang 閱讀(307) | 評(píng)論 (0)編輯 收藏

               摘要: 本文作者張彥飛,原題“聊聊TCP連接耗時(shí)的那些事兒”,有少許改動(dòng)。1、引言對(duì)于基于互聯(lián)網(wǎng)的通信應(yīng)用(比如IM聊天、推送系統(tǒng)),數(shù)據(jù)傳遞時(shí)使用TCP協(xié)議相對(duì)較多。這是因?yàn)樵赥CP/IP協(xié)議簇的傳輸層協(xié)議中,TCP協(xié)議具備可靠的連接、錯(cuò)誤重傳、擁塞控制等優(yōu)點(diǎn),所以目前在應(yīng)用場(chǎng)景上比UDP更廣泛一些。相信你也一定聽(tīng)聞過(guò)TCP也存在一些缺點(diǎn),能常都是老生常談的開(kāi)銷要略大。但是各路技...  閱讀全文

          posted @ 2022-05-26 16:10 Jack Jiang 閱讀(172) | 評(píng)論 (0)編輯 收藏

               摘要: 本文作者“Carson”,現(xiàn)就職于騰訊公司,原題“高效保活長(zhǎng)連接:手把手教你實(shí)現(xiàn)自適應(yīng)的心跳保活機(jī)制”,有較多修訂和改動(dòng)。1、引言當(dāng)要實(shí)現(xiàn)IM即時(shí)通訊聊天、消息推送等高實(shí)時(shí)性需求時(shí),我們一般會(huì)選擇長(zhǎng)連接的通信方式。而真正當(dāng)實(shí)現(xiàn)長(zhǎng)連接方式時(shí),會(huì)遇到很多技術(shù)問(wèn)題,比如最常見(jiàn)的長(zhǎng)連接保活問(wèn)題。今天,我將通過(guò)本篇文章,手把手教大家實(shí)現(xiàn)一套可自適應(yīng)的心跳保活機(jī)...  閱讀全文

          posted @ 2022-05-18 15:09 Jack Jiang 閱讀(238) | 評(píng)論 (0)編輯 收藏

          本文由ELab技術(shù)團(tuán)隊(duì)分享,原題“探秘HTTPS”,有修訂和改動(dòng)。

          1、引言

          對(duì)于IM開(kāi)發(fā)者來(lái)說(shuō),IM里最常用的通信技術(shù)就是Socket長(zhǎng)連接和HTTP短連接(通常一個(gè)主流im會(huì)是這兩種通信手段的結(jié)合)。從通信安全的角度來(lái)說(shuō),Socket長(zhǎng)連接的安全性,就是基于SSL/TLS加密的TCP協(xié)議來(lái)實(shí)現(xiàn)的(比如微信的mmtls,見(jiàn)《微信新一代通信安全解決方案:基于TLS1.3的MMTLS詳解);而對(duì)于HTTP短連接的安全性,也就是HTTPS了。

          到底什么是HTTPS?為什么要用HTTPS?今天就借此機(jī)會(huì),跟大家一起深入學(xué)習(xí)一下HTTPS的相關(guān)知識(shí),包括HTTP的發(fā)展歷程、HTTP遇到的問(wèn)題、對(duì)稱與非對(duì)稱加密算法、數(shù)字簽名、第三方證書(shū)頒發(fā)機(jī)構(gòu)等概念。

          學(xué)習(xí)交流:

          - 移動(dòng)端IM開(kāi)發(fā)入門文章:《新手入門一篇就夠:從零開(kāi)發(fā)移動(dòng)端IM

          - 開(kāi)源IM框架源碼:https://github.com/JackJiang2011/MobileIMSDK 

          本文已同步發(fā)布于:http://www.52im.net/thread-3897-1-1.html

          2、系列文章

          本文是IM通訊安全知識(shí)系列文章中的第9篇,此系列總目錄如下:

          3、寫(xiě)在前面

          說(shuō)到HTTPS,那就得回到HTTP協(xié)議。

          對(duì)于HTTP協(xié)議,大家肯定都熟得不能再熟了。那么HTTPS和HTTP的區(qū)別大家了解嗎?

          對(duì)于這個(gè)經(jīng)典的面試題,大部分人會(huì)這么回答:

          • 1)HTTPS比HTTP多了一個(gè)S(Secure):也就是說(shuō)HTTPS是安全版的HTTP;
          • 2)端口號(hào)不同:HTTP使用80端口,HTTPS使用443端口;
          • 3)加密算法:HTTPS用的是非對(duì)稱加密算法。

          上面的回答能給幾分?等看完本文我們可以再回頭來(lái)看下這個(gè)回答。

          那么,HTTPS是如何實(shí)現(xiàn)安全的短連接數(shù)據(jù)傳輸呢?想徹底搞明白這個(gè)問(wèn)題,還是要從HTTP的發(fā)展歷程說(shuō)起 ......

          4、HTTP協(xié)議回顧

          4.1 基礎(chǔ)常識(shí)

          HTTP是Hypertext Transfer Protocal 的縮寫(xiě),中文全稱是超文本傳輸協(xié)議(詳見(jiàn)《深入淺出,全面理解HTTP協(xié)議)。

          通俗了解釋就是:

          • 1)超文本是指包含但不限于文本外的圖片、音頻、視頻等多媒體資源;
          • 2)協(xié)議是通信雙方約定好的數(shù)據(jù)傳輸格式以及通信規(guī)則。

          HTTP是TCP/IP協(xié)議簇的最高層——應(yīng)用層協(xié)議:

          瀏覽器和服務(wù)器在使用HTTP協(xié)議相互傳遞超文本數(shù)據(jù)時(shí),將數(shù)據(jù)放入報(bào)文體內(nèi),同時(shí)填充首部(請(qǐng)求頭或響應(yīng)頭)構(gòu)成完整HTTP報(bào)文并交到下層傳輸層,之后每一層加上相應(yīng)的首部(控制部分)便一層層的下發(fā),最終由物理層將二進(jìn)制數(shù)據(jù)以電信號(hào)的形式發(fā)送出去。

          HTTP的請(qǐng)求如下圖所示:

          HTTP報(bào)文結(jié)構(gòu)如下:

          4.2 發(fā)展歷程

          HTTP的發(fā)展歷程如下:

          由HTTP的發(fā)展歷程來(lái)看,最開(kāi)始版本的HTTP(HTTP1.0)在每次建立TCP連接后只能發(fā)起一次HTTP請(qǐng)求,請(qǐng)求完畢就釋放TCP連接。

          我們都知道TCP連接的建立需要經(jīng)過(guò)三次握手的過(guò)程,而每次發(fā)送HTTP請(qǐng)求都需要重新建立TCP連接,毫無(wú)疑問(wèn)是很低效的。所以HTTP1.1改善了這一點(diǎn),使用長(zhǎng)連接的機(jī)制,也就是“一次TCP連接,N次HTTP請(qǐng)求”。

          HTTP協(xié)議的長(zhǎng)連接和短連接,實(shí)質(zhì)上是 TCP 協(xié)議的長(zhǎng)連接和短連接。

          在使用長(zhǎng)連接的情況下,當(dāng)一個(gè)網(wǎng)頁(yè)打開(kāi)完成后,客戶端和服務(wù)器之間用于傳輸HTTP數(shù)據(jù)的TCP連接不會(huì)關(guān)閉,客戶端再次訪問(wèn)這個(gè)服務(wù)器時(shí),會(huì)繼續(xù)使用這一條已經(jīng)建立的連接。Keep-Alive不會(huì)永久保持連接,它有一個(gè)保持時(shí)間,可以在不同的服務(wù)器軟件(如Apache)中設(shè)定這個(gè)時(shí)間。實(shí)現(xiàn)長(zhǎng)連接需要客戶端和服務(wù)端都支持長(zhǎng)連接。

          PS:對(duì)于IM開(kāi)發(fā)者來(lái)說(shuō),為了與Socket長(zhǎng)連接通道區(qū)分,通常認(rèn)為HTTP就是“短連接”雖然這個(gè)“短連接”不一定真的“短”)。

          HTTP1.0若要開(kāi)啟長(zhǎng)連接,需要加上Connection: keep-alive請(qǐng)求頭。有關(guān)HTTP協(xié)議的詳細(xì)發(fā)展歷程可閱讀《一文讀懂HTTP協(xié)議的歷史演變和設(shè)計(jì)思路》一文。

          4.3 安全問(wèn)題

          隨著HTTP越來(lái)越廣泛的使用,HTTP的安全性問(wèn)題也逐漸暴露。

          回憶一下多年前遍地都是的運(yùn)營(yíng)商劫持,當(dāng)你訪問(wèn)一個(gè)本來(lái)很正常的網(wǎng)頁(yè),但頁(yè)面上卻莫名其妙出現(xiàn)了一些廣告標(biāo)簽、跳轉(zhuǎn)腳本、欺騙性的紅包按鈕,甚至有時(shí)候本來(lái)要下載一個(gè)文件,最后下載下來(lái)卻變成了另外一個(gè)完全不同的東西,這些都是被運(yùn)營(yíng)商劫持了HTTP明文數(shù)據(jù)的現(xiàn)象。

          下圖就是似曾相識(shí)的運(yùn)營(yíng)商劫持效果圖:

          PS:關(guān)于運(yùn)營(yíng)商劫持問(wèn)題,可以詳細(xì)閱讀《全面了解移動(dòng)端DNS域名劫持等雜癥:原理、根源、HttpDNS解決方案等》。

          HTTP主要有以下3點(diǎn)安全性問(wèn)題:

           

          歸納一下就是:

          • 1)數(shù)據(jù)保密性問(wèn)題:因?yàn)镠TTP無(wú)狀態(tài),而且又是明文傳輸,所有數(shù)據(jù)內(nèi)容都在網(wǎng)絡(luò)中裸奔,包用戶括身份信息、支付賬號(hào)與密碼。這些敏感信息極易泄露造成安全隱患;
          • 2)數(shù)據(jù)完整性問(wèn)題:HTTP數(shù)據(jù)包在到達(dá)目的主機(jī)前會(huì)經(jīng)過(guò)很多轉(zhuǎn)發(fā)設(shè)備,每一個(gè)設(shè)備節(jié)點(diǎn)都可能會(huì)篡改或調(diào)包信息,無(wú)法驗(yàn)證數(shù)據(jù)的完整性;
          • 3)身份校驗(yàn)問(wèn)題:有可能遭受中間人攻擊,我們無(wú)法驗(yàn)證通信的另一方就是我們的目標(biāo)對(duì)象。

          因此,為了保證數(shù)據(jù)傳輸?shù)陌踩裕仨氁獙?duì)HTTP數(shù)據(jù)進(jìn)行加密。

          5、常見(jiàn)的加密方式

          5.1 基本情況

          常見(jiàn)的加密方式分為三種:

          • 1)對(duì)稱加密;
          • 2)非對(duì)稱加密;
          • 3)數(shù)字摘要。

          前兩種適合數(shù)據(jù)傳輸加密,而數(shù)字摘要不可逆的特性常被用于數(shù)字簽名。

          接下來(lái),我們逐一簡(jiǎn)要學(xué)習(xí)一下這三種常見(jiàn)的加密方法。

          5.2 對(duì)稱加密

          對(duì)稱加密也稱為密鑰加密或單向加密,就是使用同一套密鑰來(lái)進(jìn)行加密和解密。密鑰可以理解為加密算法。

          對(duì)稱加密圖示如下:

          廣泛使用的對(duì)稱加密有:

          對(duì)稱加密算法的優(yōu)缺點(diǎn)和適用場(chǎng)景:

          • 1)優(yōu)點(diǎn):算法公開(kāi)、簡(jiǎn)單,加密解密容易,加密速度快,效率高;
          • 2)缺點(diǎn):相對(duì)來(lái)說(shuō)不算特別安全,只有一把鑰匙,密文如果被攔截,且密鑰也被劫持,那么,信息很容易被破譯;
          • 3)適用場(chǎng)景:加解密速度快、效率高,因此適用于大量數(shù)據(jù)的加密場(chǎng)景。由于如何傳輸密鑰是較為頭痛的問(wèn)題,因此適用于無(wú)需進(jìn)行密鑰交換的場(chǎng)景,如內(nèi)部系統(tǒng),事先就可以直接確定密鑰。

          PS:可以在線體驗(yàn)對(duì)稱加密算法,鏈接是:http://www.jsons.cn/textencrypt/

          小知識(shí):base64編碼也屬于對(duì)稱加密哦!

          5.3 非對(duì)稱加密

          非對(duì)稱加密使用一對(duì)密鑰(公鑰和私鑰)進(jìn)行加密和解密。

          非對(duì)稱加密可以在不直接傳遞密鑰的情況下,完成解密,具體步驟如下:

          • 1)乙方生成兩把密鑰(公鑰和私鑰)。公鑰是公開(kāi)的,任何人都可以獲得,私鑰則是保密的;
          • 2)甲方獲取乙方的公鑰,然后用它對(duì)信息加密;
          • 3)乙方得到加密后的信息,用私鑰解密。

          以最典型的非對(duì)稱加密算法RSA為例,舉個(gè)例子:

          想要徹底搞懂RSA,需要了解數(shù)論的知識(shí),全部推導(dǎo)過(guò)程RSA加密算法。簡(jiǎn)單介紹思路:使用兩個(gè)超大質(zhì)數(shù)以及其乘積作為生成公鑰和私鑰的材料,想要從公鑰推算出私鑰是非常困難的(需要對(duì)超大數(shù)因式分解為兩個(gè)很大質(zhì)數(shù)的乘積)。目前被破解的最長(zhǎng)RSA密鑰是768個(gè)二進(jìn)制位。也就是說(shuō),長(zhǎng)度超過(guò)768位的密鑰,還無(wú)法破解(至少?zèng)]人公開(kāi)宣布)。因此可以認(rèn)為,1024位的RSA密鑰基本安全,2048位的密鑰極其安全。

          非對(duì)稱加密算法的優(yōu)缺點(diǎn)和適用場(chǎng)景:

          • 1)優(yōu)點(diǎn):強(qiáng)度高、安全性強(qiáng)于對(duì)稱加密算法、無(wú)需傳遞私鑰導(dǎo)致沒(méi)有密鑰泄露風(fēng)險(xiǎn);
          • 2)缺點(diǎn):計(jì)算量大、速度慢;
          • 3)適用場(chǎng)景:適用于需要密鑰交換的場(chǎng)景,如互聯(lián)網(wǎng)應(yīng)用,無(wú)法事先約定密鑰。

          實(shí)踐應(yīng)用過(guò)程中,其實(shí)可以與對(duì)稱加密算法結(jié)合:

          • 1)利用非對(duì)稱加密算法安全性較好的特點(diǎn)來(lái)傳遞對(duì)稱加密算法的密鑰。
          • 2)利用對(duì)稱加密算法加解密速度快的特點(diǎn),進(jìn)行數(shù)據(jù)內(nèi)容比較大的加密場(chǎng)景的加密(如HTTPS)。

          PS:對(duì)于IM開(kāi)發(fā)者來(lái)說(shuō),《探討組合加密算法在IM中的應(yīng)用》一文值得一讀。

          5.4 如何選擇?

          1)如果選擇對(duì)稱加密:

          HTTP請(qǐng)求方使用對(duì)稱算法加密數(shù)據(jù),那么為了接收方能夠解密,發(fā)送方還需要把密鑰一同傳遞到接收方。在傳遞密鑰的過(guò)程中還是可能遭到嗅探攻擊,攻擊者竊取密鑰后依然可以解密從而得到發(fā)送的數(shù)據(jù),所以這種方案不可行。

          2)如果選擇非對(duì)稱加密:

          接收方保留私鑰,把公鑰傳遞給發(fā)送方。發(fā)送方用公鑰來(lái)加密數(shù)據(jù),接收方使用私鑰解密數(shù)據(jù)。攻擊者雖然不能直接獲取這些數(shù)據(jù)(因?yàn)闆](méi)有私鑰),但是可以通過(guò)攔截傳遞的公鑰,然后把自己的公鑰傳給發(fā)送方,再用自己的私鑰對(duì)發(fā)送方發(fā)送數(shù)據(jù)進(jìn)行解密。

          整個(gè)過(guò)程通信雙方都不知道中間人的存在,但是中間人能夠獲得完整的數(shù)據(jù)信息。

          3)兩種加密方法的混合:

          先使用非對(duì)稱加密算法加密并傳遞對(duì)稱加密的密鑰,然后雙方通過(guò)對(duì)稱加密方式加密要發(fā)送的數(shù)據(jù)。看起來(lái)沒(méi)什么問(wèn)題,但事實(shí)是這樣嗎?

          中間人依然可以攔截公鑰的傳遞,并以自己的公鑰作為替換,治標(biāo)不治本。

          想要治本,就要找到一個(gè)第三方公證人來(lái)證明公鑰沒(méi)有被替換,因此就引出了數(shù)字證書(shū)的概念,這也是下一節(jié)將分享的內(nèi)容。

          6、數(shù)字證書(shū)

          6.1 CA機(jī)構(gòu)

          CA就是 Certificate Authority,即頒發(fā)數(shù)字證書(shū)的機(jī)構(gòu)。

          作為受信任的第三方,CA承擔(dān)公鑰體系中公鑰的合法性檢驗(yàn)的責(zé)任。

          證書(shū)就是源服務(wù)器向可信任的第三方機(jī)構(gòu)申請(qǐng)的數(shù)據(jù)文件。這個(gè)證書(shū)除了表明這個(gè)域名是屬于誰(shuí)的,頒發(fā)日期等,還包括了第三方證書(shū)的私鑰。

          服務(wù)器將公鑰放在數(shù)字證書(shū)中,只要證書(shū)是可信的,公鑰就是可信的。

          下面兩圖是飛書(shū)域名的證書(shū)中部分內(nèi)容的信:

          6.2 數(shù)字簽名

          摘要算法:一般用哈希函數(shù)來(lái)實(shí)現(xiàn),可以理解成一種定長(zhǎng)的壓縮算法,它能把任意長(zhǎng)度的數(shù)據(jù)壓縮到固定長(zhǎng)度。這好比是給數(shù)據(jù)加了一把鎖,對(duì)數(shù)據(jù)有任何微小的改動(dòng)都會(huì)使摘要變得截然不同。

          通常情況下:數(shù)字證書(shū)的申請(qǐng)人(服務(wù)器)將生成由私鑰和公鑰以及證書(shū)請(qǐng)求文件(Certificate Signing Request,CSR)組成的密鑰對(duì)。CSR是一個(gè)編碼的文本文件,其中包含公鑰和其他將包含在證書(shū)中的信息(例如:域名、組織、電子郵件地址等)。密鑰對(duì)和CSR生成通常在將要安裝證書(shū)的服務(wù)器上完成,并且 CSR 中包含的信息類型取決于證書(shū)的驗(yàn)證級(jí)別。與公鑰不同,申請(qǐng)人的私鑰是安全的,永遠(yuǎn)不要向 CA(或其他任何人)展示。

          生成 CSR 后:申請(qǐng)人將其發(fā)送給 CA,CA 會(huì)驗(yàn)證其包含的信息是否正確,如果正確,則使用頒發(fā)的私鑰對(duì)證書(shū)進(jìn)行數(shù)字簽名,然后將簽名放在證書(shū)內(nèi)隨證書(shū)一起發(fā)送給申請(qǐng)人。

          在SSL握手階段:瀏覽器在收到服務(wù)器的證書(shū)后,使用CA的公鑰進(jìn)行解密,取出證書(shū)中的數(shù)據(jù)、數(shù)字簽名以及服務(wù)器的公鑰。如果解密成功,則可驗(yàn)證服務(wù)器身份真實(shí)。之后瀏覽器再對(duì)數(shù)據(jù)做Hash運(yùn)算,將結(jié)果與數(shù)字簽名作對(duì)比,如果一致則可以認(rèn)為內(nèi)容沒(méi)有收到篡改。

          對(duì)稱加密和非對(duì)稱加密是公鑰加密、私鑰解密, 而數(shù)字簽名正好相反——是私鑰加密(簽名)、公鑰解密(驗(yàn)證),如下圖所示。

          限于篇幅,關(guān)于數(shù)字證書(shū)的內(nèi)容本文就不再贅述,想詳細(xì)了解的可以閱讀:

          7、為什么要使用HTTPS

          圖解HTTP》一書(shū)中提到HTTPS就是身披SSL外殼的HTTP。

          7.1 SSL

          SSL 在1999年被更名為TLS

          所以說(shuō):HTTPS 并不是一項(xiàng)新的應(yīng)用層協(xié)議,只是 HTTP 通信接口部分由 SSL 和 TLS 替代而已。

          具體就是:HTTP 會(huì)先直接和 TCP 進(jìn)行通信,而HTTPS 會(huì)演變?yōu)橄群?SSL 進(jìn)行通信,然后再由 SSL 和 TCP 進(jìn)行通信。

          SSL是一個(gè)獨(dú)立的協(xié)議,不只有 HTTP 可以使用,其他應(yīng)用層協(xié)議也可以使用,比如FTP、SMTP都可以使用SSL來(lái)加密。

          7.2 HTTPS請(qǐng)求流程

          HTTPS請(qǐng)求全流程如下圖:

          如上圖所示:

          • 1)用戶在瀏覽器發(fā)起HTTPS請(qǐng)求,默認(rèn)使用服務(wù)端的443端口進(jìn)行連接;
          • 2)HTTPS需要使用一套CA 數(shù)字證書(shū),證書(shū)內(nèi)會(huì)附帶一個(gè)服務(wù)器的公鑰Pub,而與之對(duì)應(yīng)的私鑰Private保留在服務(wù)端不公開(kāi);
          • 3)服務(wù)端收到請(qǐng)求,返回配置好的包含公鑰Pub的證書(shū)給客戶端;
          • 4)客戶端收到證書(shū),校驗(yàn)合法性,主要包括是否在有效期內(nèi)、證書(shū)的域名與請(qǐng)求的域名是否匹配,上一級(jí)證書(shū)是否有效(遞歸判斷,直到判斷到系統(tǒng)內(nèi)置或?yàn)g覽器配置好的根證書(shū)),如果不通過(guò),則顯示HTTPS警告信息,如果通過(guò)則繼續(xù);
          • 5)客戶端生成一個(gè)用于對(duì)稱加密的隨機(jī)Key,并用證書(shū)內(nèi)的公鑰Pub進(jìn)行加密,發(fā)送給服務(wù)端;
          • 6)服務(wù)端收到隨機(jī)Key的密文,使用與公鑰Pub配對(duì)的私鑰Private進(jìn)行解密,得到客戶端真正想發(fā)送的隨機(jī)Key;
          • 7)服務(wù)端使用客戶端發(fā)送過(guò)來(lái)的隨機(jī)Key對(duì)要傳輸?shù)腍TTP數(shù)據(jù)進(jìn)行對(duì)稱加密,將密文返回客戶端;
          • 8)客戶端使用隨機(jī)Key對(duì)稱解密密文,得到HTTP數(shù)據(jù)明文;
          • 9)后續(xù)HTTPS請(qǐng)求使用之前交換好的隨機(jī)Key進(jìn)行對(duì)稱加解密。

          7.3 HTTPS到底解決了什么問(wèn)題

          HTTPS確實(shí)解決了HTTP的三個(gè)安全性問(wèn)題:

          • 1) 保密性:結(jié)合非對(duì)稱加密和對(duì)稱加密實(shí)現(xiàn)保密性。用非對(duì)稱加密方式加密對(duì)稱加密的秘鑰,再用對(duì)稱加密方式加密數(shù)據(jù);
          • 2) 完整性:通過(guò)第三方CA的數(shù)字簽名解決完整性問(wèn)題;
          • 3) 身份校驗(yàn):通過(guò)第三方CA的數(shù)字證書(shū)驗(yàn)證服務(wù)器的身份。

          7.4 HTTPS優(yōu)缺點(diǎn)

          最后我們總結(jié)一下HTTPS的優(yōu)缺點(diǎn):

          可以看到:HTTPS的確是當(dāng)今安全傳輸HTTP的最優(yōu)解,但他并不是完美的,仍會(huì)有漏洞。

          8、參考資料

          [1] 深入淺出,全面理解HTTP協(xié)議

          [2] HTTP協(xié)議必知必會(huì)的一些知識(shí)

          [3] 從數(shù)據(jù)傳輸層深度解密HTTP

          [4] 一文讀懂HTTP協(xié)議的歷史演變和設(shè)計(jì)思路

          [5] 你知道一個(gè)TCP連接上能發(fā)起多少個(gè)HTTP請(qǐng)求嗎?

          [6] 如果這樣來(lái)理解HTTPS,一篇就夠了

          [7] 一分鐘理解 HTTPS 到底解決了什么問(wèn)題

          [8] 你知道,HTTPS用的是對(duì)稱加密還是非對(duì)稱加密?

          [9] HTTPS時(shí)代已來(lái),打算更新你的HTTP服務(wù)了嗎?

          [10] 一篇讀懂HTTPS:加密原理、安全邏輯、數(shù)字證書(shū)等

          [11] 全面了解移動(dòng)端DNS域名劫持等雜癥:原理、根源、HttpDNS解決方案等

          (本文已同步發(fā)布于:http://www.52im.net/thread-3897-1-1.html

          posted @ 2022-05-13 16:27 Jack Jiang 閱讀(148) | 評(píng)論 (0)編輯 收藏

          關(guān)于MobileIMSDK

          MobileIMSDK 是一套專為移動(dòng)端開(kāi)發(fā)的原創(chuàng)開(kāi)源IM通信層框架:

          • 歷經(jīng)8年、久經(jīng)考驗(yàn);
          • 超輕量級(jí)、高度提煉,lib包50KB以內(nèi);
          • 精心封裝,一套API同時(shí)支持UDP、TCP、WebSocket三種協(xié)議(可能是全網(wǎng)唯一開(kāi)源的);
          • 客戶端支持 iOSAndroid標(biāo)準(zhǔn)JavaH5小程序(開(kāi)發(fā)中..)、Uniapp(開(kāi)發(fā)中..);
          • 服務(wù)端基于Netty,性能卓越、易于擴(kuò)展;:point_left:
          • 可與姊妹工程 MobileIMSDK-Web 無(wú)縫互通實(shí)現(xiàn)網(wǎng)頁(yè)端聊天或推送等;:point_left:
          • 可應(yīng)用于跨設(shè)備、跨網(wǎng)絡(luò)的聊天APP、企業(yè)OA、消息推送等各種場(chǎng)景。

          關(guān)于RainbowChat

          ► 詳細(xì)產(chǎn)品介紹:http://www.52im.net/thread-19-1-1.html
          ► 版本更新記錄:http://www.52im.net/thread-1217-1-1.html
          ► 全部運(yùn)行截圖:Android端iOS端
          ► 在線體驗(yàn)下載:專業(yè)版(TCP協(xié)議)專業(yè)版(UDP協(xié)議)      (關(guān)于 iOS 端,請(qǐng):點(diǎn)此查看

           

          RainbowChat是一套基于開(kāi)源IM聊天框架 MobileIMSDK 的產(chǎn)品級(jí)移動(dòng)端IM系統(tǒng)。RainbowChat源于真實(shí)運(yùn)營(yíng)的產(chǎn)品,解決了大量的屏幕適配、細(xì)節(jié)優(yōu)化、機(jī)器兼容問(wèn)題(可自行下載體驗(yàn):專業(yè)版下載安裝)。

          * RainbowChat可能是市面上提供im即時(shí)通訊聊天源碼的,唯一一款同時(shí)支持TCP、UDP兩種通信協(xié)議的IM產(chǎn)品(通信層基于開(kāi)源IM聊天框架  MobileIMSDK 實(shí)現(xiàn))。

          v8.1 版更新內(nèi)容

          此版更新內(nèi)容:

          (1)Android端主要更新內(nèi)容【新增“掃一掃”等功能及優(yōu)化!】:

          • 1)[新增]“掃一掃”界面及完整功能(支持掃碼加好友、加群);
          • 2)[新增]“我的二維碼”界面及完整功能;
          • 3)[新增]“群聊二維碼”界面及完整功能;
          • 4)[升級(jí)]升級(jí)okhttp庫(kù)至4.9.3;
          • 5)[優(yōu)化]其它小優(yōu)化。

          (2)服務(wù)端主要更新內(nèi)容:

          • 1)[優(yōu)化]針對(duì)掃碼加群等功能的相關(guān)修改。

          此版主要新增功能運(yùn)行截圖更多截圖點(diǎn)此查看):

          posted @ 2022-05-11 17:49 Jack Jiang 閱讀(152) | 評(píng)論 (0)編輯 收藏

               摘要: 一、前言MobileIMSDK 是什么?MobileIMSDK  是一套專門為移動(dòng)端開(kāi)發(fā)的開(kāi)源IM即時(shí)通訊框架,超輕量級(jí)、高度提煉,一套API優(yōu)雅支持UDP 、TCP 、WebSocket 三種協(xié)議,支持iOS、Android、H5、標(biāo)準(zhǔn)Java平臺(tái),服務(wù)端基于Netty編寫(xiě)。工程地址是:1)Gitee碼云地址:https://www.oschina.net/p/mobilei...  閱讀全文

          posted @ 2022-05-05 15:15 Jack Jiang 閱讀(202) | 評(píng)論 (0)編輯 收藏

          僅列出標(biāo)題
          共51頁(yè): First 上一頁(yè) 19 20 21 22 23 24 25 26 27 下一頁(yè) Last 
          Jack Jiang的 Mail: jb2011@163.com, 聯(lián)系QQ: 413980957, 微信: hellojackjiang
          主站蜘蛛池模板: 吴忠市| 阿拉善盟| 无锡市| 吉木乃县| 连平县| 鄱阳县| 深州市| 宝兴县| 金坛市| 西峡县| 瓦房店市| 惠来县| 浪卡子县| 香港| 苏尼特左旗| 萨嘎县| 应用必备| 德惠市| 河北区| 吐鲁番市| 莎车县| 温宿县| 修文县| 淮南市| 青浦区| 大连市| 平乡县| 搜索| 岳阳县| 霸州市| 桐梓县| 阿拉善盟| 泗阳县| 永善县| 长沙市| 囊谦县| 莱阳市| 监利县| 留坝县| 大城县| 彰武县|