怎樣正確的理解 cosoket

怎樣理解 cosocket

by 院生@ORSF
筆者認爲,cosocket 是 OpenResty 世界中技術、實用價值最高的部分。讓咱們能夠用很是低廉的成本,優雅的姿式,比傳統 socket 編程效率高好幾倍的方式進行網絡編程。不管資源佔用、執行效率、併發數等都很是出色。mysql

魯迅有句名言「其實世界上本沒有路,走的人多了便有了路」,其實對於 cosocket 的中文翻譯貌似我也碰到了相似的問題。當我想給你們一個正面解釋,爬過了官方 wiki 發現,原來做者本人(章亦春)也沒有先給出 cosocket 定義。nginx

看來只能經過一些側面信息,從而讓這條路逐漸的清晰起來。git

cosocket = coroutine + socket
coroutine:協同程序(後面簡稱:協程)
socket:網絡套接字github

OpenResty 中的 cosocket 不只須要協程特性支撐,它還需 nginx 很是最重要的一部分「事件循環回調機制」,兩部分拼在一塊兒才達到了最後的 cosocket 效果,再結合 nginx 自身對各類資源的「小氣」,使得總體加分很多。在 Lua 世界中調用任何一個有關 cosocket 網絡函數內部關鍵調用如圖所示:web

從該圖中咱們能夠看到,用戶的 Lua 腳本每觸發一個網絡操做,都會觸發一個協程的 yield 以及 resume,由於每請求的 Lua 腳本實際上都運行在獨享協程之上,能夠在任何須要的時候暫停本身(yield),也能夠在任何須要的時候被喚醒(resume)。redis

暫停本身,把網絡事件註冊到 Nginx 監聽列表中,並把運行權限交給 Nginx。當有 Nginx 註冊網絡事件達到觸發條件時,喚醒對應的協程繼續處理。sql

依此爲藍板,封裝實現 connect、read、recieve 等操做,造成了你們目前所看到的 cosocket API。mongodb

能夠看到,cosocket 是依賴 Lua 協程 + nginx 事件通知兩個重要特性拼的。編程

從 0.9.9 版本開始,cosocket 對象是全雙工的,也就是說,一個專門讀取的 "light thread",一個專門寫入的 "light thread",它們能夠同時對同一個 cosocket 對象進行操做(兩個 "light threads" 必須運行在同一個 Lua 環境中,緣由見上)。可是你不能讓兩個 "light threads" 對同一個 cosocket 對象都進行讀(或者寫入、或者鏈接)操做,不然當調用 cosocket 對象時,你將獲得一個相似 "socket busy reading" 的錯誤。websocket

因此東西總結下來,到底什麼是 cosocket,中文應該怎麼翻譯,筆者本人都開始糾結了。咱們不妨從另一個角度來審視它,它到底給咱們帶來了什麼。

  • 它是異步的;

  • 它是非阻塞的;

  • 它是全雙工的;

同步與異步解釋:
同步:作完一件事再去作另外一件;
異步:同時作多件事情,某個事情有結果了再去處理。

阻塞與非阻塞解釋:
阻塞:不等到想要的結果我就不走了;
非阻塞:有結果我就帶走,沒結果我就空手而回,總之一句話:爺等不起。

異步/同步是作事派發方式,阻塞/非阻塞是如何處理事情,兩組概念不在同一個層面。

不管 ngx.socket.tcp()、ngx.socket.udp()、ngx.socket.stream()、ngx.req.socket(),它們基本流程都是同樣的,只是一些細節參數上有區別(好比 TCP 和 UDP 的區別)。下面這些函數,都是用來輔助完成更高級的 socket 行爲控制:

  • connect

  • sslhandshake

  • send

  • receive

  • close

  • settimeout

  • setoption

  • receiveuntil

  • setkeepalive

  • getreusedtimes

它們不只完整兼容 LuaSocket 庫的 TCP API,並且仍是 100% 非阻塞的。

對 cosocket 作了這麼多鋪墊,到底他有多麼重要呢?直接看一下官方默認綁定包有多少是基於 cosocket 的:

效仿這些基礎庫的封裝方法,能夠很容易完成不一樣系統或組件的對接,例如 syslog、beanstalkd、mongodb 等,直接 copy 這些組件的通信協議便可。

相關文章
相關標籤/搜索