1. 程式人生 > >keepalived +nginx 實現HA 高可用的負載均衡

keepalived +nginx 實現HA 高可用的負載均衡

想了半天沒想好該怎麼起一個頭。

寫這個部落格呢,是因為目前相把公司的專案都做成高可用的,能夠應對緊急情況的伺服器宕機事件。
之前專案部署如下圖:
這裡寫圖片描述
圖是比較簡單的,域名指向 單機的nginx 一個nginx 指向2臺應用伺服器(負載均衡方式) 。
基本的服務都能滿足,但是如果nginx伺服器宕機了,那整個應用都無法運行了,有風險。為了更好的是程式能達到高可用,所有要對nginx 要做主備模式。
然後就需要在LINUX伺服器上部署keepalived ,繫結虛擬IP(VIP),監控服務狀態。
話不想多說,再畫一個圖吧
這裡寫圖片描述
上面的這種模式使用了一個虛擬IP,一個虛擬IP繫結在2臺WEB伺服器上,一主一備(使用keepalived,一個虛擬IP只能是一主一備,就算2個keepalived都配置為主,但是還是會變成一主一備的)。
這種模式下,始終有一臺伺服器是浪費的狀態。

如果不想有伺服器浪費,就使用2個虛擬IP,如下圖
這裡寫圖片描述
域名在網路層可以使用硬負載做到負載均衡到 2個IP,或者是更多,這樣就避免了浪費資源的情況。

還有一種情況,不使用keepalived 也能實現高可用,如下圖
這裡寫圖片描述
這種方式就是 使用網路硬體做硬負載,域名直接和 web伺服器繫結。
但是這種模式有一個不好的地方,如果是內網環境 需要指定IP,那就只能給一個WEB的IP了。

圖畫的難看就將就著看看吧
下面說說安裝keepalived 和 nginx 配置和步驟。

keepalived 和 nginx 安裝和配置

1. nginx 安裝

nginx 安裝了無數次了,但是一直都是網上找了教程,也沒什麼難度,這裡主要說說配置相關的東西吧

1.下載包(網上找包吧)
2.安裝nginx依賴

yum -y install gcc pcre-devel zlib-devel openssl-devel

3.配置nginx

解壓nginx tar zxf nginx-1.8.1.tar.gz
進入nginx 目錄配置:./configure –prefix=/home/smkapp/nginx –with-http_stub_status_module –with-http_realip_module –with-http_gzip_static_module –add-module=/home/smkapp/software/nginx-goodies-nginx-sticky-module-ng-08a395c66e42 –add-module=/home/smkapp/software/nginx-http-sysguard-master –add-module=/home/smkapp/software/nginx_upstream_check_module-master

這裡有一篇說明的比較詳細:http://www.ttlsa.com/nginx/nginx-configure-descriptions/
這裡做說明:–prefix= 指定安裝目錄
–with-http_stub_status_module NGINX的狀態
–with-http_gzip_static_module 獲取先壓縮好的GZ 檔案讀取)
–with-http_realip_module 獲取真實IP
//(基於cookie的會話保持) session粘連
–add-module=/home/smkapp/software/nginx-goodies-nginx-sticky-module-ng
//防止高負載
–add-module=/home/smkapp/software/nginx-http-sysguard-master
//檢查負載均衡的 存活性
–add-module=/home/smkapp/software/nginx_upstream_check_module-master

配置檢視nginx狀態
location /nginx_status {
# Turn on nginx stats
stub_status on;
# I do not need logs for stats
access_log off;
# Security: Only allow access from 192.168.1.100 IP #
#allow 192.168.1.100;
# Send rest of the world to /dev/null #
#deny all;
}

檢查負載均衡的狀態
upstream uec_portal{
#新增sticky模組後加入此配置
sticky;
#被代理的服務
server 192.168.12.56:80;
server 192.168.12.70:8080;
#添加了nginx_upstream_check_module模組之後,該項生效
#用於檢測後方realserver的健康狀態,如果後端伺服器不可用,則請求不轉發到這臺伺服器。
#interval:每隔3s檢測一次
#rise:檢測次數,如果連續檢測2次都成功,那就證明該後端伺服器好使
#fall:檢測次數,如果連續檢測5次都失敗,那就證明該後端伺服器不好使
#timeout:超時時間為1s
check interval=3000 rise=2 fall=5 timeout=1000;
}

4. 編譯和安裝

make && make install

5.配置nginx配置檔案

直接給一個樣例

nginx/conf/nginx.conf

#work_process的執行使用者,只當nginx以root使用者啟動時開啟
#user  smkapp;

#啟動執行程序數
#普通1個執行程序帶足夠量的連線數就可以了
#如果是消耗cpu的應用(SSL、gzip或者靜態資源大於記憶體)可以設定多個執行程序
#執行程序數一般設成和cpu核數相等
worker_processes  4;

#可以開啟的檔案控制代碼數,與ulimit -n 的值保持一致。
worker_rlimit_nofile 65535;

#為每個程序分配cpu
worker_cpu_affinity 0001 0010 0100 1000;

#錯誤日誌,預設設定為warn級別
error_log  /home/smkapp/nginx/log/error.log warn;

#主程序ID
pid        /home/smkapp/nginx/run/nginx.pid;

events {
    #客戶端請求的輪詢方法,linux用epoll,macos用kqueue
    use epoll;

    #每個work程序的最大連線數,受制於系統socket限制、防火牆限制等,沒有必要設
    #的過分高,一般可以設10k
    worker_connections  10240;

    #nginx收到一個新連線通知後接受盡可能多的連線
    multi_accept on;  
}


http {
    #mine.type配置
    #引入mine.type定義檔案
    include       /home/smkapp/nginx/config/mime.types;
    #設定預設mine.type為二進位制流
    default_type  application/octet-stream;
    #標頭檔案字符集
    charset UTF-8;

    #關閉在錯誤頁面中的nginx版本數字,這樣對於安全性是有好處的
    server_tokens off;

    #增加socket和磁碟通訊效率
    sendfile       on;

    #資料傳輸方式設定
    #nginx在一個數據包裡傳送所有標頭檔案,而不一個接一個的傳送
    tcp_nopush     on;
    #nginx不要快取資料,而是一段一段的傳送,當需要及時傳送數
    #據時,就應該給應用設定這個屬性,這樣傳送一小塊資料資訊時
    #就不能立即得到返回值
    tcp_nodelay on;

    #超時設定
    #設定nginx長連線保持時間
    #如果出現502錯誤需增大該引數=120
    keepalive_timeout  65;
    #請求頭超時時間
    client_header_timeout 3m;
    #請求體超時時間
    client_body_timeout 3m;
    #關閉不響應的客戶端連線
    reset_timedout_connection on;
    #兩次客戶端讀取操作之間的超時時間
    send_timeout 3m;

    #快取大小設定
    #server name的hash table buffer大小
    server_names_hash_bucket_size 256;
    #處理客戶端報頭的buffer大小
    #根據客戶端報頭大小調整,一般為系統PAGESIZE的整數倍
    #getconf PAGESIZE獲取系統引數值,一般為4096
    client_header_buffer_size 256k;
    #處理大客戶端報頭的buffer大小
    large_client_header_buffers 4 256k;
    #客戶端請求最大報體,預設1m
    client_max_body_size 50m;
    #客戶端報體buffer,預設2*記憶體頁大小8k(32),16k(64)
    client_body_buffer_size 256k;

    #客戶端連線設定
    #防DDOS
    #白名單設定
    #geo 模組定義了一個預設值是 1 的變數 whiteiplist,當在 ip 在白名單中,變數 whiteiplist 的值為 0,反之為 1
    #如果在白名單中--> whiteiplist=0 --> $limit="" --> 不會儲存到 10m 的會話狀態(one 或者 addr)中 --> 不受限制;
    #反之,不在白名單中 --> whiteiplist=1 --> $limit=二進位制遠端地址 -->儲存進 10m 的會話狀態中 --> 受到限制。
    #geo $whiteiplist  {
    #    default 1;
    #    10.11.15.1610;
    #}
    #map $whiteiplist$limit {
    #    1$binary_remote_addr;
    #    0"";
    #}
    #限制客戶端單ip連線數的快取空間至$server_name
    #和server模組的limit_conn成對出現
    #32位系統$binary_remote_addr為4(32byte)一個連線,1m=32k連線
    #64位系統$binary_remote_addr為16(64byte)一個連線,1m=16k連線
    limit_conn_zone $binary_remote_addr zone=activity_conn:10m;
    #限制單ip併發率,單ip每秒1000個連線
    limit_req_zone  $binary_remote_addr  zone=activity_req:10m rate=1000r/s;
    #流量限制
    #超過5m後限制流量
    limit_rate_after 50m;
    #流量不大於500k
    limit_rate 500k;
    #訪問許可權控制
    #deny 192.168.1.1;
    #allow 192.168.1.0/24;
    #allow 10.1.1.0/16;
    #allow 2001:0db8::/32;
    #deny  all;

    #本地靜態檔案快取配置
    #作為反向代理或者負載均衡不需要配置
    #開啟檔案快取數量和事件,數量一般設定和ulimit -n一致
    #open_file_cache max=65535 inactive=60s;
    #指多長時間檢查一次快取的有效資訊
    #open_file_cache_valid 80s;
    #inactive 引數時間內檔案的最少使用次數
    #open_file_cache_min_uses 1;

    #日誌配置
    #access日誌格式
    log_format main '<$time_local> <$remote_addr> <$http_user_agent> <$request> <$status> <$body_bytes_sent> <$upstream_addr> <$upstream_status> <$request_time>';

    #設定access日誌儲存
    access_log  /home/smkapp/nginx/log/access.log  main buffer=16k;
    #日誌檔案控制代碼快取
    open_log_file_cache max=10 inactive=30s min_uses=2 valid=60s;





    #upstream設定
    #上游返回大於300時是否跳轉error page頁
    proxy_intercept_errors on;
    #把客戶端真實請求引數傳遞給被代理的伺服器
    #這一段設定在這裡可能有問題,放到location裡面
    proxy_set_header Host $host:$server_port;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header REMOTE-HOST $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Cookie $http_cookie;
    proxy_set_header X-Forwarded-Proto  $scheme;
    #設定被代理伺服器的cookie域名
    #proxy_cookie_domain localhost 96225.com;
    #設定被代理伺服器應答報頭中不返回給客戶端的引數
    proxy_hide_header X-Powered-By;
    proxy_hide_header X-Mod-Pagespeed;
    #客戶端關閉連線不關閉和被代理伺服器的連線,防止499錯誤
    proxy_ignore_client_abort on;
    #根據返回狀態,設定被代理伺服器返回的快取時間
    #proxy_cache_valid any 10m;
    #和被代理伺服器連線超時時間
    #官方文件建議不超過75s
    proxy_connect_timeout   75;
    #傳送報文到被代理伺服器,2次寫之間的超時時間
    proxy_send_timeout   300;
    #接受被代理伺服器報文,2次讀之間的超時時間
    proxy_read_timeout  300;
    #開啟對被代理應帶報文的buffer,預設開啟
    proxy_buffering off;
    #對被代理伺服器應答報文buffer大小
    proxy_buffers 8 32k;
    #對被代理伺服器第一部分應答內容的buffer大小
    proxy_buffer_size 128k;
    #設定加急返回客戶端的應答內容buffer大小
    proxy_busy_buffers_size   128k;
    #設定對被代理伺服器應答buffer檔案大小,大於這個值,將從upstream伺服器傳
    proxy_temp_file_write_size  128k;
    #指定buffer臨時檔案在哪個目錄下
    proxy_temp_path /home/smkapp/nginx/tmp/;
    #快取靜態檔案,和server內的proxy_cache引數以keys_zone配對使用
    proxy_cache_path /home/smkapp/nginx/cache/ levels=1:2 keys_zone=cache_one:200m inactive=1d max_size=30g;
    #開啟靜態檔案快取
    proxy_cache cache_one;
    #設定使用http 1.1,使用長連線,減少TIME_WAIT
    proxy_http_version 1.1;
    proxy_set_header Connection "";  

    #壓縮設定
    #開啟壓縮
    gzip  on;
    #在應答報頭中新增“Vary: Accept-Encoding”,保證老瀏覽器的相容性
    gzip_vary on;
    #小於16k不啟用壓縮
    gzip_min_length 16k;
    #gzip壓縮buffer,預設為1 PAGESIZE
    gzip_buffers    8 32k;
    #對於大於等於http版本請求,應答開啟壓縮
    gzip_http_version 1.1;
    #壓縮等級1-9,9最大
    gzip_comp_level 4;
    #允許或者禁止壓縮基於請求和響應的響應流。設定為any,意味著將會壓縮所有的請求。
    gzip_proxied expired no-cache no-store private auth;
    #設定需要壓縮的資料格式
    gzip_types text/plain text/xml text/css application/x-javascript application/xml application/vnd.ms-word application/xml+rss text/javascript application/ms word application/zip;
    #ie6禁用壓縮
    gzip_disable "MSIE [1-6]\.";

    #fastcgi設定
    #上游返回大於300時是否跳轉error page頁
    #fastcgi_intercept_errors on; 
    #fastcgi靜態快取
    #fastcgi_cache TEST;
    #fastcgi_cache_path /home/smkapp/nginx/cache levels=1:2 keys_zone=TEST:10m inactive=5m;
    #fastcgi_connect_timeout 75;
    #fastcgi_send_timeout 300;
    #fastcgi_read_timeout 300;
    #fastcgi_buffer_size 128k;
    #fastcgi_buffers 8 32k;
    #fastcgi_busy_buffers_size 128k;
    #fastcgi_temp_file_write_size 128k;
    #fastcgi_cache_valid 200 302 1h;
    #fastcgi_cache_valid 301 1d;
    #fastcgi_cache_valid any 1m;
    #fastcgi_cache_min_uses 1;
    #fastcgi_cache_use_stale error timeout invalid_header http_500;    

    #包含server配置檔案
    include /home/smkapp/nginx/config/server/*.conf;
}

/home/smkapp/nginx/config/server/ff.conf;

#負載均衡
upstream extactivity.com {
    #session粘連
    #sticky name=activity;
    #server 172.16.23.38:8082;
    server 172.16.23.38:8081;
        #upstream存活檢查
        #check interval=3000 rise=2 fall=5 timeout=1000;
}


server {
    #監聽的本地請求埠
    listen       8080;
    #server_name和proxy_set_header Host對應,不然就配置localhost
    #可以有多個,空格分開
    server_name  extactivity.com;

    #配置https連線,有需要時開啟。
    #ssl on;
    #ssl_certificate /home/smkapp/nginx/config/server/server.crt;
    #ssl_certificate_key /home/smkapp/nginx/config/server/server.key;
    #返回報頭地址轉換
    #如果前端開啟https需要開啟這個轉換
    #proxy_redirect http:// https://;

    #同一IP最大併發連線
    limit_conn activity_conn 800;
    #同一IP併發率
    limit_req zone=activity_req burst=50 nodelay;

    #錯誤頁面設定
    error_page 403 404 410 = http://activity.com/40x.html;
    error_page 500 502 503 504 = http://activity.com/50x.html;

    #客戶端請求限制
    #客戶端請求方法限制
    if ($request_method !~ ^(GET|HEAD|POST|OPTIONS)$) {        
         return 404;
    }
    #限制客戶端爬蟲
    if ($http_user_agent ~* LWP::Simple|BBBike|wget) {
        return 403;
    }
    if ($http_user_agent ~* Sosospider|YodaoBot) {
        return 403;
    }
    #限制只允許微信訪問,否則返回503
    #if ($http_user_agent ~* MicroMessenger|micromessenger|Android|webOS|iPhone|iPod|BlackBerry){ 
    #    set $mobile_request '1';
    #}
    #if ($request_uri ~* /weixinfeixianglog.png){
    #    set $mobile_request '1';
    #}
    #if ($request_uri ~* /40x.hmtl){
    #    set $mobile_request '1';
    #}
    #if ($request_uri ~* /50x.html){
    #    set $mobile_request '1';
    #}
    #if ($mobile_request != '1') {
    #    return 503;
    #}

    #防盜鏈
    #none 有問題,可以測試一下
    #location ~* \.(gif|jpg|png|swf|flv)$ {
    #    valid_referers none blocked activity.96225.com weixin.qq.com weixin.96225.com;
    #    if ($invalid_referer) {
    #          return 404;
    #    } 
    #}

    #單獨開通相關配置頁面及圖片
    location ~ ^/favicon\.ico$ {
      root /home/smkapp/nginx/html;
    }

    location =/40x.html {
       root /home/smkapp/nginx/html;
    }
    location =/50x.html {
       root /home/smkapp/nginx/html;
    }
    #upstream存活狀態頁
    #location /nstatus {
    #check_status;
    #    access_log off;
    #    #allow SOME.IP.ADD.RESS;
    #    #deny all;
    #}

    #防止高負載
    sysguard on;
    sysguard_load load=10.5 action=/loadlimit; 
    sysguard_mem swapratio=20% action=/swaplimit;
    location /loadlimit {
        return 503;
    }
    location /swaplimit {
        return 503;
    }

    #對於java應用檔案的安全控制
    location ~ ^/(WEB-INF)/ {   
        deny all;   
    }

    #維護控制
    set $weihu_flg '0';#系統維護標識,1為維護中
    location /sysimgs/{
       root html;
    }
    location /weihu.html{
         if ($weihu_flg = '1'){
            root html;
         }
         if ($weihu_flg = '0'){
            return 404;
         }
    }

    #設定快取的圖片字尾
   # location ~ .*\.(gif|jpg|png|css|js)(.*){
    #   proxy_pass http://activity.96225.com;
    #   proxy_redirect off;
    #   proxy_cache_valid 200 304 12h;#為不同的應答設定不同的快取時間 如200返回12個小時
    #   proxy_cache_valid 301 302 1d;
    #   proxy_cache_valid any 1m;
    #   expires 30d;
   # }



    #web代理到應用
    location /{
        proxy_pass http://172.16.23.37:8081;
        proxy_set_header Host $host:80;
        proxy_redirect Host $host:80;

    }


    location /exthtml/ {
        if ($weihu_flg = '1'){
            rewrite ^/(.*)$ /weihu.html last;
        }
        root /home/smkapp/;

#       proxy_cache cache_one;
#       proxy_cache_valid 200 304 12h;#為不同的應答設定不同的快取時間 如200返回12個小時
#       proxy_cache_valid 301 302 1d;
#       proxy_cache_valid any 1m;
#       expires 30d;
#       proxy_redirect off;
#       proxy_set_header Host $host:80;
#       proxy_redirect Host $host:80;

    }


  location ^~ /my_activity/ {
        if ($weihu_flg = '1'){
            rewrite ^/(.*)$ /weihu.html last;
        }
        proxy_pass http://172.16.23.37:8081/my_activity/;
        proxy_set_header Host $host:80;
        proxy_redirect Host $host:80;
     } 


  location ^~ /ext_my_activity/ {
        if ($weihu_flg = '1'){
            rewrite ^/(.*)$ /weihu.html last;
        }
        proxy_pass http://extactivity.com/ext_my_activity/;
        proxy_set_header Host $host:80;
        proxy_redirect Host $host:80;
     }   


}
6.配置nginx系統啟動
直接在/etc/profile 裡面新增配置、
export PATH=/home/spp/nginx1.8.2
儲存後 重新整理配置檔案即可
source /etc/profile

2. keepalived 安裝

1.編譯安裝

tar -zxvf keepalived-1.2.24.tar.gz 解壓
./configure –prefix=/usr/local/keepalived 配置安裝目錄
make && make install 編譯和安裝

這幾部做好了之後需要拷貝配置檔案
先建立資料夾 /etc/keepalived /etc/keepalived/sysconfig/
cp /home/smkapp/keepalived/etc/keepalived/keepalived.conf /etc/keepalived
cp /home/smkapp/keepalived/etc/sysconfig/keepalived /etc/keepalived/sysconfig/