使用nginx的負載均衡機制實現用戶無感更新服務

用戶請求的轉發是接口服務在部署時必須要做的一步。請求轉發的步驟大約分爲如下幾步:

  1. 域名解析到轉發服務器

  2. 轉發服務器會根據權重(weight)、備用(backup)配置轉發到統一網關

  3. 如果統一網關存在灰度的配置,需要根據身份或者頭信息過濾請求

  4. 轉發到具體的業務服務

目前市面上優秀的 請求轉發有很多種,比如:Nginx、 F5、 Kong、 Tengine等,其中 Tengine是阿里巴巴基於 Nginx進行封裝,我們本章的內容基於 Nginx進行講解,我們先來準備下 nginx的測試環境。準備環境如果你的測試環境沒有安裝 Nginx,下面我通過兩種方式來說下具體的安裝過程。

way安裝環境

如果你是 OSX系統,可以直接使用 brew管理工具進行安裝,這種方式比較簡單,自動從遠程服務器下載最新穩定的版本進行解壓、配置環境等。

# 安裝nginx

➜ ~ brew install nginx

靜靜等待~安裝完成後,我們先來修改下端口號(brew安裝包把默認的監聽端口號改爲了 8080,一般在使用解壓的方式安裝時監聽端口都是 80)。我們需要先找到 nginx.conf這個文件的位置:

➜ ~ sudo find / -name nginx.conf

/usr/local/etc/nginx/nginx.conf

 

找到文件後,我們通過 sudo vi/usr/local/etc/nginx/nginx.conf命令來修改默認的端口號,位置如下:

 

server {

listen 80;

server_name localhost;

#...

}

 

修改後保存退出。最後不要忘記重啓 Nginx服務。

➜ ~ brew services restart nginx

 

解壓包方式
首先去 nginx官方提供 http://nginx.org/download 的下載地址去挑選自己中意的版本,下面以 1.17.7版本示例:

  • http://nginx.org/download/nginx-1.17.7.tar.gz

點擊下載完成後解壓安裝即可(注意編譯環境,可能會缺少一些依賴庫,本機安裝對應的依賴就可以了)

 

# 解壓nginx

tar -xvf nginx-1.17.7.tar.gz

# 進入目錄

cd nginx-1.17.7

# 配置

./configure --prefix=/usr/local/nginx

# 編譯

sudo make

# 安裝

sudo make install

# 進入nginx執行目錄

cd /usr/local/nginx/sbin

# 啓動nginx

./nginx

 

安裝完成如果訪問 http://127.0.0.1 可以看到 Welcometo nginx!字樣,說明我們已經安裝成功了。

實例項目
爲了演示更新服務用戶無痛感知,我們先來創建一個簡單的 SpringBoot示例項目,在項目內添加一個測試接口,項目 pom.xml依賴如下所示:

<dependencies>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>

</dependencies>

 

示例接口
創建一個名爲 TestController的測試控制器,如下所示:

 

/**

* 測試控制器

*

* @author 恆宇少年

*/

@RestController

@RequestMapping(value = "/test")

public class TestController {

@Autowired

private ServerProperties serverProperties;

 

@GetMapping

public String hello() {

return "請求分發到了,端口號:" + serverProperties.getPort() + "的服務,接口訪問成功.";

}

}

 

配置轉發
我們測試所需要的請求接口已經準備好了,接下來需要在訪問 nginx時將請求轉發到我們測試的接口,配置轉發時需要用到 nginx的兩個關鍵字,分別是 upstream、 location

  • upstream:服務器組,配置請求分發到組內多臺服務器。

  • location:轉發的路徑前綴,如:"/user/",當我們訪問 http://127.0.0.1/user/1時,就會執行該 location的轉發業務。

upstream轉發流程如下圖所示

配置upstream

在 nginx.conf文件 http內添加轉發的 服務器組(upstream),如下所示:

# 負載配置

upstream test {

server 127.0.0.1:8080 weight=1;

server 127.0.0.1:9090 weight=2;

server 127.0.0.1:9000 backup;

}

 

 

配置location

在上面已經配置好了服務器組,我們需要把名爲 test的服務器組作爲代理的方式配置在 location,在 location的 server下新增一個 location,如下所示:

# 配置"/lb/"路徑的請求全部轉發到本地8080端口

location /lb/ {

proxy_pass http://test/;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_connect_timeout 50;

proxy_read_timeout 50;

proxy_send_timeout 50;

}
 

 

重啓nginx

我這裏是使用 brew的方式安裝的 nginx,所以重啓的命令如下所示:

brew services restart nginx

 

如果你是 安裝包的方式安裝:

# 進入安裝包目錄

cd /usr/local/nginx/sbin

# 重載

./nginx -s reload

 

 

權重配置

在 nginx中有一個權重的概念,根據權重值的大小來控制請求流量,當權重的配值越大時,流量分發就會越多,我們在 test服務器組內配置權重解釋:

  • server127.0.0.1:8080weight1; 權重佔比爲 1/3,每3次請求會轉發1次到這臺服務器上。

  • server127.0.0.1:9090weight2; 權重佔比爲 2/3,每3次請求會轉發2次到這臺服務器上。

備用配置

當我們在 upstream內的 server尾部添加 backup時,表示這臺服務器是備用服務器,只有其他服務器都停機時纔會啓用,我們更新時其實就利用的這一點。運行測試爲了演示方便我們直接將本章測試項目 package打包後,通過 --server.port來指定運行的端口號來模擬多臺服務器的場景。

# 啓動127.0.0.1:8080服務器

java -jar target/use-nginx-loadbalance-upgrade-service-0.0.1-SNAPSHOT.jar --server.port=8080

# 啓動127.0.0.1:9090服務器

java -jar target/use-nginx-loadbalance-upgrade-service-0.0.1-SNAPSHOT.jar --server.port=9090

# 啓動127.0.0.1:9000備用服務器

java -jar target/use-nginx-loadbalance-upgrade-service-0.0.1-SNAPSHOT.jar --server.port=9000

 

 

注意:使用多個終端窗口運行服務。

在 nginx.confserver中配置 location的轉發條件爲 /lb/路徑前綴,所以我們訪問 http://127.0.0.1/lb/test (由於 nginx監聽的端口號是80,所以通過 nginx訪問轉發時不需要攜帶端口號)就會被轉發到 test服務器組內的服務器上。

測試點:權重轉發

curl http://localhost/lb/test

端口號:8080,接口訪問成功.

 

curl http://localhost/lb/test

端口號:9090,接口訪問成功.

 

curl http://localhost/lb/test

端口號:9090,接口訪問成功.

 

curl http://localhost/lb/test

端口號:8080,接口訪問成功.

 

根據訪問的結果來看, 8080端口號的服務是每3次中請求了 1次,而 9090則是每3次中請求了 2次,這一點正是符合我們配置的權重( weight),測試通過。

測試點:備用生效

我們把 8080、 9090這兩個服務都停掉,再次訪問 http://127.0.0.1/lb/test 。

 

curl http://localhost/lb/test

端口號:9000,接口訪問成功.

 

curl http://localhost/lb/test

端口號:9000,接口訪問成功.

 

curl http://localhost/lb/test

端口號:9000,接口訪問成功.

可以看到我們的備用服務器啓用了,已經把全部的請求流量轉發到 9000這臺服務上,測試通過。

總結

當我們把 8080、 9090都停掉時,備用服務器會啓用,這時我們就可以來更新 8080、 9090這兩個服務的運行代碼,更新完成後重啓,只要 8080、 9090這兩臺服務器有一臺處於運行狀態, nginx就不會把流量分發到備用的 9000,以此類推把全部的服務都更新完成。

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