Spring Cloud微服務運維神器之Consul Template?

Spring Cloud微服務架構淺析

這篇文章中要和大家分享下的就是在Spring Cloud微服務架構模式中被運維小哥用的很爽的一個工具Consul Template?

在具體介紹Consul Template是個什麼東西之前,我們先來整體看一張微服務模式下的系統架構圖,如下圖所示:

Spring Cloud微服務運維神器之Consul Template?

在上圖中,我們看到在基於Spring Cloud的微服務體系中,所有的微服務都會被註冊到統一服務註冊中心進行服務管理,這裏使用的服務註冊中心是Consul。假設在正常情況下,我們面向C端用戶設計了一套微服務邏輯,用戶端App通過域名訪問後端微服務邏輯,而訪問的調用鏈路是通過將公網域名透過DNS解析到我們的Nginx反向代理服務器,而Nginx服務器則需要將請求打到我們的Api Gateway微服務網關(如Zuul或Spring Cloud Gateway)上。之後,Api Gateway就會根據客戶端訪問的具體服務路徑,將請求透過Consul的服務發現轉發到具體的微服務中,例如訪問訂單微服務相關的接口Api Gateway就會將請求打到訂單微服務中。

而我們知道在Spring Cloud微服務系統中,雖然Api Gateway網關服務本身並沒有什麼業務邏輯,除了進行服務路由外,也就只是通過編寫過濾器實現一些常見的服務鑑權之類的邏輯,但其本身與其他微服務一樣都是被註冊中心管理的,而在容器化的時代Api Gateway與其他微服務一樣也可能是被部署在Docker容器中,其IP端口地址本身並不是固定的。所以如果我們之前瞭解過Nginx反向代理配置的話,此時心裏就會有疑問,Api Gateway服務的IP端口都不固定怎麼搞反向負載均衡配置呢?

是不是我們應該要將Api Gateway特殊處理下,把Api Gateway的部署採用固定主機IP+端口的部署方式進行運維呢?答案顯然是可以的,但是問題是這樣做本身是不是就額外增加了微服務架構的複雜度?同時也降低了了Api Gateway網關服務部署的靈活性呢?所以,這個時候Consul Template就橫空出世了!

Consul Template是做什麼的?

說了這麼多,那麼Consul Template到底是做什麼的呢?根據官方說明Consul Template比較關鍵的一個使用場景就是可以幫助我們獲取Consul集羣中服務的列表以及服務的所有服務地址和端口。可能有同學會問,這不就是Consul本身支持的功能嗎?的確,沒啥毛病,Consul Template本身就是一個工具,其關鍵之處在於它通過這種方式可以很方便地與Nginx代理服務器集成。從而可以幫助Nginx動態地根據Consul中的服務信息維護自身的服務列表,從而與整個Spring Cloud微服務體系形成聯動,實現端到端的高可用架構體系。

此外,通過Consul Template我們也可以很容易地將微服務體系中的任何一個微服務透過Nginx使用公網域名進行服務暴露。例如,隨着微服務邏輯從業務上逐步分層,這裏所說的分層是指這個微服務體系越來越大,應用本身按照業務線會被劃分成多個子系統,例如獨立於用戶C端微服務系統,我們需要開發一個To B的微服務組,而該微服務組由於功能上獨立於C端用戶系統,所以我們並不想讓其調用鏈路透過C端Api Gateway,而是想直接將其微服務通過新域名暴露至公網服務,供App端進行調用。像這樣的需求,我們只需要使用Consul Template進行一下配置,就能實現Nginx的動態代理轉發了。這樣從架構運維體驗上來講,使用Consul Template就會讓Spring Cloud微服務的部分運維工作變得非常簡單了。

Consul Template+Nginx實現微服務部署的高可用

那麼接下來,我們就來看看如何利用Consul Template+Nginx這樣的組合來實現Spring Cloud微服務部署的高可用吧。這裏爲了演示簡單,小碼哥首先在自己的Mac筆記本上安裝一個單機版的Consul(Ps:真是的生產環境Consul是集羣部署的),下載後將命令文件拷貝至相應目錄,並啓動Consul如下:

./consul agent -dev

此時訪問本機的8500端口,例如:http://127.0.0.1:8500,就能夠看到Consul被成功啓動來,如圖所示

Spring Cloud微服務運維神器之Consul Template?

接下來,我們從Consul Template官方地址:https://releases.hashicorp.com/consul-template/0.20.0/,下載Consul Template的可執行文件。並將其解壓到/usr/local/bin/目錄即可,之後運行:“consul-template -h”命令,如果能夠正常執行則說明Consul Template在本機就安裝成功了!<mpchecktext style="margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; word-wrap: break-word !important;">,</mpchecktext>

之後作者在Mac筆記本上安裝一個Nginx反向代理服務器,下載地址爲:http://nginx.org/en/download.html,之後將軟件安裝文件存放到主機用戶目錄並開始執行安裝命令,執行如下步驟

爲安裝文件修改權限

chmod a+rwx *

執行編譯命令

./configure --without-http_rewrite_module

執行安裝命令

make && make install

啓動nginx

/usr/local/nginx/sbin/nginx

此時訪問本機80端口http://localhost/,如果出現如下畫面:

Spring Cloud微服務運維神器之Consul Template?

就說明本機nginx服務安裝成功了!注意這裏作者只是在自己的工作電腦上爲了進行演示而進行的基本安裝操作,生產Linux環境的安裝方式還請大家參考其他更加細節的文章。

在準備完Nginx、Consul及Consul Template之後,那麼該如何進行配置呢?此時作者基於Spring Cloud在本地開發來一個微服務,並且將該微服務註冊到本地剛纔安裝的Consul中,這裏作者啓動兩個實例,如下:

Spring Cloud微服務運維神器之Consul Template?

此時,在Consul中就註冊了名叫wallet服務的兩個副本,接下來作者就通過Consul Template的配置模擬下通過Nginx反向代理域名訪問wallet服務的接口,並實現負載均衡功能!

一般在正式的生產環境中域名會通過DNS解析到Nginx反向代理服務器中,這裏爲了模擬測試,我們在Mac筆記本的/private/etc/hosts文件中加一個模擬的域名映射,如下:

127.0.0.1  api.wudimanong.com

接下來我們創建一個consul-template文件模板consul-wallet.tpl,其中的內容就是要把我們在前面啓動的wallet微服務通過Nginx暴露出去,內容如下:

{{if service "wallet"}}
server {
    listen  80;
    server_name  ~^wallet\.(.+\.)?wudimanong\.(com|cn)$;
    access_log  /data/logs/nginx/wallet-access.log ;
    error_log  /data/logs/nginx/wallet-error.log ;

    client_max_body_size  1000m;

    location / {
        include proxy.conf;
        proxy_pass http://server-wallet;
    }
}

upstream server-wallet {
{{range service "wallet"}}  server {{.Address}}:{{.Port}};
{{end}}}
{{ end }}

以上文件模板的內容基本上就是和Nginx的配置語法類似,接下來我們啓動Consul Template,命令如下:

sudo consul-template -consul-addr "127.0.0.1:8500" -template "/Users/guanliyuan/consul-wallet.tpl:/usr/local/nginx/conf.d/consul-wallet.conf:/usr/local/nginx/sbin/nginx -s reload" > /Users/guanliyuan/logs/wallet-template.log 2>&1 &

啓動Consul Template之後我們可以查看通過Consul Template模版生成的Nginx配置文件“/../conf.d/consul-wallet.conf”,代碼如下:

server {
    listen  80;
    server_name  ~^wallet\.(.+\.)?wudimanong\.(com|cn)$;
    access_log  /data/logs/nginx/wallet-access.log ;
    error_log  /data/logs/nginx/wallet-error.log ;

    client_max_body_size  1000m;

    location / {
        include proxy.conf;
        proxy_pass http://server-wallet;
    }
}

upstream server-wallet {
  server 192.168.0.106:9090;
  server 192.168.0.106:9091;
}

可以看到Consul Template實際上是爲Nginx動態從Consul中獲取了服務的地址及端口列表,如果此時我們關掉wallet微服務的一個實例,相應地我們就會從生成的Nginx配置中看到下線的實例的服務地址和端口就被剔除了,代碼如下:

server {
    listen  80;
    server_name  ~^wallet\.(.+\.)?wudimanong\.(com|cn)$;
    access_log  /data/logs/nginx/wallet-access.log ;
    error_log  /data/logs/nginx/wallet-error.log ;

    client_max_body_size  1000m;

    location / {
        include proxy.conf;
        proxy_pass http://server-wallet;
    }
}

upstream server-wallet {
  server 192.168.0.106:9091;
}

到這裏大家應該是比較清晰地理解Consul Template到底是個什麼東西了。它實際上就是通過監聽Consul服務,並依據模版中定義的服務名稱去獲取服務在Consul中實例的地址及端口列表,然後動態地將這些服務的地址及端口準實時地同步到Nginx配置中。示意圖如下:

Spring Cloud微服務運維神器之Consul Template?

此時,在網絡域名正常的情況下我們通過域名訪問wallet服務相關的接口了,並且已經由Nginx爲我們實現了負載均衡邏輯。與Spring Cloud內部微服務通過Ribbon客戶端依賴實現負載均衡相配合,整個Spring Cloud的服務基本運維邏輯就算實現了!

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