一、業(yè)務(wù)背景分析 前一段時(shí)間,需要開發(fā)一套業(yè)務(wù)系統(tǒng),此系統(tǒng)需要對(duì)外統(tǒng)一提供api服務(wù),但這些服務(wù)在內(nèi)部是由多個(gè)業(yè)務(wù)子系統(tǒng)分別提供。 經(jīng)過分析,此業(yè)務(wù)系統(tǒng)需要具有以下這么幾個(gè)特性 1、不同的api服務(wù)由不同的子系統(tǒng)負(fù)責(zé) 2、每一個(gè)服務(wù)之間是相互獨(dú)立的 3、每一個(gè)服務(wù)都需要支持橫向擴(kuò)展和負(fù)載均衡 4、每一個(gè)服務(wù)都需要高可用 這么一分析,我們發(fā)現(xiàn)這里需要一個(gè)api網(wǎng)關(guān),這個(gè)api網(wǎng)關(guān)需要具有以下幾個(gè)特點(diǎn): 1、api服務(wù)器自注冊(cè),需要滿足以下兩個(gè)特點(diǎn)(當(dāng)然也可以由運(yùn)維在api網(wǎng)關(guān)管理平臺(tái)上進(jìn)行管理,此部分不影響本文的技術(shù)探討,這里不進(jìn)行詳細(xì)的描述) 1)新增一個(gè)服務(wù)時(shí),api服務(wù)器可以將相應(yīng)的服務(wù)自注冊(cè)到api網(wǎng)關(guān)上 2)某服務(wù)新增一個(gè)服務(wù)器或刪除一個(gè)服務(wù)器時(shí),api服務(wù)器可以在進(jìn)行自注銷或自注冊(cè) 2、api網(wǎng)關(guān)需要支持對(duì)同一個(gè)服務(wù)子系統(tǒng)的多個(gè)服務(wù)器進(jìn)行負(fù)載均衡 3、api網(wǎng)關(guān)需要支持對(duì)同一個(gè)服務(wù)子系統(tǒng)的多個(gè)服務(wù)器中的故障服務(wù)器進(jìn)行檢測(cè)和切換,也就是高可用 4、api網(wǎng)關(guān)系統(tǒng)本身需要支持橫向擴(kuò)展 二、方案的選擇 對(duì)于任何團(tuán)隊(duì)來講,方案不一定是自己開發(fā)的就是最好的(牛A和牛C之間的技術(shù)團(tuán)隊(duì)除外),需要綜合考慮各種因素,這個(gè)API網(wǎng)關(guān)也不例外,中間經(jīng)歷了一點(diǎn)曲折,過程如下: 1、系統(tǒng)是部署在云上面的(具體的云這里就不透露了),原本想著看這個(gè)云服務(wù)端是否有提供此功能服務(wù),不過遺憾的是此云未提供此服務(wù)(好像亞馬遜云有提供,沒有用過不知道怎么樣) 2、使用開源的方案,在開源方案上找到了一個(gè)叫kong的方案,此方案是基于nginx的反向代理開發(fā)的一套方案,經(jīng)過調(diào)研,此套方案不支持負(fù)載均衡和高可用方案(當(dāng)然不是很深入的調(diào)研),此方案本身是基于nginx的lua擴(kuò)展模塊進(jìn)行開發(fā)的,對(duì)于api網(wǎng)關(guān)的配置是使用cassandra數(shù)據(jù)庫(kù)進(jìn)行存儲(chǔ),對(duì)于團(tuán)隊(duì)的技術(shù)背景來說,這個(gè)不是那么合適。(ps:團(tuán)隊(duì)本身還不是很強(qiáng)大,業(yè)務(wù)工作量比較多,整個(gè)團(tuán)隊(duì)對(duì)lua和cassandra沒什么積累,在這個(gè)場(chǎng)合下除非此方案能直接用,并且有較多的資料,否則只能舍棄掉) 3、自主開發(fā)一套,經(jīng)過對(duì)各服務(wù)子系統(tǒng)的接口分析,發(fā)現(xiàn)直接使用nginx的反向代理和負(fù)載均衡來實(shí)現(xiàn)也不是那么復(fù)雜,所以這個(gè)方案這么誕生了 三、使用nginx作為api網(wǎng)關(guān)的調(diào)研 對(duì)于nginx的反向代理和負(fù)載均衡的資料網(wǎng)上已經(jīng)有很多,這里就不廢話了,直接看調(diào)研過程 這里假設(shè)nginx的配置文件目錄為/etc/nginx/ 1、配置的考慮 考慮到nginx的配置文件大小有要求,所以在這里不把配置直接寫入到nginx.conf,而是在nginx.conf里面去include其他目錄,比如 在/etc/nginx/目錄下新建api_servers.d目錄和api_rules.d目錄,分別用來存放api服務(wù)器的相關(guān)配置和api服務(wù)代理規(guī)則的相關(guān)配置,在http配置項(xiàng)中增加一行配置include /etc/nginx/api_servers.d/*.conf; 在提供網(wǎng)關(guān)服務(wù)的server中增加一行include /etc/nginx/api_rules.d/*.conf; 2、配置負(fù)載均衡和反向代理 在/etc/nginx/api_servers.d/目錄下新增一個(gè)文件api_test_servers.conf,內(nèi)容如下 upstream api_testa_server { server 192.168.1.101:80 weight=1 max_fails=3 fail_timeout=20; server 192.168.1.102:80 weight=1 max_fails=3 fail_timeout=20; server 192.168.1.103:80 weight=2 max_fails=3 fail_timeout=20; } upstream api_testb_server { server 192.168.1.104:80 weight=1 max_fails=3 fail_timeout=20; server 192.168.1.105:80 weight=1 max_fails=3 fail_timeout=20; } 在/etc/nginx/api_rules.d/目錄下新增一個(gè)文件api_test_rule.conf(這里以簡(jiǎn)單的url匹配來舉例) location ~(^\/ws\/apitesta)(.*) { proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_buffering off;#緩存在其他文章中會(huì)討論,在這里暫只討論基本的功能,所以直接使用off proxy_pass http://api_testa_server; } location ~(^\/ws\/apitestb)(.*) { proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_buffering off; proxy_pass http://api_testb_server; } nginx服務(wù)reload使配置生效 3、測(cè)試過程 nginx服務(wù)器的地址是192.168.1.100,服務(wù)的端口為80端口,測(cè)試過程如下 1)、 執(zhí)行wget http://192.168.1.100/ws/apitesta/phpinfo和wget http://192.168.1.100/ws/apitestb/phpinfo 分別重復(fù)執(zhí)行此命令20次,查看192.168.1.101-105這5臺(tái)web服務(wù)器的web訪問日志,發(fā)現(xiàn)101-103的/ws/apitesta/phpinfo訪問量分別為5、5、10,104和105的web訪問日志里面對(duì)/ws/apitestb/phpinfo的訪問量都是10次 2)、 關(guān)閉192.168.1.102和192.168.1.104,重復(fù)上述測(cè)試過程,發(fā)現(xiàn)兩個(gè)url均可正常訪問 四、網(wǎng)關(guān)的搭建 從上述的調(diào)研結(jié)果來看,使用nginx的反向代理和負(fù)載均衡可實(shí)現(xiàn)對(duì)api服務(wù)器的負(fù)載均衡及高可用,那么我們需要解決的就是自注冊(cè)的問題和網(wǎng)關(guān)本身的擴(kuò)展性。 對(duì)于自注冊(cè)和自注銷這個(gè)問題,對(duì)于我們的業(yè)務(wù)系統(tǒng)來說,業(yè)務(wù)的上線與下線本身不是一個(gè)特別頻繁的事情,所以直接在api網(wǎng)關(guān)上搭建一個(gè)簡(jiǎn)單的web服務(wù)即可,我們稱之為api網(wǎng)關(guān)系統(tǒng),api網(wǎng)關(guān)系統(tǒng)基本功能如下: 1、注冊(cè)或注銷時(shí)需要重新生成nginx的反向代理和負(fù)載均衡配置文件(也就是上述的api_rules.d和api_servers.d目錄下的文件),并且網(wǎng)關(guān)服務(wù)器需要對(duì)nginx執(zhí)行reload操作 2、需要對(duì)api服務(wù)的相關(guān)信息做持久化存儲(chǔ) 除了上述兩個(gè)基本功能還需要網(wǎng)關(guān)本身支持橫向擴(kuò)展,這個(gè)仔細(xì)分析一下無非就是需要以下兩個(gè)問題 1、在任一個(gè)網(wǎng)關(guān)服務(wù)器上注冊(cè)或注銷一個(gè)api服務(wù)或一個(gè)api服務(wù)的一個(gè)服務(wù)器時(shí)都需要通知到所有的網(wǎng)關(guān)服務(wù)器,所有的網(wǎng)關(guān)服務(wù)器都需要重新生成配置并且reload各自的nginx服務(wù),顯然的我們想到了消息隊(duì)列里面的topic消息(消息隊(duì)列的高可用等特性在這里不進(jìn)行特別延伸),所有的api網(wǎng)關(guān)服務(wù)器共用同一個(gè)消息隊(duì)列即可滿足此要求 2、所有的網(wǎng)關(guān)服務(wù)器需要共同同一個(gè)網(wǎng)關(guān)配置信息,這個(gè)無非是共用一個(gè)數(shù)據(jù)庫(kù)(數(shù)據(jù)庫(kù)的高可用等特性在這里不進(jìn)行特別延伸) api服務(wù)器自注冊(cè)至生效主要流程如下: 所有的網(wǎng)關(guān)服務(wù)器共用一個(gè)消息隊(duì)列,共用同一個(gè)存儲(chǔ)數(shù)據(jù)庫(kù),各網(wǎng)關(guān)服務(wù)器上的網(wǎng)關(guān)信號(hào)處理進(jìn)程向消息隊(duì)列訂閱相關(guān)的消息,當(dāng)api服務(wù)器向網(wǎng)關(guān)服務(wù)器集群中的某一臺(tái)服務(wù)器進(jìn)行注冊(cè)時(shí),所有的網(wǎng)關(guān)服務(wù)器都會(huì)收到reload消息,會(huì)從同一個(gè)數(shù)據(jù)庫(kù)中讀取同一個(gè)配置,然后重新生成nginx反向代理和負(fù)載均衡的相關(guān)配置文件,接著reload各自的nginx服務(wù),當(dāng)然這里面的網(wǎng)關(guān)信號(hào)處理進(jìn)程啟動(dòng)時(shí)也會(huì)重新生成相關(guān)的配置。 至此一個(gè)基于nginx的API網(wǎng)關(guān)完成了,當(dāng)然此文只介紹了一個(gè)實(shí)用性的主體思路,一些細(xì)節(jié)層面在這里暫不做過多描述,因?yàn)閚ginx的資料在網(wǎng)上其實(shí)已經(jīng)很多了。 --------------------- 作者:akin_zhou 來源:CSDN 原文:https://blog.csdn.net/akin_zhou/article/details/50373414 版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請(qǐng)附上博文鏈接! |
|