(五):C++分布式实时应用框架——微服务架构的演进
C++分布式實(shí)時(shí)應(yīng)用框架——微服務(wù)架構(gòu)的演進(jìn)
?技術(shù)交流合作QQ群:436466587 歡迎討論交流
上一篇:(四):C++分布式實(shí)時(shí)應(yīng)用框架——狀態(tài)中心模塊
?
版權(quán)聲明:本文版權(quán)及所用技術(shù)歸屬smartguys團(tuán)隊(duì)所有,對(duì)于抄襲,非經(jīng)同意轉(zhuǎn)載等行為保留法律追究的權(quán)利!
?
OCS(online charging system,在線計(jì)費(fèi)系統(tǒng))在進(jìn)行云化改造的過程中,從實(shí)用主義角度出發(fā),微服務(wù)架構(gòu)并不是我們的目標(biāo)。雖然我們也對(duì)系統(tǒng)進(jìn)行了容器化改造(Docker),并根據(jù)業(yè)務(wù)進(jìn)程的功能將系統(tǒng)分成了好幾類的容器,但這一切多是出于對(duì)系統(tǒng)中的某些處理節(jié)點(diǎn)進(jìn)行動(dòng)態(tài)擴(kuò)縮容的需要,跟微服務(wù)半點(diǎn)關(guān)系沒有。隨著系統(tǒng)改造 的深入,系統(tǒng)的通訊關(guān)系復(fù)雜程度開始超過我們之前的估計(jì)。如果說數(shù)量眾多的功能節(jié)點(diǎn)還有人可以勉強(qiáng)掌握,這些節(jié)點(diǎn)間錯(cuò)綜復(fù)雜的通訊關(guān)系連線已超過程序員可以駕馭的范疇。在討論如何簡(jiǎn)化程序員實(shí)現(xiàn)整個(gè)系統(tǒng)各類節(jié)點(diǎn)的通訊關(guān)系的配置過程中,節(jié)點(diǎn)微服務(wù)化的理念漸漸進(jìn)入我們的腦海之中……
下面先給大家介紹下我們所面臨的困境,下面的圖是我們系統(tǒng)一部分節(jié)點(diǎn)的通訊關(guān)系總圖(注意,只是其中一部分):
?
還記得第二篇《基于ZeroMQ的實(shí)時(shí)通訊平臺(tái)》中那個(gè)我們引以為傲的通訊配置文件嗎,就是程序中所有的通訊連接關(guān)系不再是寫死在代碼中,而是通過AppInit.json配置文件進(jìn)行配置,程序啟動(dòng)的時(shí)候再由CDRAF進(jìn)行實(shí)時(shí)加載。當(dāng)初酷炫的功能,現(xiàn)在卻成我們的惡夢(mèng)。此時(shí)AppInit.json這個(gè)文件已到達(dá)1700多行,你沒看錯(cuò),一個(gè)配置文件1700多行,并且還不是全部,還會(huì)繼續(xù)變大。
?
"OLC" : {"AUTO_START" : "YES","ENDPOINTS" : [{ // 用于與SmartMonitor建立心跳"name" : "MonitorSUB", "zmq_socket_action" : "CONNECT", // ZMQ的連接模式"zmq_socket_type" : "ZMQ_SUB" // ZMQ的通訊模式 },{ // 下發(fā)消息給OCDis,這邊存在轉(zhuǎn)發(fā)功能,支持業(yè)務(wù)實(shí)現(xiàn)按條件轉(zhuǎn)發(fā)"downstream" : [ "OCDis2OLC"],"name" : "NE2OLC", // 根據(jù)這個(gè)名字在業(yè)務(wù)代碼中實(shí)現(xiàn)轉(zhuǎn)發(fā)"zmq_socket_action" : "BIND","zmq_socket_type" : "ZMQ_STREAM" },{ // OLC到OCDis的鏈路"name" : "OCDis2OLC","statistics_on" : true,"zmq_socket_action" : "CONNECT","zmq_socket_type" : "ZMQ_DEALER"},{ // OCDis回OLC的鏈路,之所以來去分開,主要用于實(shí)現(xiàn)優(yōu)雅啟停功能(啟停節(jié)點(diǎn)保證不丟消息)"name" : "OCDis2OLC_Backway","statistics_on" : true,"zmq_socket_action" : "CONNECT","zmq_socket_type" : "ZMQ_DEALER","backway_pair" : "OCDis2OLC"},{ // 用于與SmartMonitor的命令消息鏈路"name" : "OLC2Monitor","zmq_socket_action" : "CONNECT","zmq_socket_type" : "ZMQ_DEALER"},],"ENDPOINT_TO_MONITOR" : "OLC2Monitor","INSTANCE_GROUP" : [{"instance_endpoints_address" : [{"endpoint_name" : "NE2OLC","zmq_socket_address" : "tcp://*:6701"},{"endpoint_name" : "OCDis2OLC","zmq_socket_address" : ["tcp://127.0.0.1:7201" // 跨機(jī)的IP地址與端口,配合狀態(tài)中心可實(shí)現(xiàn)自動(dòng)管理,無需人工參與配置 ]},{"endpoint_name" : "OCDis2OLC_Backway","zmq_socket_address" : ["tcp://127.0.0.1:7202"]},{"endpoint_name" : "OLC2Monitor","zmq_socket_address" : "ipc://Monitor2Business_IPC"},{"endpoint_name" : "MonitorSUB","zmq_socket_address" : "ipc://MonitorPUB"}],"instance_group_name" : "1"}]},?
一個(gè)業(yè)務(wù)程序員如果要調(diào)整系統(tǒng)中某個(gè)程序的通訊連接,一定得盯著上面那副圖研究半天,并且要搞明白“CONNECT”、“BIND"、”ZMQ_ROUTER"、“ZMQ_DEALER"等等這些zeromq專業(yè)詞匯的含義,才可能進(jìn)行準(zhǔn)確配置,我們隱隱感到這已是一個(gè)mission impossible。如何簡(jiǎn)化這個(gè)配置文件,如何對(duì)系統(tǒng)的復(fù)雜度進(jìn)行分層,讓不同層級(jí)的人員僅僅只需關(guān)注自身層級(jí)情況,再通過我們的CDRAF最終將這些散落的配置、代碼組成一個(gè)完成可運(yùn)行的系統(tǒng)才是我們現(xiàn)在亟需解決的問題。相信這也是每個(gè)系統(tǒng)架構(gòu)師所面臨的問題,當(dāng)一個(gè)系統(tǒng)的復(fù)雜度超過單個(gè)人可承受能力范圍,就要對(duì)這個(gè)系統(tǒng)進(jìn)行適當(dāng)分層,分模塊。讓每個(gè)人去管理一小部分復(fù)雜點(diǎn),并且大家只需實(shí)現(xiàn)好自己的模塊,無需去關(guān)心別的模塊的實(shí)現(xiàn)細(xì)節(jié)。通過事先設(shè)計(jì)好的接口,各個(gè)模塊可以相互協(xié)作,整體系統(tǒng)是可以依此完美地運(yùn)行的。這里CDARF正是起這么一個(gè)不同模塊的橋梁(接口)的作用。
一、節(jié)點(diǎn)間通訊模式的統(tǒng)一
原來節(jié)點(diǎn)內(nèi)的應(yīng)用程序都是通訊全能應(yīng)用程序,所謂全能是指應(yīng)用程序既可以跟節(jié)點(diǎn)內(nèi)的進(jìn)程進(jìn)行通訊也可以跟節(jié)點(diǎn)外的任意進(jìn)程進(jìn)行通訊。這樣乍看起來沒啥問題,但一旦節(jié)點(diǎn)數(shù)和進(jìn)程數(shù)變多后,通訊關(guān)系將是一個(gè)指數(shù)級(jí)增長(zhǎng)的過程。如下圖,如果再增加一個(gè)CDR節(jié)點(diǎn),或者OCS節(jié)點(diǎn),連接數(shù)都將增加非常多。
我們的解決辦法是統(tǒng)一節(jié)點(diǎn)的通訊模式,每個(gè)節(jié)點(diǎn)內(nèi)都有一個(gè)Dis進(jìn)程,統(tǒng)一對(duì)外負(fù)責(zé)跟其他節(jié)點(diǎn)進(jìn)行通訊。在收到外部發(fā)給節(jié)點(diǎn)的消息后,根據(jù)功能和負(fù)載轉(zhuǎn)發(fā)給內(nèi)部業(yè)務(wù)處理進(jìn)程。業(yè)務(wù)進(jìn)程如果有消息需要發(fā)往別的節(jié)點(diǎn),就直接發(fā)給Dis進(jìn)程,由它進(jìn)行轉(zhuǎn)發(fā)。統(tǒng)一通訊模式帶來的好處除了在節(jié)點(diǎn)和進(jìn)程增多后,通訊關(guān)系不會(huì)變得太復(fù)雜以外。由于模式統(tǒng)一, CDARF可以替業(yè)務(wù)程序員完成很多工作,直接的好處就是業(yè)務(wù)程序員不再需要配置很多與業(yè)務(wù)無關(guān)的配置。最大化的將通訊模塊的復(fù)雜度留給CDRAF去處理,業(yè)務(wù)程序員將更加專注于自身的業(yè)務(wù)邏輯。下面的圖中其實(shí)系統(tǒng)開始已經(jīng)有微服務(wù)的樣子,但我們希望做到的不僅是從系統(tǒng)架構(gòu)上是微服務(wù)架構(gòu),在程序員開發(fā)程序的時(shí)候,也應(yīng)該是帶著微服務(wù)思維的,我們的CDRAF應(yīng)該提供這么一種能力來支持這種開發(fā)模式。
?
二、配置文件的簡(jiǎn)化
通訊模式統(tǒng)一后,我們對(duì)通訊配置文件進(jìn)行了一次較大的簡(jiǎn)化,從原來1700行減少到了200行左右。這當(dāng)中省去了很多冗余的配置項(xiàng),通訊配置文件不再是對(duì)系統(tǒng)通訊簡(jiǎn)單直接的對(duì)應(yīng),而更多的是對(duì)節(jié)點(diǎn)通訊能力的一種表述。
應(yīng)用程序分為Dis和非Dis兩類,Dis類程序主要承擔(dān)節(jié)點(diǎn)間的通訊和節(jié)點(diǎn)內(nèi)的消息轉(zhuǎn)發(fā),非Dis類程序就是普通的業(yè)務(wù)處理進(jìn)程。從下面的文件中可以看到“OCDis”進(jìn)程中分為“InterContainerEndpoints”和“InnerContainerEndpoints”兩大類,分別表示節(jié)點(diǎn)間的通訊和節(jié)點(diǎn)內(nèi)的通訊。對(duì)于節(jié)點(diǎn)間的通訊,每個(gè)服務(wù)端口只要寫上相應(yīng)的“服務(wù)名字”就可以以了,配置中的“OCDisCDRDis”表示OCSDis與CDRDis的通訊,“OLCDisOLCProxy”、“OCDis_SyDis_SNR”也是類似。當(dāng)業(yè)務(wù)側(cè)程序需要對(duì)外提供一個(gè)服務(wù)(或者說與外部進(jìn)行通訊),只需要寫一個(gè)服務(wù)名字,而如:端口、機(jī)器的IP地址、服務(wù)端還是客戶端、通訊模式等等都完全不需要去關(guān)心,這是多大一種便利。配置中的注釋部分是不需要業(yè)務(wù)程序員去填的,而是由CDRAF的狀態(tài)中心,根據(jù)集群節(jié)點(diǎn)的實(shí)時(shí)情況自動(dòng)生成,并進(jìn)行連接和維護(hù)。
{"OCDis": {"MaxInstanceGroupNum": 3,"InterContainerEndpoints": {"OCDisCDRDis": {//"Port": [6001, 6002, 6003],//"Cluster": ["10.45.4.10:6001", "10.45.4.10:6001"] },"OCDisOLCProxy": {//"Port": [6101, 6102, 6103],"DownStreams": ["OCDis2IN", "OCDis2PS", "OCDis2SMS", "OCDis2ISMP", "OCDis2IMS"],"router": true},"OCDis_SyDis_SNR": { //"Peer": "ZSmartSyDis.OCDis_SyDis_SNR" }},"InnerContainerEndpoints": {"OCPro_OCDis_CDR": { "DownStreams": ["OCDisCDRDis"] },"OCPro_OCDis_SNR": { "DownStreams": ["OCDis_SyDis_SNR"] },}},"OCPro": {"Groups": ["IN", "PS", "SMS", "IMS", "ISMP"],"InnerContainerEndpoints": {"OCPro2OCDis": {"PeerMap": ["OCDis.OCDis2IN","OCDis.OCDis2PS","OCDis.OCDis2SMS","OCDis.OCDis2ISMP","OCDis.OCDis2IMS"]},"OCPro_OCDis_SNR": {"Peer": "OCDis.OCPro_OCDis_SNR"},"OCPro_OCDis_CDR": {"Peer": "OCDis"}}},"CDRDis": {"InterContainerEndpoints": {"OCDisCDRDis" : {"DownStreams": ["CDRDisCDR"],//"Peer": "OCDis" }}},"CDR": {"InnerContainerEndpoints": {"CDRDisCDR" : {"Peer": "CDRDis"}}} }
想像一下,對(duì)于每一個(gè)業(yè)務(wù)節(jié)點(diǎn),開發(fā)人員僅需考慮節(jié)點(diǎn)內(nèi)的業(yè)務(wù)實(shí)現(xiàn)邏輯,并為本節(jié)點(diǎn)對(duì)外所提供的服務(wù)起個(gè)名字,而不再需要關(guān)心這個(gè)服務(wù)到底是提供給誰,更不用操心誰會(huì)來連我的進(jìn)程,怎么連。這是多么精妙的事情!我們不僅是從架構(gòu)上做到了微服務(wù)架構(gòu),程序員在開發(fā)業(yè)務(wù)程序的時(shí)候,不需要去關(guān)心除了自身模塊以外的其它復(fù)雜信息,從此可以輕裝上陣,而不再需要負(fù)重前行。這應(yīng)該就是CDRAF對(duì)微服務(wù)架構(gòu)提供的最直接、最好的支持了,幫助業(yè)務(wù)程序員從傳統(tǒng)的開發(fā)模式轉(zhuǎn)變,進(jìn)而適應(yīng)微服務(wù)的思維方式。
?
三、節(jié)點(diǎn)間的通訊關(guān)系配置
上面我們提到配置文件只定義了節(jié)點(diǎn)的服務(wù)名,那么這么多的微服務(wù)節(jié)點(diǎn)是如何組合起來工作的?一個(gè)業(yè)務(wù)應(yīng)用系統(tǒng)會(huì)由許多的微服務(wù)一起協(xié)同提供服務(wù),這些服務(wù)對(duì)于每個(gè)不同的現(xiàn)場(chǎng)可能功能是不一樣的,或者說微服務(wù)集合是不一樣的。那么,對(duì)這些微服務(wù)的組合的過程就像一個(gè)“編排”的過程。通過“編排”,選擇合適的微服務(wù)進(jìn)行搭配組合提供服務(wù),而編排的過程就是我們通訊建立的過程。下面我們就來看一下CDRAF是如何做到“編排”功能的。
上面的第一張表,描述了所有的微服務(wù)列表,所有節(jié)點(diǎn)服務(wù)要向外通訊都必須到這張表中增加相應(yīng)的服務(wù)名,這里的服務(wù)名是與前面配置文件中的服務(wù)名相對(duì)應(yīng)的。第二張表描述了這些微服務(wù)名之間的通訊關(guān)系,比如第二條記錄表達(dá)的是OCDis程序的OCDis2CDRDis到CDRDis的OCDis2CDRDis之間會(huì)有一個(gè)通訊關(guān)系。只要通過這個(gè)簡(jiǎn)單的配置,就可以完成兩個(gè)節(jié)點(diǎn)間的通訊關(guān)系的建立。這樣的設(shè)計(jì)會(huì)帶來幾個(gè)好處。
1、對(duì)于一個(gè)復(fù)雜的系統(tǒng),可能有幾十類微服務(wù)節(jié)點(diǎn),運(yùn)行實(shí)例可能有上百個(gè),如果有上面的表二,就可以容器的從上面的數(shù)據(jù)中畫出整個(gè)集群的實(shí)時(shí)拓?fù)鋱D,這個(gè)對(duì)于系統(tǒng)的監(jiān)控是十分重要的。
2、集群通訊關(guān)系的設(shè)計(jì)上升了一個(gè)等級(jí),業(yè)務(wù)程序員只需要根據(jù)模塊接口設(shè)計(jì)提供相應(yīng)的微服務(wù)節(jié)點(diǎn),而不需要關(guān)心與其它微服務(wù)是如何協(xié)調(diào)工作的。而這些微服務(wù)如何“編排”提升到了架構(gòu)師的工作范圍的層級(jí)。這顯然是對(duì)復(fù)雜度進(jìn)行分層隔離很好的一個(gè)范例。
3、運(yùn)維或者管理人員,通過表二的配置可以很容易地操作集群里的某個(gè)微服務(wù)下線或者上線。在一個(gè)龐大的集群里面,如果某類微服務(wù)出故障,而CDARF提供了這么一種手段可以去讓這類故障微服務(wù)下線,將給系統(tǒng)的穩(wěn)定性帶來極大的可靠保證。
4.、原來集群所有的通訊都配置在一個(gè)文件中,在分布式系統(tǒng)中就涉及文件的全局一致性的問題。解決的方案可能是,如果要上線一個(gè)新類型的配置文件(新增節(jié)點(diǎn)、刪除節(jié)點(diǎn)、通訊關(guān)系改變等等),就要去更新所有在網(wǎng)節(jié)點(diǎn)的配置文件。但此時(shí)如果新的配置文件有bug,那么可能導(dǎo)致整個(gè)集群的故障,并且為了升級(jí)某個(gè)功能去升級(jí)整個(gè)集群所有節(jié)點(diǎn)的配置也是極不合理的。在新的方案中,節(jié)點(diǎn)的配置只定義節(jié)點(diǎn)內(nèi)的通訊和對(duì)外提供的微服務(wù)名。那么如果要新增某種類型的微服務(wù),不再需要去更新其它節(jié)點(diǎn)的配置,只需要將新節(jié)點(diǎn)上線,然后在上面的表一新增微服務(wù)名,表二增加連接關(guān)系就可以了。真正做到了增量升級(jí)!
?
未完待續(xù)……
?
轉(zhuǎn)載于:https://www.cnblogs.com/cdap/p/8204569.html
總結(jié)
以上是生活随笔為你收集整理的(五):C++分布式实时应用框架——微服务架构的演进的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: matlab画空间直线,空间直线x y=
- 下一篇: c语言实验报告熟悉vc,C语言实验报告源