Jack Jiang

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

          本文同時發布于“即時通訊技術圈”公眾號,鏈接是:https://mp.weixin.qq.com/s/cS5xB2DrjF52rmz6EGVJ6A。

          本文參考了公眾號鮮棗課堂的“IPv6,到底是什么?”一文的部分內容,感謝原作者。

          1、引言

          現在IPv6的技術應用已經越來越普及了,很多應用都開始支持IPv6。

           

          ▲ 去年開始,支付寶的官網上就已出現“支持IPv6”標識

          對于即時通訊技術(尤其是IM應用)的開發者來說,新產品上架蘋果的App Store因IPv6問題被拒的情況,很常見。每次也都能根據網上的資料一一解決,并順利通過審核。

          然而幾次下來,到底什么是IPv6,還是有點云里霧里。

          那么,IP協議在TCP/IP體系中到底有多重要?看看下圖便知(原因清晰版:從此處進入下載)。

           

          ▲ 紅圈處就是IP協議,它幾乎是整個TCP/IP協議簇的支撐(圖引用自《計算機網絡通訊協議關系圖》)

          總之,IP協議在TCP/IP體系中,是非常重要的一環(可以認為,沒它,也就沒有了互聯網),作為IPv4的下一代協議,了解IPv6非常有必要。而作為即時通訊開發者來說,了解IPv6就顯的尤為迫切,說不定某天你的IM就會因為IPv6問題而導致無法通信的局面出現。

          本文將用淺顯易懂的文字,帶你了解到底什么是IPv6。

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

          2、系列文章

          本文是系列文章中的第11篇,本系列文章的大綱如下:

          網絡編程懶人入門(一):快速理解網絡通信協議(上篇)

          網絡編程懶人入門(二):快速理解網絡通信協議(下篇)

          網絡編程懶人入門(三):快速理解TCP協議一篇就夠

          網絡編程懶人入門(四):快速理解TCP和UDP的差異

          網絡編程懶人入門(五):快速理解為什么說UDP有時比TCP更有優勢

          網絡編程懶人入門(六):史上最通俗的集線器、交換機、路由器功能原理入門

          網絡編程懶人入門(七):深入淺出,全面理解HTTP協議

          網絡編程懶人入門(八):手把手教你寫基于TCP的Socket長連接

          網絡編程懶人入門(九):通俗講解,有了IP地址,為何還要用MAC地址?

          網絡編程懶人入門(十):一泡尿的時間,快速讀懂QUIC協議

          網絡編程懶人入門(十一):一文讀懂什么是IPv6》(本文)

          3、復習一下什么是IPv4?

          IPv4是Internet Protocol version 4的縮寫,中文翻譯為互聯網通信協議第四版,通常簡稱為網際協議版本4。

          IPv4使用32位(4字節)地址,因此地址空間中只有 4,294,967,296(即2^32) 個地址。

          IPv4地址可被寫作任何表示一個32位整數值的形式,但為了方便人類閱讀和分析,它通常被寫作點分十進制的形式,即四個字節被分開用十進制寫出,中間用點分隔。

          通常IPv4地址的地址格式為 nnn.nnn.nnn.nnn,就像下面這樣:

          172.16.254.1

          下圖看起來更清晰一些:

          4、IPv6又是什么?

          IPv6是Internet Protocol version 6的縮寫,中文翻譯為互聯網通信協議(TCP/IP協議)第6版,通常簡稱為網際協議版6。IPv6具有比IPv4大得多的編碼地址空間,用它來取代IPv4主要是為了解決IPv4地址枯竭問題,同時它也在其他方面對于IPv4有許多改進。

          其實,IPv6并不是新技術,從IPv6最早的工作組成立1992年到現在,已過去27年。在互聯網技術的發展歷程中,IPv6年齡甚至有些太大了。

          IPv6的“6”表示的是TCP/IP協議的第六個版本,IPv4的“4”表示的是TCP/IP協議的第四個版本。其實除了這兩個版本,當然還有其它版本,TCP/IP協議其實從IPv1開始,到現在IPv10都已經出現了,這些不同版本之間并沒有關聯,也不是簡單IP地址長度的長短。

          IPv6地址由八組、每組四位16進制數字組成,每組之間由":"來分隔。

          看個簡單的例子:

          2610:00f8:0c34:67f9:0200:83ff:fe94:4c36,每個“:”前后都是4位16進制的數字,共分隔成8組。

          如下圖所示: 

           

          小知識:如何查看手機或者電腦的網絡是否支持IPv6呢?

          可以在你手機或者電腦上的瀏覽器中打開:Ipv6-test.com,就像下圖這樣: 

          5、為什么要使用IPv6?

          最主要的原因,就是地址數量不夠用了。

          IPv4迄今為止已經使用了30多年。最早期的時候,互聯網只是設計給美國軍方用的,根本沒有考慮到它會變得如此龐大,成為全球網絡。

          尤其是進入21世紀后,隨著計算機和智能手機的迅速普及,互聯網開始爆發性發展,越來越多的上網設備出現,越來越多的人開始連接互聯網。這就意味著,需要越來越多的IP地址。

          IPv4的地址總數是2的32次方,也就是約42.9億個。而全球的網民總數早已超過這個數目。

           

          所以說,IPv4地址池接近枯竭,根本無法滿足互聯網發展的需要。人們迫切需要更高版本的IP協議,更大數量的IP地址池。(有點像固定電話號碼升位。)

          6、IPv6會帶給我們什么?

          首先,最重要的一點,就是前面所說的地址池擴容。IPv4的地址池是約42.9億,IPv6能達到多少呢?

          數量如下:

          340282366920938463463374607431768211456個…

          不用數了,太多了… 簡單說,是2的128次方。

          這個數量,即使是給地球上每一顆沙子都分配一個IP,也是妥妥夠用的。

           

          ▲ 這圖你看懂了嗎?嗯,我也沒看懂,反正就是很多的樣子

          這個數量值是怎么得來的呢?還是它的地址位長決定的。

          如果以二進制來寫,IPv6的地址是128位。不過,這樣寫顯然不太方便(一行都寫不下)。所以,通常用十六進制來寫,也就縮短成32位(32位會分為8組,每組4位)。 

          下面就是一個標準、合法的IPv6地址示例:

          2001:0db8:85a3:08d3:1319:8a2e:0370:7344

          注意:IPv6的地址是可以簡寫的,每項數字前導的0可以省略。

          例如,下面這個地址:

          2001:0DB8:02de:0000:0000:0000:0000:0e13

          粉紅的“0”就可以省略,變成:

          2001: DB8:2de:0:0:0:0:e13

          如果有一組或連續幾組都是0,那么可以簡寫成“::”,也就是:

          2001: DB8:2de::e13

          注意:一個IPv6地址,只能有一個“::”。

          為什么?很簡單,你看下面這四個地址,如果所有0全都縮寫,會變成什么樣?

          2001:0000:0000:0000:0000:25de:0000:cade

          2001: 0000: 0000:0000:25de:0000:0000:cade

          2001: 0000: 0000:25de:0000:0000:0000:cade

          2001: 0000: 25de:0000:0000:0000:0000:cade

          是的,都是2001::25de::cade,沖突了。所以,這個地址是非法的,不允許存在的。

          關于IPv6還有很多技術細節,因篇幅原因,不再贅述。

          除了地址數量之外,IPv6還有很多優點,例如:

          1)IPv6使用更小的路由表。使得路由器轉發數據包的速度更快;

          2)IPv6增加了增強的組播支持以及對流的控制,對多媒體應用很有利,對服務質量(QoS)控制也很有利;

          3)IPv6加入了對自動配置的支持。這是對DHCP協議的改進和擴展,使得網絡(尤其是局域網)的管理更加方便和快捷;

          4)IPv6具有更高的安全性。用戶可以對網絡層的數據進行加密并對IP報文進行校驗,極大地增強了網絡的安全性;

          5)IPv6具有更好的擴容能力。如果新的技術或應用需要時,IPV6允許協議進行擴充;

          6)IPv6具有更好的頭部格式。IPV6使用新的頭部格式,就簡化和加速了路由選擇過程,提高了效率;

          ……

          7、IPv6的優點這么多,為什么之前普及卻這么慢?

          IPv6優點這么多,為什么它問世已經20年了,還是沒有完全替代IPv4呢?這里面的水就很深了。。。說白了,主要還是和利益有關。

          7.1 NAT這類技術,讓IPv4得以續命

          如果按照本世紀初專家們的預測,我們IPv4的地址早已枯竭幾萬次了。但是,一直挺到現在,大家仍然還在用IPv4,對老百姓來說,并沒有因為地址不夠而無法上網。

          這是為什么呢? 就是因為除了IPv6之外,我們還有一些技術,可以變相地緩解地址不足。

          例如NAT(Network Address Translation,網絡地址轉換)。

          NAT是什么意思?當我們在家里或公司上網時,你的電腦肯定有一個類似192.168.0.1的地址,這種地址屬于私網地址,不屬于公共的互聯網地址。

          ▲ 一個典型的NAT應用場景(圖自《IPv6,到底是什么?》)

          每一個小的局域網,都會使用一個網段的私網地址,在與外界連接時,再變換成公網地址。這樣一來,幾十個或幾百個電腦,都只需要一個公網地址。

          甚至還可以私網套私網,NAT套NAT,一層一層套。這樣一來,大大節約了公網IP地址數量。正因為如此,才讓我們“續命”到了今天,不至于無法上網。

          但是,NAT這種方式也有很多缺點,雖然私網地址訪問互聯網地址方便,但互聯網地址訪問私網地址就困難了。很多服務,都會受到限制,你只能通過復雜的設置才能解決,也會影響網絡的處理效率。

          ▲ NAT內網的計算機是不能被外網直接訪問的(圖自《IPv6,到底是什么?》)

          7.2 升級IPv6涉及運營商的利益

          物以稀為貴,地址越稀缺,就越值錢。掌握地址的人,就越開心。誰開心?運營商和ISP(互聯網服務提供商)。

          他們就像是經銷商,從上游(互聯網域名與號碼分配機構,即ICANN)申請到IP地址,再賣給下游用戶。稀缺沒關系,反正,他一定能賺取更多的差價。

          如果大家去找運營商或ISP買帶寬,或者租賃云服務,帶公共地址的,一定比不帶公共地址的貴很多很多。

          除了地址可以賺錢之外,如果升級支持IPv6,對運營商和ISP來說,也意味著很大的資金投入。現在新設備基本都是支持的,但畢竟還是有一些老設備,如果在使用壽命到期之前就換,就是虧錢。

          所以,運營商和ISP都沒有動力去啟用IPv6。 

          至于設備商或手機電腦廠商,出于提前考慮,早已普遍支持了IPv6,意見并不是很大,也決定不了什么。必竟,提供基礎設施服務的運營商們更強勢。

          8、IPv6未來會怎樣

          隨著5G時代的到來,有了IPv6的加持,萬物互聯或許會成為現實。對于我等實時通信類軟件的開發人員來說,某些場景下,或許再也不需要為“P2P打洞”這種事情煩惱了。 

          ▲ 5G+IPv6,萬物互聯不是夢

          未來已來,你準備好了嗎?

          9、參考資料

          [1] IPv6入門教程

          [2] IPv6,到底是什么?

          [3] 關于IPv6的發展史!IPv6的秘密史!

          [4] 科普:一文讀懂IPv6是什么?

          [5] 漫話:全球IPv4地址正式耗盡?到底什么是IPv4和IPv6?

          附錄:更多網絡編程基礎知識文章

          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中的NAT穿越(打洞)方案詳解(進階分析篇)

          P2P技術詳解(四):P2P技術之STUN、TURN、ICE詳解

          通俗易懂:快速理解P2P技術中的NAT穿透原理

          高性能網絡編程(一):單臺服務器并發TCP連接數到底可以有多少

          高性能網絡編程(二):上一個10年,著名的C10K并發連接問題

          高性能網絡編程(三):下一個10年,是時候考慮C10M并發問題了

          高性能網絡編程(四):從C10K到C10M高性能網絡應用的理論探索

          高性能網絡編程(五):一文讀懂高性能網絡編程中的I/O模型

          高性能網絡編程(六):一文讀懂高性能網絡編程中的線程模型

          Java的BIO和NIO很難懂?用代碼實踐給你看,再不懂我轉行!

          不為人知的網絡編程(一):淺析TCP協議中的疑難雜癥(上篇)

          不為人知的網絡編程(二):淺析TCP協議中的疑難雜癥(下篇)

          不為人知的網絡編程(三):關閉TCP連接時為什么會TIME_WAIT、CLOSE_WAIT

          不為人知的網絡編程(四):深入研究分析TCP的異常關閉

          不為人知的網絡編程(五):UDP的連接性和負載均衡

          不為人知的網絡編程(六):深入地理解UDP協議并用好它

          不為人知的網絡編程(七):如何讓不可靠的UDP變的可靠?

          不為人知的網絡編程(八):從數據傳輸層深度解密HTTP

          不為人知的網絡編程(九):理論聯系實際,全方位深入理解DNS

          技術掃盲:新一代基于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轉換又是什么鬼?

          腦殘式網絡編程入門(七):面視必備,史上最通俗計算機網絡分層詳解

          腦殘式網絡編程入門(八):你真的了解127.0.0.1和0.0.0.0的區別?

          以網游服務端的網絡接入層設計為例,理解實時通信的技術挑戰

          邁向高階:優秀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請求嗎?

          知乎技術分享:知乎千萬級并發的高性能長連接網關技術實踐

          5G時代已經到來,TCP/IP老矣,尚能飯否?

          >> 更多同類文章 ……

          歡迎關注我的“即時通訊技術圈”公眾號: 

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

          posted @ 2020-04-17 11:21 Jack Jiang 閱讀(402) | 評論 (0)編輯 收藏

          本文已同時發布于我的“即時通訊技術圈”公眾號。

          1、引言

          哈羅,大家好,我是Jack Jiang。。。(一股濃濃的自媒體視頻旁白味道)。

          對于經??次椅恼碌募磿r通訊開發者來說,今天要討論的這個話題,貌似有點不著邊際。

          是的,自從我整理完《IM開發者的零基礎通信技術入門》系列文章之后,對于網絡編程的理解,開始有點飄了。

          言歸正傳?,F在,5G技術離我們的生活越來越近了,號稱網絡延遲1ms、下行速度10Gb/s的5G,在這樣逆天的網絡性能指標下,老驥伏櫪的TCP/IP是否仍能Hold的住?帶著這個思考,便有了本文的內容。

           

          ▲ 5G網速有多快?看圖感受一下(圖自《零基礎,史上最強5G技術掃盲》)

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

          2、學好TCP/IP夠用嗎?

          對于即時通訊技術的開發者,從技術棧來說,一條最普通的聊天消息的送達,肯定要涉及到網絡編程技術,而網絡編程最核心的也就是TCP/IP協議(準確的說是TCP/IP協議簇,見《TCP/IP詳解》),毫無疑問深入的學習TCP/IP協議肯定是非常有必要了。

          基本上,對于普通的IM或消息推送系統開發來說,對TCP/IP相關的計算機網絡基礎比較熟悉的話,完全夠用了。

           

          ▲ 這本書很多人都讀過

          3、移動網絡問題,只能賴我代碼爛?

          親手寫過即時通訊的網絡通信層的同學都很清楚,在移動網絡中(我說的移動網絡具體指的是運營商的2g/3g/4g/5g這些),因為無線通信的介質和技術實現特殊性,出現了很多傳統有線互聯網不曾有過的網絡通信問題。

          就拿IM在移動弱網中出現的各種問題來說,多數開發者都不自信的認為這應該是自已的網絡層代碼寫的不夠優秀,是的,很多時候也確實是這樣。

          我收集整理的下面這幾篇資料,就討論的是這些,有興趣可以讀一下:

          現代移動端網絡短連接的優化手段總結:請求速度、弱網適應、安全保障

          百度APP移動端網絡深度優化實踐分享(三):移動端弱網優化篇

          微信移動端應對弱網絡情況的探索和實踐PPT [附件下載]

          YY直播在移動弱網環境下的深度優化實踐分享(視頻+PPT)[附件下載]

          其實,很少有人會去思考,在TCP/IP協議被發明出來的50年后,對于現代的移動網絡來說,是否仍然能工作的好?以弱網問題為例,難道我寫的IM總是丟消息、掉線就僅僅是“我”的代碼太爛? 

          沒錯,這不僅僅是應用層的代碼編寫問題,它或許涉及到TCP/IP的設計局限,甚至移動網絡的底層設計也并不是最完美的。

          下面這兩篇文章,對于弱網問題思考,已經深入到運營商的通信技術這一層,強烈建議讀一讀:

          移動端IM開發者必讀(一):通俗易懂,理解移動網絡的“弱”和“慢”

          移動端IM開發者必讀(二):史上最全移動弱網絡優化方法總結

          如果你的認知,已經開始對底層的網絡通信技術有所困惑,下面這幾篇就是為你準備的:

          IM開發者的零基礎通信技術入門(六):移動終端的接頭人——“基站”技術

          IM開發者的零基礎通信技術入門(七):移動終端的千里馬——“電磁波”

          IM開發者的零基礎通信技術入門(八):零基礎,史上最強“天線”原理掃盲

          IM開發者的零基礎通信技術入門(九):無線通信網絡的中樞——“核心網”

          IM開發者的零基礎通信技術入門(十):零基礎,史上最強5G技術掃盲

          IM開發者的零基礎通信技術入門(十一):為什么WiFi信號差?一文即懂!

          IM開發者的零基礎通信技術入門(十二):上網卡頓?網絡掉線?一文即懂!

          IM開發者的零基礎通信技術入門(十三):為什么手機信號差?一文即懂!

          IM開發者的零基礎通信技術入門(十四):高鐵上無線上網有多難?一文即懂!

          4、簡單復習一下TCP/IP

          從字面意義上講,有人可能會認為 TCP/IP 是指 TCP 和 IP 兩種協議。實際生活當中有時也確實就是指這兩種協議。

          然而在很多情況下,它只是利用 IP 進行通信時所必須用到的協議簇的統稱。

          具體來說,IP 或 ICMP、TCP 或 UDP、TELNET 或 FTP、以及 HTTP 等都屬于 TCP/IP 協議。他們與 TCP 或 IP 的關系緊密,是互聯網必不可少的組成部分。TCP/IP 一詞泛指這些協議,因此,有時也稱 TCP/IP 為網際協議簇。

          互聯網進行通信時,需要相應的網絡協議,TCP/IP 原本就是為使用互聯網而開發制定的協議簇。因此,互聯網的協議就是 TCP/IP,TCP/IP 就是互聯網的協議。 

          ▲ 上圖反映了TCP/IP協議族的關系(圖片引用自《計算機網絡通訊協議關系圖》)

          5、TCP/IP或許太老了

          對于現代移動網絡來說,TCP/IP或許太老了。我們簡單了解一下TCP/IP協議的產生過程。

          1973年:卡恩與瑟夫開發出了TCP/IP協議中最核心的兩個協議:TCP協議和IP協議。

          1974年:卡恩與瑟夫正式發表了TCP/IP協議并對其進行了詳細的說明。同時,為了驗證TCP/IP協議的可用性,使一個數據包由一端發出,在經過近10萬km的旅程后到達服務端。在這次傳輸中,數據包沒有丟失一個字節,這充分說明了TCP/IP協議的成功。

          1983年:TCP/IP協議正式替代NCP,從此以后TCP/IP成為大部分因特網共同遵守的一種網絡規則。

          1984年:TCP/IP協議得到美國國防部的肯定,成為多數計算機共同遵守的一個標準。 

          是的,你沒有看錯,TCP/IP協議設計于距今50年前!

           

          ▲ 羅伯特·卡恩(左者)與文特·瑟夫(右者)(圖片引用自《技術往事:改變世界的TCP/IP協議》)

          6、TCP/IP原本是為固定網絡設計的

          雖然TCP/IP自上世紀70年代發明以來,連接了無數的計算機,推動了互聯網的蓬勃發展。

          但不可回避的現實是,基于TCP/IP的互聯網,它的初衷是為固定網絡和網絡互連而設計,而今天我們已經發展到了移動互聯時代。

          再往后看,未來5G將面臨AR/VR、超高清視頻、物聯網、車聯網等各種應用、用例紛呈,加之網絡安全的緊迫性越發凸顯,TCP/IP或許難以適應未來。

          7、TCP/IP或許并不適合移動網絡

          7.1 TCP/IP設計之初無法預見高速移動網時代

          在TCP/IP剛被設計的年代,即傳統固定互聯網的公元元年,主機是固定的,用于編址的IP也是固定的,世界是平的。

          可是隨著應用程序以及芯片技術的活力涌現,設備越來越小,App越來越豐富,當你覺得渾身憋得慌的時候,移動互聯網時代來了。

          但傳統的TCP/IP并不適合移動網絡,以TCP/IP協議簇中我們最常用的TCP協議來說,傳統的TCP基于TCP/IP協議頭字段的五元組,而標識設備的IP地址僅僅標識了設備位置,并沒有標識設備本身(實際上不管到了什么年代,IP地址都不應該標識設備本身,它就是標識位置的!問題是,TCP不應該用一個標識位置的元素來標識設備)。

          而對于移動互聯網來說,一旦移動設備(比如智能手機)換了位置(通信基站切換了),其IP地址也會改變,進而既有的TCP連接將全部中斷。

           

          ▲ 運營商的基站是有覆蓋范圍的,而且覆蓋范圍并不大

          對于底層的移動網絡通信技術有所了解的開發人員或許知道,手機的通信是由基站進行代理的,而基站是固定的。換句話說,當你移動到下一個基站的位置時,手機就得自動切換到新的基站,進而重新進行一系列的跟運營商的無線體系進行連接建立的過程。

          這在日常生活中使用并沒有什么問題,但在時速達到350公里每小時的復興號高鐵上用手機上網時,這就會導致嚴重的問題。因為基站的信號覆蓋范圍有限,在手機移動速度如此之快的情況下,基站的切換也將頻繁到讓網絡工程師們崩潰(有興趣可以讀一下《IM開發者的零基礎通信技術入門(十四):高鐵上無線上網有多難?一文即懂!》)。

          TCP/IP和網絡的關系,可以作個有趣的類比。

          假設互聯網是公路,那么TCP/IP這就是這條公路上的一套交通規則。這套規則在制定時,可能考慮到的只是普通的市場內道路(最多是高速公路使用),而現在的5G時代,就好比時速350公里的高速鐵路,試想普通的市內交通規則套用在高速鐵路上,那難道不算是災難嗎。

          必竟普通的市內交通速度不會很快,各種規則的制定誤差和余量可以比較大,但高速鐵路上,速度飛快、交通信號控制精確無比的情況下,這套規則,對于開高鐵的司機來說,肯定是膽顫心驚。而TCP/IP對于5G來說,就好比這套老的交通規則,用它來駕馭這么快速的5G快車,是不是很瘋狂?

           

          7.2 TCP/IP與電信網的基因不同

          基于TCP/IP的互聯網原本是為固定網絡和網絡互聯設計,而運營商的移動網絡是為移動性連接而生。互聯網的連接是分布式的,而移動通信網絡是集中控制的。

          這兩者的技術基因確實有很大不同,在早期移動網絡網絡性能較慢的情況下,這兩者的結合,矛盾似乎并不突出。

          實際上,在傳統電信網(就是大家最常用的電話、短信網絡)與IT互聯網是兩撥人各自有玩耍(電信網為代表的就是3GPP標準化組織,互聯網為代表的就是IETF標準化組織)。

          在那個移動網還不發達的年代,這兩撥人各自玩各自的,大家誰也不用鳥誰。

          隨著人們對移動上網需求越來越旺盛,搞電信網的這撥人只能想辦法接入傳統的互聯網,必竟在當時傳統互聯網太強勢,而移動網的應用場景還在摸索階段,為了能快速解決移動上網的問題,與是也不好麻煩IETF這撥人,所有痛苦默默承受——雖然TCP/IP在移動網上的實施并不合適,但只能想辦法縫縫補補,把移動網的標準制定,往它上面靠。

          這就好比,TCP/IP這輛車已經造好了,至于你搞移動網的人,是修一條普通馬路(2G)、還是一條高速公司路(3G)、或者是現在的高速鐵路(5G),反正你只能將就這輛車。原本應該是什么路上跑什么車,而現在是不管你什么路,只能跑這輛車。反正車子跑不好,不怪車子,怪路。。

          好奇葩的邏輯,而這個邏輯就好比是現在的TCP/IP跟移動網的關系。

          所以,在5G,甚至未來的6G、7G時代,這種“勉強”的結合,拋必帶來網絡低效、基礎設施成本高昂等問題。

          8、移動運營商們已經意識到問題

          是的,大佬們已經意識到了問題的嚴重性,正在著手解決。

          2020年4月初,歐洲電信標準協會(ETSI)已成立了一個新的行業規范工作組“Non-IP Networking”(ISG NIN),以解決新服務、尤其是5G服務面臨的老式網絡協議所存在的問題。

          ▲ 詳細新聞內容《點此查看

          該工作組的目標是為5G網絡研究開發新的網絡協議,以替代TCP/IP。

          是的,這些移動運營商已經發現在4G、甚至5G網絡中使用的基于TCP/IP的技術存在一些問題。

          由于TCP/IP協議最初是為互聯網設計,而非為移動通信網絡而生,當移動通信網絡引入TCP/IP后,增加了移動性、安全性、QoS等功能,這使得網絡更復雜,頻譜使用效率較低。為了解決這些問題,后續的修補和替代方案又導致了成本、時延和功耗增加。

          大佬們終于承認,對于5G的某些高級服務,TCP/IP確實被認為不是最佳的。

          9、移動網絡未來會怎樣?

          雖然TCP/IP可能越來越難以適應移動網絡的發展,但不可否認,短期內TCP/IP的不可替代性。

          必竟,基于TCP/IP的傳統互聯網所構建的軟件和硬件世界(尤其是硬件)并不是一朝一夕的事,而替換掉這些,無論是從成本還是各方利益來說,都是個需要反復權衡和博弈的事。

          一個很好的例子是,IPv4和IPv6,雖然誰都知道IPv4的困境,但IPv6喊了這么多年目前想要普及,仍然還比較遙遠,要知道IPv6已經喊了10年了。因為這小小的IP地址,牽涉的是互聯網從硬到軟幾乎所有環節,影響之大,無出其右。

          對于IM開發者來說,因為移動網絡的特殊性,而技術改朝換代也并不鮮見。

          比如眾所周之的XMPP協議,設計之初也是野心勃勃——“要讓上IM就像打開網頁一樣簡單!”。確實,XMPP無論是肉眼可讀性,還是數據結構的優雅,都非常優秀,但悲劇的是,設計者們從來沒有想過移動網會發展成今天這樣,或者說設計者們從未考慮過XMPP在移動網下的使用。于是,后面的故事,大家都很清楚——每個人都在抱怨XMPP臃腫、冗余(是的,這里我收集了一大堆這樣的文章),這算個是把優點做成缺點的典型案例了。

          或許,未來會有那么一天,移動網絡終有屬于為自已定制的網絡協議標準。而對于搞網絡通信的程序員來說,如果這套新的標準讓能基于移動網絡的代碼編寫,變的愉快起來,那真是謝天謝地了!

          10、參考資料

          [1] TCP/IP 已完 ?New IP 之后,又來一個 Non-IP

          [2] 5G:再見,TCP/IP

          [3] 重新設計TCP/IP協議棧以支持設備移動性

          [4] 5G要拋棄TCP/IP?

          [5] ETSI LAUNCHES NEW GROUP ON NON-IP NETWORKING ADDRESSING 5G NEW SERVICES

          附錄:更多網絡編程基礎資料

          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中的NAT穿越(打洞)方案詳解(進階分析篇)

          P2P技術詳解(四):P2P技術之STUN、TURN、ICE詳解

          通俗易懂:快速理解P2P技術中的NAT穿透原理

          高性能網絡編程(一):單臺服務器并發TCP連接數到底可以有多少

          高性能網絡編程(二):上一個10年,著名的C10K并發連接問題

          高性能網絡編程(三):下一個10年,是時候考慮C10M并發問題了

          高性能網絡編程(四):從C10K到C10M高性能網絡應用的理論探索

          高性能網絡編程(五):一文讀懂高性能網絡編程中的I/O模型

          高性能網絡編程(六):一文讀懂高性能網絡編程中的線程模型

          Java的BIO和NIO很難懂?用代碼實踐給你看,再不懂我轉行!

          不為人知的網絡編程(一):淺析TCP協議中的疑難雜癥(上篇)

          不為人知的網絡編程(二):淺析TCP協議中的疑難雜癥(下篇)

          不為人知的網絡編程(三):關閉TCP連接時為什么會TIME_WAIT、CLOSE_WAIT

          不為人知的網絡編程(四):深入研究分析TCP的異常關閉

          不為人知的網絡編程(五):UDP的連接性和負載均衡

          不為人知的網絡編程(六):深入地理解UDP協議并用好它

          不為人知的網絡編程(七):如何讓不可靠的UDP變的可靠?

          不為人知的網絡編程(八):從數據傳輸層深度解密HTTP

          不為人知的網絡編程(九):理論聯系實際,全方位深入理解DNS

          網絡編程懶人入門(一):快速理解網絡通信協議(上篇)

          網絡編程懶人入門(二):快速理解網絡通信協議(下篇)

          網絡編程懶人入門(三):快速理解TCP協議一篇就夠

          網絡編程懶人入門(四):快速理解TCP和UDP的差異

          網絡編程懶人入門(五):快速理解為什么說UDP有時比TCP更有優勢

          網絡編程懶人入門(六):史上最通俗的集線器、交換機、路由器功能原理入門

          網絡編程懶人入門(七):深入淺出,全面理解HTTP協議

          網絡編程懶人入門(八):手把手教你寫基于TCP的Socket長連接

          網絡編程懶人入門(九):通俗講解,有了IP地址,為何還要用MAC地址?

          網絡編程懶人入門(十):一泡尿的時間,快速讀懂QUIC協議

          技術掃盲:新一代基于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轉換又是什么鬼?

          腦殘式網絡編程入門(七):面視必備,史上最通俗計算機網絡分層詳解

          腦殘式網絡編程入門(八):你真的了解127.0.0.1和0.0.0.0的區別?

          以網游服務端的網絡接入層設計為例,理解實時通信的技術挑戰

          邁向高階:優秀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請求嗎?

          知乎技術分享:知乎千萬級并發的高性能長連接網關技術實踐

          5G時代已經到來,TCP/IP老矣,尚能飯否?

          >> 更多同類文章 ……

          歡迎關注我的“即時通訊技術圈”公眾號: 

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

          posted @ 2020-04-13 23:41 Jack Jiang 閱讀(503) | 評論 (0)編輯 收藏

               摘要: 本文作者騰訊WXG后臺開發工程師jeryyzhang,收錄時有改動,感謝原作者的分享。1、引言大約3年前,微信技術團隊分享了《微信后臺基于時間序的海量數據冷熱分級架構設計實踐》一文,文中總結了微信這種超級IM基于時間序的海量數據存儲架構的設計實踐,也得以讓大家了解了微信后臺的架構設計思路。時隔3年,微信再次分享了基于時間序的新一代海量數據存儲架構的設計實踐(可以認為是《微信后臺基于時間序的海量數據...  閱讀全文

          posted @ 2020-04-09 15:07 Jack Jiang 閱讀(330) | 評論 (0)編輯 收藏

               摘要: 一、引言2020年春節早已過去兩月有余,回顧本次騰訊手Q春節紅包活動的玩法,主要以答題形式結合中國傳統文化(成語、詩詞、對聯、歷史等)的方式進行,達到寓教于樂的效果。 ▲ 2020年春節QQ的紅包活動對于這種大體量的IM社交應用運營活動,技術上除了前端、后臺的大力支撐,對于手Q客戶端來說,又是從哪些方面來保證整個紅包活動的靈活性、穩定性和用戶體驗的呢?帶著這個問題,我們一起來...  閱讀全文

          posted @ 2020-04-06 23:41 Jack Jiang 閱讀(305) | 評論 (0)編輯 收藏

               摘要: 本文原文由微信客戶端高級工程師方秋枋原創發表于WeMobileDev公眾號,收錄時有修訂和加工,感謝作者的無私分享。1、引言作為一個重要業務,微信支付在客戶端上面臨著各種問題。其中最核心問題就是分平臺實現導致的問題:1)iOS 和安卓實現不一致:容易出 Bug、通過溝通保證不了質量;2)擴展性差且無法快速響應業務需求:需求變更迭代周期長、數據上報不全面;3)質量保障體系不完善:缺少業務及設計知識沉...  閱讀全文

          posted @ 2020-03-25 17:00 Jack Jiang 閱讀(426) | 評論 (0)編輯 收藏

               摘要: 1、引言很多人一想到IM應用開發,第一印象就是“長連接”、“socket”、“?;?#8221;、“協議”這些關鍵詞,沒錯,這些確實是IM開發中肯定會涉及的技術范疇。但,當你真正開始編寫第一行代碼時,最現實的問題實際上是“聊天消息ID該怎么生成?”這個看似微不足道的小事情。說它看似微不足道,...  閱讀全文

          posted @ 2020-03-19 17:34 Jack Jiang 閱讀(378) | 評論 (0)編輯 收藏

          本文原文由作者Amazing10原創發布于公眾號業余碼農,收錄時有改動,感謝原作者的技術分享。

          1、引言

          某天中午,吃完午飯,攤在自己的躺椅上,想趁吃飽喝足的午后時間靜靜享受獨自的靜謐。

           
           

          干點什么好呢?于是單手操作鼠標打開了一個陌生而隱秘的網站。正開著某個視頻起勁。。。

          突然瀏覽器彈出了一個提示:

          請使用微信掃碼登錄賬號,繼續觀看

          這...

           
           

          但是由于強烈的好奇驅使,迫于無奈,只好選擇登錄再繼續觀看。于是熟練的掏出手機,打開微信掃一掃對準上面的二維碼,只聽見 “叮” 的一聲,網頁上的二維碼放佛活過來了,直接刷新出了本尊的微信頭像,同時手機上也彈出登錄的提醒。

           
           

          心中略微驚嘆,但沒來得及多想。忙點擊手機界面中登錄按鈕。此時網頁刷新,恢復了正常,表示可以繼續觀看。

          上網沖浪的時間總是過得很快,很快就有些疲倦。于是閉上眼睛,腦海中卻浮現出了剛剛微信掃描二維碼,然后登錄網頁的場景,心中再次驚嘆,并開始思考起其中的原理來。。。

          言歸正傳,本文將以輕松活潑的語言形式,為你分析和講解微信手機掃碼登錄的技術原理,希望在你的IM中開發此功能時有所啟發。

          推薦閱讀:另一篇同類文章《IM的掃碼登錄功能如何實現?一文搞懂主流的掃碼登錄技術原理》也值得一讀。

          學習交流:

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

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

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

          2、IM開發干貨系列文章

          本文是系列文章中的第23篇,總目錄如下:

          IM消息送達保證機制實現(一):保證在線實時消息的可靠投遞

          IM消息送達保證機制實現(二):保證離線消息的可靠投遞

          如何保證IM實時消息的“時序性”與“一致性”?

          IM單聊和群聊中的在線狀態同步應該用“推”還是“拉”?

          IM群聊消息如此復雜,如何保證不丟不重?

          一種Android端IM智能心跳算法的設計與實現探討(含樣例代碼)

          移動端IM登錄時拉取數據如何作到省流量?

          通俗易懂:基于集群的移動端IM接入層負載均衡方案分享

          淺談移動端IM的多點登錄和消息漫游原理

          IM開發基礎知識補課(一):正確理解前置HTTP SSO單點登錄接口的原理

          IM開發基礎知識補課(二):如何設計大量圖片文件的服務端存儲架構?

          IM開發基礎知識補課(三):快速理解服務端數據庫讀寫分離原理及實踐建議

          IM開發基礎知識補課(四):正確理解HTTP短連接中的Cookie、Session和Token

          IM群聊消息的已讀回執功能該怎么實現?

          IM群聊消息究竟是存1份(即擴散讀)還是存多份(即擴散寫)?

          IM開發基礎知識補課(五):通俗易懂,正確理解并用好MQ消息隊列

          一個低成本確保IM消息時序的方法探討

          IM開發基礎知識補課(六):數據庫用NoSQL還是SQL?讀這篇就夠了!

          IM里“附近的人”功能實現原理是什么?如何高效率地實現它?

          IM開發基礎知識補課(七):主流移動端賬號登錄方式的原理及設計思路

          IM開發基礎知識補課(八):史上最通俗,徹底搞懂字符亂碼問題的本質

          IM的掃碼登功能如何實現?一文搞懂主流應用的掃碼登錄技術原理

          IM要做手機掃碼登陸?先看看微信的掃碼登錄功能技術原理》(本文)

          3、原理解析

          微信掃碼登錄現在在日常生活中已經是常見不能再常見的場景之一了,但是要知道微信首次公開這項功能時,卻是驚艷眾人。移動端與PC端以這樣一種巧妙的方式鏈接在了一起,的確是讓人驚嘆。

          以下是一個典型的微信掃碼登錄全過程: 

          本來想在Web版微信上截圖,但掃碼登陸后出現了下面的提示(貌似很多人都碰到過): 

          好吧,這很微信,反正就是不想讓你好好用,用戶愛咋咋滴。。。

          如上圖所示,操作過程如下:

          1)第一步:電腦上打開PC端(出現2維碼);

          2)第二步:拿出手機,掃碼2維碼;

          3)第三步:PC端顯示掃碼成功;

          4)第四步:手機端“確認”登錄;

          5)第五步:成功登陸PC端。

          上述實際操作過程,用戶體驗相當順滑,也難怪剛出來那會,能驚艷到很多人。

          那么,對于上述操作過程的技術實現原理是什么樣的呢?

          想起來之前聽過的前后端的概念,知道賬戶的數據信息一般都是放在服務器上,前端負責向后端 “討要數據” 并顯示,后端則是對前端的 “討要” 做出反應。

          這樣一來,猜測微信登錄的過程可能就是:

          1)網頁前端向微信后臺請求賬號數據;

          2)微信后臺接受網頁前端的請求,然后將他的賬號數據返回;

          3)網頁前端接收到了數據后,在瀏覽器里進行顯示。

          于是,手腳麻利的畫了個示意圖:

          當我正準備沾沾自喜的時候,突然看到桌面上的手機。咦,如果就只是這么個過程,那手機的作用是啥。于是才開始意識到,問題沒這么簡單。

          好吧,我們城要再深入一點探秘微信掃碼登錄的過程。

          4、過程分析

          為了更深入的分析整個過程,我們可以去看看微信網頁版,地址是:https://wx.qq.com/。

           

          筆者看著網頁中碩大的二維碼陷入了沉思——這個二維碼跟手機賬號有沒有什么對應關系呢?如果沒有,那它又是怎么生成的呢?

          思考間,于是打開了瀏覽器的開發者工具。

          在網絡監控一覽找到了這幅二維碼,與之對應的鏈接是:

          https://login.weixin.qq.com/qrcode/gaO8cOQweA==

          如下圖所示:

          然后習慣性地,嘗試多次刷新頁面,發現二維碼不斷發生變化,鏈接也不斷更改:

          https://login.weixin.qq.com/qrcode/AencxgKNFQ==

          https://login.weixin.qq.com/qrcode/YcD7f_DxvA==

          https://login.weixin.qq.com/qrcode/QblN8lCn2g==

          似乎發現了些東西:二維碼不斷變化,其對應的鏈接尾的代碼也相應變化,并且是隨機性的變化。

          這也就是說,每一次頁面刷新都會隨機且唯一地生成一個二維碼。這或許可以與手機登錄的過程聯系起來。

          似乎開始明白了,于是再次拿起手機,熟練的使用微信掃描了此時的二維碼。

          “叮” 的一聲,網頁上的二維碼頓時變成了我帥氣的微信頭像。這個時候,我才突然意識到,是掃碼之后網頁才與他的微信賬號建立起了聯系。

          如下圖所示: 

          也就是說:

          1)沒有掃碼之前,頁面上的二維碼只是隨機生成的且與用戶無關的碼;

          2)而當用戶掃碼之后,二維碼便與用戶帳號綁定在了一起。

          原來手機掃碼的用處是這樣!

          此時注意到,手機微信上彈出了『微信登錄確認』的提醒。這個時候謹慎地點擊了下方的登錄按鈕。

          如下圖所示: 

          隨著平滑的動畫一閃而過,網頁上已經顯示出了我的微信賬號信息,顯示微信賬號已經登錄。再一次體驗這個過程,心中開始思索手機微信在登錄過程中所起到的具體作用。

          首先需要明白幾個過程:

          1)進入網頁登陸界面,隨機生成一個二維碼;

          2)通過手機掃描二維碼,將微信賬號與二維碼綁定;

          3)在手機微信點擊登錄按鈕,授權網頁登錄微信賬號;

          4)網頁獲得的賬號信息,將數據顯示。

          5、原理解釋

          回顧上述過程,結合最開始的原理猜測,開始思索整個環節,是哪里理解的不對。。。

          1)網頁的二維碼到底從何而來?

          2)是誰向微信后臺請求了賬號數據?

          實際上:不同的網站可能都需要通過微信后臺進行數據的獲取,那么每一個網站必然也存在它的后臺來給微信后臺發送請求。

          這樣一來,整個過程就能解釋得通了:

          1)網站頁面刷新,網頁后臺向微信后臺請求授權登錄;

          2)微信后臺返回登錄所需二維碼;

          3)用戶通過手機掃描二維碼,并在手機上授權登錄后,微信后臺告知網頁后臺已授權;

          4)網頁后臺向微信后臺請求微信賬號數據;

          5)微信后臺返回賬號數據;

          6)網頁后臺接收數據并通過瀏覽器顯示;

          6、技術剖析

          正如上節所述,想清楚了整個過程后,我們應該對整個過程的技術實現進行進一步的探究。

          在微信開發官方文檔中,我找到了第三方網站應用微信登錄開發指南:

          https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html

          我將整個過程梳理了一遍,畫出了這個圖: 

          如上圖所示,整個技術實現如下。

          (1)二維碼的獲得:

          • 1)用戶打開網站后,網站后臺根據微信OAuth2.0協議向微信開發平臺請求授權登錄,并傳遞事先在微信開發平臺中審核通過的AppID和AppSecrect等參數;
          • 2)微信開發平臺對AppID等參數進行驗證,并向網站后臺返回二維碼;
          • 3)網站后臺將二維碼傳送至網站前端進行顯示。

          (2)微信客戶端授權登錄:

          • 1)用戶使用微信客戶端掃描二維碼并授權登錄;
          • 2)微信客戶端將二維碼特定的uid與微信賬號綁定,傳送至微信開發平臺;
          • 3)微信開發平臺驗證綁定數據,調用網站后臺的回調接口,發送授權臨時票據code;

          (3)網站后臺請求數據:

          • 1)網站后臺接收到code,表明微信開發平臺同意數據請求;
          • 2)網站后臺根據code參數,再加上AppID和AppSecret請求微信開發平臺換取access_token;
          • 3)微信開發平臺驗證參數,并返回access_token;
          • 4)網站后臺收到access_token后即可進行參數分析獲得用戶賬號數據。

          在上述過程中,有幾個參數值得解釋一下(來源官方文檔):

          • 1)AppID:應用唯一標識,在微信開放平臺提交應用審核通過后獲得;
          • 2)AppSecret:應用密鑰,在微信開放平臺提交應用審核通過后獲得;
          • 3)code:授權臨時票據,第三方通過code進行獲取access_token的時候需要用到,code的超時時間為10分鐘,一個code只能成功換取一次access_token即失效。code的臨時性和一次性保障了微信授權登錄的安全性。

          整個過程從網站后臺向微信開發平臺請求授權登錄開始,最終目的是為了獲得access_token:

          access_token:用戶授權第三方應用發起接口調用的憑證

          在獲得了access_token后就可以解析用戶的一些基本信息,包括頭像、用戶名、性別、城市等。這樣一來,整個微信掃描登錄的過程就完成了。

          7、寫在最后

          研究到這,終于大體上對微信掃碼登錄的整個過程有了清晰的認知??雌饋硭坪跻膊浑y,開發者只需要在網頁后端做好對微信公眾平臺的接口調用即可實現掃碼登錄。

          伸了伸懶腰,忽然又想到在整個過程中還需要考慮超時的問題。比如二維碼超時未掃描、二維碼掃描后超時授權、獲得access_token后超時等等問題。

          我發現一個簡單的功能實現起來還是需要考慮許多細節,真的是紙上得來終覺淺呀。于是我下定決心,下次得少上網沖浪了,花點時間搭個服務器先把微信掃碼登錄過程實現看看。

          不過,還得先去在微信開放平臺注冊開發者帳號,并擁有一個已審核通過的網站應用,并獲得相應的AppID和AppSecret才行。

          想了想,還是讓我先趟一會兒吧。。。

           

          附錄:更多IM開發相關文章

          [1] IM開發熱門文章:

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

          移動端IM開發者必讀(一):通俗易懂,理解移動網絡的“弱”和“慢”

          移動端IM開發者必讀(二):史上最全移動弱網絡優化方法總結

          從客戶端的角度來談談移動端IM的消息可靠性和送達機制

          現代移動端網絡短連接的優化手段總結:請求速度、弱網適應、安全保障

          騰訊技術分享:社交網絡圖片的帶寬壓縮技術演進之路

          小白必讀:閑話HTTP短連接中的Session和Token

          移動端IM開發需要面對的技術問題

          開發IM是自己設計協議用字節流好還是字符流好?

          請問有人知道語音留言聊天的主流實現方式嗎?

          通俗易懂:基于集群的移動端IM接入層負載均衡方案分享

          微信對網絡影響的技術試驗及分析(論文全文)

          即時通訊系統的原理、技術和應用(技術論文)

          開源IM工程“蘑菇街TeamTalk”的現狀:一場有始無終的開源秀

          QQ音樂團隊分享:Android中的圖片壓縮技術詳解(上篇)

          QQ音樂團隊分享:Android中的圖片壓縮技術詳解(下篇)

          騰訊原創分享(一):如何大幅提升移動網絡下手機QQ的圖片傳輸速度和成功率

          騰訊原創分享(二):如何大幅壓縮移動網絡下APP的流量消耗(上篇)

          騰訊原創分享(三):如何大幅壓縮移動網絡下APP的流量消耗(下篇)

          如約而至:微信自用的移動端IM網絡層跨平臺組件庫Mars已正式開源

          基于社交網絡的Yelp是如何實現海量用戶圖片的無損壓縮的?

          騰訊技術分享:騰訊是如何大幅降低帶寬和網絡流量的(圖片壓縮篇)

          騰訊技術分享:騰訊是如何大幅降低帶寬和網絡流量的(音視頻技術篇)

          字符編碼那點事:快速理解ASCII、Unicode、GBK和UTF-8

          全面掌握移動端主流圖片格式的特點、性能、調優等

          子彈短信光鮮的背后:網易云信首席架構師分享億級IM平臺的技術實踐

          微信技術分享:微信的海量IM聊天消息序列號生成實踐(算法原理篇)

          自已開發IM有那么難嗎?手把手教你自擼一個Andriod版簡易IM (有源碼)

          融云技術分享:解密融云IM產品的聊天消息ID生成策略

          適合新手:從零開發一個IM服務端(基于Netty,有完整源碼)

          拿起鍵盤就是干:跟我一起徒手開發一套分布式IM系統

          >> 更多同類文章 …… 

          [2] 有關WEB端即時通訊開發:

          新手入門貼:史上最全Web端即時通訊技術原理詳解

          Web端即時通訊技術盤點:短輪詢、Comet、Websocket、SSE

          SSE技術詳解:一種全新的HTML5服務器推送事件技術

          Comet技術詳解:基于HTTP長連接的Web端實時通信技術

          新手快速入門:WebSocket簡明教程

          WebSocket詳解(一):初步認識WebSocket技術

          WebSocket詳解(二):技術原理、代碼演示和應用案例

          WebSocket詳解(三):深入WebSocket通信協議細節

          WebSocket詳解(四):刨根問底HTTP與WebSocket的關系(上篇)

          WebSocket詳解(五):刨根問底HTTP與WebSocket的關系(下篇)

          WebSocket詳解(六):刨根問底WebSocket與Socket的關系

          socket.io實現消息推送的一點實踐及思路

          LinkedIn的Web端即時通訊實踐:實現單機幾十萬條長連接

          Web端即時通訊技術的發展與WebSocket、Socket.io的技術實踐

          Web端即時通訊安全:跨站點WebSocket劫持漏洞詳解(含示例代碼)

          開源框架Pomelo實踐:搭建Web端高性能分布式IM聊天服務器

          使用WebSocket和SSE技術實現Web端消息推送

          詳解Web端通信方式的演進:從Ajax、JSONP 到 SSE、Websocket

          MobileIMSDK-Web的網絡層框架為何使用的是Socket.io而不是Netty?

          理論聯系實際:從零理解WebSocket的通信原理、協議格式、安全性

          微信小程序中如何使用WebSocket實現長連接(含完整源碼)

          八問WebSocket協議:為你快速解答WebSocket熱門疑問

          快速了解Electron:新一代基于Web的跨平臺桌面技術

          一文讀懂前端技術演進:盤點Web前端20年的技術變遷史

          Web端即時通訊基礎知識補課:一文搞懂跨域的所有問題!

          >> 更多同類文章 ……

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

          posted @ 2020-03-13 17:15 Jack Jiang 閱讀(371) | 評論 (0)編輯 收藏

               摘要: 一、引言對于后端程序員來說,127.0.0.1和0.0.0.0這兩個IP地址再熟悉不過了,看起來好像就那么回事,但真正較起真來,這兩個IP地址到底有什么作用以及到底有什么不同?貌似誰可以輕松回答,但張嘴卻又不知從何說起。。。(這要是面視,估計真會被這搞砸...)本文將系統地總結127.0.0.1和0.0.0.0這兩個IP地址的作用,以及它們之間的區別,希望能為你解惑。  * 推...  閱讀全文

          posted @ 2020-03-03 15:53 Jack Jiang 閱讀(682) | 評論 (0)編輯 收藏

               摘要: 1、引言上個月在知乎上發表的由“袁輝輝”分享的關于TIM進程永生方面的文章(即時通訊網重新整理后的標題是:《史上最強Android?;钏悸罚荷钊肫饰鲵v訊TIM的進程永生技術》),短時間內受到大量關注,可惜在短短的幾十個小時后,就在一股神秘力量的干預下被強行刪除了。。。 ▲ 該文在知乎上從發布到刪除的時間歷程(中間省略了N條讀者的評論)在《史上最強And...  閱讀全文

          posted @ 2020-02-26 22:44 Jack Jiang 閱讀(486) | 評論 (0)編輯 收藏

          本文由馬蜂窩技術團隊電商交易基礎平臺研發工程師"Anti Walker"原創分享。

          一、引言

          即時通訊(IM)功能對于電商平臺來說非常重要,特別是旅游電商。

          從商品復雜性來看,一個旅游商品可能會包括用戶在未來一段時間的衣、食、住、行等方方面面。從消費金額來看,往往單次消費額度較大。對目的地的陌生、在行程中可能的問題,這些因素使用戶在購買前、中、后都存在和商家溝通的強烈需求。可以說,一個好用的 IM 可以在一定程度上對企業電商業務的 GMV 起到促進作用。

          本文我們將結合馬蜂窩旅游電商IM系統的發展歷程,單獨介紹基于Go重構分布式IM系統過程中的實踐和總結(本文相當于《從游擊隊到正規軍(一):馬蜂窩旅游網的IM系統架構演進之路》一文的進階篇),希望可以給有相似問題的朋友一些借鑒。

          另外:如果你對Go在高并發系統中的應用感興趣,即時通訊網的以下兩篇也值得一讀:

          Go語言構建千萬級在線的高并發消息推送系統實踐(來自360公司)

          12306搶票帶來的啟示:看我如何用Go實現百萬QPS的秒殺系統(含源碼)

          系列文章:

          從游擊隊到正規軍(一):馬蜂窩旅游網的IM系統架構演進之路

          從游擊隊到正規軍(二):馬蜂窩旅游網的IM客戶端架構演進和實踐總結

          從游擊隊到正規軍(三):基于Go的馬蜂窩旅游網分布式IM系統技術實踐》(* 本文

          關于馬蜂窩旅游網: 

          馬蜂窩旅游網是中國領先的自由行服務平臺,由陳罡和呂剛創立于2006年,從2010年正式開始公司化運營。馬蜂窩的景點、餐飲、酒店等點評信息均來自上億用戶的真實分享,每年幫助過億的旅行者制定自由行方案。

          學習交流:

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

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

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

          二、相關文章

          一套海量在線用戶的移動端IM架構設計實踐分享(含詳細圖文)

          一套原創分布式即時通訊(IM)系統理論架構方案

          從零到卓越:京東客服即時通訊系統的技術架構演進歷程

          蘑菇街即時通訊/IM服務器開發之架構選擇

          以微博類應用場景為例,總結海量社交系統的架構設計步驟

          一套高可用、易伸縮、高并發的IM群聊、單聊架構方案設計實踐

          騰訊QQ1.4億在線用戶的技術挑戰和架構演進之路PPT

          微信技術總監談架構:微信之道——大道至簡(演講全文)

          如何解讀《微信技術總監談架構:微信之道——大道至簡》

          快速裂變:見證微信強大后臺架構從0到1的演進歷程(一)

          瓜子IM智能客服系統的數據架構設計(整理自現場演講,有配套PPT)

          阿里釘釘技術分享:企業級IM王者——釘釘在后端架構上的過人之處

          三、技術背景和問題

          與廣義上的即時通訊不同,電商各業務線有其特有業務邏輯,如客服聊天系統的客人分配邏輯、敏感詞檢測邏輯等,這些往往要耦合進通信流程中。隨著接入業務線越來越多,即時通訊服務冗余度會越來越高。同時整個消息鏈路追溯復雜,服務穩定性很受業務邏輯的影響。

          之前我們 IM 應用中的消息推送主要基于輪詢技術,消息輪詢模塊的長連接請求是通過 php-fpm 掛載在阻塞隊列上實現。當請求量較大時,如果不能及時釋放 php-fpm 進程,對服務器的性能消耗很大。

          為了解決這個問題,我們曾用 OpenResty+Lua 的方式進行改造,利用 Lua 協程的方式將整體的 polling 的能力從 PHP 轉交到 Lua 處理,釋放一部 PHP 的壓力。這種方式雖然能提升一部分性能,但 PHP-Lua 的混合異構模式,使系統在使用、升級、調試和維護上都很麻煩,通用性也較差,很多業務場景下還是要依賴 PHP 接口,優化效果并不明顯。

          為了解決以上問題,我們決定結合電商 IM 的特定背景對 IM 服務進行重構,核心是實現業務邏輯和即時通訊服務的分離。

          更多有關馬蜂窩旅游網的IM系統架構的演進過程,請詳讀:《從游擊隊到正規軍(一):馬蜂窩旅游網的IM系統架構演進之路》一文,在此不再贅述。

          四、基于Go的雙層分布式IM架構

          4.1、實現目標

          1)業務解耦:

          將業務邏輯與通信流程剝離,使 IM 服務架構更加清晰,實現與電商 IM 業務邏輯的完全分離,保證服務穩定性。

          2)接入方式靈活:

          之前新業務接入時,需要在業務服務器上配置 OpenResty 環境及 Lua 協程代碼,非常不便,IM 服務的通用性也很差。考慮到現有業務的實際情況,我們希望 IM 系統可以提供 HTTP 和 WebSocket 兩種接入方式,供業務方根據不同的場景來靈活使用。

          比如已經接入且運行良好的電商定制化團隊的待辦系統、定制游搶單系統、投訴系統等下行相關的系統等,這些業務沒有明顯的高并發需求,可以通過 HTTP 方式迅速接入,不需要熟悉稍顯復雜的 WebSocket 協議,進而降低不必要的研發成本。

          3)架構可擴展:

          為了應對業務的持續增長給系統性能帶來的挑戰,我們考慮用分布式架構來設計即時通訊服務,使系統具有持續擴展及提升的能力。

          4.2、語言選擇

          目前,馬蜂窩技術體系主要包括 PHP,Java,Golang,技術棧比較豐富,使業務做選型時可以根據問題場景選擇更合適的工具和語言。

          結合 IM 具體應用場景,我們選擇 Go 的原因包括:

          • 1)運行性能:在性能上,尤其是針對網絡通信等 IO 密集型應用場景。Go 系統的性能更接近 C/C++;
          • 2)開發效率:Go 使用起來簡單,代碼編寫效率高,上手也很快,尤其是對于有一定 C++ 基礎的開發者,一周就能上手寫代碼了。

          4.3、架構設計

          整體架構圖如下: 

          名詞解釋:

          • 1)客戶:一般指購買商品的用戶;
          • 2)商家:提供服務的供應商,商家會有客服人員,提供給客戶一個在線咨詢的作用;
          • 3)分發模塊:即 Dispatcher,提供消息分發的給指定的工作模塊的橋接作用;
          • 4)工作模塊:即 Worker 服務器,用來提供 WebSocket 服務,是真正工作的一個模塊。

          架構分層:

          • 1)展示層:提供 HTTP 和 WebSocket 兩種接入方式;
          • 2)業務層:負責初始化消息線和業務邏輯處理。如果客戶端以 HTTP 方式接入,會以 JSON 格式把消息發送給業務服務器進行消息解碼、客服分配、敏感詞過濾,然后下發到消息分發模塊準備下一步的轉換;通過 WebSocket 接入的業務則不需要消息分發,直接以 WebSocket 方式發送至消息處理模塊中;
          • 3)服務層:由消息分發和消息處理這兩層組成,分別以分布式的方式部署多個 Dispatcher 和 Worker 節點。Dispatcher 負責檢索出接收者所在的服務器位置,將消息以 RPC 的方式發送到合適的 Worker 上,再由消息處理模塊通過 WebSocket 把消息推送給客戶端;
          • 4)數據層:Redis 集群,記錄用戶身份、連接信息、客戶端平臺(移動端、網頁端、桌面端)等組成的唯一 Key。

          4.4、服務流程

          步驟一:

          如上圖右側所示:

          用戶客戶端與消息處理模塊建立 WebSocket 長連接;

          通過負載均衡算法,使客戶端連接到合適的服務器(消息處理模塊的某個 Worker);

          連接成功后,記錄用戶連接信息,包括用戶角色(客人或商家)、客戶端平臺(移動端、網頁端、桌面端)等組成唯一 Key,記錄到 Redis 集群。

          步驟二:

          如圖左側所示,當購買商品的用戶要給管家發消息的時候,先通過 HTTP 請求把消息發給業務服務器,業務服務端對消息進行業務邏輯處理。

          1)該步驟本身是一個 HTTP 請求,所以可以接入各種不同開發語言的客戶端。通過 JSON 格式把消息發送給業務服務器,業務服務器先把消息解碼,然后拿到這個用戶要發送給哪個商家的客服的。

          2)如果這個購買者之前沒有聊過天,則在業務服務器邏輯里需要有一個分配客服的過程,即建立購買者和商家的客服之間的連接關系。拿到這個客服的 ID,用來做業務消息下發;如果之前已經聊過天,則略過此環節。

          3)在業務服務器,消息會異步入數據庫。保證消息不會丟失。

          步驟三:

          業務服務端以 HTTP 請求把消息發送到消息分發模塊。這里分發模塊的作用是進行中轉,最終使服務端的消息下發給指定的商家。

          步驟四:

          基于 Redis 集群中的用戶連接信息,消息分發模塊將消息轉發到目標用戶連接的 WebSocket 服務器(消息處理模塊中的某一個 Worker)

          1)分發模塊通過 RPC 方式把消息轉發到目標用戶連接的 Worker,RPC 的方式性能更快,而且傳輸的數據也少,從而節約了服務器的成本。

          2)消息透傳 Worker 的時候,多種策略保障消息一定會下發到 Worker。

          步驟五:

          消息處理模塊將消息通過 WebSocket 協議推送到客戶端。

          1)在投遞的時候,接收者要有一個 ACK(應答) 信息來回饋給 Worker 服務器,告訴 Worker 服務器,下發的消息接收者已經收到了。

          2)如果接收者沒有發送這個 ACK 來告訴 Worker 服務器,Worker 服務器會在一定的時間內來重新把這個信息發送給消息接收者。

          3)如果投遞的信息已經發送給客戶端,客戶端也收到了,但是因為網絡抖動,沒有把 ACK 信息發送給服務器,那服務器會重復投遞給客戶端,這時候客戶端就通過投遞過來的消息 ID 來去重展示。

          以上步驟的數據流轉大致如圖所示:

          4.5、系統完整性設計

          4.5.1 可靠性

          (1)消息不丟失:

          為了避免消息丟失,我們設置了超時重傳機制。服務端會在推送給客戶端消息后,等待客戶端的 ACK,如果客戶端沒有返回 ACK,服務端會嘗試多次推送。

          目前默認 18s 為超時時間,重傳 3 次不成功,斷開連接,重新連接服務器。重新連接后,采用拉取歷史消息的機制來保證消息完整。

          (2)多端消息同步:

          客戶端現有 PC 瀏覽器、Windows 客戶端、H5、iOS/Android,系統允許用戶多端同時在線,且同一端可以多個狀態,這就需要保證多端、多用戶、多狀態的消息是同步的。

          我們用到了 Redis 的 Hash 存儲,將用戶信息、唯一連接對應值 、連接標識、客戶端 IP、服務器標識、角色、渠道等記錄下來,這樣通過 key(uid) 就能找到一個用戶在多個端的連接,通過 key+field 能定位到一條連接。

          4.5.2 可用性

          上文我們已經說過,因為是雙層設計,就涉及到兩個 Server 間的通信,同進程內通信用 Channel,非同進程用消息隊列或者 RPC。綜合性能和對服務器資源利用,我們最終選擇 RPC 的方式進行 Server 間通信。

          在對基于 Go 的 RPC 進行選行時,我們比較了以下比較主流的技術方案: 

          1)Go STDRPC:Go 標準庫的 RPC,性能最優,但是沒有治理;

          2)RPCX:性能優勢 2*GRPC + 服務治理;

          3)GRPC:跨語言,但性能沒有 RPCX 好;

          4)TarsGo:跨語言,性能 5*GRPC,缺點是框架較大,整合起來費勁;

          5)Dubbo-Go:性能稍遜一籌, 比較適合 Go 和 Java 間通信場景使用。

          最后我們選擇了 RPCX,因為性能也很好,也有服務的治理。

          兩個進程之間同樣需要通信,這里用到的是 ETCD 實現服務注冊發現機制。

          當我們新增一個 Worker,如果沒有注冊中心,就要用到配置文件來管理這些配置信息,這挺麻煩的。而且你新增一個后,需要分發模塊立刻發現,不能有延遲。

          如果有新的服務,分發模塊希望能快速感知到新的服務。利用 Key 的續租機制,如果在一定時間內,沒有監聽到 Key 有續租動作,則認為這個服務已經掛掉,就會把該服務摘除。

          在進行注冊中心的選型時,我們主要調研了 ETCD、ZooKeeper、Consul

          三者的壓測結果參考如下: 

           

          結果顯示,ETCD 的性能是最好的。另外,ETCD 背靠阿里巴巴,而且屬于 Go 生態,我們公司內部的 K8S 集群也在使用。

          綜合考量后,我們選擇使用 ETCD 作為服務注冊和發現組件。并且我們使用的是 ETCD 的集群模式,如果一臺服務器出現故障,集群其他的服務器仍能正常提供服務。

          小結一下:通過保證服務和進程間的正常通訊,及 ETCD 集群模式的設計,保證了 IM 服務整體具有極高的可用性。

          4.5.3 擴展性

          消息分發模塊和消息處理模塊都能進行水平擴展。當整體服務負載高時,可以通過增加節點來分擔壓力,保證消息即時性和服務穩定性。

          4.5.4 安全性

          處于安全性考慮,我們設置了黑名單機制,可以對單一 uid 或者 ip 進行限制。比如在同一個 uid 下,如果一段時間內建立的連接次數超過設定的閾值,則認為這個 uid 可能存在風險,暫停服務。如果暫停服務期間該 uid 繼續發送請求,則限制服務的時間相應延長。

          4.6、性能優化和踩過的坑

          4.6.1 性能優化

          1)JSON 編解碼:

          開始我們使用官方的 JSON 編解碼工具,但由于對性能方面的追求,改為使用滴滴開源的 Json-iterator,使在兼容原生 Golang 的 JSON 編解碼工具的同時,效率上有比較明顯的提升。

          以下是壓測對比的參考圖: 

          2)time.After:

          在壓測的時候,我們發現內存占用很高,于是使用 Go Tool PProf 分析 Golang 函數內存申請情況,發現有不斷創建 time.After 定時器的問題,定位到是心跳協程里面。

          原來代碼如下: 

          優化后的代碼為:

          優化點在于 for 循環里不要使用 select + time.After 的組合。

          3)Map 的使用:

          在保存連接信息的時候會用到 Map。因為之前做 TCP Socket 的項目的時候就遇到過一個坑,即 Map 在協程下是不安全的。當多個協程同時對一個 Map 進行讀寫時,會拋出致命錯誤:fetal error:concurrent map read and map write,有了這個經驗后,我們這里用的是 sync.Map

          4.6.2 踩坑經驗

          1)協程異常:

          基于對開發成本和服務穩定性等問題的考慮,我們的 WebSocket 服務基于 Gorilla/WebSocket 框架開發。其中遇到一個問題,就是當讀協程發生異常退出時,寫協程并沒有感知到,結果就是導致讀協程已經退出但是寫協程還在運行,直到觸發異常之后才退出。

          這樣雖然從表面上看不影響業務邏輯,但是浪費后端資源。在編碼時應該注意要在讀協程退出后主動通知寫協程,這樣一個小的優化可以這在高并發下能節省很多資源。

          2)心跳設計:

          舉個例子:之前我們在閑時心跳功能的開發中走了一些彎路。最初在服務器端的心跳發送是定時心跳,但后來在實際業務場景中使用時發現,設計成服務器讀空閑時心跳更好。因為用戶都在聊天呢,發一個心跳幀,浪費感情也浪費帶寬資源。

          這時候,建議大家在業務開發過程中如果代碼寫不下去就暫時不要寫了,先結合業務需求用文字梳理下邏輯,可能會發現之后再進行會更順利。

          3)每天分割日志: 

          日志模塊在起初調研的時候基于性能考慮,確定使用 Uber 開源的 ZAP 庫,而且滿足業務日志記錄的要求。日志庫選型很重要,選不好也是影響系統性能和穩定性的。

          ZAP 的優點包括:

          1)顯示代碼行號這個需求,ZAP 支持而 Logrus 不支持,這個屬于提效的。行號展示對于定位問題很重要;

          2)ZAP 相對于 Logrus 更為高效,體現在寫 JSON 格式日志時,沒有使用反射,而是用內建的 json encoder,通過明確的類型調用,直接拼接字符串,最小化性能開銷。

          小坑:每天寫一個日志文件的功能,目前 ZAP 不支持,需要自己寫代碼支持,或者請求系統部支持。

          五、性能表現

          壓測 1:

          上線生產環境并和業務方對接以及壓測,目前定制業務已接通整個流程,寫了一個 Client。模擬定期發心跳幀,然后利用 Docker 環境。開啟了 50 個容器,每個容器模擬并發起 2 萬個連接。這樣就是百萬連接打到單機的 Server 上。單機內存占用 30G 左右。

          壓測 2:

          同時并發 3000、4000、5000 連接,以及調整發送頻率,分別對應上行:60萬、80 萬、100 萬、200 萬, 一個 6k 左右的日志結構體。

          其中有一半是心跳包 另一半是日志結構體。在不同的壓力下的下行延遲數據如下: 

          結論:

          隨著上行的并發變大,延遲控制在 24-66 毫秒之間。所以對于下行業務屬于輕微延遲。另外針對 60 萬 5k 上行的同時,用另一個腳本模擬開啟 50 個協程并發下行 1k 的數據體,延遲是比沒有并發下行的時候是有所提高的,延遲提高了 40ms 左右。

          六、本文小結

          基于 Go 重構的 IM 服務在 WebSocket 的基礎上,將業務層設計為配有消息分發模塊和消息處理模塊的雙層架構模式,使業務邏輯的處理前置,保證了即時通訊服務的純粹性和穩定性;同時消息分發模塊的 HTTP 服務方便多種編程語言快速對接,使各業務線能迅速接入即時通訊服務。

          最后,我還想為 Go 搖旗吶喊一下。很多人都知道馬蜂窩技術體系主要是基于 PHP,有一些核心業務也在向 Java 遷移。與此同時,Go 也在越來越多的項目中發揮作用?,F在,云原生理念已經逐漸成為主流趨勢之一,我們可以看到在很多構建云原生應用所需要的核心項目中,Go 都是主要的開發語言,比如 Kubernetes,Docker,Istio,ETCD,Prometheus 等,包括第三代開源分布式數據庫 TiDB。

          所以我們可以把 Go 稱為云原生時代的母語?!冈圃鷷r代,是開發者最好的時代」,在這股浪潮下,我們越早走進 Go,就可能越早在這個新時代搶占關鍵賽道。希望更多小伙伴和我們一起,加入到 Go 的開發和學習陣營中來,拓寬自己的技能圖譜,擁抱云原生。

          附錄:更多IM架構設計方面的文章

          [1] 有關IM架構設計的文章:

          淺談IM系統的架構設計

          簡述移動端IM開發的那些坑:架構設計、通信協議和客戶端

          一套海量在線用戶的移動端IM架構設計實踐分享(含詳細圖文)

          一套原創分布式即時通訊(IM)系統理論架構方案

          從零到卓越:京東客服即時通訊系統的技術架構演進歷程

          蘑菇街即時通訊/IM服務器開發之架構選擇

          騰訊QQ1.4億在線用戶的技術挑戰和架構演進之路PPT

          微信后臺基于時間序的海量數據冷熱分級架構設計實踐

          微信技術總監談架構:微信之道——大道至簡(演講全文)

          如何解讀《微信技術總監談架構:微信之道——大道至簡》

          快速裂變:見證微信強大后臺架構從0到1的演進歷程(一)

          17年的實踐:騰訊海量產品的技術方法論

          移動端IM中大規模群消息的推送如何保證效率、實時性?

          現代IM系統中聊天消息的同步和存儲方案探討

          IM開發基礎知識補課(二):如何設計大量圖片文件的服務端存儲架構?

          IM開發基礎知識補課(三):快速理解服務端數據庫讀寫分離原理及實踐建議

          IM開發基礎知識補課(四):正確理解HTTP短連接中的Cookie、Session和Token

          WhatsApp技術實踐分享:32人工程團隊創造的技術神話

          微信朋友圈千億訪問量背后的技術挑戰和實踐總結

          王者榮耀2億用戶量的背后:產品定位、技術架構、網絡方案等

          IM系統的MQ消息中間件選型:Kafka還是RabbitMQ?

          騰訊資深架構師干貨總結:一文讀懂大型分布式系統設計的方方面面

          以微博類應用場景為例,總結海量社交系統的架構設計步驟

          快速理解高性能HTTP服務端的負載均衡技術原理

          子彈短信光鮮的背后:網易云信首席架構師分享億級IM平臺的技術實踐

          知乎技術分享:從單機到2000萬QPS并發的Redis高性能緩存實踐之路

          IM開發基礎知識補課(五):通俗易懂,正確理解并用好MQ消息隊列

          微信技術分享:微信的海量IM聊天消息序列號生成實踐(算法原理篇)

          微信技術分享:微信的海量IM聊天消息序列號生成實踐(容災方案篇)

          新手入門:零基礎理解大型分布式架構的演進歷史、技術原理、最佳實踐

          一套高可用、易伸縮、高并發的IM群聊、單聊架構方案設計實踐

          阿里技術分享:深度揭秘阿里數據庫技術方案的10年變遷史

          阿里技術分享:阿里自研金融級數據庫OceanBase的艱辛成長之路

          社交軟件紅包技術解密(一):全面解密QQ紅包技術方案——架構、技術實現等

          社交軟件紅包技術解密(二):解密微信搖一搖紅包從0到1的技術演進

          社交軟件紅包技術解密(三):微信搖一搖紅包雨背后的技術細節

          社交軟件紅包技術解密(四):微信紅包系統是如何應對高并發的

          社交軟件紅包技術解密(五):微信紅包系統是如何實現高可用性的

          社交軟件紅包技術解密(六):微信紅包系統的存儲層架構演進實踐

          社交軟件紅包技術解密(七):支付寶紅包的海量高并發技術實踐

          社交軟件紅包技術解密(八):全面解密微博紅包技術方案

          社交軟件紅包技術解密(九):談談手Q紅包的功能邏輯、容災、運維、架構等

          即時通訊新手入門:一文讀懂什么是Nginx?它能否實現IM的負載均衡?

          即時通訊新手入門:快速理解RPC技術——基本概念、原理和用途

          多維度對比5款主流分布式MQ消息隊列,媽媽再也不擔心我的技術選型了

          從游擊隊到正規軍(一):馬蜂窩旅游網的IM系統架構演進之路

          從游擊隊到正規軍(二):馬蜂窩旅游網的IM客戶端架構演進和實踐總結

          IM開發基礎知識補課(六):數據庫用NoSQL還是SQL?讀這篇就夠了!

          瓜子IM智能客服系統的數據架構設計(整理自現場演講,有配套PPT)

          阿里釘釘技術分享:企業級IM王者——釘釘在后端架構上的過人之處

          >> 更多同類文章 ……

          [2] 更多其它架構設計相關文章:

          騰訊資深架構師干貨總結:一文讀懂大型分布式系統設計的方方面面

          快速理解高性能HTTP服務端的負載均衡技術原理

          子彈短信光鮮的背后:網易云信首席架構師分享億級IM平臺的技術實踐

          知乎技術分享:從單機到2000萬QPS并發的Redis高性能緩存實踐之路

          新手入門:零基礎理解大型分布式架構的演進歷史、技術原理、最佳實踐

          阿里技術分享:深度揭秘阿里數據庫技術方案的10年變遷史

          阿里技術分享:阿里自研金融級數據庫OceanBase的艱辛成長之路

          達達O2O后臺架構演進實踐:從0到4000高并發請求背后的努力

          優秀后端架構師必會知識:史上最全MySQL大表優化方案總結

          小米技術分享:解密小米搶購系統千萬高并發架構的演進和實踐

          一篇讀懂分布式架構下的負載均衡技術:分類、原理、算法、常見方案等

          通俗易懂:如何設計能支撐百萬并發的數據庫架構?

          多維度對比5款主流分布式MQ消息隊列,媽媽再也不擔心我的技術選型了

          從新手到架構師,一篇就夠:從100到1000萬高并發的架構演進之路

          美團技術分享:深度解密美團的分布式ID生成算法

          12306搶票帶來的啟示:看我如何用Go實現百萬QPS的秒殺系統(含源碼)

          >> 更多同類文章 ……

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

          posted @ 2020-02-19 16:47 Jack Jiang 閱讀(288) | 評論 (0)編輯 收藏

          僅列出標題
          共51頁: First 上一頁 30 31 32 33 34 35 36 37 38 下一頁 Last 
          Jack Jiang的 Mail: jb2011@163.com, 聯系QQ: 413980957, 微信: hellojackjiang
          主站蜘蛛池模板: 黑龙江省| 房山区| 伊宁县| 鹤庆县| 陆河县| 巨鹿县| 弋阳县| 叶城县| 筠连县| 铁岭市| 宝丰县| 崇州市| 景洪市| 墨脱县| 临汾市| 芦溪县| 仙桃市| 蒙自县| 汕尾市| 韶山市| 贵港市| 綦江县| 桃源县| 仁怀市| 衡阳市| 靖安县| 神池县| 怀来县| 万源市| 绍兴市| 吴旗县| 江都市| 邵阳市| 庆城县| 长宁区| 云龙县| 格尔木市| 田阳县| 伽师县| 崇礼县| 奉贤区|