搭建負載均衡和服務發現服務的目的
隨着網站業務的不斷提升,單個服務器的性能越來越難滿足客戶的業務需求,所以很多情況下,需要使用多服務器實例和負載均衡器來滿足業務需要。
Nginx
什么是Nginx
Nginx一款高性能的Web服務器,它既可以單獨使用,也可以作為負載均衡器與其他Web服務器組合使用。
Nginx安裝
我們可用從Nginx官網上(http://nginx.org/)下載最新的Windows版本壓縮包。
壓縮包解壓之后目錄結構如下:
Nginx的配置
events {
worker_connections 1024;
}
http {
upstream backend
{
server 127.0.0.1:91 weight=1;
server 127.0.0.1:92 weight=1;
}
server
{
location / {
proxy_pass http://backend;
}
}
}
其中upstream部分定義了對於HTTP請求的負載均衡。 當用戶發送請求到http://backend的時候,Nginx會將這個請求轉發到指定服務器IP列表中的一個。配置中的weight字段設置了指定服務器IP的權重,權重越高,轉發的可能性越高。
常見問題
Nginx默認會占用80端口,這個和IIS有沖突, 所以需要在nginx.conf中修改Nginx的默認端口
events {
worker_connections 1024;
}
http {
upstream backend
{
server 127.0.0.1:92 weight=1;
server 127.0.0.1:93 weight=1;
}
server
{
listen 81;
server_name localhost;
location / {
proxy_pass http://backend;
}
}
}
實例
當前網站有2個實例部署在IIS中,siteA IP 127.0.0.1:92, siteB IP 127.0.0.1:93。
siteA和siteB都只有一個index.html頁面。
代碼如下:
siteA
<!DOCTYPE html>
<html>
<head>
<title>Nginx Sample</title>
</head>
<body>
<h1>This is site A</h1>
</body>
</html>
siteB
<!DOCTYPE html>
<html>
<head>
<title>Nginx Sample</title>
</head>
<body>
<h1>This is site B</h1>
</body>
</html>
Nginx服務器使用81端口。 我們希望實現的效果是當用戶訪問http://127.0.0.1:81時,Nginx隨機將請求轉發到http://127.0.0.1:92或者http://127.0.0.1:93上
siteA網站的index.html頁效果如下
siteB網站的index.html頁效果如下
實現步驟
a. 首先我們修改Nginx的配置文件
events {
worker_connections 1024;
}
http {
upstream 127.0.0.1
{
server 127.0.0.1:91 weight=1;
server 127.0.0.1:92 weight=1;
}
server
{
listen 81;
server_name localhost;
location / {
proxy_pass http://127.0.0.1;
}
}
}
b. 在命令行啟動NginX
c. 打開瀏覽器,輸入http://127.0.0.1:81, 反復按F5刷新, 網站內容在siteA和siteB之間切換,這說明負載均衡已經成功啟用。
Consul
什么是Consul
Consul是一款用高性能服務注冊/服務健康檢查組件
Consul安裝
我們可以從官網(https://www.consul.io/downloads.html) 中對應版本的32位或64位程序。下載之后就是一個可執行文件consul.exe
如何啟動Consul
使用命令consul agent -dev, consul就會已開發模式啟動(開發模式不會啟用持久化,程序關閉后所有配置會丟失)
Consul服務后台###
Consul服務啟動之后,我們可以訪問,http://localhost:8500 來訪問Consul的管理后台,界面如下。
在這個管理后台中可以查看Consul注冊的所有服務和所有主機節點。
注冊服務###
Consul服務啟動之后,我們可以調用一些相應的Api來注冊服務(相關Api列表 https://www.consul.io/api/index.html)
繼續我們的實例
現在我們嘗試將之前的siteA, siteB注冊到Consul中。
a. 首先這里我們去下載一個Curl程序(https://curl.haxx.se/) 來調用Api(這里可以用POSTMAN代替)
b. 創建2個json文件siteA.json, siteB.json。其內容如下
siteA.json
{
"ID":"webA",
"Name":"web",
"Tags":[],
"Address":"127.0.0.1",
"Port":92,
"EnableTagOverride":false
}
siteB.json
{
"ID":"webB",
"Name":"web",
"Tags":[],
"Address":"127.0.0.1",
"Port":93,
"EnableTagOverride":false
}
這里的Name就是服務名稱,ID就是該服務的一個實例ID。
c. 使用curl調用注冊服務Api,將siteA和siteB注冊到Consul中
curl --request PUT --data @siteA.json http://localhost:8500/v1/agent/service/register
curl --request PUT --data @siteB.json http://localhost:8500/v1/agent/service/register
d. 回到Consul管理頁面,我們會發現服務列表中會出現一個名為web的服務,這個服務有2個實例
如果看到以上結果,就說明2個Web服務實例注冊成功了。
添加服務健康檢查
將服務注冊到Consul之后,得到的第一個好處就是可以借助Consul對每個服務實例進行健康檢查。
繼續修改我們的實例
a. 關閉之前打開的Consul服務,新開一個命令行窗口,使用consul agent -dev重新開啟一個新的Consul服務
b. 在siteA和siteB網站目錄中,分別添加一個healthcheck.html文件,其內容如下
<html>
<head>
<title>Nginx Sample</title>
</head>
<body>
<h1>This is health check page</h1>
</body>
</html>
c. 修改之前的siteA.json和siteB.json
siteA.json
{
"ID":"webA",
"Name":"web",
"Tags":[],
"Address":"127.0.0.1",
"Port":92,
"Checks":[{
"http":"http://127.0.0.1:92/healthcheck.html",
"interval":"5s"
}],
"EnableTagOverride":false
}
siteB.json
{
"ID":"webB",
"Name":"web",
"Tags":[],
"Address":"127.0.0.1",
"Port":93,
"Checks":[{
"http":"http://127.0.0.1:93/healthcheck.html",
"interval":"5s"
}],
"EnableTagOverride":false
}
d. 重新使用curl調用注冊服務Api, 將siteA和siteB注冊到Consul中
e. 打開siteA目錄,將healthcheck.html改名為healthcheck1.html(這個操作相當於模擬siteA所在的服務器崩潰, consul請求不到healthcheck.html文件了)
f. 回到Consul管理界面,我們看一下結果,它會顯示webA檢查失敗
g. 將healthcheck1.html改名會healthcheck.html, 等待5秒后,返回consul界面中,webA已經變回檢測通過狀態。
Consul Template
什么是Consul Template
Consul Template是Consul的一個擴展組件,可以讀取Consul中的服務配置,根據指定模板生成不同的配置文件。
所以這里我們就可以組合使用Consul, Consul Template來動態生成Nginx的配置文件, 並自動重啟Nginx。
安裝Consul Template
我們可以從官網(https://releases.hashicorp.com/consul-template)中下載consul-template.exe
啟動Consul Template
consul-template -consul-addr 127.0.0.1:8500 -template "./2.tpl:./conf/nginx.conf:nginx -s reload"
這里-consul-addr
參數是指定consul服務的地址, -template
是指定consul template使用的模板,生成的新文件地址,以及生成新文件之后的執行的命令。
繼續我們的案例
現在我們添加一個新的siteC, ip為127.0.0.1:94, siteC中也只有index.html和healthcheck.html2個文件
a. 創建2.tpl, 文件內容如下, 這里使用的是consul-template的模板語法(相應語法介紹可以查看https://github.com/hashicorp/consul-template)
events {
worker_connections 1024;
}
http {
upstream 127.0.0.1{
{{ range service "web" }}
server {{ .Address }}:{{ .Port }} weight=1;{{ end }}
}
server {
listen 81;
server_name localhost;
location / {
proxy_pass http://127.0.0.1;
}
}
}
b. 使用命令consul-template -consul-addr 127.0.0.1:8500 -template "2.tpl:conf/nginx.conf:nginx -s reload"
啟動consul-template
c. 創建siteC.json, 使用curl將siteC注冊到consul中, siteC.json內容如下
{
"ID":"webC",
"Name":"web",
"Tags":[],
"Address":"127.0.0.1",
"Port":94,
"Checks":[{
"http":"http://127.0.0.1:94/healthcheck.html",
"interval":"5s"
}],
"EnableTagOverride":false
}
d. 打開瀏覽器,輸入http://localhost:81, 反復按F5刷新,你會發現siteC已經加入到了Nginx負載均衡配置中。d
e. 然后我們進行一個測試,我們將siteA的healthcheck.html重命名為healthcheck1.html
f. 回到剛才頁面中繼續按F5刷新,我們會發現現在只顯示siteB和siteC的內容了,這是因為siteA已經被consul認定為不健康的服務,所以consul-template重新生成Nginx的配置文件,將siteA中配置文件中抹除,並重新啟動了Nginx。