分布式聯(lián)機(jī)服務(wù)技術(shù)框架(IBP)設(shè)計與實戰(zhàn)(二抑胎、平臺體系架構(gòu))

版本號 修訂日期 修訂人 內(nèi)容
0.0.1.0 2018-01-27 厲華 創(chuàng)建

1. 總體架構(gòu)

architecture.png

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ù)端福扬。

注冊代理

architecture2.png

每個通訊節(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ī)熱更原理

restart_graceful.png

首先更新好磁盤上的平臺程序和庫,然后發(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)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末户辫,一起剝皮案震驚了整個濱河市渐夸,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌渔欢,老刑警劉巖墓塌,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異奥额,居然都是意外死亡桃纯,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進(jìn)店門披坏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人盐数,你說我怎么就攤上這事棒拂。” “怎么了玫氢?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵帚屉,是天一觀的道長。 經(jīng)常有香客問我漾峡,道長攻旦,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任生逸,我火速辦了婚禮牢屋,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘槽袄。我一直安慰自己烙无,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布遍尺。 她就那樣靜靜地躺著截酷,像睡著了一般。 火紅的嫁衣襯著肌膚如雪乾戏。 梳的紋絲不亂的頭發(fā)上迂苛,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天三热,我揣著相機(jī)與錄音,去河邊找鬼三幻。 笑死就漾,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的赌髓。 我是一名探鬼主播从藤,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼锁蠕!你這毒婦竟也來了夷野?” 一聲冷哼從身側(cè)響起逗噩,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤嚎莉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后俺叭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體舌仍,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡妒貌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了铸豁。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片灌曙。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖节芥,靈堂內(nèi)的尸體忽然破棺而出在刺,到底是詐尸還是另有隱情,我是刑警寧澤头镊,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布蚣驼,位于F島的核電站,受9級特大地震影響相艇,放射性物質(zhì)發(fā)生泄漏颖杏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一坛芽、第九天 我趴在偏房一處隱蔽的房頂上張望留储。 院中可真熱鬧,春花似錦咙轩、人聲如沸欲鹏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽赔嚎。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間尤误,已是汗流浹背侠畔。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留损晤,地道東北人软棺。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像尤勋,于是被迫代替她去往敵國和親喘落。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,446評論 2 348

推薦閱讀更多精彩內(nèi)容