<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          它扛住 100 億次請求,就問你服不服?。?!

          共 2213字,需瀏覽 5分鐘

           ·

          2020-11-15 13:34

          點擊上方[全棧開發(fā)者社區(qū)]右上角[...][設(shè)為星標(biāo)?]

          來源:github.com/xiaojiaqi/10billionhongbaos/

          • 1. 前言
          • 2. 背景知識
          • 3. 確定目標(biāo)
          • 4. 基礎(chǔ)軟件和硬件
          • 5. 技術(shù)分析和實現(xiàn)
          • 6. 代碼實現(xiàn)及分析
          • 7. 實踐
          • 8. 分析數(shù)據(jù)
          • 總結(jié):

          1. 前言

          前幾天,偶然看到了 《扛住100億次請求——如何做一個“有把握”的春晚紅包系統(tǒng)”》(url)一文,看完以后,感慨良多,收益很多。正所謂他山之石,可以攻玉,雖然此文發(fā)表于2015年,我看到時已經(jīng)是2016年末,但是其中的思想仍然是可以為很多后端設(shè)計借鑒,。同時作為一個工程師,看完以后又會思考,學(xué)習(xí)了這樣的文章以后,是否能給自己的工作帶來一些實際的經(jīng)驗?zāi)??所謂紙上得來終覺淺,絕知此事要躬行,能否自己實踐一下100億次紅包請求呢?否則讀完以后腦子里能剩下的東西 不過就是100億 1400萬QPS整流 這樣的字眼,剩下的文章將展示作者是如何以此過程為目標(biāo),在本地環(huán)境的模擬了此過程。

          注:本文以及作者所有內(nèi)容,僅代表個人理解和實踐,過程和微信團(tuán)隊沒有任何關(guān)系,真正的線上系統(tǒng)也不同,只是從一些技術(shù)點進(jìn)行了實踐,請讀者進(jìn)行區(qū)分。

          2. 背景知識

          QPS: Queries per second 每秒的請求數(shù)目

          搖紅包:客戶端發(fā)出一個搖紅包的請求,如果系統(tǒng)有紅包就會返回,用戶獲得紅包

          發(fā)紅包:產(chǎn)生一個紅包里面含有一定金額,紅包指定數(shù)個用戶,每個用戶會收到紅包信息,用戶可以發(fā)送拆紅包的請求,獲取其中的部分金額。

          3. 確定目標(biāo)

          在一切系統(tǒng)開始以前,我們應(yīng)該搞清楚我們的系統(tǒng)在完成以后,應(yīng)該有一個什么樣的負(fù)載能力。

          3.1 用戶總數(shù):

          通過文章我們可以了解到接入服務(wù)器638臺, 服務(wù)上限大概是14.3億用戶, 所以單機(jī)負(fù)載的用戶上限大概是14.3億/638臺=228萬用戶/臺。但是目前中國肯定不會有14億用戶同時在線,參考 http://qiye.qianzhan.com/show/detail/160818-b8d1c700.html 的說法,2016年Q2 微信用戶大概是8億,月活在5.4 億左右。所以在2015年春節(jié)期間,雖然使用的用戶會很多,但是同時在線肯定不到5.4億。

          3.2. 服務(wù)器數(shù)量:

          一共有638臺服務(wù)器,按照正常運維設(shè)計,我相信所有服務(wù)器不會完全上線,會有一定的硬件冗余,來防止突發(fā)硬件故障。假設(shè)一共有600臺接入服務(wù)器。

          3.3 單機(jī)需要支持的負(fù)載數(shù):

          每臺服務(wù)器支持的用戶數(shù):5.4億/600 = 90萬。也就是平均單機(jī)支持90萬用戶。如果真實情況比90萬更多,則模擬的情況可能會有偏差,但是我認(rèn)為QPS在這個實驗中更重要。

          3.4. 單機(jī)峰值QPS:

          文章中明確表示為1400萬QPS.這個數(shù)值是非常高的,但是因為有600臺服務(wù)器存在,所以單機(jī)的QPS為 1400萬/600= 約為2.3萬QPS, 文章曾經(jīng)提及系統(tǒng)可以支持4000萬QPS,那么系統(tǒng)的QPS 至少要到4000萬/600 = 約為 6.6萬, 這個數(shù)值大約是目前的3倍,短期來看并不會被觸及。但是我相信應(yīng)該做過相應(yīng)的壓力測試。

          3.5. 發(fā)放紅包:

          文中提到系統(tǒng)以5萬個每秒的下發(fā)速度,那么單機(jī)每秒下發(fā)速度50000/600 =83個/秒,也就是單機(jī)系統(tǒng)應(yīng)該保證每秒以83個的速度下發(fā)即可。最后考慮到系統(tǒng)的真實性,還至少有用戶登錄的動作,拿紅包這樣的業(yè)務(wù)。真實的系統(tǒng)還會包括聊天這樣的服務(wù)業(yè)務(wù)。

          最后整體的看一下 100億次搖紅包這個需求,假設(shè)它是均勻地發(fā)生在春節(jié)聯(lián)歡晚會的4個小時里,那么服務(wù)器的QPS 應(yīng)該是10000000000/600/3600/4.0=1157. 也就是單機(jī)每秒1000多次,這個數(shù)值其實并不高。如果完全由峰值速度1400萬消化 10000000000/(1400*10000) = 714秒,也就是說只需要峰值堅持11分鐘,就可以完成所有的請求。可見互聯(lián)網(wǎng)產(chǎn)品的一個特點就是峰值非常高,持續(xù)時間并不會很長。

          總結(jié):

          從單臺服務(wù)器看.它需要滿足下面一些條件

          1. 支持至少100萬連接用戶
          2. 每秒至少能處理2.3萬的QPS,這里我們把目標(biāo)定得更高一些 分別設(shè)定到了3萬和6萬。
          3. 搖紅包:支持每秒83個的速度下發(fā)放紅包,也就是說每秒有2.3萬次搖紅包的請求,其中83個請求能搖到紅包,其余的2.29萬次請求會知道自己沒搖到。當(dāng)然客戶端在收到紅包以后,也需要確??蛻舳撕头?wù)器兩邊的紅包數(shù)目和紅包內(nèi)的金額要一致。因為沒有支付模塊,所以我們也把要求提高一倍,達(dá)到200個紅包每秒的分發(fā)速度
          4. 支持用戶之間發(fā)紅包業(yè)務(wù),確保收發(fā)兩邊的紅包數(shù)目和紅包內(nèi)金額要一致。同樣也設(shè)定200個紅包每秒的分發(fā)速度為我們的目標(biāo)。

          想完整模擬整個系統(tǒng)實在太難了,首先需要海量的服務(wù)器,其次需要上億的模擬客戶端。這對我來說是辦不到,但是有一點可以確定,整個系統(tǒng)是可以水平擴(kuò)展的,所以我們可以模擬100萬客戶端,在模擬一臺服務(wù)器 那么就完成了1/600的模擬。

          和現(xiàn)有系統(tǒng)區(qū)別:和大部分高QPS測試的不同,本系統(tǒng)的側(cè)重點有所不同。我對2者做了一些對比。


          常見高QPS系統(tǒng)壓力測試本系統(tǒng)壓力測試
          連接數(shù)一般<1000 (幾百以內(nèi))1000000 (1百萬)
          單連接吞吐量非常大 每個連接幾十M字節(jié)吞吐非常小 每個連接每次幾十個字節(jié)
          需要的IO次數(shù)不多非常多

          4. 基礎(chǔ)軟件和硬件

          4.1 軟件:

          Golang 1.8r3 , shell, python (開發(fā)沒有使用c++ 而是使用了golang, 是因為使用golang 的最初原型達(dá)到了系統(tǒng)要求。雖然golang 還存在一定的問題,但是和開發(fā)效率比,這點損失可以接受) 服務(wù)器操作系統(tǒng): Ubuntu 12.04 客戶端操作系統(tǒng): debian 5.0

          4.2 硬件環(huán)境

          服務(wù)端:dell R2950。8核物理機(jī),非獨占有其他業(yè)務(wù)在工作,16G內(nèi)存。這臺硬件大概是7年前的產(chǎn)品,性能應(yīng)該不是很高要求。服務(wù)器硬件版本:服務(wù)器CPU信息:

          客戶端:esxi 5.0 虛擬機(jī),配置為4核 5G內(nèi)存。一共17臺,每臺和服務(wù)器建立6萬個連接。完成100萬客戶端模擬

          5. 技術(shù)分析和實現(xiàn)

          5.1) 單機(jī)實現(xiàn)100萬用戶連接

          這一點來說相對簡單,筆者在幾年前就早完成了單機(jī)百萬用戶的開發(fā)以及操作?,F(xiàn)代的服務(wù)器都可以支持百萬用戶。相關(guān)內(nèi)容可以查看 github代碼以及相關(guān)文檔。https://github.com/xiaojiaqi/C1000kPracticeGuide系統(tǒng)配置以及優(yōu)化文檔:https://github.com/xiaojiaqi/C1000kPracticeGuide/tree/master/docs/cn

          5.2) 3萬QPS

          這個問題需要分2個部分來看客戶端方面和服務(wù)器方面。

          客戶端QPS

          因為有100萬連接連在服務(wù)器上,QPS為3萬。這就意味著每個連接每33秒,就需要向服務(wù)器發(fā)一個搖紅包的請求。因為單IP可以建立的連接數(shù)為6萬左右, 有17臺服務(wù)器同時模擬客戶端行為。我們要做的就保證在每一秒都有這么多的請求發(fā)往服務(wù)器即可。其中技術(shù)要點就是客戶端協(xié)同。但是各個客戶端的啟動時間,建立連接的時間都不一致,還存在網(wǎng)絡(luò)斷開重連這樣的情況,各個客戶端如何判斷何時自己需要發(fā)送請求,各自該發(fā)送多少請求呢?

          我是這樣解決的:利用NTP服務(wù),同步所有的服務(wù)器時間,客戶端利用時間戳來判斷自己的此時需要發(fā)送多少請求。算法很容易實現(xiàn):假設(shè)有100萬用戶,則用戶id 為0-999999.要求的QPS為5萬, 客戶端得知QPS為5萬,總用戶數(shù)為100萬,它計算 100萬/5萬=20,所有的用戶應(yīng)該分為20組,如果 time() % 20 == 用戶id % 20,那么這個id的用戶就該在這一秒發(fā)出請求,如此實現(xiàn)了多客戶端協(xié)同工作。每個客戶端只需要知道 總用戶數(shù)和QPS 就能自行準(zhǔn)確發(fā)出請求了。(擴(kuò)展思考:如果QPS是3萬 這樣不能被整除的數(shù)目,該如何辦?如何保證每臺客戶端發(fā)出的請求數(shù)目盡量的均衡呢?)

          服務(wù)器QPS

          服務(wù)器端的QPS相對簡單,它只需要處理客戶端的請求即可。但是為了客觀了解處理情況,我們還需要做2件事情。

          第一: 需要記錄每秒處理的請求數(shù)目,這需要在代碼里埋入計數(shù)器。第二: 我們需要監(jiān)控網(wǎng)絡(luò),因為網(wǎng)絡(luò)的吞吐情況,可以客觀的反映出QPS的真實數(shù)據(jù)。為此,我利用python腳本 結(jié)合ethtool 工具編寫了一個簡單的工具,通過它我們可以直觀的監(jiān)視到網(wǎng)絡(luò)的數(shù)據(jù)包通過情況如何。它可以客觀的顯示出我們的網(wǎng)絡(luò)有如此多的數(shù)據(jù)傳輸在發(fā)生。工具截圖:

          5.3) 搖紅包業(yè)務(wù)

          搖紅包的業(yè)務(wù)非常簡單,首先服務(wù)器按照一定的速度生產(chǎn)紅包。紅包沒有被取走的話,就堆積在里面。服務(wù)器接收一個客戶端的請求,如果服務(wù)器里現(xiàn)在有紅包就會告訴客戶端有,否則就提示沒有紅包。因為單機(jī)每秒有3萬的請求,所以大部分的請求會失敗。只需要處理好鎖的問題即可。我為了減少競爭,將所有的用戶分在了不同的桶里。這樣可以減少對鎖的競爭。如果以后還有更高的性能要求,還可以使用 高性能隊列——Disruptor來進(jìn)一步提高性能。

          注意,在我的測試環(huán)境里是缺少支付這個核心服務(wù)的,所以實現(xiàn)的難度是大大的減輕了。另外提供一組數(shù)字:2016年淘寶的雙11的交易峰值僅僅為12萬/秒,微信紅包分發(fā)速度是5萬/秒,要做到這點是非常困難的。(http://mt.sohu.com/20161111/n472951708.shtml)

          5.4) 發(fā)紅包業(yè)務(wù)

          發(fā)紅包的業(yè)務(wù)很簡單,系統(tǒng)隨機(jī)產(chǎn)生一些紅包,并且隨機(jī)選擇一些用戶,系統(tǒng)向這些用戶提示有紅包。這些用戶只需要發(fā)出拆紅包的請求,系統(tǒng)就可以隨機(jī)從紅包中拆分出部分金額,分給用戶,完成這個業(yè)務(wù)。同樣這里也沒有支付這個核心服務(wù)。

          5.5)監(jiān)控

          最后 我們需要一套監(jiān)控系統(tǒng)來了解系統(tǒng)的狀況,我借用了我另一個項目(https://github.com/xiaojiaqi/fakewechat) 里的部分代碼完成了這個監(jiān)控模塊,利用這個監(jiān)控,服務(wù)器和客戶端會把當(dāng)前的計數(shù)器內(nèi)容發(fā)往監(jiān)控,監(jiān)控需要把各個客戶端的數(shù)據(jù)做一個整合和展示。同時還會把日志記錄下來,給以后的分析提供原始數(shù)據(jù)。線上系統(tǒng)更多使用opentsdb這樣的時序數(shù)據(jù)庫,這里資源有限,所以用了一個原始的方案

          監(jiān)控顯示日志大概這樣

          6. 代碼實現(xiàn)及分析

          在代碼方面,使用到的技巧實在不多,主要是設(shè)計思想和golang本身的一些問題需要考慮。首先golang的goroutine 的數(shù)目控制,因為至少有100萬以上的連接,所以按照普通的設(shè)計方案,至少需要200萬或者300萬的goroutine在工作。這會造成系統(tǒng)本身的負(fù)擔(dān)很重。其次就是100萬個連接的管理,無論是連接還是業(yè)務(wù)都會造成一些心智的負(fù)擔(dān)。我的設(shè)計是這樣的:

          架構(gòu)圖

          首先將100萬連接分成多個不同的SET,每個SET是一個獨立,平行的對象。每個SET 只管理幾千個連接,如果單個SET 工作正常,我只需要添加SET就能提高系統(tǒng)處理能力。按照SET分還有一個好處,可以將一個SET作為一個業(yè)務(wù)單元,在不同性能服務(wù)器上可以負(fù)載不同的壓力,比如8核機(jī)器管理10個SET,4核機(jī)器管理5個SET 可以細(xì)粒度的分流壓力,并容易遷移處理 其次謹(jǐn)慎的設(shè)計了每個SET里數(shù)據(jù)結(jié)構(gòu)的大小,保證每個SET的壓力不會太大,不會出現(xiàn)消息的堆積。再次減少了gcroutine的數(shù)目,每個連接只使用一個goroutine,發(fā)送消息在一個SET里只有一個gcroutine負(fù)責(zé),這樣節(jié)省了100萬個goroutine。這樣整個系統(tǒng)只需要保留 100萬零幾百個gcroutine就能完成業(yè)務(wù)。大量的節(jié)省了cpu 和內(nèi)存 系統(tǒng)的工作流程大概如下:每個客戶端連接成功后,系統(tǒng)會分配一個goroutine讀取客戶端的消息,當(dāng)消息讀取完成,將它轉(zhuǎn)化為消息對象放至在SET的接收消息隊列,然后返回獲取下一個消息 在SET內(nèi)部,有一個工作goroutine,它只做非常簡單而高效的事情,它做的事情如下,檢查SET的接受消息,它會收到3類消息

          1, 客戶端的搖紅包請求消息

          2, 客戶端的其他消息 比如聊天 好友這一類

          3, 服務(wù)器端對客戶端消息的回應(yīng)

          對于 第1種消息 客戶端的搖紅包請求消息 是這樣處理的,從客戶端拿到搖紅包請求消息,試圖從SET的紅包隊列里 獲取一個紅包,如果拿到了就把紅包信息 返回給客戶端,否則構(gòu)造一個沒有搖到的消息,返回給對應(yīng)的客戶端。對于第2種消息 客戶端的其他消息 比如聊天 好友這一類,只需簡單地從隊列里拿走消息,轉(zhuǎn)發(fā)給后端的聊天服務(wù)隊列即可,其他服務(wù)會把消息轉(zhuǎn)發(fā)出去。對于第3種消息 服務(wù)器端對客戶端消息的回應(yīng)。SET 只需要根據(jù)消息里的用戶id,找到SET里保留的用戶連接對象,發(fā)回去就可以了。

          對于紅包產(chǎn)生服務(wù),它的工作很簡單,只需要按照順序在輪流在每個SET的紅包產(chǎn)生對列里放至紅包對象就可以了。這樣可以保證每個SET里都是公平的,其次它的工作強(qiáng)度很低,可以保證業(yè)務(wù)穩(wěn)定。

          見代碼 https://github.com/xiaojiaqi/10billionhongbaos

          7. 實踐

          實踐的過程分為3個階段

          階段1

          分別啟動服務(wù)器端和監(jiān)控端,然后逐一啟動17臺客戶端,讓它們建立起100萬的鏈接。在服務(wù)器端,利用ss 命令 統(tǒng)計出每個客戶端和服務(wù)器建立了多少連接。

          命令如下:Alias ss2=Ss –ant | grep 1025 | grep EST | awk –F: “{print $8}” | sort | uniq –c’

          結(jié)果如下:

          階段2

          利用客戶端的http接口,將所有的客戶端QPS 調(diào)整到3萬,讓客戶端發(fā)出3W QPS強(qiáng)度的請求。

          運行如下命令:

          啟動腳本

          觀察網(wǎng)絡(luò)監(jiān)控和監(jiān)控端反饋,發(fā)現(xiàn)QPS 達(dá)到預(yù)期數(shù)據(jù),網(wǎng)絡(luò)監(jiān)控截圖:

          3萬qps

          在服務(wù)器端啟動一個產(chǎn)生紅包的服務(wù),這個服務(wù)會以200個每秒的速度下發(fā)紅包,總共4萬個。此時觀察客戶端在監(jiān)控上的日志,會發(fā)現(xiàn)基本上以200個每秒的速度獲取到紅包。

          ![搖紅包] (https://raw.githubusercontent.com/xiaojiaqi/10billionhongbaos/master/images/yao.png)

          等到所有紅包下發(fā)完成后,再啟動一個發(fā)紅包的服務(wù),這個服務(wù)系統(tǒng)會生成2萬個紅包,每秒也是200個,每個紅包隨機(jī)指定3位用戶,并向這3個用戶發(fā)出消息,客戶端會自動來拿紅包,最后所有的紅包都被拿走。

          發(fā)紅包

          階段3

          利用客戶端的http接口,將所有的客戶端QPS 調(diào)整到6萬,讓客戶端發(fā)出6W QPS強(qiáng)度的請求。

          6wqps

          如法炮制,在服務(wù)器端,啟動一個產(chǎn)生紅包的服務(wù),這個服務(wù)會以200個每秒的速度下發(fā)紅包。總共4萬個。此時觀察客戶端在監(jiān)控上的日志,會發(fā)現(xiàn)基本上以200個每秒的速度獲取到紅包。等到所有紅包下發(fā)完成后,再啟動一個發(fā)紅包的服務(wù),這個服務(wù)系統(tǒng)會生成2萬個紅包,每秒也是200個,每個紅包隨機(jī)指定3位用戶,并向這3個用戶發(fā)出消息,客戶端會自動來拿紅包,最后所有的紅包都被拿走。

          最后,實踐完成。

          8. 分析數(shù)據(jù)

          在實踐過程中,服務(wù)器和客戶端都將自己內(nèi)部的計數(shù)器記錄發(fā)往監(jiān)控端,成為了日志。我們利用簡單python 腳本和gnuplt 繪圖工具,將實踐的過程可視化,由此來驗證運行過程。

          第一張是 客戶端的QPS發(fā)送數(shù)據(jù)這張圖的橫坐標(biāo)是時間,單位是秒,縱坐標(biāo)是QPS,表示這時刻所有客戶端發(fā)送的請求的QPS。圖的第一區(qū)間,幾個小的峰值,是100萬客戶端建立連接的, 圖的第二區(qū)間是3萬QPS 區(qū)間,我們可以看到數(shù)據(jù) 比較穩(wěn)定的保持在3萬這個區(qū)間。最后是6萬QPS區(qū)間。但是從整張圖可以看到QPS不是完美地保持在我們希望的直線上。這主要是以下幾個原因造成的

          1. 當(dāng)非常多goroutine 同時運行的時候,依靠sleep 定時并不準(zhǔn)確,發(fā)生了偏移。我覺得這是golang本身調(diào)度導(dǎo)致的。當(dāng)然如果cpu比較強(qiáng)勁,這個現(xiàn)象會消失。
          2. 因為網(wǎng)絡(luò)的影響,客戶端在發(fā)起連接時,可能發(fā)生延遲,導(dǎo)致在前1秒沒有完成連接。
          3. 服務(wù)器負(fù)載較大時,1000M網(wǎng)絡(luò)已經(jīng)出現(xiàn)了丟包現(xiàn)象,可以通過ifconfig 命令觀察到這個現(xiàn)象,所以會有QPS的波動。

          第二張是 服務(wù)器處理的QPS圖

          和客戶端的向?qū)?yīng)的,服務(wù)器也存在3個區(qū)間,和客戶端的情況很接近。但是我們看到了在大概22:57分,系統(tǒng)的處理能力就有一個明顯的下降,隨后又提高的尖狀。這說明代碼還需要優(yōu)化。

          整體觀察在3萬QPS區(qū)間,服務(wù)器的QPS比較穩(wěn)定,在6萬QSP時候,服務(wù)器的處理就不穩(wěn)定了。我相信這和我的代碼有關(guān),如果繼續(xù)優(yōu)化的話,還應(yīng)該能有更好的效果。

          將2張圖合并起來

          基本是吻合的,這也證明系統(tǒng)是符合預(yù)期設(shè)計的。

          這是紅包生成數(shù)量的狀態(tài)變化圖

          非常的穩(wěn)定。

          這是客戶端每秒獲取的搖紅包狀態(tài)

          可以發(fā)現(xiàn)3萬QPS區(qū)間,客戶端每秒獲取的紅包數(shù)基本在200左右,在6萬QPS的時候,以及出現(xiàn)劇烈的抖動,不能保證在200這個數(shù)值了。我覺得主要是6萬QPS時候,網(wǎng)絡(luò)的抖動加劇了,造成了紅包數(shù)目也在抖動。

          最后是golang 自帶的pprof 信息,其中有g(shù)c 時間超過了10ms, 考慮到這是一個7年前的硬件,而且非獨占模式,所以還是可以接受。

          總結(jié):

          按照設(shè)計目標(biāo),我們模擬和設(shè)計了一個支持100萬用戶,并且每秒至少可以支持3萬QPS,最多6萬QPS的系統(tǒng),簡單模擬了微信的搖紅包和發(fā)紅包的過程??梢哉f達(dá)到了預(yù)期的目的。如果600臺主機(jī)每臺主機(jī)可以支持6萬QPS,只需要7分鐘就可以完成 100億次搖紅包請求。

          雖然這個原型簡單地完成了預(yù)設(shè)的業(yè)務(wù),但是它和真正的服務(wù)會有哪些差別呢?我羅列了一下

          區(qū)別真正服務(wù)本次模擬
          業(yè)務(wù)復(fù)雜更復(fù)雜非常簡單
          協(xié)議Protobuf 以及加密簡單的協(xié)議
          支付復(fù)雜
          日志復(fù)雜
          性能更高
          用戶分布用戶id分散在不同服務(wù)器,需要hash以后統(tǒng)一, 復(fù)雜。用戶id 連續(xù),很多優(yōu)化使代碼簡單 非常高效
          安全控制復(fù)雜
          熱更新及版本控制復(fù)雜
          監(jiān)控細(xì)致簡單


          覺得本文對你有幫助?請分享給更多人

          關(guān)注「全棧開發(fā)者社區(qū)」加星標(biāo),提升全棧技能


          本公眾號會不定期給大家發(fā)福利,包括送書、學(xué)習(xí)資源等,敬請期待吧!

          如果感覺推送內(nèi)容不錯,不妨右下角點個在看轉(zhuǎn)發(fā)朋友圈或收藏,感謝支持。


          好文章,留言、點贊、在看和分享一條龍吧??

          瀏覽 64
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  四季AV之日韩人妻无码 | 91性爱在线观看 | 国产精品久久久久永久免费看 | 年轻人在线毛片免费看视频在线 | 黄色日批视频在线观看 |