nginx是一款很是優秀的反向代理工具,支持請求分發,負載均衡,以及緩存等等很是實用的功能。在請求處理上,nginx採用的是epoll模型,這是一種基於事件監聽的模型,於是其具有很是高效的請求處理效率,單機併發能力可以達到上百萬。nginx接收到的請求能夠經過負載均衡策略分發到其下一級的應用服務器,這些服務器通常是以集羣方式部署的,於是在性能不足的狀況下,應用服務器能夠經過加機器的方式擴展流量。此時,對於一些特大型的網站,性能的瓶頸就來自於nginx了,由於單機的nginx的併發能力是有上限的,而nginx自己是不支持集羣模式的,於是此時對nginx的橫向擴展就顯得尤其重要。html
keepalived是一款服務器狀態檢測和故障切換的工具。在其配置文件中,能夠配置主備服務器和該服務器的狀態檢測請求。也就是說keepalived能夠根據配置的請求,在提供服務期間不斷向指定服務器發送請求,若是該請求返回的狀態碼是200,則表示該服務器狀態是正常的,若是不正常,那麼keepalived就會將該服務器給下線掉,而後將備用服務器設置爲上線狀態。java
lvs是一款用於四層負載均衡的工具。所謂的四層負載均衡,對應的是網絡七層協議,常見的如HTTP協議是創建在七層協議上的,而lvs做用於四層協議上,也即:傳輸層,網絡層,數據鏈路層和物理層。這裏的傳輸層主要協議有TCP和UDP協議,也就是說lvs主要支持的方式是TCP和UDP。也正是由於lvs是處於四層負載均衡上的,於是其處理請求的能力比常見的服務器要高很是多,好比nginx的請求處理就是創建在網絡七層上的,lvs的負載均衡能力是nginx的十倍以上。nginx
經過上面的介紹,咱們能夠發現,在特大型網站中,應用服務器是能夠橫向擴容的,而nginx是不支持橫向擴容的,此時nginx就會成爲性能瓶頸。而lvs是一款負載均衡工具,於是若是咱們結合lvs和nginx,那麼就能夠經過部署多臺nginx服務器,經過lvs的負載均衡能力,將請求均衡的分發到各個nginx服務器上,再由nginx服務器分發到各個應用服務器,這樣,咱們就實現了nginx的橫向擴展了。因爲nginx本質上也是一款應用服務器,於是其也有可能宕機,於是這裏結合keepalived就能夠實現nginx的故障檢測和服務切換。也就是說,經過keepalived+lvs+nginx,咱們實現了nginx的高可用集羣模式。算法
在上面的介紹中,咱們會注意到,雖然keepalived+lvs+nginx實現了nginx的集羣模式,可是在咱們使用nginx的時候,其自己是有一個ip和端口的,默認監聽的端口是80和443,那麼lvs是如何實現將請求分發給具備不一樣ip和端口的nginx服務器的呢?這裏就是經過虛擬ip實現的,所謂虛擬ip就是對外提供一個公共的ip,外部客戶端請求的都是這個ip,lvs在接收到虛擬ip的請求以後,經過配置的調度器和負載均衡策略,選擇一個目標nginx服務器,而後將請求轉發給該服務器。這裏lvs有兩個概念,就是調度器和負載均衡策略,所謂的調度器指的是lvs將會以何種方式處理請求和響應數據,其主要有三種調度器:shell
1. VMware; 2. 4臺CentOs7虛擬主機:172.16.28.130, 172.16.28.131, 172.16.28.132, 172.16.28.133 3. 系統服務:LVS, Keepalived 4. Web服務器:nginx 5. 集羣搭建:LVS DR模式
在四臺虛擬機上,咱們以以下方式搭建集羣:後端
172.16.28.130 lvs+keepalived 172.16.28.131 lvs+keepalived 172.16.28.132 nginx 172.16.28.133 nginx
這裏咱們使用172.16.28.130
和172.16.28.131
兩臺機器做爲lvs+keepalived
的工做機器,也就是說這兩臺機器的做用主要是進行負載均衡和故障檢測和下線的;咱們使用172.16.28.132
和172.16.28.133
兩臺機器做爲應用服務器,主要是對外提供服務的。這四臺服務器做爲整個後端集羣服務,而且對外提供的虛擬ip是172.16.28.120
。須要說明的是,這裏的keepalived
所檢測的服務是兩臺lvs
服務器,這兩臺服務器,一臺做爲master服務器,一臺做爲backup服務器,二者在負載均衡的配置上是徹底同樣的。在正常狀況下,客戶端請求虛擬ip的時候,lvs
會將該請求轉發到master服務器上,而後master服務器根據配置的負載均衡策略選擇一臺應用服務器,而且將請求發送給該應用服務器進行處理。若是在某個時刻,lvs的master服務器因爲故障宕機了,keepalived就會檢測到該故障,而且進行故障下線,而後將backup機器上線用於提供服務,從而實現故障轉移的功能。瀏覽器
在172.16.28.130
和172.16.28.131
上安裝ipvs和keepalived:緩存
# 安裝ipvs sudo yum install ipvsadm
# 安裝keepalived sudo yum install keepalived
在172.16.28.132
和172.16.28.133
上安裝nginx:bash
# 安裝nginx sudo yum install nginx
須要注意的是,在兩臺nginx服務器上須要將防火牆關閉,不然lvs+keepalived的兩臺機器就沒法將請求發送到兩臺nginx服務器上來:服務器
# 關閉防火牆 systemctl disable firewalld.service
查看兩臺負載均衡機器是否支持lvs:
sudo lsmod |grep ip_vs
# 若是看到以下結果,則說明是支持的 [zhangxufeng@localhost ~]$ sudo lsmod|grep ip_vs ip_vs 145497 0 nf_conntrack 137239 1 ip_vs libcrc32c 12644 3 xfs,ip_vs,nf_conntrack
若是上述命令沒有任何結果,則執行sudo ipvsadm
命令啓動ipvs以後,再經過上述命令進行查看便可。啓動ipvs以後,咱們就能夠在/etc/keepalived/
目錄下編輯keepalived.conf
文件,咱們以172.16.28.130
機器做爲master機器,master節點配置以下:
# Global Configuration global_defs { lvs_id director1 # 指定lvs的id } # VRRP Configuration vrrp_instance LVS { state MASTER # 指定當前節點爲master節點 interface ens33 # 這裏的ens33是網卡的名稱,經過ifconfig或者ip addr能夠查看 virtual_router_id 51 # 這裏指定的是虛擬路由id,master節點和backup節點須要指定同樣的 priority 151 # 指定了當前節點的優先級,數值越大優先級越高,master節點要高於backup節點 advert_int 1 # 指定發送VRRP通告的間隔,單位是秒 authentication { auth_type PASS # 鑑權,默認經過 auth_pass 123456 # 鑑權訪問密碼 } virtual_ipaddress { 172.16.28.120 # 指定了虛擬ip } } # Virtual Server Configuration - for www server # 後臺真實主機的配置 virtual_server 172.16.28.120 80 { delay_loop 1 # 健康檢查的時間間隔 lb_algo rr # 負載均衡策略,這裏是輪詢 lb_kind DR # 調度器類型,這裏是DR persistence_time 1 # 指定了持續將請求打到同一臺真實主機的時間長度 protocol TCP # 指定了訪問後臺真實主機的協議類型 # Real Server 1 configuration # 指定了真實主機1的ip和端口 real_server 172.16.28.132 80 { weight 1 # 指定了當前主機的權重 TCP_CHECK { connection_timeout 10 # 指定了進行心跳檢查的超時時間 nb_get_retry 3 # 指定了心跳超時以後的重複次數 delay_before_retry 3 # 指定了在嘗試以前延遲多長時間 } } # Real Server 2 Configuration real_server 172.16.28.133 80 { weight 1 # 指定了當前主機的權重 TCP_CHECK { connection_timeout 10 # 指定了進行心跳檢查的超時時間 nb_get_retry 3 # 指定了心跳超時以後的重複次數 delay_before_retry 3 # 指定了在嘗試以前延遲多長時間 } } }
上面是master節點上keepalived的配置,對於backup節點,其配置與master幾乎是一致的,只是其state和priority參數不一樣。以下是backup節點的完整配置:
# Global Configuration global_defs { lvs_id director2 # 指定lvs的id } # VRRP Configuration vrrp_instance LVS { state BACKUP # 指定當前節點爲master節點 interface ens33 # 這裏的ens33是網卡的名稱,經過ifconfig或者ip addr能夠查看 virtual_router_id 51 # 這裏指定的是虛擬路由id,master節點和backup節點須要指定同樣的 priority 150 # 指定了當前節點的優先級,數值越大優先級越高,master節點要高於backup節點 advert_int 1 # 指定發送VRRP通告的間隔,單位是秒 authentication { auth_type PASS # 鑑權,默認經過 auth_pass 123456 # 鑑權訪問密碼 } virtual_ipaddress { 172.16.28.120 # 指定了虛擬ip } } # Virtual Server Configuration - for www server # 後臺真實主機的配置 virtual_server 172.16.28.120 80 { delay_loop 1 # 健康檢查的時間間隔 lb_algo rr # 負載均衡策略,這裏是輪詢 lb_kind DR # 調度器類型,這裏是DR persistence_time 1 # 指定了持續將請求打到同一臺真實主機的時間長度 protocol TCP # 指定了訪問後臺真實主機的協議類型 # Real Server 1 configuration # 指定了真實主機1的ip和端口 real_server 172.16.28.132 80 { weight 1 # 指定了當前主機的權重 TCP_CHECK { connection_timeout 10 # 指定了進行心跳檢查的超時時間 nb_get_retry 3 # 指定了心跳超時以後的重複次數 delay_before_retry 3 # 指定了在嘗試以前延遲多長時間 } } # Real Server 2 Configuration real_server 172.16.28.133 80 { weight 1 # 指定了當前主機的權重 TCP_CHECK { connection_timeout 10 # 指定了進行心跳檢查的超時時間 nb_get_retry 3 # 指定了心跳超時以後的重複次數 delay_before_retry 3 # 指定了在嘗試以前延遲多長時間 } } }
將master和backup配置成徹底同樣的緣由是,在master宕機時,能夠根據backup的配置進行服務的無縫切換。
在lvs+keepalived機器配置完成以後,咱們下面配置兩臺應用服務器的nginx配置。這裏咱們是將nginx做爲應用服務器,在其配置文件中配置返回狀態碼爲200,而且會將當前主機的ip返回,以下是其配置:
worker_processes auto; # pid /run/nginx.pid; events { worker_connections 786; } http { server { listen 80; # 這裏是直接返回200狀態碼和一段文本 location / { default_type text/html; return 200 "Hello, Nginx! Server zhangxufeng@172.16.28.132\n"; } } }
worker_processes auto; # pid /run/nginx.pid; events { worker_connections 786; } http { server { listen 80; # 這裏是直接返回200狀態碼和一段文本 location / { default_type text/html; return 200 "Hello, Nginx! Server zhangxufeng@172.16.28.133\n"; } } }
能夠看到,兩臺機器返回的文本中主機ip是不同的。nginx配置完成後,能夠經過以下命令進行啓動:
sudo nginx
在啓動nginx以後,咱們須要配置虛擬ip,這是由於咱們使用的lvs調度器是DR模式,前面咱們講到過,這種模式下,對客戶端的響應是真實服務器直接返回給客戶端的,而真實服務器須要將響應報文中的源ip修改成虛擬ip,這裏配置的虛擬ip就是起這個做用的。咱們編輯/etc/init.d/lvsrs
文件,寫入以下內容:
#!/bin/bash ifconfig lo:0 172.16.28.120 netmask 255.255.255.255 broadcast 172.16.28.120 up route add -host 172.16.28.120 dev lo:0 echo "0" > /proc/sys/net/ipv4/ip_forward echo "1" > /proc/sys/net/ipv4/conf/lo/arp_ignore echo "2" > /proc/sys/net/ipv4/conf/lo/arp_announce echo "1" > /proc/sys/net/ipv4/conf/all/arp_ignore echo "2" > /proc/sys/net/ipv4/conf/all/arp_announce exit 0
編寫完成後運行該腳本文件便可。而後將兩臺lvs+keepalived機器上的keepalived服務啓動起來便可:
sudo service keepalived start
最後能夠經過以下命令查看配置的lvs+keepalived的策略:
[zhangxufeng@localhost keepalived]$ sudo ipvsadm -ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 172.16.28.120:80 rr -> 172.16.28.132:80 Route 1 0 0
根據上述步驟,咱們配置完成了一個lvs+keepalived+nginx的集羣。在瀏覽器中,咱們能夠訪問http://172.16.28.120
便可看到以下響應:
Hello, Nginx! Server zhangxufeng@172.16.28.132
屢次刷新瀏覽器以後,能夠看到瀏覽器中顯示的文本切換以下,這是由於lvs的負載均衡策略產生的:
Hello, Nginx! Server zhangxufeng@172.16.28.133
本文首先對lvs和keepalived的工做原理進行了講解,分別介紹了其工做的幾種模式,而後對lvs+keepalived+nginx搭建nginx集羣的方式進行詳細講解,而且說明了其中所須要注意的問題。