記錄Nginx搭建網關服務

1、業務背景分析
前一段時間,須要開發一套業務系統,此係統須要對外統一提供api服務,但這些服務在內部是由多個業務子系統分別提供。
通過分析,此業務系統須要具備如下這麼幾個特性


一、不一樣的api服務由不一樣的子系統負責
二、每個服務之間是相互獨立的
三、每個服務都須要支持橫向擴展和負載均衡
四、每個服務都須要高可用


這麼一分析,咱們發現這裏須要一個api網關,這個api網關須要具備如下幾個特色:
一、api服務器自注冊,須要知足如下兩個特色(固然也能夠由運維在api網關管理平臺上進行管理,此部分不影響本文的技術探討,這裏不進行詳細的描述)
   1)新增一個服務時,api服務器能夠將相應的服務自注冊到api網關上
   2)某服務新增一個服務器或刪除一個服務器時,api服務器能夠在進行自注銷或自注冊
二、api網關須要支持對同一個服務子系統的多個服務器進行負載均衡
三、api網關須要支持對同一個服務子系統的多個服務器中的故障服務器進行檢測和切換,也就是高可用
四、api網關係統自己須要支持橫向擴展


2、方案的選擇
對於任何團隊來說,方案不必定是本身開發的就是最好的(牛A和牛C之間的技術團隊除外),須要綜合考慮各類因素,這個API網關也不例外,中間經歷了一點曲折,過程以下:


一、系統是部署在雲上面的(具體的雲這裏就不透露了),本來想着看這個雲服務端是否有提供此功能服務,不過遺憾的是此雲未提供此服務(好像亞馬遜雲有提供,沒有用過不知道怎麼樣)
二、使用開源的方案,在開源方案上找到了一個叫kong的方案,此方案是基於nginx的反向代理開發的一套方案,通過調研,此套方案不支持負載均衡和高可用方案(固然不是很深刻的調研),此方案自己是基於nginx的lua擴展模塊進行開發的,對於api網關的配置是使用cassandra數據庫進行存儲,對於團隊的技術背景來講,這個不是那麼合適。(ps:團隊自己還不是很強大,業務工做量比較多,整個團隊對lua和cassandra沒什麼積累,在這個場合下除非此方案能直接用,而且有較多的資料,不然只能捨棄掉)php

三、自主開發一套,通過對各服務子系統的接口分析,發現直接使用nginx的反向代理和負載均衡來實現也不是那麼複雜,因此這個方案這麼誕生了nginx

 

3、使用nginx做爲api網關的調研
對於nginx的反向代理和負載均衡的資料網上已經有不少,這裏就不廢話了,直接看調研過程
這裏假設nginx的配置文件目錄爲/etc/nginx/
一、配置的考慮
  考慮到nginx的配置文件大小有要求,因此在這裏不把配置直接寫入到nginx.conf,而是在nginx.conf裏面去include其餘目錄,好比
  在/etc/nginx/目錄下新建api_servers.d目錄和api_rules.d目錄,分別用來存放api服務器的相關配置和api服務代理規則的相關配置,在http配置項中增長一行配置include /etc/nginx/api_servers.d/*.conf;
  在提供網關服務的server中增長一行include /etc/nginx/api_rules.d/*.conf;


二、配置負載均衡和反向代理
   在/etc/nginx/api_servers.d/目錄下新增一個文件api_test_servers.conf,內容以下
   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/目錄下新增一個文件api_test_rule.conf(這裏以簡單的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;#緩存在其餘文章中會討論,在這裏暫只討論基本的功能,因此直接使用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服務reload使配置生效


三、測試過程
 nginx服務器的地址是192.168.1.100,服務的端口爲80端口,測試過程以下
1)、 執行wget http://192.168.1.100/ws/apitesta/phpinfo和wget http://192.168.1.100/ws/apitestb/phpinfo
分別重複執行此命令20次,查看192.168.1.101-105這5臺web服務器的web訪問日誌,發現101-103的/ws/apitesta/phpinfo訪問量分別爲五、五、10,104和105的web訪問日誌裏面對/ws/apitestb/phpinfo的訪問量都是10次
2)、 關閉192.168.1.102和192.168.1.104,重複上述測試過程,發現兩個url都可正常訪問


4、網關的搭建
從上述的調研結果來看,使用nginx的反向代理和負載均衡可實現對api服務器的負載均衡及高可用,那麼咱們須要解決的就是自注冊的問題和網關自己的擴展性。
對於自注冊和自注銷這個問題,對於咱們的業務系統來講,業務的上線與下線自己不是一個特別頻繁的事情,因此直接在api網關上搭建一個簡單的web服務便可,咱們稱之爲api網關係統,api網關係統基本功能以下:
一、註冊或註銷時須要從新生成nginx的反向代理和負載均衡配置文件(也就是上述的api_rules.d和api_servers.d目錄下的文件),而且網關服務器須要對nginx執行reload操做
二、須要對api服務的相關信息作持久化存儲
除了上述兩個基本功能還須要網關自己支持橫向擴展,這個仔細分析一下無非就是須要如下兩個問題
一、在任一個網關服務器上註冊或註銷一個api服務或一個api服務的一個服務器時都須要通知到全部的網關服務器,全部的網關服務器都須要從新生成配置而且reload各自的nginx服務,顯然的咱們想到了消息隊列裏面的topic消息(消息隊列的高可用等特性在這裏不進行特別延伸),全部的api網關服務器共用同一個消息隊列便可知足此要求
二、全部的網關服務器須要共同同一個網關配置信息,這個無非是共用一個數據庫(數據庫的高可用等特性在這裏不進行特別延伸)


api服務器自注冊至生效主要流程以下:web

全部的網關服務器共用一個消息隊列,共用同一個存儲數據庫,各網關服務器上的網關信號處理進程向消息隊列訂閱相關的消息,當api服務器向網關服務器集羣中的某一臺服務器進行註冊時,全部的網關服務器都會收到reload消息,會從同一個數據庫中讀取同一個配置,而後從新生成nginx反向代理和負載均衡的相關配置文件,接着reload各自的nginx服務,固然這裏面的網關信號處理進程啓動時也會從新生成相關的配置。數據庫

至此一個基於nginx的API網關完成了,此文轉載了大牛的日誌,僅此本身記錄學習api

相關文章
相關標籤/搜索