• <tr id="yyy80"></tr>
  • <sup id="yyy80"></sup>
  • <tfoot id="yyy80"><noscript id="yyy80"></noscript></tfoot>
  • 99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看 ?

    基于事件驅(qū)動(dòng)的高性能WebSocket服務(wù)器的設(shè)計(jì)與實(shí)現(xiàn)

    2018-02-27 03:06:31曹文彬譚新明劉傳文
    關(guān)鍵詞:隊(duì)列進(jìn)程消息

    曹文彬 譚新明 劉 備 劉傳文

    (武漢理工大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)學(xué)院 湖北 武漢 430063)

    0 引 言

    隨著互聯(lián)網(wǎng)Web 2.0技術(shù)的高速發(fā)展,基于瀏覽器的Web應(yīng)用已經(jīng)成為用戶(hù)獲取互聯(lián)網(wǎng)信息的主要途徑之一。Web技術(shù)在不同領(lǐng)域的深入應(yīng)用和信息時(shí)代高并發(fā)連接請(qǐng)求下海量數(shù)據(jù)的不斷產(chǎn)生,使得Web應(yīng)用程序?qū)g覽器與服務(wù)器間的數(shù)據(jù)實(shí)時(shí)傳遞有了更高的要求[1],主要體現(xiàn)在數(shù)據(jù)傳遞的實(shí)時(shí)性和高并發(fā)帶來(lái)的海量數(shù)據(jù)這兩個(gè)方面。傳統(tǒng)的即時(shí)通信大多基于“拉取”方式,比如文獻(xiàn)[2],通過(guò)輪詢(xún)查看服務(wù)器是否有新消息,缺點(diǎn)是定期輪詢(xún)?cè)诘托畔⒙实那闆r下,可能打開(kāi)或者關(guān)閉許多不必要的連接造成資源的浪費(fèi)。文獻(xiàn)[3]對(duì)輪詢(xún)進(jìn)行了改進(jìn),會(huì)對(duì)通信雙方建立的連接保持一段時(shí)間,但是還會(huì)存在通信效率低下、資源浪費(fèi)的情況。文獻(xiàn)[4]提出的是基于Iframe的流(streaming)技術(shù),缺點(diǎn)是這種方式不可跨域,并且錯(cuò)誤處理可控性不強(qiáng)。以上方式不僅沒(méi)有提高數(shù)據(jù)傳遞的實(shí)時(shí)性,反而制約了實(shí)時(shí)Web應(yīng)用的性能。與傳統(tǒng)方式相比,基于WebSocket協(xié)議的“推送”方式則是由服務(wù)器將消息主動(dòng)地發(fā)送給瀏覽器用戶(hù)。這種通信取代了單個(gè)TCP套接字,通過(guò)第一次請(qǐng)求連接就建立起雙向通信實(shí)時(shí)響應(yīng)的Socket連接,可以減少瀏覽器與服務(wù)器之間的交互次數(shù),從而降低網(wǎng)絡(luò)通信的負(fù)擔(dān),提高實(shí)時(shí)通信效率。

    目前,主流語(yǔ)言都支持WebSocket協(xié)議在服務(wù)器端的實(shí)現(xiàn),而本文采用基于Node.js平臺(tái)的JavaScript語(yǔ)言來(lái)實(shí)現(xiàn),主要原因有:1) W3C標(biāo)準(zhǔn)化的WebSocket API和Node.js平臺(tái)支持的語(yǔ)言都是JavaScript,并且都是基于事件驅(qū)動(dòng)模式編程,可以減低開(kāi)發(fā)難度,縮短開(kāi)發(fā)周期。2) Node.js的事件驅(qū)動(dòng)和非阻塞I/O模型在相對(duì)低系統(tǒng)資源耗用下性能突出,負(fù)載能力出眾,十分適合在分布式設(shè)備上運(yùn)行的數(shù)據(jù)密集型的實(shí)時(shí)Web應(yīng)用[5-6]??偟膩?lái)說(shuō),正是因?yàn)镹ode.js在處理高并發(fā)的用戶(hù)連接請(qǐng)求時(shí)處理能力出色,所以才選擇Node.js作為WebSocket服務(wù)器的實(shí)現(xiàn)平臺(tái),解決高并發(fā)所帶來(lái)的問(wèn)題。

    本文考慮到實(shí)時(shí)數(shù)據(jù)傳輸?shù)男屎涂赡苊鎸?duì)的大量用戶(hù),基于Node.js設(shè)計(jì)了一款WebSocket服務(wù)器,可以應(yīng)對(duì)高并發(fā)場(chǎng)景下實(shí)時(shí)數(shù)據(jù)的推送問(wèn)題。在服務(wù)器的實(shí)現(xiàn)過(guò)程中,首先對(duì)WebSocket技術(shù)應(yīng)用和Node.js平臺(tái)進(jìn)行了研究分析,根據(jù)WebSocket服務(wù)器應(yīng)該具有的功能進(jìn)行關(guān)鍵技術(shù)的選擇。其次進(jìn)行了WebSocket服務(wù)器的框架設(shè)計(jì),并對(duì)其中的功能模塊進(jìn)行了詳細(xì)說(shuō)明。緊接著詳細(xì)闡述了WebSocket服務(wù)器的實(shí)現(xiàn)細(xì)節(jié),并將改善后的Node.js應(yīng)用其中。最后通過(guò)功能測(cè)試和性能測(cè)實(shí)驗(yàn)證了WebSocket服務(wù)器實(shí)時(shí)數(shù)據(jù)推送的可行性。

    1 相關(guān)工作

    1.1 WebSocket服務(wù)器的研究

    隨著WebSocket技術(shù)的發(fā)展,對(duì)于Web實(shí)時(shí)通信系統(tǒng)、社交訂閱系統(tǒng)、監(jiān)控系統(tǒng)等實(shí)時(shí)場(chǎng)景中的數(shù)據(jù)推送問(wèn)題,目前已經(jīng)逐步采用基于WebSocket的推送方式實(shí)現(xiàn),取代了傳統(tǒng)的拉取方式。通過(guò)研究發(fā)現(xiàn),WebSocket技術(shù)在服務(wù)器端已經(jīng)有了廣泛的研究應(yīng)用。文獻(xiàn)[7]中建立了一個(gè)Web應(yīng)用程序來(lái)測(cè)量實(shí)時(shí)風(fēng)傳感器數(shù)據(jù)的單向傳輸延遲,該Web應(yīng)用程序用WebSocket連接替代了HTTP連接,并與HTTP輪詢(xún)和長(zhǎng)輪詢(xún)進(jìn)行了比較。文獻(xiàn)[8]提出了基于WebSocket的印刷包裝機(jī)遠(yuǎn)程監(jiān)控方法,并用MFC完成了服務(wù)端程序,有效提高了印刷包裝行業(yè)的生產(chǎn)流程數(shù)字化程度。文獻(xiàn)[9]將WebSocket運(yùn)用在云監(jiān)控系統(tǒng)中,實(shí)驗(yàn)結(jié)果表明WebSocket監(jiān)控系統(tǒng)的平均延遲時(shí)間通常低于輪詢(xún),F(xiàn)lashSocket和Socket解決方案。文獻(xiàn)[10]設(shè)計(jì)了基于B/S架構(gòu)的實(shí)時(shí)監(jiān)測(cè)Web可視化系統(tǒng),利用WebSocket在客戶(hù)端和服務(wù)器端間建立全雙工通信,實(shí)現(xiàn)生產(chǎn)數(shù)據(jù)實(shí)時(shí)推送,有效降低了網(wǎng)絡(luò)吞吐量,提高了通信效率。文獻(xiàn)[11]設(shè)計(jì)并實(shí)現(xiàn)了一種基于WebSocket推送技術(shù)和SVG技術(shù)的B/S模式下的實(shí)時(shí)監(jiān)控系統(tǒng),提高了監(jiān)視系統(tǒng)的實(shí)時(shí)性、穩(wěn)定性。文獻(xiàn)[12]提出了一種基于WebSocket協(xié)議的服務(wù)器推送技術(shù),利用了復(fù)雜時(shí)間處理技術(shù)對(duì)數(shù)據(jù)進(jìn)行快速處理。

    總的來(lái)說(shuō):1) 上述文獻(xiàn)只提及到WebSocket技術(shù)在數(shù)據(jù)實(shí)時(shí)推送方面的優(yōu)勢(shì),對(duì)于高并發(fā)請(qǐng)求可能帶來(lái)的大量實(shí)時(shí)數(shù)據(jù),并沒(méi)有說(shuō)明如何處理;2) 上述文獻(xiàn)只是在服務(wù)器端引入了WebSocket技術(shù),以實(shí)現(xiàn)某個(gè)場(chǎng)景下數(shù)據(jù)實(shí)時(shí)推送的功能,沒(méi)有以WebSocket技術(shù)為核心,從服務(wù)器角度去設(shè)計(jì)、實(shí)現(xiàn)一款WebSocket服務(wù)器。綜合以上分析,本文以Node.js、Redis、RabbitMQ等開(kāi)源項(xiàng)目為基礎(chǔ),設(shè)計(jì)并實(shí)現(xiàn)了一個(gè)基于事件驅(qū)動(dòng)的WebSocket服務(wù)器,不僅考慮到了傳統(tǒng)的拉取方式難以保障數(shù)據(jù)的實(shí)時(shí)性,而且從服務(wù)器性能角度考慮,引入第三方框架,解決實(shí)時(shí)數(shù)據(jù)的緩存問(wèn)題。

    WebSocket服務(wù)器利用Node.js平臺(tái)是因?yàn)镹ode.js本身就適用于高并發(fā)的Web系統(tǒng),可以給服務(wù)器的處理性能提供保障。利用緩存數(shù)據(jù)庫(kù)Redis設(shè)計(jì)了分層的緩存層,實(shí)現(xiàn)數(shù)據(jù)的內(nèi)部級(jí)存儲(chǔ)。引入的異步消息隊(duì)列RabbitMQ,降低了WebSocket服務(wù)器的壓力,提高了吞吐量。具體來(lái)說(shuō),本文的主要貢獻(xiàn)如下:1) 在Web系統(tǒng)中的數(shù)據(jù)實(shí)時(shí)推送方面,引入第三方框架,設(shè)計(jì)并實(shí)現(xiàn)了一個(gè)WebSocket推送服務(wù)器;2) 對(duì)于實(shí)時(shí)推送服務(wù)器的運(yùn)行平臺(tái)Node.js在單進(jìn)程方面存在的不足進(jìn)行優(yōu)化改進(jìn),使實(shí)時(shí)推送服務(wù)器在穩(wěn)定和高并發(fā)性能方面更加突出。

    1.2 Node.js的高并發(fā)和穩(wěn)定性研究

    對(duì)于本文研究的高性能WebSocket服務(wù)器來(lái)說(shuō),高并發(fā)是服務(wù)器應(yīng)該達(dá)到的首要性能指標(biāo),其次服務(wù)器在運(yùn)行的過(guò)程中要保障穩(wěn)定性。通過(guò)Marc Fasel從CouchDB上讀取JSON數(shù)據(jù)來(lái)比較Node.js和JavaEE之間的性能,以及雷凱等對(duì)Node.js和Apache下的Python和PHP所做的性能對(duì)比實(shí)驗(yàn)可知,Node.js在高并發(fā)的場(chǎng)景下表現(xiàn)穩(wěn)定,并且可以對(duì)連接進(jìn)行很好的響應(yīng)[13-14]。

    Node.js作為WebSocket服務(wù)器中的關(guān)鍵技術(shù),采用基于事件驅(qū)動(dòng)的異步I/O模型[15]。異步I/O是指如果調(diào)用線(xiàn)程執(zhí)行I/O操作,線(xiàn)程只是發(fā)送I/O請(qǐng)求給操作系統(tǒng),線(xiàn)程本身不被阻塞而繼續(xù)執(zhí)行,當(dāng)I/O完成操作系統(tǒng)將會(huì)以事件的形式通知線(xiàn)程。事件驅(qū)動(dòng)是指為了能夠處理異步I/O,線(xiàn)程一直在執(zhí)行一個(gè)事件循環(huán),循環(huán)檢查是否有未處理的事件,并調(diào)用相應(yīng)的事件處理函數(shù)。在Node.js整個(gè)異步I/O的執(zhí)行回調(diào)過(guò)程中,事件循環(huán)類(lèi)似于一個(gè)生產(chǎn)者/消費(fèi)者模型,首先通過(guò)觀察者來(lái)判斷是否有事件需要處理,而不同的底層操作系統(tǒng)所提供的線(xiàn)程池部分正是通過(guò)libuv來(lái)消除差異。Node.js提供的這一套處理機(jī)制,保證了用戶(hù)的請(qǐng)求能夠被整個(gè)異步I/O模型高效、快速的處理。Node.js異步I/O的回調(diào)流程如圖1所示。

    圖1 Node.js異步I/O的回調(diào)流程圖

    圖1的回調(diào)過(guò)程是在Node.js的單進(jìn)程模式下完成的,通過(guò)研究發(fā)現(xiàn),Node.js的單進(jìn)程模式在帶來(lái)好處的同時(shí)也存在一些缺陷。首先,Node.js的單線(xiàn)程無(wú)法利用多核CPU,造成了多核CPU的浪費(fèi);其次,一旦單線(xiàn)程停止響應(yīng)或者崩潰退出,錯(cuò)誤會(huì)引起整個(gè)應(yīng)用退出,服務(wù)器就會(huì)立即停止工作。在Node.js的現(xiàn)行版本中,官方內(nèi)置了一個(gè)Cluster模塊,該模塊可以直接運(yùn)行多個(gè)進(jìn)程實(shí)現(xiàn)Node.js多核處理,能夠提高CPU利用率。但是通過(guò)對(duì)Cluster模塊源碼的研究發(fā)現(xiàn)了一些問(wèn)題:1) Cluster模塊在進(jìn)程管理方面十分有限,判斷子進(jìn)程是否正常工作的方式是:給子進(jìn)程分配新任務(wù)時(shí),查看子進(jìn)程是否有響應(yīng)。隨著失效的子進(jìn)程越來(lái)越多時(shí),可能出現(xiàn)所有的子進(jìn)程都無(wú)法處理任務(wù)的情況。2) Cluster在任務(wù)分配的策略上采用的是Round-Robin方式,雖然實(shí)現(xiàn)起來(lái)簡(jiǎn)單,但僅提供這一種分派策略在選擇方案上顯得單一,其次在不同的應(yīng)用環(huán)境中因?yàn)榇嬖诟鞣N細(xì)節(jié)上的差異,僅通過(guò)這一種方式無(wú)法保證每次任務(wù)分配達(dá)到的效果是合理的。

    本文對(duì)Node.js的多進(jìn)程模塊進(jìn)行了改進(jìn)和優(yōu)化,提高了Node.js的并發(fā)處理能力和穩(wěn)定性,為WebSocket服務(wù)器的高性能提供了保障。

    2 WebSocket服務(wù)器的設(shè)計(jì)

    整個(gè)服務(wù)器采用了三層架構(gòu)方式,分別是用戶(hù)服務(wù)層、中間層和數(shù)據(jù)服務(wù)層。用戶(hù)服務(wù)層負(fù)責(zé)接收用戶(hù)獲取實(shí)時(shí)數(shù)據(jù)的連接請(qǐng)求,并將用戶(hù)信息傳遞給中間層。中間層負(fù)責(zé)接收用戶(hù)服務(wù)層傳遞過(guò)來(lái)的用戶(hù)信息,并對(duì)數(shù)據(jù)服務(wù)層提供的實(shí)時(shí)數(shù)據(jù)進(jìn)行處理。然后再把實(shí)時(shí)數(shù)據(jù)通過(guò)用戶(hù)服務(wù)層推送給用戶(hù),數(shù)據(jù)服務(wù)層則會(huì)調(diào)用數(shù)據(jù)中心提供的API獲取實(shí)時(shí)數(shù)據(jù)。用戶(hù)服務(wù)層主要包括連接建立與維護(hù)、消息推送模塊。中間層主要由任務(wù)分派、緩存數(shù)據(jù)庫(kù)、進(jìn)程監(jiān)控、實(shí)時(shí)數(shù)據(jù)處理等功能模塊組成。數(shù)據(jù)服務(wù)層包括實(shí)時(shí)數(shù)據(jù)的獲取和消息隊(duì)列,具體的分層架構(gòu)設(shè)計(jì)如圖2所示。

    結(jié)合圖2中的WebSocket服務(wù)器架構(gòu),對(duì)WebSocket服務(wù)器的處理流程進(jìn)行了設(shè)計(jì),如圖3所示,主要包括以下部分:

    (1) 用戶(hù)請(qǐng)求連接

    服務(wù)器在啟動(dòng)后,會(huì)一直監(jiān)聽(tīng)來(lái)自用戶(hù)的WebSocket請(qǐng)求。當(dāng)用戶(hù)的WebSocket請(qǐng)求到來(lái),請(qǐng)求所攜帶訂閱或取消訂閱信息將會(huì)被WebSocket服務(wù)器解析,并將解析的請(qǐng)求信息存儲(chǔ)到緩存數(shù)據(jù)庫(kù)中。

    (2) 緩存數(shù)據(jù)庫(kù)

    主要用來(lái)存儲(chǔ)用戶(hù)連接信息以及worker子進(jìn)程的相關(guān)信息。目前Redis,Memcached都是key-value型的高性能緩沖數(shù)據(jù)庫(kù),但是Redis相比Memcached來(lái)說(shuō),支持更多服務(wù)器端的數(shù)據(jù)操作和更加豐富的數(shù)據(jù)結(jié)構(gòu)[16]。本文中將采用Redis作為WebSocket服務(wù)器的緩存數(shù)據(jù)庫(kù),用以減少程序中內(nèi)存泄露的風(fēng)險(xiǎn)。

    (3) 主進(jìn)程進(jìn)行任務(wù)分派

    WebSocket服務(wù)器在啟動(dòng)時(shí)就會(huì)創(chuàng)建多個(gè)worker進(jìn)程,通過(guò)負(fù)載均衡算法,主進(jìn)程將WebSocket服務(wù)器接收到的客戶(hù)端請(qǐng)求分發(fā)到各個(gè)worker子進(jìn)程處理。每個(gè)worker子進(jìn)程會(huì)處理多個(gè)任務(wù),在緩存數(shù)據(jù)庫(kù)中會(huì)有一個(gè)“子進(jìn)程任務(wù)信息表”,用來(lái)存放子進(jìn)程和任務(wù)之間的對(duì)應(yīng)關(guān)系,便于進(jìn)行消息推送。

    (4) 進(jìn)程管理

    主要是對(duì)“子進(jìn)程隊(duì)列表”中的子進(jìn)程進(jìn)行監(jiān)控、維護(hù)。緩存數(shù)據(jù)庫(kù)中會(huì)存放一張“子進(jìn)程隊(duì)列表”,保存的是當(dāng)前所有有效子進(jìn)程的相關(guān)信息,包括處理任務(wù)數(shù)、是否有效、運(yùn)行時(shí)間等。對(duì)于檢測(cè)到的失效進(jìn)程,會(huì)刪除表中相應(yīng)的進(jìn)程信息,而對(duì)于重啟的新進(jìn)程,會(huì)把相關(guān)信息添加到表中。每隔一段時(shí)間,會(huì)收集子進(jìn)程的狀態(tài)信息更新“子進(jìn)程隊(duì)列表”,確保表中信息的準(zhǔn)確性和時(shí)效性。

    (5) 實(shí)時(shí)數(shù)據(jù)獲取

    (6) 消息隊(duì)列

    在數(shù)據(jù)獲取和數(shù)據(jù)處理單元之間設(shè)計(jì)一個(gè)消息隊(duì)列,主要是應(yīng)對(duì)某時(shí)刻出現(xiàn)大量的更新數(shù)據(jù),起到消峰減壓的效果。本文采用了RabbitMQ作為消息中間件,首先將“數(shù)據(jù)中心”的消息發(fā)送到RabbitMQ消息隊(duì)列中,再由用戶(hù)請(qǐng)求處理子進(jìn)程從RabbitMQ中進(jìn)行消息消費(fèi)。

    (7) 子進(jìn)程進(jìn)行數(shù)據(jù)處理

    根據(jù)不同的應(yīng)用場(chǎng)景,實(shí)時(shí)數(shù)據(jù)的處理規(guī)則需要進(jìn)行定制。WebSocket服務(wù)器發(fā)送的數(shù)據(jù)可能是文本、圖片、二進(jìn)制或者是其他數(shù)據(jù)類(lèi)型的數(shù)據(jù),但是WebSocket協(xié)議只能處理文本數(shù)據(jù)消息和二進(jìn)制數(shù)據(jù)消息,所以要進(jìn)行數(shù)據(jù)類(lèi)型的轉(zhuǎn)換。

    (8) 消息推送

    每個(gè)worker進(jìn)程都維護(hù)了自己服務(wù)的所有客戶(hù)端連接,并且這些連接信息都存儲(chǔ)在緩存數(shù)據(jù)庫(kù)中,進(jìn)程只需要將數(shù)據(jù)處理單元處理的數(shù)據(jù)發(fā)送到對(duì)應(yīng)的用戶(hù)連接中。

    圖3 WebSocket服務(wù)器處理流程示意圖

    通過(guò)對(duì)實(shí)際應(yīng)用中的大多數(shù)即時(shí)通信服務(wù)器的研究,本節(jié)對(duì)WebSocket服務(wù)器的整體架構(gòu)進(jìn)行了設(shè)計(jì)。在設(shè)計(jì)的過(guò)程中著重考慮了以下幾方面:1) 在工作場(chǎng)景中WebSocket服務(wù)器可能面臨的高并發(fā);2) 對(duì)于多進(jìn)程的管理,以保障WebSocket服務(wù)器的穩(wěn)定性;3) WebSocket服務(wù)器的跨平臺(tái)性和擴(kuò)展性。

    3 WebSocket服務(wù)器的實(shí)現(xiàn)

    3.1 用戶(hù)請(qǐng)求連接

    WebSocket服務(wù)器的用戶(hù)請(qǐng)求處理包括:用戶(hù)請(qǐng)求連接和用戶(hù)發(fā)送的消息格式定義。客戶(hù)端請(qǐng)求WebSocket服務(wù)器建立連接的過(guò)程,就是打開(kāi)階段的握手協(xié)議,可以選擇Socket.IO進(jìn)行實(shí)現(xiàn)。

    摘 要:初中生的英語(yǔ)核心素養(yǎng)包括:語(yǔ)言能力、文化意識(shí)、思維品質(zhì)、學(xué)習(xí)能力,共四個(gè)維度。初中英語(yǔ)課堂設(shè)計(jì)提倡發(fā)展學(xué)生思維品質(zhì),采用既強(qiáng)調(diào)語(yǔ)言學(xué)習(xí)過(guò)程又有利于提高學(xué)生學(xué)習(xí)成效的語(yǔ)言教學(xué)途徑和方法?;谟⒄Z(yǔ)學(xué)科核心素養(yǎng)設(shè)計(jì)的英語(yǔ)課堂是教師特別是外國(guó)語(yǔ)學(xué)校教師值得重視和積極開(kāi)展的。以牛津英語(yǔ)7B unit 5 welcome to the unit 教學(xué)為例,探討通過(guò)精心設(shè)計(jì)英語(yǔ)課堂教學(xué),提高學(xué)生核心素養(yǎng)。

    當(dāng)用戶(hù)與WebSocket服務(wù)器建立連接后,用戶(hù)發(fā)送的消息體格式要滿(mǎn)足一定規(guī)則:一種是數(shù)據(jù)信息的訂閱請(qǐng)求,另外一種就是數(shù)據(jù)信息的取消訂閱請(qǐng)求。訂閱請(qǐng)求為“subscribe”,取消訂閱請(qǐng)求為“unSubscribe”。當(dāng)WebSocket服務(wù)器應(yīng)用于多應(yīng)用多租戶(hù)模式中,用appID識(shí)別符區(qū)分不同的應(yīng)用,每個(gè)請(qǐng)求攜帶的信息用“msg”識(shí)別符進(jìn)行識(shí)別。每個(gè)請(qǐng)求可能訂閱或取消訂閱多個(gè)數(shù)據(jù)信息,若請(qǐng)求多個(gè)數(shù)據(jù)信息,數(shù)據(jù)信息之間用“,”隔開(kāi)。最終訂閱請(qǐng)求發(fā)送的字符串格式為″{appID:″+appID+″,cmd:′subscribe′,msg:[″+message+″]}″,取消訂閱請(qǐng)求發(fā)送的字符串格式為″{appID:″+appID+″,cmd:“unSubscribe”,msg:[″+message+″]}″。

    3.2 實(shí)時(shí)數(shù)據(jù)獲取和數(shù)據(jù)處理

    實(shí)時(shí)數(shù)據(jù)獲取是指WebSocket服務(wù)器從數(shù)據(jù)中心獲取實(shí)時(shí)更新的數(shù)據(jù),數(shù)據(jù)中心提供獲取實(shí)時(shí)數(shù)據(jù)的接口getRealTimeData(int appID,List ids),其中appID是應(yīng)用編號(hào),ids是用戶(hù)請(qǐng)求訂閱的數(shù)據(jù)id的集合。WebSocket服務(wù)器采用每隔一定時(shí)間間隔調(diào)用一次接口,來(lái)保證數(shù)據(jù)的實(shí)時(shí)性。在這一部分的實(shí)現(xiàn)過(guò)程中,采取了“主動(dòng)通知”模式。所謂主動(dòng)通知,就是當(dāng)數(shù)據(jù)發(fā)送更改時(shí),主動(dòng)通知子進(jìn)程。在實(shí)現(xiàn)的過(guò)程中,需要?jiǎng)?chuàng)建一個(gè)獨(dú)立的通知進(jìn)程,為了不混合業(yè)務(wù)邏輯,此進(jìn)程只用來(lái)發(fā)送數(shù)據(jù)更新的通知和查詢(xún)狀態(tài)是否更改。主動(dòng)通知模式相比于所有的子進(jìn)程都去定時(shí)輪詢(xún),降低了查詢(xún)狀態(tài)的開(kāi)銷(xiāo),并且由于不會(huì)涉及多個(gè)進(jìn)程進(jìn)行狀態(tài)查詢(xún),狀態(tài)響應(yīng)處的壓力也不會(huì)過(guò)大,所以可以降低輪詢(xún)時(shí)間,提升數(shù)據(jù)的準(zhǔn)確性。

    數(shù)據(jù)處理部分主要是指數(shù)據(jù)類(lèi)型的轉(zhuǎn)換,WebSocket服務(wù)器發(fā)送的數(shù)據(jù)可能是文本、圖片、二進(jìn)制或者是其他數(shù)據(jù)類(lèi)型的數(shù)據(jù),然而WebSocket協(xié)議只能處理文本數(shù)據(jù)消息和二進(jìn)制數(shù)據(jù)消息[17]。因此WebSocket服務(wù)器從數(shù)據(jù)中心獲得實(shí)時(shí)更新的數(shù)據(jù)后,需要對(duì)不同類(lèi)型的實(shí)時(shí)數(shù)據(jù)進(jìn)行處理統(tǒng)一轉(zhuǎn)換為成二進(jìn)制。

    Node.js提供了一個(gè)全局構(gòu)造函數(shù)Buffer,可以對(duì)二進(jìn)制數(shù)據(jù)進(jìn)行操作,實(shí)現(xiàn)string、int、Json等格式的轉(zhuǎn)換。具體接口和說(shuō)明如表1所示。

    表1 WebSocket服務(wù)器數(shù)據(jù)處理接口

    3.3 緩存數(shù)據(jù)庫(kù)

    WebSocket服務(wù)器接收客戶(hù)端發(fā)送的消息體時(shí),能夠獲取客戶(hù)端和WebSocket服務(wù)器之間的連接信息connection。同時(shí)客戶(hù)端向WebSocket服務(wù)器發(fā)送的是滿(mǎn)足一定格式的消息體,WebSocket服務(wù)器通過(guò)解析消息體,可以獲取到{“appID”+“msg”}信息??蛻?hù)端可能發(fā)送多個(gè)消息體,WebSocket服務(wù)器會(huì)將客戶(hù)端發(fā)送的消息體進(jìn)行拆分,以{“appid”+“msg”}為key,以訂閱該key的所有connection的集合connections為value存儲(chǔ)到Redis中。例如,一個(gè)用戶(hù)發(fā)送了多個(gè)消息體,通過(guò)解析得到信息{“appID1”+“UserOneGetMsg1”}、{“appID1”+“UserOneGetMsg2”}、{“appID2”+“UserOneGetMsg1”}。Redis首先會(huì)判斷Key集合中是否存在這些信息,假如通過(guò)判斷匹配到了{(lán)“appID1”+“UserOneGetMsg1”},就把該用戶(hù)的connection添加到對(duì)應(yīng)的集合connections中;假如通過(guò)判斷沒(méi)有匹配到{“appID1”+“UserOneGetMsg2”},則會(huì)新建一個(gè)對(duì)應(yīng)的集合connections,然后把用戶(hù)連接信息connection再添加到新建集合中。消息體的解析過(guò)程以及生成的新數(shù)據(jù)在Redis中的存儲(chǔ)流程如圖4所示。

    圖4 Redis中的存儲(chǔ)流程圖

    3.4 消息隊(duì)列

    RabbitMQ是AMQP(高級(jí)消息隊(duì)列)協(xié)議的一個(gè)開(kāi)源實(shí)現(xiàn),作為老牌的消息中間件不僅功能完善、性能穩(wěn)定,還有很多監(jiān)聽(tīng)插件可以選擇,提供了豐富的API。本文選用RabbitMQ作為WebSocket服務(wù)器的消息隊(duì)列中間件,以期達(dá)到以下兩個(gè)方面的效果:1) 減少程序中隊(duì)列消費(fèi)不及時(shí)造成的內(nèi)存泄露問(wèn)題。2) 提升服務(wù)器的性能。

    在Node.js中提供了一個(gè)amqp模塊,該模塊為所有遵循AMQP協(xié)議的消息隊(duì)列服務(wù)器提供Node.js環(huán)境下的客戶(hù)端。具體的實(shí)現(xiàn)步驟:1) 安裝RabbitMQ消息服務(wù)器,進(jìn)行環(huán)境變量和權(quán)限的設(shè)置。2) 用瀏覽器打開(kāi)http://localhost:15672,檢測(cè)是否能夠訪(fǎng)問(wèn)RabbitMQ管理控制臺(tái)。3) 安裝Node.js與RabbitMQ交互所需要的node-amqp模塊。4) 通過(guò)amqp.createConnection()函數(shù)建立連接,生成隊(duì)列并進(jìn)行隊(duì)列初始化。

    3.5 消息的推送

    WebSocket服務(wù)器提供了兩個(gè)消息推送接口,具體接口和說(shuō)明如表2所示,它們分別支持文本類(lèi)型和二進(jìn)制類(lèi)型的數(shù)據(jù)推送。

    表2 WebSocket服務(wù)器數(shù)據(jù)推送接口

    WebSocket服務(wù)器從數(shù)據(jù)中心獲得實(shí)時(shí)更新的數(shù)據(jù)后,執(zhí)行實(shí)時(shí)數(shù)據(jù)的推送,其具體執(zhí)行流程如圖5所示。

    圖5 數(shù)據(jù)推送流程圖

    3.6 進(jìn)程管理

    WebSocket服務(wù)器的Node.js平臺(tái)雖然最初版本采用的是單進(jìn)程工作模式,但在隨后的發(fā)行版本中引入了多進(jìn)程模式,以改善單進(jìn)程對(duì)多核CPU利用率低、單進(jìn)程崩潰等問(wèn)題。進(jìn)程管理模塊就是對(duì)WebSocket服務(wù)器的多個(gè)工作子進(jìn)程進(jìn)行監(jiān)控、維護(hù),一旦發(fā)現(xiàn)有失效的工作子進(jìn)程,就會(huì)創(chuàng)建新的工作子進(jìn)程替代失效子進(jìn)程繼續(xù)工作,并將任務(wù)按負(fù)載均衡策略分派給不同的工作子進(jìn)程處理,為WebSocket服務(wù)器的穩(wěn)定性提供保障。在進(jìn)程管理模塊的實(shí)現(xiàn)過(guò)程中,對(duì)原有的進(jìn)程管理模塊進(jìn)行了優(yōu)化,分別增加了“心跳機(jī)制”和最小連接策略。

    首先,對(duì)多進(jìn)程的管理模式進(jìn)行了重新設(shè)計(jì),主進(jìn)程根據(jù)配置創(chuàng)建若干個(gè)子進(jìn)程,并將創(chuàng)建的子進(jìn)程信息存入到“子進(jìn)程隊(duì)列表”中,然后通過(guò)“心跳機(jī)制”對(duì)子進(jìn)程進(jìn)行監(jiān)控,并根據(jù)收集到的子進(jìn)程信息對(duì)“子進(jìn)程隊(duì)列表”進(jìn)行更新。若是在監(jiān)控中發(fā)現(xiàn)有失效進(jìn)程,主進(jìn)程會(huì)創(chuàng)建新的子進(jìn)程,并將已失效的子進(jìn)程從“子進(jìn)程隊(duì)列表”中刪除。監(jiān)控子進(jìn)程是否失效是通過(guò)“心跳機(jī)制”來(lái)實(shí)現(xiàn):worker進(jìn)程定時(shí)發(fā)送心跳給master進(jìn)程,若master進(jìn)程在一定時(shí)間內(nèi)未能收到worker進(jìn)程的心跳,則可以認(rèn)為此worker進(jìn)程已經(jīng)停止響應(yīng),否則會(huì)重啟一個(gè)新的worker進(jìn)程繼續(xù)提供服務(wù)。通過(guò)引入這種監(jiān)控機(jī)制,可以保障一直有工作進(jìn)程響應(yīng)客戶(hù)請(qǐng)求,提升了服務(wù)器的穩(wěn)定性,能夠?qū)崿F(xiàn)持續(xù)、健壯地為客戶(hù)提供服務(wù),改進(jìn)后的進(jìn)程管理模塊如圖6所示。

    圖6 改進(jìn)后的進(jìn)程管理模塊功能流程圖

    WebSocket服務(wù)器接收到的新請(qǐng)求首先會(huì)被主進(jìn)程監(jiān)聽(tīng)到,然后才會(huì)分派給子進(jìn)程。任務(wù)分派的方式是通過(guò)進(jìn)程間的通信來(lái)實(shí)現(xiàn)的,在進(jìn)行任務(wù)分派時(shí),主進(jìn)程會(huì)按照制定的負(fù)載均衡策略分派任務(wù)給某一個(gè)子進(jìn)程處理。Node.js原有的任務(wù)分配策略只有靜態(tài)的輪轉(zhuǎn)算法,本文增加了針對(duì)長(zhǎng)連接的最少連接策略。最小連接算法解決了靜態(tài)輪轉(zhuǎn)算法只能保證請(qǐng)求數(shù)量均衡的弱點(diǎn),考慮了各個(gè)工作子進(jìn)程當(dāng)前的負(fù)載信息,相對(duì)靜態(tài)輪轉(zhuǎn)算法具有較好的均衡效果。

    最少連接算法原理簡(jiǎn)單易懂,在本文中主要是通過(guò)對(duì)比“子進(jìn)程隊(duì)列表”中每個(gè)子進(jìn)程的當(dāng)前連接數(shù)目,選擇其中連接數(shù)最少的子進(jìn)程接收新來(lái)的任務(wù),然后在一個(gè)更新周期結(jié)束之后,對(duì)隊(duì)列表中的連接數(shù)進(jìn)行更新。例如一個(gè)由n個(gè)子進(jìn)程組成的進(jìn)程隊(duì)列P={P(0),P(1),P(2),…,P(i),…,P(n-1)},其中變量i(0≤i

    圖7 Node.js進(jìn)程管理模塊最少連接算法流程圖

    4 實(shí)驗(yàn)及結(jié)果

    4.1 實(shí)驗(yàn)環(huán)境

    操作系統(tǒng):64位Windows 10;處理器:Core i5-4590 @ 3.30 GHz 四核;內(nèi)存:8 GB。

    4.2 功能測(cè)試

    將WebSocket服務(wù)器應(yīng)用在多應(yīng)用、多租戶(hù)的實(shí)際場(chǎng)景中,由此在實(shí)驗(yàn)中設(shè)計(jì)了兩種不同的應(yīng)用,不同的應(yīng)用發(fā)送不同的數(shù)據(jù)。數(shù)據(jù)由Node.js自身循環(huán)產(chǎn)生,產(chǎn)生的兩種數(shù)據(jù),用Json形式表示如下:模擬的A應(yīng)用的數(shù)據(jù)格式為{appID:1,sensorNum:′001′,data:[″+Math.round(Math.random()*100)+″]},B應(yīng)用的數(shù)據(jù)格式為{appID:2,deviceNum:′001′,lng:?+lng+?,lat:?+lat+?}。原始數(shù)據(jù)如圖8所示。

    圖8 功能測(cè)試部部分原始數(shù)據(jù)包

    這里產(chǎn)生的數(shù)據(jù)相當(dāng)于WebSocket服務(wù)器運(yùn)行中從數(shù)據(jù)中心獲得的實(shí)時(shí)數(shù)據(jù),將數(shù)據(jù)直接推送到RabbitMQ消息隊(duì)列中。在RabbitMQ網(wǎng)頁(yè)管理后臺(tái),可以查看RabbitMQ消息,如圖9所示,即表示消息已經(jīng)成功進(jìn)入了消息隊(duì)列。

    圖9 RabbitMQ消息隊(duì)列后臺(tái)管理

    頁(yè)面一打開(kāi)就會(huì)發(fā)送WebSocket連接請(qǐng)求到WebSocket服務(wù)器,WebSocket服務(wù)器接收到用戶(hù)請(qǐng)求并且連接成功后,會(huì)根據(jù)用戶(hù)訂閱消息把數(shù)據(jù)信息實(shí)時(shí)地推送給客戶(hù)端瀏覽器。頁(yè)面的訂閱按鈕模擬用戶(hù)發(fā)送WebSocket訂閱請(qǐng)求,頁(yè)面的取消按鈕模擬用戶(hù)發(fā)送WebSocket取消訂閱請(qǐng)求,如圖10所示。

    圖10 取消訂閱后重新訂閱

    圖10中框出表示:用戶(hù)在取消訂閱后,瀏覽器客戶(hù)端將不再接收到sensorNum為002的數(shù)據(jù)信息,而sensorNum為001的數(shù)據(jù)信息會(huì)持續(xù)接收到。通過(guò)實(shí)驗(yàn)也表明,WebSocket服務(wù)器是可以達(dá)到基本功能需求的。

    4.3 性能測(cè)試

    WebSocket服務(wù)器的性能測(cè)試采用Jmeter2.0.11作為測(cè)試工具,并安裝支持WebSocket協(xié)議的JMeterWebSocketSampler-1.0.2-SNAPSHOT.jar插件。安裝好插件后創(chuàng)建一個(gè)WebSocket服務(wù)器測(cè)試線(xiàn)程組,并在線(xiàn)程組中添加測(cè)試線(xiàn)程WebSocketTest,同時(shí)添加察看結(jié)果樹(shù)、Summary-Report、聚合報(bào)告等多個(gè)監(jiān)聽(tīng)器。

    通過(guò)表3可知當(dāng)并發(fā)連接數(shù)低于750時(shí),錯(cuò)誤率為0;當(dāng)連接數(shù)達(dá)到1 500時(shí),錯(cuò)誤率在1.52%左右,是可以滿(mǎn)足在多應(yīng)用多租戶(hù)模式下的實(shí)時(shí)數(shù)據(jù)推送需求的。

    表3 系統(tǒng)性能測(cè)試

    5 結(jié) 語(yǔ)

    本文回顧了即時(shí)通信領(lǐng)域發(fā)展過(guò)程中的技術(shù)方案,進(jìn)行了詳細(xì)的對(duì)比分析,歸納總結(jié)了WebSocket的特性,并推薦在實(shí)時(shí)系統(tǒng)中采用WebSocket技術(shù)。分析了國(guó)內(nèi)外WebSocket技術(shù)在服務(wù)器端的應(yīng)用,總結(jié)出目前并沒(méi)有從服務(wù)器角度去設(shè)計(jì)一款WebSocket服務(wù)器,用以解決在高并發(fā)、穩(wěn)定性等方面可能存在的問(wèn)題。研究總結(jié)了Node.js、Redis、RabbitMQ等開(kāi)源項(xiàng)目

    的特點(diǎn),設(shè)計(jì)出了WebSocket服務(wù)器的架構(gòu)圖,詳細(xì)闡述了各模塊的實(shí)現(xiàn)方案。為了進(jìn)一步提高WebSocket服務(wù)器的高并發(fā)和穩(wěn)定性,對(duì)Node.js多進(jìn)程模塊進(jìn)行改進(jìn)和優(yōu)化。最后對(duì)WebSocket服務(wù)器進(jìn)行實(shí)驗(yàn)測(cè)試,驗(yàn)證結(jié)果表明該WebSocket服務(wù)器在功能和性能上達(dá)到了預(yù)期設(shè)計(jì)的目標(biāo)。在下一階段的研究中,將會(huì)在WebSocket服務(wù)器中加入日志管理模塊,通過(guò)日志回放服務(wù)器的運(yùn)行狀態(tài)。

    [1] 陸晨,馮向陽(yáng),蘇厚勤.HTML5 WebSocket握手協(xié)議的研究與實(shí)現(xiàn)[J].計(jì)算機(jī)應(yīng)用與軟件,2015,32(1):128-131.

    [2] Takagi H,Kleinrock L.Analysis of polling systems[J].Performance Evaluation,1985,5(3):206.

    [3] Loreto S,Saintandre P,Salsano S,et al.Known Issues and Best Practices for the Use of Long Polling and Streaming in Bidirectional HTTP[J].Choice Current Reviews for Academic Libraries,2011,4(1846):4.

    [4] Loreto S,Saintandre P,Salsano S,et al.Known Issues and Best Practices for the Use of Long Polling and Streaming in Bidirectional HTTP[J].Choice Current Reviews for Academic Libraries,2011,4(1846):4.

    [5] 許會(huì)元,何利力.NodeJS的異步非阻塞I/O研究[C]//全國(guó)工業(yè)控制計(jì)算機(jī)技術(shù)年會(huì),2014.

    [6] Tilkov S,Vinoski S.Node.js:Using JavaScript to Build High-Performance Network Programs[J].IEEE Internet Computing,2010,14(6):80-83.

    [7] Pimentel V,Nickerson B G.Communicating and Displaying Real-Time Data with WebSocket[J].IEEE Internet Computing,2012,16(4):45-53.

    [8] 蔡錦達(dá),蔣振飛.基于WebSocket的印刷包裝機(jī)械遠(yuǎn)程監(jiān)控方法的研究[J].包裝工程,2013(15):87-90.

    [9] Ma K,Zhang W.Introducing browser-based high-frequency cloud monitoring system using WebSocket Proxy[J].International Journal of Grid & Utility Computing,2015,6(1).

    [10] 劉維峰,左澤軍,趙利強(qiáng),等.基于HTML5的生產(chǎn)裝置實(shí)時(shí)監(jiān)測(cè)可視化[J].計(jì)算機(jī)工程與設(shè)計(jì),2015(3):809-813.

    [11] 金豐,張悅,雍鵬.基于雙服務(wù)器的B/S模式監(jiān)測(cè)系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)[J].計(jì)算機(jī)仿真,2014,31(2):201-205.

    [12] 張玲,張翠肖.WebSocket服務(wù)器推送技術(shù)的研究[J].河北省科學(xué)院學(xué)報(bào),2014,31(2):49-53.

    [13] Lei K,Ma Y,Tan Z.Performance Comparison and Evaluation of Web Development Technologies in PHP,Python, and Node.js[C]//IEEE,International Conference on Computational Science and Engineering.IEEE Computer Society,2014:661-668.

    [14] Marc Fasel.Performance Comparison Between Node.js and Java EE For Reading JSON Data from CouchDB[EB/OL].[2013-10-22].http://blog.shinetech.com/2013/10/22/performance-comparison-between-node-js-and-java-ee.

    [15] O’reilly.Node:up and running:scalable server-side code with javascript[M].Oreilly Media,2012.

    [16] 王心妍.Memcached和Redis在高速緩存方面的應(yīng)用[J].無(wú)線(xiàn)互聯(lián)科技,2012(9):8-9.

    [17] Melnikov A.The WebSocket Protocol[OL].2011.https://www.rfc-editor.org/rfc/rfc6455.txt.

    猜你喜歡
    隊(duì)列進(jìn)程消息
    隊(duì)列里的小秘密
    基于多隊(duì)列切換的SDN擁塞控制*
    軟件(2020年3期)2020-04-20 00:58:44
    一張圖看5G消息
    債券市場(chǎng)對(duì)外開(kāi)放的進(jìn)程與展望
    在隊(duì)列里
    豐田加速駛?cè)胱詣?dòng)駕駛隊(duì)列
    消息
    消息
    消息
    社會(huì)進(jìn)程中的新聞學(xué)探尋
    狂野欧美激情性bbbbbb| 欧美日韩在线观看h| 欧美精品高潮呻吟av久久| 五月天丁香电影| 热re99久久国产66热| 欧美bdsm另类| 女人久久www免费人成看片| 日韩视频在线欧美| 人人妻人人看人人澡| 国产日韩欧美亚洲二区| 一级爰片在线观看| 精品亚洲乱码少妇综合久久| 亚洲av综合色区一区| 国产精品伦人一区二区| 亚洲欧美日韩卡通动漫| 欧美性感艳星| 人人妻人人澡人人看| 国产精品偷伦视频观看了| 男女免费视频国产| 永久免费av网站大全| 国产精品一区二区在线观看99| 久久亚洲国产成人精品v| 国产69精品久久久久777片| 国产高清有码在线观看视频| 人人澡人人妻人| 啦啦啦中文免费视频观看日本| 国国产精品蜜臀av免费| 爱豆传媒免费全集在线观看| 久久人人爽人人爽人人片va| 欧美另类一区| 九色成人免费人妻av| 最新中文字幕久久久久| 国产精品国产三级专区第一集| 日韩一本色道免费dvd| 赤兔流量卡办理| 亚洲性久久影院| 精品酒店卫生间| 最近中文字幕2019免费版| 久久久国产精品麻豆| 久久精品国产亚洲av涩爱| 日日啪夜夜爽| 亚洲欧美日韩另类电影网站| 免费看av在线观看网站| 午夜91福利影院| 国产精品嫩草影院av在线观看| 亚洲精品色激情综合| 多毛熟女@视频| 一级毛片我不卡| 精品亚洲乱码少妇综合久久| 五月开心婷婷网| av播播在线观看一区| 精品久久久久久电影网| 99热网站在线观看| 亚洲成人手机| 久久久久久久久久久丰满| kizo精华| 一级,二级,三级黄色视频| 成人国产麻豆网| 天堂8中文在线网| 国产成人aa在线观看| 亚洲人成网站在线播| 又爽又黄a免费视频| 中国美白少妇内射xxxbb| 美女脱内裤让男人舔精品视频| av天堂中文字幕网| 日本wwww免费看| 国产精品人妻久久久影院| 日韩大片免费观看网站| 精品国产一区二区三区久久久樱花| 免费看不卡的av| 精品视频人人做人人爽| 久久精品国产a三级三级三级| 乱人伦中国视频| 青春草视频在线免费观看| 日韩精品免费视频一区二区三区 | 国产亚洲av片在线观看秒播厂| 欧美成人午夜免费资源| 免费黄网站久久成人精品| 久久久久久久大尺度免费视频| 亚洲人与动物交配视频| 乱系列少妇在线播放| 嫩草影院入口| 热99国产精品久久久久久7| 嫩草影院新地址| 亚洲色图综合在线观看| 国产av精品麻豆| 美女脱内裤让男人舔精品视频| 黄色日韩在线| 国产伦理片在线播放av一区| 亚洲国产毛片av蜜桃av| 一级黄片播放器| 久久久久网色| 51国产日韩欧美| 久久精品国产亚洲网站| 成人漫画全彩无遮挡| 亚洲国产日韩一区二区| 99久国产av精品国产电影| av女优亚洲男人天堂| 久久国产亚洲av麻豆专区| 深夜a级毛片| 99视频精品全部免费 在线| 欧美日本中文国产一区发布| 国产av一区二区精品久久| 成年女人在线观看亚洲视频| 亚洲欧美一区二区三区国产| 六月丁香七月| 日韩制服骚丝袜av| 婷婷色综合大香蕉| 婷婷色综合大香蕉| 成人黄色视频免费在线看| 在线精品无人区一区二区三| 久久久欧美国产精品| 久久久久久久亚洲中文字幕| 成年女人在线观看亚洲视频| 高清在线视频一区二区三区| 国产淫片久久久久久久久| 亚洲欧美日韩卡通动漫| 日本av手机在线免费观看| 亚洲成人手机| 女性被躁到高潮视频| 国产精品嫩草影院av在线观看| 日韩免费高清中文字幕av| 男人和女人高潮做爰伦理| 曰老女人黄片| 啦啦啦啦在线视频资源| 乱系列少妇在线播放| 国产欧美日韩一区二区三区在线 | 偷拍熟女少妇极品色| 成人特级av手机在线观看| 日日撸夜夜添| 欧美另类一区| 有码 亚洲区| 亚洲va在线va天堂va国产| 女性被躁到高潮视频| 亚洲精品国产色婷婷电影| 夫妻午夜视频| 亚洲欧美成人综合另类久久久| 交换朋友夫妻互换小说| 日本黄大片高清| 久久久亚洲精品成人影院| 国产精品一区二区三区四区免费观看| 亚洲国产精品999| 国产成人一区二区在线| 人妻一区二区av| 亚洲第一区二区三区不卡| 欧美日韩一区二区视频在线观看视频在线| 久久鲁丝午夜福利片| 国产成人精品福利久久| 成年女人在线观看亚洲视频| 亚洲精品中文字幕在线视频 | 18+在线观看网站| 久久久国产欧美日韩av| 丁香六月天网| 美女中出高潮动态图| 日本欧美视频一区| 波野结衣二区三区在线| 99re6热这里在线精品视频| 亚洲欧美清纯卡通| 成年女人在线观看亚洲视频| 下体分泌物呈黄色| 久久人人爽人人片av| 青春草国产在线视频| 国产老妇伦熟女老妇高清| 中文字幕av电影在线播放| 亚洲欧洲精品一区二区精品久久久 | 免费看av在线观看网站| 在现免费观看毛片| 在线 av 中文字幕| 欧美成人午夜免费资源| 69精品国产乱码久久久| 亚洲精品乱码久久久久久按摩| 亚洲一区二区三区欧美精品| 免费高清在线观看视频在线观看| 精品人妻偷拍中文字幕| 欧美区成人在线视频| 人妻夜夜爽99麻豆av| 亚洲精品aⅴ在线观看| 欧美日韩一区二区视频在线观看视频在线| 天天躁夜夜躁狠狠久久av| 婷婷色麻豆天堂久久| 亚洲精品,欧美精品| 少妇被粗大猛烈的视频| 亚洲国产欧美在线一区| 女人精品久久久久毛片| 国产欧美另类精品又又久久亚洲欧美| 亚洲国产精品一区三区| 国产免费视频播放在线视频| 一二三四中文在线观看免费高清| 国产免费一区二区三区四区乱码| 国模一区二区三区四区视频| 日韩免费高清中文字幕av| 少妇人妻精品综合一区二区| 日韩一区二区视频免费看| 高清午夜精品一区二区三区| 五月伊人婷婷丁香| 亚洲四区av| 99久久精品一区二区三区| 久久鲁丝午夜福利片| 久久久午夜欧美精品| 国产男人的电影天堂91| 简卡轻食公司| 十八禁网站网址无遮挡 | 久热久热在线精品观看| 女人久久www免费人成看片| 99热国产这里只有精品6| 精品久久国产蜜桃| 丰满饥渴人妻一区二区三| 欧美日韩国产mv在线观看视频| 美女视频免费永久观看网站| 免费av不卡在线播放| 最新中文字幕久久久久| 高清欧美精品videossex| 精品一区二区三卡| freevideosex欧美| 亚洲欧美清纯卡通| 两个人免费观看高清视频 | 久久久久久人妻| 插逼视频在线观看| 午夜免费鲁丝| 国产爽快片一区二区三区| 人妻制服诱惑在线中文字幕| 视频区图区小说| 午夜91福利影院| 久久久欧美国产精品| 精品人妻偷拍中文字幕| 久久人人爽av亚洲精品天堂| 狠狠精品人妻久久久久久综合| 国产精品人妻久久久久久| 黄片无遮挡物在线观看| 国产免费一区二区三区四区乱码| 国产免费又黄又爽又色| 国产永久视频网站| 亚洲国产精品一区三区| 三上悠亚av全集在线观看 | 欧美xxxx性猛交bbbb| 国产高清三级在线| 大香蕉久久网| 日韩欧美 国产精品| 免费黄频网站在线观看国产| 高清毛片免费看| h日本视频在线播放| 免费人妻精品一区二区三区视频| 又粗又硬又长又爽又黄的视频| 免费不卡的大黄色大毛片视频在线观看| 久久精品久久久久久噜噜老黄| av天堂久久9| 最近的中文字幕免费完整| 中文字幕人妻熟人妻熟丝袜美| 日韩成人伦理影院| 国产成人精品福利久久| 不卡视频在线观看欧美| 国产成人freesex在线| 欧美精品人与动牲交sv欧美| 搡女人真爽免费视频火全软件| 自拍欧美九色日韩亚洲蝌蚪91 | 中文在线观看免费www的网站| 久久精品国产亚洲av天美| 日韩在线高清观看一区二区三区| 久久国产精品大桥未久av | 久热久热在线精品观看| 国产成人精品一,二区| kizo精华| freevideosex欧美| 国产视频首页在线观看| 一本久久精品| 丝袜喷水一区| 免费观看性生交大片5| 久久久久视频综合| 又粗又硬又长又爽又黄的视频| 欧美少妇被猛烈插入视频| 狂野欧美激情性xxxx在线观看| 能在线免费看毛片的网站| 亚洲精品日本国产第一区| 亚洲精品乱码久久久v下载方式| 久久久a久久爽久久v久久| 一个人看视频在线观看www免费| 99视频精品全部免费 在线| 国产女主播在线喷水免费视频网站| 天天操日日干夜夜撸| 亚洲av国产av综合av卡| √禁漫天堂资源中文www| 国产精品熟女久久久久浪| 人妻系列 视频| 国产精品不卡视频一区二区| 国产精品一区二区性色av| 国产精品福利在线免费观看| 桃花免费在线播放| 久久久国产一区二区| 成人特级av手机在线观看| 成人影院久久| 狂野欧美激情性bbbbbb| 欧美精品高潮呻吟av久久| 黄色日韩在线| 日韩伦理黄色片| 日日摸夜夜添夜夜爱| 国产老妇伦熟女老妇高清| 久久精品国产a三级三级三级| 久久精品熟女亚洲av麻豆精品| 寂寞人妻少妇视频99o| 国产一区二区三区av在线| 亚洲自偷自拍三级| 大片免费播放器 马上看| 狂野欧美激情性bbbbbb| 国产免费视频播放在线视频| 大码成人一级视频| 一级毛片电影观看| 国产中年淑女户外野战色| 亚洲国产精品国产精品| 国产亚洲av片在线观看秒播厂| 老司机影院成人| 国产深夜福利视频在线观看| 夜夜爽夜夜爽视频| 91久久精品电影网| 国产成人精品婷婷| 午夜老司机福利剧场| 免费看av在线观看网站| 精品一区二区三卡| 亚洲av日韩在线播放| 国产熟女午夜一区二区三区 | 国产精品偷伦视频观看了| 天堂俺去俺来也www色官网| kizo精华| 亚洲欧洲日产国产| 少妇精品久久久久久久| 这个男人来自地球电影免费观看 | 国产乱来视频区| 人妻夜夜爽99麻豆av| 久久精品久久精品一区二区三区| 国产女主播在线喷水免费视频网站| 午夜久久久在线观看| 建设人人有责人人尽责人人享有的| 久久精品国产亚洲av涩爱| 大码成人一级视频| 久久精品国产鲁丝片午夜精品| 亚洲精品自拍成人| 麻豆成人午夜福利视频| 亚洲成人av在线免费| 在线观看三级黄色| 又爽又黄a免费视频| 大又大粗又爽又黄少妇毛片口| 国产永久视频网站| 国产精品嫩草影院av在线观看| 国产毛片在线视频| 我要看日韩黄色一级片| 日日啪夜夜爽| 亚洲国产av新网站| 久久精品国产鲁丝片午夜精品| 男女啪啪激烈高潮av片| 大香蕉97超碰在线| 制服丝袜香蕉在线| 国产精品熟女久久久久浪| 亚洲,欧美,日韩| 日本猛色少妇xxxxx猛交久久| 婷婷色av中文字幕| 欧美精品人与动牲交sv欧美| 亚洲,一卡二卡三卡| 国产成人午夜福利电影在线观看| 大码成人一级视频| 久久久久久久亚洲中文字幕| 亚洲欧洲国产日韩| 免费黄网站久久成人精品| 久久久午夜欧美精品| 亚洲欧美清纯卡通| 亚洲第一区二区三区不卡| 久久久久久久精品精品| 午夜91福利影院| 色94色欧美一区二区| 在线观看三级黄色| 91精品国产九色| 人人妻人人澡人人爽人人夜夜| 大又大粗又爽又黄少妇毛片口| 精品卡一卡二卡四卡免费| 日日摸夜夜添夜夜爱| 亚洲国产精品成人久久小说| 又黄又爽又刺激的免费视频.| 欧美区成人在线视频| 26uuu在线亚洲综合色| 免费观看性生交大片5| videos熟女内射| 交换朋友夫妻互换小说| 国产男人的电影天堂91| 成年人午夜在线观看视频| 国产日韩欧美在线精品| 国产女主播在线喷水免费视频网站| 亚洲精品国产成人久久av| 香蕉精品网在线| 精品国产露脸久久av麻豆| 99久久中文字幕三级久久日本| 老司机影院成人| 国产精品国产av在线观看| 一区二区三区精品91| 中国国产av一级| 亚洲av成人精品一区久久| 日韩一本色道免费dvd| 精品久久久精品久久久| 久久久久国产网址| av卡一久久| 国产精品.久久久| 亚洲婷婷狠狠爱综合网| 在线观看免费视频网站a站| 日韩欧美 国产精品| 欧美国产精品一级二级三级 | 在线观看av片永久免费下载| av国产精品久久久久影院| 精品视频人人做人人爽| 99久久中文字幕三级久久日本| 国产欧美日韩一区二区三区在线 | 99热网站在线观看| 欧美精品高潮呻吟av久久| 亚洲综合色惰| 在线观看一区二区三区激情| 菩萨蛮人人尽说江南好唐韦庄| 午夜激情福利司机影院| 午夜福利在线观看免费完整高清在| 成人无遮挡网站| 久久女婷五月综合色啪小说| 精品少妇内射三级| 免费av不卡在线播放| 久久99热这里只频精品6学生| 色5月婷婷丁香| 91久久精品国产一区二区三区| 欧美精品高潮呻吟av久久| 97超视频在线观看视频| 少妇精品久久久久久久| 九九久久精品国产亚洲av麻豆| 狠狠精品人妻久久久久久综合| 久久99精品国语久久久| 丝袜脚勾引网站| 亚洲激情五月婷婷啪啪| 女性被躁到高潮视频| 老司机影院毛片| 久久综合国产亚洲精品| 久久久久国产精品人妻一区二区| 色视频在线一区二区三区| 如何舔出高潮| 国产午夜精品久久久久久一区二区三区| 免费看av在线观看网站| 欧美精品一区二区大全| 久久久精品94久久精品| 久久久久久人妻| 国内揄拍国产精品人妻在线| 少妇熟女欧美另类| 亚洲熟女精品中文字幕| 狂野欧美激情性bbbbbb| 永久网站在线| 国产片特级美女逼逼视频| 日韩,欧美,国产一区二区三区| 久久人人爽人人爽人人片va| 久久久国产欧美日韩av| 大码成人一级视频| 精品一品国产午夜福利视频| 免费av中文字幕在线| 精品视频人人做人人爽| 多毛熟女@视频| 日韩成人伦理影院| 精品少妇内射三级| 国产成人精品久久久久久| 国产成人免费无遮挡视频| 国产成人freesex在线| 免费观看性生交大片5| 精品人妻熟女毛片av久久网站| 偷拍熟女少妇极品色| 中文字幕久久专区| 2022亚洲国产成人精品| 日韩 亚洲 欧美在线| 免费看光身美女| 免费观看无遮挡的男女| 亚洲中文av在线| 好男人视频免费观看在线| 国产伦在线观看视频一区| 色哟哟·www| 成人午夜精彩视频在线观看| 美女国产视频在线观看| 十八禁高潮呻吟视频 | 久久国产精品男人的天堂亚洲 | 亚洲av中文av极速乱| 国产精品一区www在线观看| 制服丝袜香蕉在线| 国产 精品1| 免费高清在线观看视频在线观看| 午夜激情福利司机影院| 亚洲一区二区三区欧美精品| 啦啦啦视频在线资源免费观看| 欧美一级a爱片免费观看看| 精品一区二区免费观看| 国产片特级美女逼逼视频| 人妻制服诱惑在线中文字幕| 五月玫瑰六月丁香| 18禁动态无遮挡网站| 肉色欧美久久久久久久蜜桃| 热re99久久国产66热| 看免费成人av毛片| 亚洲av免费高清在线观看| 成年美女黄网站色视频大全免费 | 91精品国产九色| 国产精品秋霞免费鲁丝片| 欧美成人精品欧美一级黄| 哪个播放器可以免费观看大片| 国产无遮挡羞羞视频在线观看| 亚洲精品日韩在线中文字幕| 国产成人aa在线观看| 国产精品国产三级专区第一集| 超碰97精品在线观看| 一区二区三区精品91| 欧美丝袜亚洲另类| 色婷婷av一区二区三区视频| 欧美一级a爱片免费观看看| 一级片'在线观看视频| 亚洲丝袜综合中文字幕| 久久影院123| 一个人看视频在线观看www免费| 日本爱情动作片www.在线观看| 国产精品一区二区三区四区免费观看| 大片免费播放器 马上看| h日本视频在线播放| 国模一区二区三区四区视频| 大话2 男鬼变身卡| 国产精品一区www在线观看| www.av在线官网国产| 精品久久久久久久久亚洲| 人体艺术视频欧美日本| 免费不卡的大黄色大毛片视频在线观看| 妹子高潮喷水视频| 美女大奶头黄色视频| 精品人妻熟女av久视频| 日本黄大片高清| 久久精品国产亚洲网站| 国产精品福利在线免费观看| 国产精品国产三级国产专区5o| 国产黄色免费在线视频| 老司机影院成人| 久久99精品国语久久久| 建设人人有责人人尽责人人享有的| 蜜臀久久99精品久久宅男| 国产成人aa在线观看| 一级,二级,三级黄色视频| 99热6这里只有精品| 亚洲精品久久久久久婷婷小说| 国产精品一二三区在线看| 蜜臀久久99精品久久宅男| 51国产日韩欧美| av免费观看日本| 免费黄频网站在线观看国产| 亚洲精品乱久久久久久| 一个人免费看片子| 夫妻午夜视频| 大香蕉久久网| 国产老妇伦熟女老妇高清| 亚洲av国产av综合av卡| 日本黄色片子视频| 少妇人妻久久综合中文| 国产一区有黄有色的免费视频| 精品久久久久久久久av| 国产在线男女| 一二三四中文在线观看免费高清| 黑丝袜美女国产一区| 简卡轻食公司| 69精品国产乱码久久久| 国产乱人偷精品视频| 女人精品久久久久毛片| 极品少妇高潮喷水抽搐| 精品午夜福利在线看| 日韩欧美一区视频在线观看 | 夜夜爽夜夜爽视频| 久久久久人妻精品一区果冻| 精品人妻熟女毛片av久久网站| 日本爱情动作片www.在线观看| 日本黄色日本黄色录像| 男男h啪啪无遮挡| 日韩欧美 国产精品| 色视频在线一区二区三区| 大香蕉久久网| 国产美女午夜福利| 九九久久精品国产亚洲av麻豆| 男人添女人高潮全过程视频| 亚洲内射少妇av| 久久久久久久久久久免费av| av国产精品久久久久影院| 国产在线视频一区二区| 美女cb高潮喷水在线观看| 亚洲av日韩在线播放| 欧美3d第一页| 99热网站在线观看| 色5月婷婷丁香| 亚洲精品日本国产第一区| 免费高清在线观看视频在线观看| 欧美日韩亚洲高清精品| 中国三级夫妇交换| 国产探花极品一区二区| 精品久久久精品久久久| 成人毛片60女人毛片免费| 国产精品久久久久久精品古装| 极品人妻少妇av视频| 免费人成在线观看视频色| 久久午夜综合久久蜜桃| 老司机影院毛片| 99热6这里只有精品| 欧美bdsm另类| 少妇的逼水好多| 91精品国产国语对白视频| 国产成人精品久久久久久| 欧美丝袜亚洲另类| 又粗又硬又长又爽又黄的视频| 亚洲无线观看免费| 亚洲四区av| 日本wwww免费看| 免费看不卡的av| 最后的刺客免费高清国语| 纵有疾风起免费观看全集完整版| 在线观看www视频免费| 少妇被粗大猛烈的视频| 一级爰片在线观看| 黄色毛片三级朝国网站 | a级毛色黄片| 五月玫瑰六月丁香|