版本號 | 修訂日期 | 修訂人 | 內(nèi)容 |
---|---|---|---|
0.0.1.0 | 2018-01-27 | 厲華 | 創(chuàng)建 |
- 1. 總體架構(gòu)
- 2. 架構(gòu)模塊
1. 總體架構(gòu)
IBP體系架構(gòu)采用全解耦式設(shè)計垫言。
1.1. 注冊節(jié)點
注冊節(jié)點主要部署注冊中心悯衬。
注冊中心(ibms)
注冊節(jié)點主要負(fù)責(zé)接受管理自身客戶端連接挤渔,接收處理維護(hù)集群配置指令抄伍、接收觸發(fā)自動推導(dǎo)下發(fā)配置和應(yīng)用包、接收觸發(fā)保存配置到磁盤等集晚;接受各通訊節(jié)點注冊代理連接懊悯,被索取本節(jié)點和關(guān)聯(lián)節(jié)點配置蜓谋,接收訂閱配置變動事件;接受通訊服務(wù)端平臺連接炭分,建立心跳監(jiān)測桃焕。
全體系只有一個注冊中心實例,由于松耦合架構(gòu)捧毛,即使異常也不會對當(dāng)時和后續(xù)服務(wù)請求產(chǎn)生影響观堂,也無需引入選舉等復(fù)雜算法操控。唯一要注意的是要做好落地配置冗余呀忧,額外設(shè)置遠(yuǎn)程落地集群配置副本师痕。
1.2. 通訊節(jié)點
眾多通訊節(jié)點組成節(jié)點網(wǎng),交易請求從一個節(jié)點到另一個節(jié)點而账。通訊節(jié)點既可以有客戶端胰坟,也可以有服務(wù)端,或者同時有客戶端和服務(wù)端福扬。
注冊代理
每個通訊節(jié)點內(nèi)有一個注冊代理腕铸,負(fù)責(zé)連接注冊中心取回屬于本節(jié)點和關(guān)聯(lián)節(jié)點的配置惜犀,構(gòu)建本地索引共享內(nèi)存和配置共享內(nèi)存,并與注冊中心保持連接訂閱配置變動事件狠裹。
索引共享內(nèi)存和配置共享內(nèi)存被本地通訊客戶端API和通訊服務(wù)端平臺連接虽界,通過注冊代理API訪問其中配置信息。索引共享內(nèi)存KEY對外公開涛菠,配置共享內(nèi)存KEY私有莉御,存放在索引共享內(nèi)存中,本地應(yīng)用先連接索引共享內(nèi)存即可知道當(dāng)前最新配置共享內(nèi)存KEY連接之俗冻。配置共享內(nèi)存內(nèi)布局被精心設(shè)計成高效查詢數(shù)據(jù)結(jié)構(gòu)礁叔。
注冊代理一旦得到新配置,構(gòu)建新配置共享內(nèi)存迄薄,然后把索引共享內(nèi)存指向新配置共享內(nèi)存琅关。注冊代理維護(hù)著一組配置共享內(nèi)存信息鏈,并周期性檢查老版配置共享內(nèi)存如果沒有其它應(yīng)用連接就刪除清理讥蔽。通訊客戶端API和通訊服務(wù)端平臺在空閑時會調(diào)用注冊代理API檢查轉(zhuǎn)連最新配置共享內(nèi)存涣易。
注冊代理處理新配置時也會檢查應(yīng)用包簽名和本地簽名是否一致,如果不一致則聯(lián)動向注冊中心請求下發(fā)新版應(yīng)用包冶伞。
通訊客戶端API除了保存?zhèn)蓽y到的通訊服務(wù)端平臺負(fù)載覆寫到配置項內(nèi)存外新症,沒有其它寫操作,前者采用CAS方式更新數(shù)據(jù)响禽,如果失敗則放棄更新徒爹。
所以配置共享內(nèi)存無需任何鎖保護(hù),這能完全避免對并發(fā)處理的性能損耗芋类。
通訊客戶端API
通訊節(jié)點內(nèi)可部署通訊客戶端API隆嗅,提供給客戶端應(yīng)用調(diào)用以發(fā)起交易。
通訊客戶端API支持長短環(huán)境句柄侯繁、長短連接榛瓮、并行交易等多種場景選用;支持交易附帶多個請求文件和多個響應(yīng)文件巫击;支持通訊失敗時細(xì)粒度識別交易是否可疑。
通訊客戶端API在并行交易基礎(chǔ)上實現(xiàn)了分布式事務(wù)二階段提交精续。
通訊客戶端API在處理交易時會請求服務(wù)端附帶負(fù)載信息回來坝锰,保存在配置共享內(nèi)存供本節(jié)點所有通訊客戶端API下次交易時負(fù)載均衡挑選服務(wù)端用。
通訊服務(wù)端平臺
通訊節(jié)點內(nèi)可部署通訊服務(wù)端平臺重付,負(fù)責(zé)接受通訊客戶端發(fā)起交易的后端業(yè)務(wù)邏輯處理顷级。
通訊服務(wù)端平臺進(jìn)程結(jié)構(gòu)一般由管理進(jìn)程和一組工作進(jìn)程組成。選用多進(jìn)程而非多線程是考量當(dāng)業(yè)務(wù)邏輯導(dǎo)致系統(tǒng)異常時的隔離性确垫。
通訊服務(wù)端平臺支持三種服務(wù)模式:即時創(chuàng)建短進(jìn)程模式弓颈,管理進(jìn)程接受到交易時創(chuàng)建工作進(jìn)程處理交易帽芽,處理完銷毀工作進(jìn)程,適合在系統(tǒng)資源較少的環(huán)境翔冀;靜態(tài)進(jìn)程池模式导街,管理進(jìn)程啟動時創(chuàng)建一組工作進(jìn)程,以Leader-follow方式在ACCEPT臨界區(qū)保護(hù)下爭奪交易連接并處理之纤子;動態(tài)進(jìn)程池模式在靜態(tài)進(jìn)程池模式上擁有根據(jù)當(dāng)前負(fù)載自動伸縮工作進(jìn)程池搬瑰。
通訊服務(wù)端平臺進(jìn)程池工作進(jìn)程處理可配置數(shù)量交易后自動重啟,以周期性回收泄露內(nèi)存控硼、描述字泽论,解決業(yè)務(wù)邏輯代碼缺陷造成的資源泄露,使工作進(jìn)程池始終保持健康卡乾。
通訊服務(wù)端平臺管理進(jìn)程監(jiān)控工作進(jìn)程工作時長翼悴,如發(fā)現(xiàn)有業(yè)務(wù)邏輯代碼死循環(huán)、處理時間過長幔妨、僵死等情況時及時清退工作進(jìn)程鹦赎,使工作進(jìn)程池始終保持活力。
通訊服務(wù)端平臺通過加載包含業(yè)務(wù)邏輯的動態(tài)庫(應(yīng)用包)實現(xiàn)業(yè)務(wù)處理陶冷,動態(tài)庫使用后保存打開句柄到緩存池中供下次直接使用以提高性能钙姊,同時注冊文件系統(tǒng)主動通知監(jiān)控磁盤文件變動。
2. 架構(gòu)模塊
2.1. 集群配置結(jié)構(gòu)
IBP集群配置分為通訊節(jié)點信息埂伦、交易碼配置煞额、項目信息(通訊節(jié)點與交易碼關(guān)系,用于推導(dǎo))沾谜。
通訊節(jié)點信息
通訊節(jié)點信息包含節(jié)點名膊毁、狀態(tài)、節(jié)點主機(jī)集群IP和PORT基跑、應(yīng)用自定義KV配置婚温。
通訊節(jié)點信息配置etc/ibp_nodes.conf示例:
{
"nodes" :
[
{
"node" : "ECIF" ,
"invalid" : "0" ,
"hosts" :
[
{ "ip" : "158.1.0.56" , "port" : 18001 } ,
{ "ip" : "158.1.0.57" , "port" : 18001 } ,
{ "ip" : "158.1.0.58" , "port" : 18001 }
]
} ,
{
"node" : "CORE" ,
"invalid" : "0" ,
"hosts" :
[
{ "ip" : "66.88.1.10" , "port" : 10601 }
]
} ,
...
}
交易碼信息
交易碼信息包含交易碼、交易描述媳否、應(yīng)用包名(動態(tài)庫文件名)栅螟、客戶端通訊超時時間、服務(wù)端應(yīng)用超時時間篱竭、缺省服務(wù)端節(jié)點名力图、狀態(tài)。當(dāng)服務(wù)端應(yīng)用超時時間為0是自動按通訊超時*1.5計算掺逼。
交易碼信息配置etc/ibp_apps.conf示例:
{
"apps" :
[
{
"app" : "ibp_test_echo" ,
"desc" : "測試報文回射服務(wù)" ,
"bin" : "ibp_test_echo.so" ,
"timeout" : "50" ,
"timeout2" : "0" ,
"invalid" : "0"
} ,
{
"app" : "ibp_test_file" ,
"desc" : "測試文件回射服務(wù)" ,
"bin" : "ibp_test_file.so" ,
"timeout" : "120" ,
"timeout2" : "0" ,
"invalid" : "0"
} ,
...
}
項目信息
項目信息包含項目名吃媒、服務(wù)端節(jié)點集群、客戶端節(jié)點集群、交易碼集合赘那。
項目信息配置etc/ibp_projects.conf示例:
{
"projects" :
[
{
"project" : "echo_project" ,
"server_nodes" : "ECIF" ,
"client_nodes" : "CORE" ,
"apps" : "ibp_test_echo ibp_test_file"
} ,
...
]
}
2.2. 注冊中心(ibms)
注冊中心父進(jìn)程啟動后裝載主配置文件到內(nèi)存掛接成紅黑樹結(jié)構(gòu)刑桑,轉(zhuǎn)換自己為守護(hù)進(jìn)程,創(chuàng)建子進(jìn)程并監(jiān)控之募舟。
主配置文件etc/ibms.conf
示例:
{
"ibms" :
{
"server" : // 服務(wù)器配置
{
"ip" : "158.1.0.54" ,
"port" : 16001
} ,
"config" : // IBP集群配置文件名
{
"nodes_conf" : "ibp_nodes.conf" , // 通訊節(jié)點信息配置文件名
"apps_conf" : "ibp_apps.conf" , // 交易碼信息配置文件名
"projects_conf" : "ibp_projects.conf" // 項目信息配置文件名
} ,
"security" : // 安全機(jī)制配置
{
"old_key_disable_elapse" : 120 , // 老密鑰失效時間(單位:秒)
"new_key_enable_elapse" : 60 // 新密鑰生效時間(單位:秒)
} ,
"misc" : // 雜項配置
{
"auto_download_bin_enable" : 0 , // 是否啟用立即自動推導(dǎo)下發(fā)應(yīng)用包
"second_config_dump" : "158.1.0.55:26001" // 冗余落地配置副本的ibcmd地址
} ,
"log" : // ibms日志配置
{
"iblog_server" : "" , // 該選項已棄用祠斧,改用logpipe實現(xiàn)大小轉(zhuǎn)檔和異步實時日志收集
"event_output" : "file::log/event.log" , // 事件日志文件名
"main_output" : "file::log/ibms_main.log" , // 啟動初始化日志文件名
"main_loglevel" : DEBUG , // 啟動初始化日志等級
"monitor_output" : "file::log/ibms_monitor.log" , // 注冊中心父進(jìn)程日志文件名
"monitor_loglevel" : INFO , // 注冊中心父進(jìn)程日志等級
"worker_output" : "file::log/ibms_worker.log" , // 注冊中心子進(jìn)程日志文件名
"worker_loglevel" : INFO // 注冊中心子進(jìn)程日志等級
}
}
}
子進(jìn)程通過多路復(fù)用等待接受偵聽端口連接、接收已連接會話通訊數(shù)據(jù)并返回處理結(jié)果胃珍。
當(dāng)要停止注冊中心時梁肿,發(fā)送SIGTERM信號給父進(jìn)程,父進(jìn)程通過匿名管道發(fā)送退出命令給子進(jìn)程觅彰,子進(jìn)程處理完手頭工作后結(jié)束吩蔑,父進(jìn)程清理環(huán)境后也結(jié)束。
子進(jìn)程接受注冊中心命令客戶端填抬、圖形客戶端連接烛芬,接收增刪改查配置指令并返回處理結(jié)果,也接收開始自動推導(dǎo)下發(fā)配置飒责、下發(fā)應(yīng)用包赘娄、保存配置到磁盤等指令并返回處理結(jié)果。
子進(jìn)程也接受通訊節(jié)點注冊代理連接宏蛉,提供該節(jié)點及關(guān)聯(lián)節(jié)點配置遣臼,接受訂閱配置變動事件,也便于注冊中心監(jiān)測所有通訊節(jié)點的注冊代理生存情況拾并。
子進(jìn)程也接受通訊服務(wù)端連接揍堰,并保持心跳,以便在注冊中心監(jiān)測所有通訊服務(wù)端生存情況嗅义。
子進(jìn)程對外接口采用通訊協(xié)議采用RESTful API屏歹,報文格式采用JSON(壓縮)。
當(dāng)開啟配置ibms.misc.auto_download_bin_enable
為1時之碗,實時監(jiān)控應(yīng)用包目錄$HOME/so/
蝙眶,一旦發(fā)生新建或更新應(yīng)用包事件則立即自動推導(dǎo)下發(fā)應(yīng)用包。
當(dāng)配置ibms.misc.second_config_dump
有值時褪那,當(dāng)落地保存集群配置后再落地一份集群配置到目標(biāo)環(huán)境(通過ibcmd)幽纷。
當(dāng)集群配置很多時,啟動注冊中心裝載配置耗時將很長博敬。IBP引入預(yù)編譯配置機(jī)制霹崎,預(yù)讀入集群配置導(dǎo)出內(nèi)存鏡像成二進(jìn)制文件(文件名為對應(yīng)配置文件加后綴.bin
,如ibp_nodes.conf
的二進(jìn)制鏡像文件為ibp_nodes.conf.bin
)冶忱,下次啟動時如果發(fā)現(xiàn)有二進(jìn)制鏡像文件則直接裝載,省卻解析配置過程,使得裝載巨量配置在瞬息之間囚枪。
2.3. 注冊代理(ibma)
注冊代理進(jìn)程啟動后裝載主配置文件派诬,連接注冊中心索要本節(jié)點配置和相關(guān)節(jié)點配置(涉及應(yīng)用包檢查本地版本與注冊中心版本是否一致,如果不一致則自動聯(lián)動請求下發(fā)最新版本)链沼,構(gòu)造本地索引共享內(nèi)存(如果存在則刷新)和配置共享內(nèi)存默赂,轉(zhuǎn)換自己為守護(hù)進(jìn)程。
主配置文件etc/ibma.conf
示例:
{
"ibma" :
{
"this_node" : "ECIF" , // 本節(jié)點名
"comm" :
{
"min_compress_size" : 16 // 當(dāng)HTTP體大于該大小時自動啟用壓縮
} ,
"log" :
{
"iblog_server" : "" ,
"event_output" : "file::log/event.log" ,
"main_output" : "file::log/ibma_ECIF_127.0.0.1:18111_main.log" ,
"main_loglevel" : INFO ,
"worker_output" : "file::log/ibma_ECIF_127.0.0.1:18111_worker.log" ,
"worker_loglevel" : INFO
}
} ,
"ibac" :
{
"connecting_timeout" : 10 // 客戶端連接(connect)服務(wù)端超時時間(單位:秒)
"retry_connect_timeval" : 60 , // 當(dāng)連接失敗后暫禁時間段(單位:秒)
} ,
"ibms" :
{
"server" :
{
"ip" : "127.0.0.1" , // 注冊中心IP
"port" : 16001 // 注冊中心PORT
}
}
}
進(jìn)程訂閱注冊中心集群配置變動事件括勺,如果發(fā)生事件則重新構(gòu)造新配置共享內(nèi)存缆八,串入配置共享內(nèi)存鏈,刷新索引共享內(nèi)存內(nèi)的配置共享內(nèi)存KEY疾捍。
進(jìn)程周期性檢查配置共享內(nèi)存鏈奈辰,如果有老版配置共享內(nèi)存除了注冊代理外沒有其它進(jìn)程相連,清除該配置共享內(nèi)存乱豆。
索引共享內(nèi)存內(nèi)布局:
區(qū)號 | 內(nèi)容 | 大小 |
---|---|---|
第一區(qū) | 最新版配置共享內(nèi)存KEY | sizeof(key_t) |
配置共享內(nèi)存內(nèi)布局:
區(qū)號 | 內(nèi)容 | 大小 |
---|---|---|
第一區(qū) | 頭結(jié)構(gòu)信息奖恰,包含本節(jié)點名等主配置信息、通訊節(jié)點數(shù)量等集群配置概要信息等 | 頭結(jié)構(gòu)大小 |
第二區(qū) | 哈希存放通訊節(jié)點信息宛裕,用于高效查詢 | 通訊節(jié)點信息結(jié)構(gòu)大小×數(shù)量x哈希膨脹因子 |
第三區(qū) | 順序存放通訊節(jié)點主機(jī)信息瑟啃,第二區(qū)中的每一個通訊節(jié)點信息都指出所屬該節(jié)點的主機(jī)集群信息存放開始地址和結(jié)束地址 | 所有通訊節(jié)點主機(jī)信息結(jié)構(gòu)大小×數(shù)量 |
第四區(qū) | 哈希存放交易碼信息,用于高效查詢 | 交易碼信息結(jié)構(gòu)大小×數(shù)量x哈希膨脹因子 |
第五區(qū) | 哈希存放應(yīng)用自定義KV信息揩尸,用于高效查詢 | 應(yīng)用自定義KV信息結(jié)構(gòu)大小×數(shù)量x哈希膨脹因子 |
注冊代理對外提供API給通訊客戶端API和通訊服務(wù)端平臺用以連接共享內(nèi)存蛹屿、檢查轉(zhuǎn)連、訪問各類集群配置岩榆。
2.4. 通訊客戶端API(ibac)
通訊客戶端API是一個函數(shù)庫错负,不假設(shè)應(yīng)用進(jìn)程結(jié)構(gòu)、信號燈環(huán)境等系統(tǒng)環(huán)境設(shè)置朗恳,適應(yīng)各種各樣的客戶端系統(tǒng)環(huán)境場景湿颅。
通訊客戶端API提供了低層、中層兩層函數(shù)集合給客戶端應(yīng)用粥诫,適應(yīng)各種各樣的客戶端調(diào)用場景油航。
2.4.1. 低層函數(shù)集
環(huán)境類
/* 創(chuàng)建ibac環(huán)境 */
struct IbacEnv *IBACCreateEnvirment( char *config_filename );
/* 銷毀ibac環(huán)境 */
void IBACDestroyEnvirment( struct IbacEnv *p_env );
連接類
/* 連接服務(wù)端 */
int IBACConnect( struct IbacEnv *p_env , char *node , char *app );
/* 斷開服務(wù)端 */
void IBACDisconnect( struct IbacEnv *p_env );
通訊收發(fā)類
/* 發(fā)送請求和接收響應(yīng) */
int IBACSendRequestAndReceiveResponse( struct IbacEnv *p_env , char *app , char **pp_msg , int *p_msg_len , ... );
2.4.2. 中層函數(shù)集
/* 連接服務(wù)端,發(fā)送請求和接收響應(yīng)怀浆,斷開服務(wù)端 */
int IBACRequester( struct IbacEnv *p_env , char *node , char *app , char **pp_msg , int *p_msg_len , ... );
2.4.3. 調(diào)用流程
長短進(jìn)程
短進(jìn)程:先創(chuàng)建ibac環(huán)境(內(nèi)部調(diào)用注冊代理API連接最新版配置共享內(nèi)存谊囚、內(nèi)部環(huán)境初始化),發(fā)起交易执赡,銷毀ibac環(huán)境镰踏。
長進(jìn)程:創(chuàng)建ibac環(huán)境,反復(fù)使用同一個ibac環(huán)境發(fā)起交易沙合,進(jìn)程退出前銷毀ibac環(huán)境奠伪。
長短連接
短連接:發(fā)起交易前調(diào)用連接服務(wù)端,收發(fā)通訊數(shù)據(jù),斷開服務(wù)端绊率。
長連接:連接服務(wù)端谨敛,反復(fù)使用這條連接收發(fā)通訊數(shù)據(jù),最后斷開服務(wù)端滤否。(長連接能提高通訊效率脸狸,但也會使負(fù)載均衡能力減弱)。
2.4.4. 負(fù)載均衡算法
當(dāng)此交易響應(yīng)通訊報文中夾帶服務(wù)端負(fù)載信息(工作狀態(tài)進(jìn)程數(shù)量/進(jìn)程總數(shù)量)藐俺,通訊客戶端API以CAS方式覆寫到配置共享內(nèi)存炊甲,寫失敗則丟棄。下筆交易發(fā)起連接服務(wù)端時欲芹,挑選服務(wù)端負(fù)載壓力最小的主機(jī)卿啡。
2.4.5. 臨時文件名格式
IBP體系中,交易業(yè)務(wù)報文還能附帶文件耀石,即臨時文件牵囤。
代碼中臨時文件名變量定義如下:
char req_filename[ IBP_MAXLEN_FILENAME + 1 ] ;
臨時文件必須都存放在$HOME/file/
目錄里,可以使用IBP創(chuàng)建臨時文件函數(shù)創(chuàng)建
FILE *IBPCreateTempFile( char *file_id , char *filename , char *pathfilename , char *mode )
臨時文件名格式為:
(file_id)_(10個可見隨機(jī)字符).tmp
在接收端滞伟,使用file_id
來獲取指定類臨時文件揭鳞。
2.4.6. 通訊收發(fā)函數(shù)參數(shù)特別說明
參數(shù)*pp_msg
輸入時指向業(yè)務(wù)請求報文地址,輸出時修改成指向業(yè)務(wù)響應(yīng)報文地址(存放緩存區(qū)在ibac環(huán)境中托管分配梆奈,無需應(yīng)用控制)野崇。如果調(diào)用后客戶端應(yīng)用還要訪問業(yè)務(wù)請求報文緩沖區(qū),請在調(diào)用前做好地址備份亩钟。
參數(shù)*p_msg_len
輸入時存放業(yè)務(wù)請求報文大小乓梨,輸出時修改成業(yè)務(wù)響應(yīng)報文大小。
最后參數(shù)...
清酥,指出交易附帶文件集合扶镀,格式為:
,(0~n個請求附帶文件名列表),NULL,(0~n個響應(yīng)附帶文件名列表),NULL
比如無請求響應(yīng)附帶文件:
,NULL,NULL
比如有一個請求附帶文件,沒有響應(yīng)附帶文件:
,req_filename,NULL,NULL
比如沒有請求附帶文件焰轻,有兩個響應(yīng)附帶文件:
,NULL,rsp_filename1,rsp_filename2,NULL
比如有三個請求附帶文件臭觉,有兩個響應(yīng)附帶文件:
req_filename1,req_filename2,req_filename3,NULL,rsp_filename1,rsp_filename2,NULL
2.4.7. 交易可疑狀態(tài)查詢
IBP通訊協(xié)議設(shè)計保證當(dāng)通訊失敗時告知應(yīng)用該交易是否可疑
int IBACGetCommStatus( struct IbacEnv *p_env );
當(dāng)該函數(shù)返回IBAC_COMM_STATUS_ON_SENDING
時說明交易處于可疑狀態(tài),需要追加執(zhí)行業(yè)務(wù)查證交易辱志、反交易蝠筑、沖正交易,或通知人工介入揩懒。
2.4.8. 并行交易(未跟上最新版本)
并行交易允許客戶端應(yīng)用同時向多個通訊節(jié)點發(fā)送交易什乙,并行等待直到所有響應(yīng)都收妥,或者通訊失敗已球。
連接類
struct IbacMultiRequesters
{
char *node ; /* IBP通訊節(jié)點 */
char *app ; /* 交易碼 */
char **pp_msg ; /* 請求報文 或 響應(yīng)報文 */
int *p_msg_len ; /* 請求報文長度 或 響應(yīng)報文長度 */
struct IbacAddonFiles req_files ; /* 請求文件數(shù)組 */
struct IbacAddonFiles rsp_files ; /* 響應(yīng)文件數(shù)組 */
} ;
/*
struct IbacMultiRequesters a_multi_requesters[] =
{
{ "ibma-1" , "TESTTPS1" , & p_msg1 , & msg1_len , { NULL } , { NULL } } ,
{ "ibma-2" , "TESTTPS2" , & p_msg2 , & msg2_len , { req2_filename1 , req2_filename2 } , { rsp2_filename1 , rsp2_filename2 } }
} ;
*/
/* 連接服務(wù)端集 */
int IBACMultiConnect( struct IbacMultiEnvs *p_multi_envs , struct IbacMultiRequesters *multi_requesters );
/* 斷開服務(wù)端集 */
void IBACMultiDisconnect( struct IbacMultiEnvs *p_multi_envs , struct IbacMultiRequesters *multi_requesters );
通訊收發(fā)類
/* 發(fā)送并行交易請求并接收響應(yīng) */
int IBACMultiSendRequestsAndReceiveResponses( struct IbacMultiEnvs *p_multi_envs , struct IbacMultiRequesters *multi_requesters );
查詢是否交易可疑
/* 得到通訊狀態(tài) */
int IBACMultiGetCommStatus( struct IbacMultiEnvs *p_multi_envs );
2.4.9. 二階段提交(未跟上最新版本)
基于并行交易機(jī)制臣镣,實現(xiàn)了二階段提交辅愿。
通訊收發(fā)類
/* 發(fā)送二階段提交或回滾請求并接收響應(yīng) */
#define IBAC_MULTI_COMMIT_DATABASE 1
#define IBAC_MULTI_ROLLBACK_DATABASE 0
int IBACMultiSendCommitOrRollbackAndReceiveResponses( struct IbacMultiEnvs *p_multi_envs , struct IbacMultiRequesters *multi_requesters , int commit_or_rollback_flag );
此函數(shù)在并行交易通訊收發(fā)后調(diào)用,需要服務(wù)端配合退疫。
2.5. 通訊服務(wù)端平臺(ibas)
通訊服務(wù)端平臺父進(jìn)程啟動后裝載主配置文件到內(nèi)存渠缕,轉(zhuǎn)換自己為守護(hù)進(jìn)程。
主配置文件etc/ibas.conf
示例:
{
"ibas" :
{
"server" : // 服務(wù)端偵聽地址
{
"ip" : "158.1.0.56" , // 通訊服務(wù)端偵聽IP
"port" : 18001 // 通訊服務(wù)端偵聽PORT
} ,
"mpm" : // 多進(jìn)程控制
{
"mode" : "STATIC_WORKERPOOL" , /* FORK,STATIC_WORKERPOOL,DYNAMIC_WORKERPOOL */ // 服務(wù)模式:分別是 即時創(chuàng)建短工作進(jìn)程褒繁、靜態(tài)工作進(jìn)程池、動態(tài)工作進(jìn)程池
"max_count" : 10 , // 最大工作進(jìn)程數(shù)量 或 靜態(tài)保持工作進(jìn)程數(shù)量
"DYNAMIC_WORKERPOOL" :
{
"min_idle_count" : 1 , // 最小空閑狀態(tài)工作進(jìn)程數(shù)量(動態(tài)進(jìn)程池時有效)
"max_idle_count" : 5 , // 最大空閑狀態(tài)工作進(jìn)程數(shù)量(動態(tài)進(jìn)程池時有效)
"create_interval" : 1 , // 每調(diào)整周期最大創(chuàng)建工作進(jìn)程數(shù)量(動態(tài)進(jìn)程池時有效)
"destroy_interval" : 10 , // 每調(diào)整周期最大銷毀工作進(jìn)程數(shù)量(動態(tài)進(jìn)程池時有效)
"max_process_count" : 10000 // 每個工作進(jìn)程處理多少交易后自動重啟馍忽,以釋放應(yīng)用泄露的系統(tǒng)資源棒坏,保持工作進(jìn)程健康
}
} ,
"security" : // 安全控制
{
"sign_flag" : 1 , // 與客戶端握手時,建議雙方業(yè)務(wù)報文是否簽名
"compress_flag" : 1 , // 與客戶端握手時遭笋,建議雙方業(yè)務(wù)報文是否壓縮
"encrypt_flag" : 1 // 與客戶端握手時坝冕,建議雙方業(yè)務(wù)報文是否加密
} ,
"app" : // 應(yīng)用包選項
{
"max_so_cache_count" : 1000 // 應(yīng)用包打開句柄緩存池最大緩存數(shù)量,采用LRU踢出使用最少的應(yīng)用包打開句柄緩存
} ,
"log" : // 日志配置
{
"iblog_server" : "" ,
"event_output" : "file::log/event.log" ,
"main_output" : "file::log/ibas_158.1.0.56-18001_main.log" ,
"main_loglevel" : DEBUG ,
"monitor_output" : "file::log/ibas_158.1.0.56-18001_monitor.log" ,
"monitor_loglevel" : INFO ,
"worker_output" : "file::log/ibas_158.1.0.56-18001_worker_%d.log" ,
"worker_loglevel" : INFO ,
"app_output" : "file::log/app_%s.log" ,
"app_loglevel" : INFO
}
} ,
"ibma" :
{
"config_filename" : "ibma.conf" // 本地注冊代理主配置文件瓦呼,用于連接配置共享內(nèi)存
}
}
2.5.1. 進(jìn)程結(jié)構(gòu)
主配置參數(shù)mpm/mode
設(shè)置了通訊服務(wù)端服務(wù)模式(進(jìn)程結(jié)構(gòu))喂窟,目前有:
配置參數(shù) | 服務(wù)模式 | 說明 |
---|---|---|
FORK | 即時創(chuàng)建模式 | 管理進(jìn)程等待接受新連接,即時創(chuàng)建短工作進(jìn)程處理交易央串,交易處理完后結(jié)束工作進(jìn)程 |
STATIC_WORKERPOOL | 靜態(tài)工作進(jìn)程池 | 管理進(jìn)程啟動后陸續(xù)創(chuàng)建工作進(jìn)程直至進(jìn)程池完整磨澡,管理進(jìn)程僅負(fù)責(zé)監(jiān)控工作進(jìn)程異常重啟,工作進(jìn)程采用Leader-follow 模型和ACCEPT臨界區(qū) 质和,即同一時間只有一個偵聽狀態(tài)工作進(jìn)程進(jìn)入ACCEPT臨界區(qū) 擁有accept 權(quán)力稳摄,當(dāng)新連接進(jìn)來后,被其捕獲饲宿,切換自身為工作狀態(tài)厦酬,離開ACCEPT臨界區(qū) 去處理通訊收發(fā)、報文轉(zhuǎn)換和業(yè)務(wù)邏輯瘫想,操作系統(tǒng)挑選堵在ACCEPT臨界區(qū) 外的一個空閑狀態(tài)工作進(jìn)程進(jìn)入臨界區(qū)仗阅,后者切換自身為偵聽狀態(tài)等待下一個新連接到來,前者處理完交易后切換自身為空閑狀態(tài)嘗試/堵在ACCEPT臨界區(qū) 外国夜,如此前赴后繼 |
DYNAMIC_WORKERPOOL | 動態(tài)工作進(jìn)程池 | 在靜態(tài)工作進(jìn)程池基礎(chǔ)上增加了周期性根據(jù)進(jìn)程池繁忙程度自動伸縮進(jìn)程池大小 |
2.5.2. 通訊接入
拿到新連接的初切工作狀態(tài)的工作進(jìn)程會根據(jù)通訊接收到的數(shù)據(jù)判斷通訊協(xié)議减噪,交由對應(yīng)的通訊適配器處理。
目前支持二進(jìn)制通訊協(xié)議IB1支竹、IB2旋廷,以及包裝HTTP的IBP通訊協(xié)議。
2.5.3. 應(yīng)用包打開句柄緩存池
每個應(yīng)用包其實就是一個動態(tài)庫文件礼搁,通訊平臺根據(jù)通訊協(xié)議中標(biāo)注的交易碼饶碘,通過注冊代理API查詢對應(yīng)動態(tài)庫文件名,裝載之馒吴,定位入口函數(shù)指針并調(diào)用之扎运,調(diào)用完后緩存動態(tài)庫打開句柄和入口函數(shù)指針到緩存池(紅黑樹)中瑟曲,供下次直接使用以提高性能,同時注冊文件系統(tǒng)主動通知該動態(tài)庫文件變動事件豪治,如發(fā)生變動則在緩存池中清理該動態(tài)庫打開句柄洞拨,迫使下次使用前重新裝載。
2.5.4. 應(yīng)用包接口
平臺通過入口函數(shù)進(jìn)入應(yīng)用包(動態(tài)庫)负拟,應(yīng)用包負(fù)責(zé)報文適配轉(zhuǎn)換烦衣、業(yè)務(wù)邏輯處理(交易管理公共層、分階段模板管理層掩浙、TM函數(shù)層)花吟。
入口函數(shù)原型:
int somain( struct HttpBuffer *req_body , struct HttpBuffer *rsp_body , struct IbasAddonFiles *addon_files );
req_body
是通訊接收到的業(yè)務(wù)請求報文,rsp_body
是交易處理完待發(fā)送的業(yè)務(wù)響應(yīng)報文厨姚,可以通過struct HttpBuffer
緩沖區(qū)操作函數(shù)集讀寫其內(nèi)容衅澈。
addon_files
是附帶文件容器,可以通過struct IbasAddonFiles
操作函數(shù)集查詢請求附帶文件谬墙,壓入響應(yīng)附帶文件今布。
IBP提供了報文轉(zhuǎn)換層、交易管理公共層拭抬、分階段模板層供應(yīng)用代碼選用規(guī)范應(yīng)用開發(fā)部默,具體參見本系列《四、業(yè)務(wù)邏輯管理框架與分階段模板》玖喘。
2.5.5. 工作進(jìn)程生命周期
每個工作進(jìn)程都有其生命周期甩牺。
如果配置了app/max_so_cache_count
,則在處理指定數(shù)量交易后工作進(jìn)程正常結(jié)束累奈,管理進(jìn)程捕獲工作進(jìn)程正常結(jié)束事件贬派,創(chuàng)建新的工作進(jìn)程替代老的繼續(xù)工作。
如果工作進(jìn)程異常結(jié)束澎媒,管理進(jìn)程也會在第一時間捕獲并重啟進(jìn)程搞乏。
2.5.6. 三層超時清理
由于設(shè)計或代碼問題工作進(jìn)程可能會有死循環(huán)、處理時間過長戒努、進(jìn)程異常僵死等情況请敦。
工作進(jìn)程切換為工作狀態(tài)時,會設(shè)置鬧鐘储玫,服務(wù)端應(yīng)用超時時間T后觸發(fā)自殺信號結(jié)束自己侍筛,結(jié)束事件會被管理進(jìn)程捕獲并啟動新工作進(jìn)程替代老工作進(jìn)程。
管理進(jìn)程也會周期性掃描所有工作狀態(tài)工作進(jìn)程撒穷,如果發(fā)現(xiàn)有進(jìn)程處理總耗時超過1.5T則會發(fā)送TERM信號勸其結(jié)束匣椰,如果再次發(fā)現(xiàn)超過2T則會發(fā)送KILL信號無條件殺滅該工作進(jìn)程,殺滅事件會被管理進(jìn)程捕獲并啟動新工作進(jìn)程替代老工作進(jìn)程端礼。
自動化的三層超時清理機(jī)制使得工作進(jìn)程池始終長期保持健康狀態(tài)禽笑,無需人工介入處理入录。
2.5.7. 應(yīng)用包不停機(jī)熱更原理
注冊代理得到新版應(yīng)用包落地成更新期應(yīng)用包文件,刪除磁盤上應(yīng)用包文件佳镜,改名更新期應(yīng)用包文件為應(yīng)用包文件僚稿;通訊服務(wù)端平臺工作進(jìn)程空閑時接收文件系統(tǒng)主動通知應(yīng)用包變動,如果是刪除事件則清理緩存池中該應(yīng)用包打開句柄蟀伸,如果是改名事件則糾正文件系統(tǒng)監(jiān)控應(yīng)用包文件蚀同;通訊服務(wù)端平臺接收交易后打開應(yīng)用包,如打開失敗則嘗試打開更新期應(yīng)用包啊掏。通過以上機(jī)制唤崭,可以實現(xiàn)理論上完全不停機(jī)應(yīng)用熱更,為運維帶來巨大便捷脖律。
2.5.8. 通訊服務(wù)端平臺不停機(jī)熱更原理
首先更新好磁盤上的平臺程序和庫,然后發(fā)送USR2信號給管理進(jìn)程腕侄,管理進(jìn)程創(chuàng)建新一代管理進(jìn)程(代碼映像取自磁盤上最新版本)小泉,并把偵聽端口繼承給它,新一代管理進(jìn)程初始化成功后創(chuàng)建新一代工作進(jìn)程組冕杠,此時新老兩代進(jìn)程池同時處理服務(wù)請求微姊,確認(rèn)新一代正常工作后,發(fā)送TERM信號給老一代管理進(jìn)程做優(yōu)雅結(jié)束分预。通過以上機(jī)制兢交,可以實現(xiàn)理論上完全不停機(jī)平臺熱更,為運維帶來巨大便捷笼痹。
2.6. 遠(yuǎn)程命令代理(ibcmd)
如果通過ssh或rsh做遠(yuǎn)程執(zhí)行命令配喳、上傳下載文件,會有權(quán)限過大隱患凳干,IBP設(shè)計了遠(yuǎn)程命令代理晴裹,部署在各個節(jié)點上,用于命令受控的執(zhí)行命令和傳輸文件救赐。
在節(jié)點上運行遠(yuǎn)程命令代理服務(wù)端涧团,在遠(yuǎn)程機(jī)器上用遠(yuǎn)程命令代理客戶端向服務(wù)端發(fā)送命令并執(zhí)行,發(fā)送文件傳輸指令處理文件上傳或下載经磅。
執(zhí)行遠(yuǎn)程命令前會先經(jīng)過黑名單審計泌绣,尤其用于組合shell命令的分隔符等會被檢查出來并拒絕執(zhí)行遠(yuǎn)程命令,然后經(jīng)過白名單審計预厌,只有出現(xiàn)在白名單內(nèi)的命令才能通過審查并執(zhí)行阿迈。黑白名單配置支持'*'和'?'匹配。
遠(yuǎn)程命令代理一般用于需要隔離權(quán)限的執(zhí)行一些命令場合配乓。
2.7. 集群管理
注冊中心發(fā)送ssh公鑰給所有節(jié)點的root用戶仿滔,注冊中心通過無密登錄直接操作所有節(jié)點主機(jī)集群惠毁。
2.7.1. 集群啟停
所有節(jié)點主機(jī)集群配置在$HOME/etc/ibp_cluster.conf
。
注冊中心注冊代理集群管理腳本ibma_cluster.sh
管理所有節(jié)點或指定節(jié)點主機(jī)集群的注冊代理的啟動崎页、停止鞠绰、查詢狀態(tài),以及自定義命令執(zhí)行飒焦,后者包含推送最新版本IBP安裝包到所有節(jié)點主機(jī)集群蜈膨、解開更新包。
ibas_cluster.sh
是類似于ibma_cluster.sh
的集群管理腳本牺荠,只不過對象是管理通訊服務(wù)端平臺翁巍,,命令參數(shù)還包含優(yōu)雅重啟等休雌。
2.7.2. 集群伸縮
注冊中心還擁有一鍵伸縮集群功能灶壶,注冊中心通過客戶端命令行或圖形管理平臺先維護(hù)一份已注冊root權(quán)限裸機(jī)資源列表,當(dāng)觸發(fā)一鍵擴(kuò)大集群指令時杈曲,注冊中心遠(yuǎn)程自動操控新節(jié)點創(chuàng)建用戶驰凛、推送解開安裝包、推送實例化配置担扑、向自己登記節(jié)點主機(jī)信息恰响、啟動注冊代理、向該節(jié)點和關(guān)聯(lián)節(jié)點發(fā)送下發(fā)配置和應(yīng)用包指令涌献、啟動通訊服務(wù)端平臺(如果設(shè)置為服務(wù)端角色)胚宦,這樣該節(jié)點和關(guān)聯(lián)節(jié)點的本地節(jié)點配置中就增加了新增節(jié)點主機(jī)信息。
一鍵縮小集群同理燕垃。
2.8. 集群日志收集(logpipe)
老版日志歸集采用IBP日志庫的遠(yuǎn)程推送和日志服務(wù)器iblog
來實現(xiàn)枢劝,但考慮到同步推送日志(即使只推送event.log
)對交易處理的影響,就用本人以前自研的開源日志收集工具logpipe
來代替利术。
logpipe是一個分布式呈野、高可用的用于采集、傳輸印叁、對接落地的日志工具被冒,采用了插件風(fēng)格的框架結(jié)構(gòu)設(shè)計,支持多輸入多輸出按需配置組件用于流式日志收集架構(gòu)轮蜕,無第三方依賴昨悼。
logpipe的輸入文件插件支持異步實時的采集日志,輸出文件插件支持以相同文件名落地日志跃洛,輸出TCP插件支持負(fù)載均衡輪詢發(fā)送日志以規(guī)避單節(jié)點故障造成傳輸斷點率触,以上這些特性正是IBP日志收集架構(gòu)所需要。
使用logpipe
配置日志采集端和日志歸集端非常簡單汇竭。
2.8.1. 日志歸集端
在日志服務(wù)器上部署日志歸集端以落地日志到統(tǒng)一存儲葱蝗,也要控制單個日志文件最大大小穴张。
$ cat $HOME/etc/logpipe.conf
{
"log" :
{
"log_file" : "/tmp/logpipe_log.log" ,
"log_level" : "WARN"
} ,
"inputs" :
[
{ "plugin":"so/logpipe-input-tcp.so" , "ip":"158.1.0.55" , "port":10101 }
] ,
"outputs" :
[
{ "plugin":"so/logpipe-output-file.so" , "path":"/home/iblog/log" , "rotate_size":10000000 }
]
}
用以下命令啟用日志歸集端
$ logpipe -f $HOME/etc/logpipe.conf
2.8.2. 日志采集端
在注冊中心、所有通訊節(jié)點部署日志采集端以異步實時采集日志两曼,同時還控制單個日志文件最大大小皂甘,配置大小轉(zhuǎn)檔后的日志文件立即刪除。
$ cat $HOME/etc/logpipe.conf
{
"log" :
{
"log_file" : "/tmp/logpipe_log.log" ,
"log_level" : "WARN"
} ,
"inputs" :
[
{ "plugin":"so/logpipe-input-file.so" , "path":"/home/ecif/log" , "rotate_size":10000000 , "exec_after_rotating":"rm -f ${LOGPIPE_ROTATING_NEW_FILENAME}" }
] ,
"outputs" :
[
{ "plugin":"so/logpipe-output-tcp.so" , "ip":"158.1.0.55","port":10101 }
]
}
用以下命令啟用日志采集端
$ logpipe -f $HOME/etc/logpipe.conf
2.8.3. 其它日志歸檔
logpipe還支持日志歸檔到HDFS悼凑、ES偿枕,以及同時歸檔多個目標(biāo)。