nginx搭建網關服務器

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


1、不同的api服務由不同的子系統負責
2、每一個服務之間是相互獨立的
3、每一個服務都需要支持橫向擴展和負載均衡
4、每一個服務都需要高可用


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


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


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

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

 

三、使用nginx作爲api網關的調研
對於nginx的反向代理和負載均衡的資料網上已經有很多,這裏就不廢話了,直接看調研過程
這裏假設nginx的配置文件目錄爲/etc/nginx/
1、配置的考慮
  考慮到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;


2、配置負載均衡和反向代理
   在/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使配置生效


3、測試過程
 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訪問量分別爲5、5、10,104和105的web訪問日誌裏面對/ws/apitestb/phpinfo的訪問量都是10次
2)、 關閉192.168.1.102和192.168.1.104,重複上述測試過程,發現兩個url均可正常訪問


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


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

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

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章