使用Nginx、Keepalived構建文藝負載均衡

面對網站服務器端負載增大的問題,是「拿15萬¥買一臺服務器」來解決,仍是靠「加三倍服務器」來解決?仍是用其它一些辦法?javascript

對於一個訪問量日益增長的網站架構而言,從單機到集羣、從集羣到分佈式,架構演化是必然的。php

接手環境,分析瓶頸,擴展架構css

筆者如今的環境在剛接手時算是單機LAMP環境。在單機LAMP環境時,因爲訪問量逐漸變大,網站會常常出現打不開的狀況,爲了解決這個問題在LAMP前端臨時加了一臺vanish來緩存一些靜態文件,從而減輕了web服務器的負載。再到後來爲了知足業務訪問需求,將架構改成CDN+Nginx負載均衡(反向代理)+LNMP+代碼層緩存+MySQL主從,從而將網站總體負載性能提高15倍,且訪問速度也獲得很大提高。前端

負載均衡爲何要選擇使用Nginx呢?java

普通負載均衡用LVS,文藝負載均衡用Nginx/F5/HAproxy,XX負載均衡用NLBnode

LVS:四層負載均衡的典型表明,目前已經被添加到linux發行版的內核。LVS用於較爲成熟,所以再也不作類述,在此推薦一篇不錯的LVS文章:《互聯網運營智慧》第六章負載均衡及服務器集羣(LVS)linux

Nginx/F5/HAproxy:均爲七層負載均衡,F5爲商業設備,功能強大,但價格不菲,因此在此不作討論;HAproxy爲重量級的七層負載均衡/反向代理程序,通常應用於大中型站點;而Nginx雖然屬於輕量級產品,可是功能絕不遜色與HAproxy,如能夠對靜態文件能夠實現緩存、能夠經過URL、目錄結構、靜動分離對網站實現分流,還能夠實現對後端服務器狀態碼健康檢測、對網絡依賴較小、對虛擬主機支持友好等等,這也是筆者選擇Nginx來作負載均衡的緣由。nginx

NLB:windows下的東東,性能、可操做性可想而知。在此也提醒一下各位同仁,針對HTTP類的應用千萬不要選擇使用windows,如一樣的業務放linux上只需兩臺服務器,而放windows上可能會須要三臺甚至更多,運維/硬件採購成本也會增長,同時license也是一筆不小的費用。國內較大的一些web站點後端架構爲windows的分別有京東商城、噹噹網、凡客誠品、麥包包。web

使用Nginx構建負載均衡時須要注意的幾個問題redis

Session同步:因爲筆者所維護的架構硬件預算受限,因此在整個架構中沒有共享存儲,針對於session處理,筆者使用ip_hash來解決後端服務器session問題。另外,關於存儲session,推薦使用redis或memcached(感謝小衛、小灰狼 兩位兄弟的建議)

網站代碼存儲:仍是因爲沒有共享存儲,因此筆者每臺web服務器本地均存放一份代碼,爲了保證多臺web服務器的代碼數據一致性,使用rsync+inotify實現動態同步(具體實現方法會在後面的文章中介紹)。假若硬件條件容許的狀況下,推薦使用NFS來存儲;若考慮到NFS沒法知足性能需求,能夠將NFS的硬盤換成SSD或者使用分佈式文件系統來解決。

負載均衡模式選擇:在不受session困擾的狀況下,負載均衡模式可使用weight,由於ip_hash會有致使後端服務器負載不均的狀況出現。

開始部署Nginx和Keepalived

爲了不負載均衡出現單點故障,因此使用keepalived對Nginx負載均衡作了HA,也就是說當主負載均衡發生軟硬件故障時,負載均衡服務將有備用負載均衡服務器自動接管服務,環境拓撲以下:

Vip:192.168.1.100

Nginx-proxy-master:192.168.1.101

Nginx-proxy-backup:192.168.1.102

安裝Nginx與Keepalived

在Nginx-proxy-master和Nginx-proxy-backup上分別安裝Nginx、Keepalived,兩臺主機安裝步驟相同

安裝Nginx

#yum -y install pcre pcre-devel
#useradd www -s /sbin/nologin
#tar zxvf nginx-0.7.62.tar.gz
#cd nginx-0.7.62
#./configure \
--prefix=/usr/local/nginx \
--user=www \
--group=www \
--with-http_stub_status_module \
--with-http_ssl_module
#make && make install

安裝Keepalived

#tar zxvf keepalived-1.1.17.tar.gz
#cd cd keepalived-1.1.17
#./configure --prefix=/usr/local/keepalived
#make && make install
#rm -rf /usr/local/keepalived/etc/keepalived/keepalived.conf
#mkdir /etc/keepalived

配置Nginx

注:Nginx-proxy-master和Nginx-proxy-backup的Nginx配置相同
#more /usr/local/nginx/conf/nginx.conf
user  www www;
worker_processes 4;
error_log  logs/error.log  crit;
pid        logs/nginx.pid;
worker_rlimit_nofile 51200;
 
events {
       use epoll;
       worker_connections 51200;
       }
 
http  {
      include       mime.types;
      default_type  application/octet-stream;
      server_names_hash_bucket_size 256;
      client_header_buffer_size 256k;
      large_client_header_buffers 4 256k;
      keepalive_timeout  120;
      client_max_body_size  50m;
      client_body_buffer_size  256k;
      server_tokens      off;
     
      gzip               on;
      gzip_min_length    1k;
      gzip_buffers  4 1024k;
      gzip_http_version 1.1;
      gzip_comp_level     6;
      gzip_types        text/plain application/x-javascript text/css application/xml;
 
      #gzip_vary          on;
      proxy_hide_header Vary;
 
      proxy_connect_timeout    600;
      proxy_read_timeout       600;
      proxy_send_timeout       600;
      proxy_buffer_size        16k;
      proxy_buffers            4 64k;
      proxy_busy_buffers_size 128k;
      proxy_temp_file_write_size 128k;
 
      sendfile on;
      tcp_nodelay on;
    # add_header Cache-Control no-cache;
 
upstream blog.luwenju.com  {
 
                ip_hash;
                server   192.168.1.201:80;
                server   192.168.1.202:80;
                server   192.168.1.203:80;
                }
 
server  {
         listen  80;
         server_name  blog.luwenju.com;
         location / {
         index        index.php;
              proxy_pass         http://blog.luwenju.com;
              proxy_set_header   Host             $host;
              proxy_next_upstream error timeout invalid_header http_500 http_502 http_504;
 
              proxy_set_header   X-Forwarded-For        $remote_addr;
                     }
         location /NginxStatus {
                  stub_status    on;
                  allow 192.168.1.0/24;
                  }
              log_format  blog.luwenju.com  '$remote_addr - $remote_user [$time_local] $upstream_addr $upstream_status $request'
 
                                '"$status" $body_bytes_sent "$http_referer"'
 
                                '"$http_user_agent" "$http_x_forwarded_for"';
 
              access_log /usr/local/nginx/logs/blog.luwenju.com_access.log  blog.luwenju.com;
         }
}

說明:upstream爲服務器池。以本配置文件爲例,upstream中共包含三臺web服務器,負載均衡方式爲ip_hash。server爲主機,用於爲upstream內的三臺web服務器實現反向代理,從而到達負載均衡的目的。在本配置文件中只設置了一個主機(server),若是要實現虛擬主機,將一個server分別對應一個upstream便可。

另外,還有兩個關於日誌設置的問題:

負載均衡上是否須要開啓access_log系統/程序剛上線時須要開啓,用於Nginx調試,後期運行穩定後建議將日誌打印關閉,由於對於訪問量較大的網站來講大量日誌寫入磁盤也會致使磁盤性能降低。

如何設置日誌格式可能使用Nginx部署過負載均衡的朋友都知道,當把Nginx反向代理服務器部署在web前端時,web服務器的access_log就沒法獲取用戶的真實ip地址了,針對這個問題的解決辦法會放到後面的文章中<Nginx日誌設置及日誌分析>

在Nginx-proxy-master服務器上配置Keepalived

#more /etc/keepalived/keepalived.conf
! Configuration File for keepalived
 
     global_defs {
     router_id nginx-proxy-ha
     }
 
vrrp_script check_nginx {
     script "/etc/keepalived/check_nginx.sh"
     interval 2
     weight 2
     }
 
vrrp_instance VI_1 {
     state MASTER
     interface eth0
     virtual_router_id 51
     priority 200
     advert_int 1
     authentication {
     auth_type PASS
     auth_pass 1234
     }
 
track_interface { 
     eth0  
 
     } 
 
 
track_script {
     check_nginx
     }
 
virtual_ipaddress {
     192.168.1.100
     }
}

有關check_nginx.sh的說明 若是Nginx-proxy-master上的nginx進程因爲某種緣由中止了,可是keepalived進程還正常運行着,這時候Nginx-proxy-backup上的keepalived會認爲Nginx-proxy-master是正常的(由於master檢測到backup的keepalived進程還存在),因此在這種狀況下當Nginx進程死亡的時候Keepalived也不會發生故障轉移。那麼這個腳本的做用就是讓keepalived實時監控Nginx進程,當發現Nginx進程不存在的時候自動將本機的keepalived進程殺死,從而實現故障轉移,腳本內容以下(注:Nginx-proxy-master和Nginx-proxy-backup上此腳本內容均同樣)

#more /etc/keepalived/check_nginx.sh
#!/bin/bash
if [ "$(ps -ef | grep "nginx: master process"| grep -v grep )" == "" ]
 
 then
  killall -9  keepalived
 
fi

在Nginx-proxy-backup服務器上配置Keepalived

注:Nginx-proxy-backup上keepalived的配置與Nnginx-proxy-master只有兩處不一樣,state爲BACKUP、優先級低於master

#more /etc/keepalived/keepalived.conf
! Configuration File for keepalived
 
     global_defs {
     router_id nginx-proxy-ha
     }
 
vrrp_script check_nginx {
     script "/etc/keepalived/check_nginx.sh"
 
     interval 2
     weight 2
     }
 
vrrp_instance VI_1 {
     state BACKUP
     interface eth0
     virtual_router_id 51
     priority 180
     advert_int 1
     authentication {
     auth_type PASS
     auth_pass 1234
     }
 
track_interface { 
     eth0  
 
     } 
 
 
track_script {
     check_nginx
     }
 
virtual_ipaddress {
     192.168.1.100
     }
}

啓動Nginx和Keepalived

#/usr/local/nginx/sbin/nginx
#/usr/local/keepalived/sbin/keepalived –D
 
#echo 「/usr/local/nginx/sbin/nginx」>>/etc/rc.local
#echo 「/usr/local/keepalived/sbin/keepalived –D」 >>/etc/rc.local

測試負載均衡是否正常工做

一、打開瀏覽器,分別訪問Nginx-proxy-master、Nginx-proxy-backup、vip,如都能訪問到後端web內容,則說明如上全部配置正確

二、殺死Nginx-proxy-master服務器上的Nginx進程,觀察keepalived進程是否自動消失、觀察vip是否已經轉移到了Nginx-proxy-backup服務器上,如殺死Nginx進程後,keepalived進程也隨之消失,且vip已經轉移到Nginx-proxy-backup服務器,則說明Nginx-proxy-master可正常實現故障轉移

三、依次啓動 Nginx-proxy-master的Nginx、Keepalived(必須先啓動Nginx後啓動Keepalived。若是先啓動Keepalived,Keepalived檢測到Nginx沒有啓動仍是會執行殺死本身進程的腳本),而後將Nginx-proxy-backup的Nginx進程殺死,看vip是否會自動轉移到Nginx-proxy-master服務器上,如殺死Nginx進程後,keepalived進程也隨之消失,且vip已經轉移到Nginx-proxy-master服務器,則說明Nginx-proxy-backup可正常實現故障轉移

至此,Nginx負載均衡配置完畢。另外,Nginx很是穩定,筆者的Nginx負載均衡運行在HP DL380服務器上(一顆至強E5620CPU,16G內存,萬轉SAS硬盤),運行四個月以來,從未出現過任何問題。在負載性能上,2000併發狀況下load average:僅爲0.02, 0.01, 0.00,CPU使用率僅爲3%,內存使用爲1G(算上linux系統自己使用,系統爲64bit)。

相關文章
相關標籤/搜索