老婆一塊兒來上海工做,每月消費立立刻來了,作了一個android記帳應用,把每筆賬都實時記錄進去。開始是單機版的,只能兩我的分別記,月底再merge一下。恰好有一臺阿里雲的ECS,因而準備升級爲帶服務端版的,通訊協議能夠直接用android的http庫,但考慮到愈來愈多的app應用都開始走私有協議(好比原來運維的手機淘寶),定製一套個性化的協議自己就比較麻煩,擴展性也很差,因而想到了protobuf-rpc。但還須要一個成熟的network frame(手寫的話不知道要搞到何時),因而想到了nginx。android
github地址:https://github.com/zmkeil/nrpcnginx
Nginx是一款高性能的web服務器,清晰的代碼結構及優良的模塊化,很是易於擴展爲各類各樣的網絡服務器。其構建的基礎組件如內存池,鏈表等及event,network接口所有包含在core/event目錄中,並且性能很是高,直接面向互聯網服務,網絡IO方面沒有任何問題。git
爲了保證對nginx的修改最少,我將RPC框架當成nginx的一個模塊,啓動時將它動態加入到nginx的模塊列表(ngx_modules[])中去。github
另外提供很是簡易的編程接口(和大部分RPC實現相似),監聽端口、protobuf service等信息均可以在應用程序初始化階段經過編程接口來設置,全部初始化完成以後,應用程序能夠直接調用server.start()來啓動服務,這個方法其實是調用nginx的main函數(更名爲ngx_start),而後就進入了nginx的正常流程,初始化全部模塊(包括咱們的NRPC模塊),而後打開全部監聽端口,並啓動work進程,開始接受request。主進程自動進入deamon模式,而且設置相應的信號處理程序。因此應用程序在調用完server.start()後,就能夠直接return了(其實是不會執行到的)。web
此外,nginx的core、event模塊的配置,能夠直接用nginx.conf文件來配置,就像原汁原味的nginx同樣。編程
啓動過程以下圖所示:服務器
右側是簡易的應用程序流程:網絡
一、首先建立一個server,包括一些初始化工做session
二、而後經過server.push_service_set()接口,爲該server添加一個service_set,並配置其監聽地址,通常爲「0.0.0.0:port」。同時,會將該service_set信息添加到全局變量nrpc_listens[]中去。併發
三、而後向該service_set中添加service。這裏對service使用了兩層邏輯的管理:一個監聽端口對應一個service_set,一個service_set能夠包含多個service。由於主要是考慮面向公網應用,服務器資源寶貴,能夠同時提供多種服務。
四、最後經過server.start()啓動服務,如前所述,這回調用nginx的啓動流程,打開全部監聽端口。這裏設置了nrpc的ls->handler = ngx_nrpc_init_connection,後續全部nrpc的請求入口就從這裏開始。
該模塊實現了RPC的基本功能,好比端口配置,service添加/刪除,超時設置,local_session_context等。另外還有一些經常使用的功能。
1.繼承了nginx的core、event模塊的全部特性
2.鏈接保持及複用
3.QPS併發限流
服務端流程以下圖:
大體流程如上圖:
一、第一行3個函數和第三行1個函數,都是經過nginx的event、network接口接收/發送請求,nginx是徹底非阻塞的事件模型,寫起來和通常的同步寫法有些區別
二、中間一行的函數則是實現了protobuf的框架接口。這裏提供的多種protocol,主要是針對輸入的,目前實現的只接受protobuf格式的請求,考慮到http的通用性,之後會實現接口http格式的請求,內部轉化成protobuf格式,返回response時再轉化成http格式。
利用pthread實現,和服務端是隔離的,代碼單獨組織在channel.cpp、connection_pool.cpp和controller.cpp(和服務端共用的)中,一些特性以下:
1.提供同步、異步兩種模式,用戶能夠串行發請求,並同步處理返回結果;也能夠併發發請求,異步處理結果,並提供join功能
2.自動重試機制,但RPC失敗時,客戶端會自動重試屢次(可配置),不須要用戶代碼作任何處理
3.實現一個簡單的鏈接池,能夠複用鏈接
客戶端流程以下圖:
github中的sample有示例代碼,詳細的使用方法README中有介紹,https://github.com/zmkeil/nrpc。
這算是個人第一個開源項目,代碼有不少不嚴謹的地方,歡迎指正,歡迎使用。
另外特別以此記念爺爺,爺爺去世有兩週了,在這個臨近新春的寒冷的四九天裏,是遺憾吧,或是解脫吧。爺爺生於舊社會,經歷過軍閥、日本侵華、文革,一輩子勤勤懇懇,和睦待人,村裏造橋鋪路,春耕秋收,都事事爲先,受人尊敬。記得初中時,我有一次做文比賽獲得一等獎,題目是第一次XX,我寫的是第一次寫毛筆字,爺爺爲我調墨鋪紙。