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/