1,2,3...Skynet框架

一:啟動過程,參考http://www.itdecent.cn/p/f7e59559a975

通過解析配置文件來啟動服務(wù)器

例如簡單的一個命令./skynet examples/config,就是解析config文件配置服務(wù)器的參數(shù)與相關(guān)進(jìn)程的啟動順序,這可以滿足我們對服務(wù)器的需要。

看我當(dāng)時給出的注釋:


這個配置文件實(shí)際上就是一段 lua 代碼,通常,我們以 key = value 的形式對配置項(xiàng)賦值。從注釋可以看出來。

skynet 在啟動時,會讀取里面必要的配置項(xiàng),并將配置項(xiàng)以字符串形式保存在 skynet 內(nèi)部的 env 表中。這些配置項(xiàng)可以通過 skynet.getenv 獲取。


下面看看bootstrap要啟動的是哪些服務(wù)

首先是

skynet.launch()在manager.lua中

先啟動launcher服務(wù)。skynet.launch(...)主要通過skynet.core模塊中的command()函數(shù)執(zhí)行可變參數(shù)中的服務(wù),并返回為服務(wù)開辟的地址。skynet.name()函數(shù)其實(shí)就是給返回的地址起一個名字,這個函數(shù)里面會先調(diào)用globalname()函數(shù)去判斷在全局表中是否有這個名字,有的話就直接為這個地址設(shè)置名字。沒有的話還要調(diào)用harbor.lua模塊中的harbor.globalname函數(shù)去注冊地址,設(shè)置名字。


下面要判斷harbor是0還是非0,因?yàn)檫@個會決定是否啟動單節(jié)點(diǎn)模式下。此時 master 和 address 以及 standalone 都不能設(shè)置??梢詮拇a中看出來


第一句就是斷言standalone 等于nil,然后在全局表中設(shè)置standalone為true。然后就是調(diào)用pcall函數(shù)去調(diào)用skynet.newservice()函數(shù)啟動cdummy服務(wù)。問題是這是一個什么服務(wù)??碿dummy.lua模塊中的start()函數(shù),主要是調(diào)用skynet.dispatch函數(shù)調(diào)度新服務(wù)的啟動,這個服務(wù)好像什么也沒做?最后返回一個服務(wù)地址,并為該地址命名cslave (也就是說這個cslave服務(wù)無事可做?)

非0


啟動cmaster服務(wù),主要負(fù)責(zé)監(jiān)聽端口號,并負(fù)責(zé)握手連接??纯丛创a

調(diào)用socket.listen()函數(shù)監(jiān)聽master_addr,master_addr是standalone的地址。socket.listen()函數(shù)其實(shí)調(diào)用了socketdriven C函數(shù)(在lua-socket.c中的luaopen_socketdriver函數(shù),返回LUAMOD_API)中的llisten()函數(shù),監(jiān)聽成功就返回1。接著cmaster會調(diào)用socket.start()函數(shù)。

這個master_addr是0.0.0.0:2013中心節(jié)點(diǎn)

這個函數(shù)調(diào)用socketdriver的lstart()函數(shù),做的工作是獲取skynet中socket的上下文,為下面調(diào)用connect()函數(shù)做準(zhǔn)備,這個connect函數(shù)會調(diào)用作為參數(shù)傳進(jìn)來的回調(diào)函數(shù),用的是tcp連接。connect函數(shù)會喚醒一個休眠的協(xié)程完成連接操縱,返回連接id。

接下來會啟動cslave服務(wù)。這個服務(wù)做的事情有點(diǎn)多,主要是與cmaster建立連接。先看看他拿了一些配置項(xiàng)

master地址,就是我們認(rèn)為設(shè)置要連接的地址;

slave_address地址,這里的配置文件設(shè)置的地址與master一樣,端口號不一樣,不是太懂

可以看到開始監(jiān)聽slave_address地址。接著調(diào)用socket.open()函數(shù)連接到master_addr

driver.connect()函數(shù)返回的是socket池中的id,表示連接的套接字已經(jīng)設(shè)置好,可以進(jìn)行連接。接著connect()函數(shù)就喚醒休眠的協(xié)程找到socket池中的套接字進(jìn)行連接。這里會回調(diào)cmaster中start函數(shù)里面的回調(diào)函數(shù)。cmaster會拿到driver.connect()函數(shù)返回的socket池中的id,然后準(zhǔn)備與該套接字進(jìn)行連接


然后會進(jìn)行握手嘗試,返回的是slave_id和slave_addr。handshake()函數(shù)做的事情是調(diào)用read_pakage()函數(shù),從之前的套接字中讀取數(shù)據(jù),也就是cslave中driver.connect()返回的socket池中的id,拿到要連接的slave_id, slave_addr,然后判斷這個slave是否已經(jīng)注冊,沒有的話就調(diào)用report_slave()函數(shù)向slave服務(wù)發(fā)送handshake回應(yīng)

然后注冊slave_node。如果注冊成功的話,為slave創(chuàng)建監(jiān)控進(jìn)程monitor_slave

注意handshake過程中cslave也對cmaster作出回應(yīng)

這里也可以看到slave也為master創(chuàng)建monitor_master()進(jìn)程。這里是雙方相互監(jiān)聽,相互通過套接字讀取數(shù)據(jù)


再回到bootstrap.lua中,還要開啟datacenterd服務(wù)。來看看這個服務(wù)做了什么。

這個服務(wù)大概就是調(diào)用skynet.dispatch()函數(shù)通過解析命令對數(shù)據(jù)進(jìn)行讀寫更新。

最后還開啟了一個service_mgr服務(wù),注冊.service服務(wù)。

然后就是我們自己定義的main或start服務(wù)了。


sprotoloader.lua 讀取協(xié)議文件并注冊該協(xié)議,通過下標(biāo)加載協(xié)議。

proto.lua是客戶端跟服務(wù)器之間溝通的消息格式,也就是一個協(xié)議。

協(xié)議的解析的實(shí)現(xiàn)在sprotoparser.lua,有點(diǎn)難看懂,后面看懂了再說

sproto.lua是跟具體的package建立協(xié)議

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容