基於Nginx dyups模塊的站點動態上下線並實現簡單服務治理

今天主要討論一下,對於分佈式服務,站點如何平滑的上下線問題。 nginx

在分佈式服務下,咱們會用nginx作負載均衡, 業務站點訪問某服務站點的時候, 統一走nginx, 而後nginx根據必定的輪詢策略,將請求路由到後端一臺指定的服務器上。 
 
這樣的架構是沒有問題的, 可是咱們這裏考慮幾個問題, 
1. 網站上下線問題:咱們網站平時更新站點的時候是直接覆蓋文件,而後重啓, 那這樣會形成一些請求中斷,若是是非核心邏輯那還好, 若是是核心邏輯,那請求中斷,會影響一些數據一致性,好比資金, 交易,訂單等。  
 2. 動態加減機器,好比某個站點訪問量大,要新增機器,那就須要修改nginx的配置,而後reload, 這樣會中斷鏈接。 雖然reload很快,可是仍是會有一瞬間的請求中斷。 
 
對於第一個問題,咱們能夠在請求量少的時候去更新, 可是這種在一些服務穩定的公司可用, 對於互聯網企業,可能2-3天就一個版本, 並且須要馬上上線, 若是每次都要等到凌晨4點去更新, 可能整個的開發節奏都被帶慢了。 
對於第二個問題, 對於能夠預見的流量,好比大促來臨,能夠提早3天放在請求量少的時候更新。 
 
最近幾年,隨着SOA的普及和微服務的出現,特別是dubbo的出現,服務治理的概念被提出來。 服務治理是一個很宏大的概念,包括 服務註冊,服務自動發現,服務路由,服務依賴,集羣容錯,服務降級,服務監測,服務審批等,固然不是每一個服務中心都必須實現這些東西, 公司能夠根據本身的實際需求來定製實現。 
基於以上這些狀況, 我計劃實現一個工具,這個工具首先解決站點上下線和動態擴容問題,也就是說在不須要重啓nginx的狀況下,而且在保證請求不丟失的狀況下來更新站點。 同時帶有部分服務治理功能。 
 
 
服務上線
1. 在一個新服務上線的時候,通常會提早申請幾臺機器, 運維會在nginx上新增server,並新增server對應的upstream ,正常狀況下upstream應該配置是後端服務器的IP,可是這裏不配置(若是容許,甚至這一步均可以省略)。 
2. 服務部署好並啓動,在啓動的時候,向註冊中心註冊自身的服務信息,包括IP和端口。 
3. 註冊中心收到請求後,會對服務進行健康檢測,確保提供的服務沒有問題,則將服務狀態標示爲 預上線狀態。 
4. 在後臺管理中心,就能夠將 預上線的服務設置爲 上線,服務管理中心會調用nginx的上線接口,將服務IP新增或者更新到upstream中,服務就能夠提供訪問。   
 
服務更新
假如咱們如今有一個服務須要更新,則執行如下步驟:
1. 在後臺管理中心,將一個服務設爲 下線,此時服務中心會調用nginx的下線接口,將指定服務器的IP設置爲下線。 
2. 在等待1分鐘後,確保沒有新鏈接連過來,則能夠開始更新服務站點。
3. 更新完畢後,再手動設爲 上線,此時服務中心會調用nginx的上線接口,將指定服務器的IP設置爲上線。固然對於成熟的服務,這些均可以自動化,有些公司會有一些自動化發佈工具, 與自動化發佈工具集成,能夠一鍵下線,更新並上線。 
 
服務運行期間
在服務運行過程當中,會有一個健康檢測的服務對全部提供服務的站點進行健康檢測,一旦檢測到有問題,就執行 下線邏輯。 直到問題被解決,最後執行 上線流程。 
 
動態加減機器
在服務運行過程當中,可能由於某些緣由,服務請求飆高(前提是這些請求都是合法的),超過了當前集羣的承載能力,當系統檢測到這些狀況後,能夠動態擴充機器,好比如今流行的docker,在啓動容器的時候,同時啓動應用,應用在啓動的時候,將自身信息註冊給註冊中心,註冊中心再將這些信息同步到nginx,應用就能夠提供訪問,總體上就能夠實現彈性計算。 
 
爲何不實現服務動態發現?
   這裏能夠看到圖中已經有一個服務註冊中心。 既然有了服務註冊中心了, 那可讓業務站點鏈接服務註冊中心來獲取真實的服務IP,而後繞過nginx來鏈接服務,這裏之因此沒有這樣作,是由於:
    1.  實現服務動態發現,這個須要和RPC框架配合,並且須要作服務的軟負載,失敗重連,限流等,整個項目設計就上升了一個複雜度, 考慮到有些項目還未使用RPC,而且不想對原有的項目有過多的侵入, 因此這裏不作實現。 可是並不意味沒有這些功能,服務的負載, 失敗重連, 限流,其實這些功能在nginx中一樣也有,能夠直接使用,因此沒有必要從新再開發。 
    2.  實現服務動態發現,獲取到真實的服務IP,而後直連,這些通常是在流量特別大,nginx上出現短板的時候使用,但實際狀況,通常不多會耗盡nginx的性能,即便有,也能夠經過ngxin水平擴展來實現,因此這裏依然使用nginx做爲負載均衡。 
 
這裏講一下這個項目的關鍵點:
1. 服務的註冊和健康檢測這個沒有技術難點,這裏不作解釋。
2. 關於操做nginx上下線,這裏的確是一個難點,由於nginx自己並無提供這些上下線API,須要openresty並配合一些第三方擴展來實現。 這裏主要用到了兩個擴展模塊: ngx_http_dyups_module  lua-upstream-nginx-module
   ngx_http_dyups_module( https://github.com/yzprofile/ngx_http_dyups_module)提供了粗粒度的upstream管理方法,能夠對整個upstream進行新增,刪除。 
  lua-upstream-nginx-module( https://github.com/openresty/lua-upstream-nginx-module) ,則提供了細粒度的管理方式,能夠對某一個服務IP進行管理,其中提供的set_peer_down方法,能夠對upstream中的某個ip進行上下線。
3. 也可使用 ngx_dynamic_upstream( https://github.com/cubicdaiya/ngx_dynamic_upstream)
這些插件有一個共同點,那就是在不須要重啓nginx的基礎上, 動態修改nginx的配置。 
1. 最後我想請大夥討論一下,大家公司是怎麼上下線的, 是直接覆蓋,仍是有其餘策略。 歡迎在評論區討論。
相關文章
相關標籤/搜索