• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            Fork me on GitHub
            隨筆 - 215  文章 - 13  trackbacks - 0
            <2016年8月>
            31123456
            78910111213
            14151617181920
            21222324252627
            28293031123
            45678910


            專注即時(shí)通訊及網(wǎng)游服務(wù)端編程
            ------------------------------------
            Openresty 官方模塊
            Openresty 標(biāo)準(zhǔn)模塊(Opm)
            Openresty 三方模塊
            ------------------------------------
            本博收藏大部分文章為轉(zhuǎn)載,并在文章開頭給出了原文出處,如有再轉(zhuǎn),敬請保留相關(guān)信息,這是大家對原創(chuàng)作者勞動成果的自覺尊重!!如為您帶來不便,請于本博下留言,謝謝配合。

            常用鏈接

            留言簿(1)

            隨筆分類

            隨筆檔案

            相冊

            Awesome

            Blog

            Book

            GitHub

            Link

            搜索

            •  

            積分與排名

            • 積分 - 215473
            • 排名 - 118

            最新評論

            閱讀排行榜

            http://wiki.jikexueyuan.com/project/openresty/ngx_lua/whats_cosocket.html

            怎樣理解 cosocket

            筆者認(rèn)為,cosocket 是 OpenResty 世界中技術(shù)、實(shí)用價(jià)值最高部分。讓我們可以用非常低廉的成本,優(yōu)雅的姿勢,比傳統(tǒng) socket 編程效率高好幾倍的方式進(jìn)行網(wǎng)絡(luò)編程。無論資源占用、執(zhí)行效率、并發(fā)能力都非常出色。

            魯迅有句名言“其實(shí)世界上本沒有路,走的人多了便有了路”,其實(shí)對于 cosocket 的中文翻譯貌似我也碰到了類似的問題。當(dāng)我想給大家一個(gè)正面解釋,爬過了官方 wiki 發(fā)現(xiàn),原來作者本人(章亦春)也沒有先給出 cosocket 定義。

            看來只能通過一些側(cè)面信息,從而讓這條路逐漸的清晰起來。

            cosocket = coroutine + socket

            coroutine:協(xié)同程序(后面簡稱:協(xié)程) socket:網(wǎng)絡(luò)套接字

            OpenResty 中的 cosocket 不僅需要協(xié)程特性支撐,它還需 Nginx 非常最重要的“事件循環(huán)回調(diào)機(jī)制”,兩部分結(jié)合在一起最終達(dá)到了 cosocket 效果,外加 Nginx 自身對各種資源的“小氣”,LuaJIT 的執(zhí)行效率,最終加分不少。在 Lua 世界中調(diào)用任何一個(gè)有關(guān) cosocket 網(wǎng)絡(luò)函數(shù)內(nèi)部關(guān)鍵調(diào)用如圖所示:

            從該圖中我們可以看到,用戶的 Lua 腳本每觸發(fā)一個(gè)網(wǎng)絡(luò)操作,都會有協(xié)程的 yield 以及 resume,因?yàn)檎埱蟮?Lua 腳本實(shí)際上都運(yùn)行在獨(dú)享協(xié)程之上,可以在任何需要的時(shí)候暫停自己(yield),也可以在任何需要的時(shí)候被喚醒(resume)。

            暫停自己,把網(wǎng)絡(luò)事件注冊到 Nginx 監(jiān)聽列表中,并把運(yùn)行權(quán)限交給 Nginx。當(dāng)有 Nginx 注冊網(wǎng)絡(luò)事件達(dá)到觸發(fā)條件時(shí),喚醒對應(yīng)的協(xié)程繼續(xù)處理。

            以此為藍(lán)板,封裝實(shí)現(xiàn) connect、read、recieve 等操作,形成了大家目前所看到的 cosocket API。

            可以看到,cosocket 是依賴 Lua 協(xié)程 + Nginx 事件通知兩個(gè)重要特性拼的。

            從 0.9.9 版本開始,cosocket 對象是全雙工的,也就是說,一個(gè)專門讀取的 "light thread",一個(gè)專門寫入的 "light thread",它們可以同時(shí)對同一個(gè) cosocket 對象進(jìn)行操作(兩個(gè) "light threads" 必須運(yùn)行在同一個(gè) Lua 環(huán)境中,原因見上)。但是你不能讓兩個(gè) "light threads" 對同一個(gè) cosocket 對象都進(jìn)行讀(或者寫入、或者連接)操作,否則當(dāng)調(diào)用 cosocket 對象時(shí),你將得到一個(gè)類似 "socket busy reading" 的錯(cuò)誤。

            所以東西總結(jié)下來,到底什么是 cosocket,中文應(yīng)該怎么翻譯,筆者本人都開始糾結(jié)了。我們不妨從另外一個(gè)角度來審視它,它到底給我們帶來了什么。

            • 它是同步的;
            • 它是非阻塞的;
            • 它是全雙工的;

            同步與異步解釋: 同步:做完一件事再去做另一件; 異步:同時(shí)做多件事情,某個(gè)事情有結(jié)果了再去處理。

            阻塞與非阻塞解釋: 阻塞:不等到想要的結(jié)果我就不走了; 非阻塞:有結(jié)果我就帶走,沒結(jié)果我就空手而回,總之一句話:爺?shù)炔黄稹?/p>

            異步/同步是做事派發(fā)方式,阻塞/非阻塞是如何處理事情,兩組概念不在同一個(gè)層面。

            無論 ngx.socket.tcp()、ngx.socket.udp()、ngx.socket.stream()、ngx.req.socket(),它們基本流程都是一樣的,只是一些細(xì)節(jié)參數(shù)上有區(qū)別(比如 TCP 和 UDP 的區(qū)別)。下面這些函數(shù),都是用來輔助完成更高級的 socket 行為控制:

            • connect
            • sslhandshake
            • send
            • receive
            • close
            • settimeout
            • setoption
            • receiveuntil
            • setkeepalive
            • getreusedtimes

            它們不僅完整兼容 LuaSocket 庫的 TCP API,而且還是 100% 非阻塞的。

            這里給大家 show 一個(gè)例子,對 cosocket 使用有一個(gè)整體認(rèn)識。

            location /test {     resolver 114.114.114.114;      content_by_lua_block {         local sock = ngx.socket.tcp()         local ok, err = sock:connect("www.baidu.com", 80)         if not ok then             ngx.say("failed to connect to baidu: ", err)             return         end          local req_data = "GET / HTTP/1.1\r\nHost: www.baidu.com\r\n\r\n"         local bytes, err = sock:send(req_data)         if err then             ngx.say("failed to send to baidu: ", err)             return         end          local data, err, partial = sock:receive()         if err then             ngx.say("failed to recieve to baidu: ", err)             return         end          sock:close()         ngx.say("successfully talk to baidu! response first line: ", data)     } }

            可以看到,這里的 socket 操作都是同步非阻塞的,完全不像 node.js 那樣充滿各種回調(diào),整體看上去非常簡潔優(yōu)雅,效率還非常棒。

            對 cosocket 做了這么多鋪墊,到底他有多么重要呢?直接看一下官方默認(rèn)綁定包有多少是基于 cosocket 的:

            效仿這些基礎(chǔ)庫的實(shí)現(xiàn)方法,可以完成不同系統(tǒng)或組件的對接,例如 syslog、beanstalkd、mongodb 等,直接 copy 這些組件的通訊協(xié)議即可。

            posted on 2018-06-22 09:17 思月行云 閱讀(2984) 評論(0)  編輯 收藏 引用 所屬分類: Nginx\Openresty
            久久婷婷色香五月综合激情| 日本久久久精品中文字幕| 伊人色综合久久天天人守人婷 | 7777精品久久久大香线蕉| 久久久久人妻一区精品性色av| 国产精品久久自在自线观看| 久久午夜福利电影| 婷婷伊人久久大香线蕉AV | av无码久久久久久不卡网站| 欧美久久综合性欧美| 日产精品久久久久久久| 亚洲伊人久久大香线蕉苏妲己| 久久福利资源国产精品999| 91精品国产91久久久久久蜜臀| 99精品久久久久久久婷婷| 久久精品国产亚洲av瑜伽| 国产午夜精品久久久久免费视| 性做久久久久久久久久久| 国产69精品久久久久99| 91精品国产9l久久久久| 日本五月天婷久久网站| 久久久久国产精品三级网| 亚洲成色999久久网站| 久久精品天天中文字幕人妻 | 欧美久久精品一级c片片| 无码久久精品国产亚洲Av影片| 伊人久久国产免费观看视频| 青青青青久久精品国产| 精品久久久久久久久中文字幕| 午夜精品久久久久久99热| 97久久国产露脸精品国产| 色8激情欧美成人久久综合电| 久久免费视频一区| 久久九九免费高清视频| 久久精品人妻一区二区三区| 日本精品久久久久中文字幕8| 久久99国产精品99久久| 久久九九全国免费| 国产99久久九九精品无码| 99精品久久久久久久婷婷| 久久精品国产精品亚洲|