一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

云風(fēng)的 BLOG: 開(kāi)發(fā)筆記(25) : 改進(jìn)的 RPC

 quasiceo 2016-07-17

開(kāi)發(fā)筆記(25) : 改進(jìn)的 RPC

自從動(dòng)了重新實(shí)現(xiàn) skynet 的念頭,最近忙的跟狗一樣。每天 10 點(diǎn)醒來(lái)就忙著寫代碼,一句廢話都不想說(shuō),一直到晚上 11 點(diǎn)回家睡覺(jué)。連續(xù)干了快一個(gè)月了。

到昨天,終于把全部代碼基本移植到了新框架下,正常啟動(dòng)了起來(lái)。這項(xiàng)工作算是搞一段落。慶幸的是,我這個(gè)月的工作,并沒(méi)有影響到其他人對(duì)游戲邏輯的開(kāi)發(fā)。只是我單方面的同步不斷新增的邏輯邏輯代碼。

Skynet 的重寫,實(shí)際上在半個(gè)月前就已經(jīng)完成。那時(shí),已經(jīng)可以用新的服務(wù)器承載原有的獨(dú)立的用戶認(rèn)證系統(tǒng)了。那么后半個(gè)月的這些瑣碎工作,其實(shí)都是在移植那些游戲邏輯代碼。

在 Skynet 原始設(shè)計(jì)的時(shí)候,api 是比較簡(jiǎn)潔的,原則上講,是可以透明替換。但實(shí)際上,在使用中,增加了許多陰暗角落。一些接口層的小變動(dòng),增加的隱式特性,使得并不能百分百兼容。另外,原來(lái)的一些通訊協(xié)議和約定不算太合理,在重新制作時(shí),我換掉了部分的方案,但需要編寫一個(gè)兼容的鏈路層。

比如:以前,我們把通過(guò) tcp 接入的 client 和 server 內(nèi)部同進(jìn)程內(nèi)的服務(wù)等同處理。認(rèn)為它們都是通過(guò)相同的二進(jìn)制數(shù)據(jù)包協(xié)議通訊。但是,同進(jìn)程內(nèi)的服務(wù)間通訊明顯是可以被優(yōu)化的,他們可以通過(guò) C 結(jié)構(gòu)而不是被編碼過(guò)的數(shù)據(jù)包交換信息,并可以做到由發(fā)起請(qǐng)求方分配內(nèi)存,接受方釋放內(nèi)存,減少無(wú)謂的數(shù)據(jù)復(fù)制。在老的版本中,強(qiáng)行把兩者統(tǒng)一了起來(lái),失去了許多優(yōu)化空間。在新版本里,我增加了較少的約定,修改了一點(diǎn)接口,就大幅度提升了進(jìn)程內(nèi)服務(wù)間信息交換的效率。

另一方面,一旦固定采用單進(jìn)程多線程方案,之前的多進(jìn)程共享數(shù)據(jù)的模塊就顯得過(guò)于厚重了。新的方案更為輕量,也更適合 lua 使用。這項(xiàng)工作在上一篇 blog 中提到過(guò)。這和 skynet 的重寫原本是兩件事情,但我強(qiáng)行放在一起做遷移,增加了許多難度。但考慮到,原本我就需要梳理一次我們的全部服務(wù)器端代碼(包括大量我沒(méi)有 review 過(guò)的),就把這兩件事情同時(shí)做了。

在這個(gè)過(guò)程中,可以剔除許多冗余代碼,去掉一些我們?cè)?jīng)以為會(huì)用到,到實(shí)際廢棄的模塊。徹底解決一些歷史變更引起的問(wèn)題。過(guò)程很痛苦,但很值得。新寫的代碼各種類型檢查更嚴(yán)格,就此發(fā)現(xiàn)了老的邏輯層代碼中許多隱藏的 bug 。一些原有用 erlang 實(shí)現(xiàn)的模塊,重新用 lua 實(shí)現(xiàn)了一遍,混合太多語(yǔ)言做開(kāi)發(fā),一些很疼的地方,經(jīng)歷過(guò)的人自然清楚。以后如非必要,盡量不用 lua 之外的語(yǔ)言往這個(gè)系統(tǒng)里增加組件了。

btw, 新系統(tǒng)還沒(méi)有經(jīng)過(guò)壓力測(cè)試。一些優(yōu)化工作也沒(méi)有展開(kāi)。但初步看起來(lái),還是卓有成效的。至少,改進(jìn)了數(shù)據(jù)共享模塊,以及提出許多冗余后,整個(gè)系統(tǒng)的內(nèi)存占用量下降到原來(lái)的 1/5 不到。CPU 占用率也有大幅度的下降。當(dāng)然,這幾乎不關(guān) C 還是 Erlang 做開(kāi)發(fā)的事,重點(diǎn)得益于經(jīng)過(guò)半年的需求總結(jié),以及我梳理了大部分模塊后做的整體改進(jìn)。


今天想重點(diǎn)談?wù)勏旅嬉欢螘r(shí)間我希望做的改進(jìn)。是關(guān)于服務(wù)間 RPC 的。

目前能找到年初的一篇記錄 ,經(jīng)過(guò)大半年的演化,已經(jīng)不完全是記錄的那個(gè)樣子了。但大體上的思路一直沿用著。

這個(gè)方案的優(yōu)點(diǎn)在于,使用通用的 google proto buffer 協(xié)議做嚴(yán)格的 RPC 協(xié)議定義。但缺點(diǎn)也是很明顯的,最麻煩的地方在于,在一個(gè)需要大量服務(wù)間交互的應(yīng)用環(huán)境內(nèi),新實(shí)現(xiàn)一組 RPC 需要做大量的工作,這對(duì)程序員是一個(gè)負(fù)擔(dān)。

程序員需要:一,在一個(gè)協(xié)議描述文件中,定義出協(xié)議名以及對(duì)應(yīng)的協(xié)議號(hào);二,在對(duì)應(yīng)名字的 proto buffer 文件中,定義出協(xié)議對(duì)應(yīng)的輸入?yún)?shù)和輸出參數(shù)列表;三,在特定的位置,創(chuàng)建特定名字的 lua 源文件,在里面實(shí)現(xiàn)特定名字的協(xié)議過(guò)程。

有時(shí),這個(gè)流程是好事,它能夠在 lua 這種弱類型系統(tǒng)中,輔助檢查出潛在的錯(cuò)誤;但對(duì)開(kāi)發(fā)效率的影響也是顯著的。同時(shí),這個(gè)長(zhǎng)長(zhǎng)的流程,以及對(duì)應(yīng)的各種編解碼工作,也引起了部分性能損失。

我希望在以后的系統(tǒng)中,引入更為方便簡(jiǎn)潔的 RPC 機(jī)制。

簡(jiǎn)單的說(shuō),我的最終需求是:程序員不需要為 RPC 調(diào)用和本地調(diào)用寫不同的代碼。程序員需要心里了解一次調(diào)用是遠(yuǎn)程調(diào)用,但他不必為實(shí)現(xiàn)這些方法做額外的事情。在他不需要把一些方法定義為遠(yuǎn)程方法時(shí),只需要把源文件換個(gè)位置,或是重新組織一下代碼加載的過(guò)程,就可以輕松的完成。遠(yuǎn)程對(duì)象和本地對(duì)象對(duì)調(diào)用者來(lái)說(shuō),也應(yīng)該盡可能的透明。

我今天把這個(gè)想法基本實(shí)現(xiàn)了。

經(jīng)過(guò)重寫 skynet ,我對(duì)這類事務(wù)的處理稍微建立了一點(diǎn)模式。首先,應(yīng)該把同進(jìn)程內(nèi)的服務(wù)間 RPC 調(diào)用同跨進(jìn)程的調(diào)用區(qū)分開(kāi)。

跨進(jìn)程(跨機(jī))調(diào)用,可以通過(guò)增加一個(gè)特定的服務(wù),在鏈路層把它們接起來(lái)即可。應(yīng)該專心實(shí)現(xiàn)同進(jìn)程內(nèi),不同服務(wù)間的高性能 RPC 才是重點(diǎn)。等這一步完成,只需要為異地對(duì)象建立一個(gè)本地副本做消息中轉(zhuǎn)就夠了。

我們應(yīng)該專心考慮 Lua State 實(shí)現(xiàn)的服務(wù),而不必過(guò)于考慮不同語(yǔ)言間的 RPC 調(diào)用。一起以 Lua 為主語(yǔ)言來(lái)考慮功能。

首先我引入了之前實(shí)現(xiàn)好的 Lua 數(shù)據(jù)序列化模塊 。并對(duì)它做了一些改動(dòng) ,合并到 skynet 項(xiàng)目中。

這個(gè)改動(dòng)是,讓序列化模塊底層理解遠(yuǎn)程對(duì)象。增加了一個(gè)遠(yuǎn)程對(duì)象類型。因?yàn)樗械?Lua State 其實(shí)是在一個(gè)系統(tǒng)進(jìn)程內(nèi)的,數(shù)據(jù)交換工作通過(guò) Lua 的 C 擴(kuò)展庫(kù)就可以完成。在同個(gè)進(jìn)程內(nèi),每個(gè)遠(yuǎn)程對(duì)象都有唯一的數(shù)字 id 。傳遞遠(yuǎn)程對(duì)象,只需要傳遞這個(gè) id 即可。

每個(gè) Lua State 中,維護(hù)一張表,記錄所有在這個(gè) State 中創(chuàng)建出來(lái)的遠(yuǎn)程對(duì)象,以及對(duì)應(yīng)的 id 。在序列化模塊中,一旦發(fā)現(xiàn)提到的遠(yuǎn)程對(duì)象是自己進(jìn)程內(nèi)的,就自動(dòng)翻譯成本地對(duì)象。

序列化模塊本身不處理任何遠(yuǎn)程對(duì)象的特殊行為。它把這個(gè)工作交給外部注入。skynet 模塊把遠(yuǎn)程調(diào)用的方法注入到遠(yuǎn)程對(duì)象中。

所謂 RPC 調(diào)用,就是一個(gè)遠(yuǎn)程對(duì)象加一個(gè)方法名,加上若干參數(shù)。通過(guò)序列化方法,打包成一個(gè)數(shù)據(jù)包,查詢到遠(yuǎn)程對(duì)象所在的服務(wù)地址,發(fā)送過(guò)去即可。

而所謂遠(yuǎn)程對(duì)象,其實(shí)只是在 lua table 里設(shè)置一個(gè)叫 __remote 的字段,設(shè)入數(shù)字 handle 就可以讓序列化模塊識(shí)別了。

這個(gè)模塊并不復(fù)雜,我實(shí)現(xiàn)在了 skynet.lua 中,不到 100 行代碼。

作為一個(gè)范例,我實(shí)現(xiàn)了一個(gè)叫 root 的遠(yuǎn)程對(duì)象,讓它在一個(gè)獨(dú)立服務(wù) 中啟動(dòng)。它可以提供一個(gè)基本的名字服務(wù)。在一個(gè)簡(jiǎn)單的 test 程序 中,我們可以看到一個(gè)遠(yuǎn)程對(duì)象把自己注冊(cè)到 root 里,別的服務(wù)從 root 拿到這個(gè)對(duì)象,就可以向本地對(duì)象一樣調(diào)用上面的方法了。

云風(fēng) 提交于 August 29, 2012 03:44 PM | 固定鏈接

Comments

靈活與不安全共存,不知道外掛檢測(cè)的代價(jià)有多大?

Posted by: Anonymous | (9) September 4, 2012 02:12 PM

RPC本來(lái)就是remote,沒(méi)有必要再把inner-proc的概念歸并到RPC,remote的數(shù)據(jù)串化肯定要值拷貝。邏輯多線程并發(fā)服務(wù)器,并發(fā)的是IO以及針對(duì)所有邏輯實(shí)體的IO觸發(fā),而針對(duì)單個(gè)邏輯實(shí)體可以采取順序執(zhí)行(當(dāng)前只能被一根線程執(zhí)行)。這也就是erlang里的概念吧,Actor Model。

Posted by: tinyzhang | (8) September 1, 2012 02:48 PM

一定要用RPC么,見(jiàn)識(shí)過(guò)的項(xiàng)目代碼都木有用到,去開(kāi)發(fā)這個(gè)是不是有點(diǎn)兒奢侈?

Posted by: pass86 | (7) August 31, 2012 11:50 PM

越來(lái)月看不動(dòng)

Posted by: ctx | (6) August 30, 2012 02:10 PM

年初的時(shí)候看到描述的rpc,當(dāng)時(shí)覺(jué)得為每個(gè)rpc調(diào)用都定義一個(gè)proto buffer的協(xié)議,是為支持跨語(yǔ)言的rpc調(diào)用。

我是覺(jué)得如果rpc只在lua里面進(jìn)行使用,那只需要定義一個(gè)對(duì)lua數(shù)據(jù)類型描述的協(xié)議就行了,這樣對(duì)rpc的編寫者/調(diào)用者來(lái)說(shuō)都是透明的。

Posted by: 呂子熏 | (5) August 30, 2012 01:38 PM

我也感覺(jué)profbuf實(shí)現(xiàn)起來(lái)有些麻煩,以及效率問(wèn)題,所以我的RPC方案就是序列化+類型反射

Posted by: qele | (4) August 30, 2012 01:38 PM

一直排斥將rpc和本地調(diào)用透明化,說(shuō)不上理由,只是覺(jué)得味道不對(duì)吧。

Posted by: zcpro | (3) August 29, 2012 06:17 PM

個(gè)人覺(jué)得rpc主要的設(shè)計(jì)要點(diǎn)很簡(jiǎn)單,第一個(gè)是網(wǎng)絡(luò)io與應(yīng)用層分離,這樣多個(gè)應(yīng)用邏輯可以復(fù)用io(socket),第二個(gè)是協(xié)議分層設(shè)計(jì),底層協(xié)議需要嚴(yán)格的變動(dòng)很小的邏輯,上層應(yīng)用層就可以靈活多變了。
我覺(jué)得你沒(méi)有關(guān)注第二點(diǎn),沒(méi)做分層,只在嚴(yán)格-寬松之間進(jìn)行了衡量,容易兩極化。

Posted by: 劉聰 | (2) August 29, 2012 06:00 PM

什么時(shí)候,終結(jié)者病毒會(huì)自主產(chǎn)生呢

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    亚洲一区二区精品久久av | 91免费一区二区三区| 亚洲一区二区三区三区| 懂色一区二区三区四区| 亚洲视频在线观看免费中文字幕| 午夜精品成年人免费视频| 国产又粗又长又爽又猛的视频| 欧美黑人在线精品极品| 欧美日韩亚洲巨色人妻| 日本精品视频一二三区| 国产又粗又黄又爽又硬的| 少妇熟女精品一区二区三区| 日韩黄色大片免费在线| 在线观看视频日韩精品| 在线观看国产午夜福利| 一区二区三区亚洲国产| 亚洲香艳网久久五月婷婷| 国产精品午夜视频免费观看| 亚洲黄片在线免费小视频| 婷婷亚洲综合五月天麻豆| 欧美亚洲三级视频在线观看| 午夜国产福利在线播放| 高清在线精品一区二区| 91人妻久久精品一区二区三区 | 国产熟女一区二区三区四区| 亚洲av又爽又色又色| 亚洲精品深夜福利视频| 高跟丝袜av在线一区二区三区| 日韩欧美一区二区黄色 | 欧美日韩亚洲精品内裤| 日韩精品一区二区三区含羞含羞草| 99久久精品国产日本| 日韩午夜福利高清在线观看| 国产对白老熟女正在播放| 91人妻人人精品人人爽| 97人妻精品一区二区三区免| 日韩精品视频免费观看| 丰满熟女少妇一区二区三区| 不卡免费成人日韩精品| 日韩一级毛一欧美一级乱| 观看日韩精品在线视频|