keepalived 、varnish

(第十六周作業(yè))

1、Nginx+Keepalived實(shí)現(xiàn)站點(diǎn)高可用

需要兩臺(tái)centos服務(wù)器,A機(jī)B機(jī),A機(jī)是主機(jī),B機(jī)是備機(jī),兩機(jī)都關(guān)閉SeLinux,配置防火墻開放合適的端口,時(shí)間同步
1)在A機(jī)和B機(jī),安裝Nginx和keepalived工具
yum -y install nginx
yum -y install keepalived
2)在A機(jī)和B機(jī),編寫Nginx服務(wù)檢測(cè)腳本:/etc/keepalived/check_nginx.sh?

#!/bin/bash
counter=$(ps -C nginx --no-heading|wc -l)
if [ "${counter}" = "0" ]; then? ?
?????/usr/local/bin/nginx
? ? sleep 2? ?
? ? counter=$(ps -C nginx --no-heading|wc -l)? ?
????if [ "${counter}" = "0" ]; then? ? ? ?
????????/etc/init.d/keepalived stop? ?
????fi
fi

說明:ps -C表示使用進(jìn)程名稱進(jìn)行選擇?--no-headers顯示結(jié)果中不顯示沒有標(biāo)題,后面用wc -l進(jìn)行統(tǒng)計(jì)nginx進(jìn)程數(shù)量。
?如果進(jìn)程數(shù)量為0,則使用/usr/local/bin/nginx進(jìn)行重啟nginx,等待2秒等待重啟完成,然后再一次統(tǒng)計(jì)nginx進(jìn)程數(shù)量,
如果數(shù)量還是為0,則停止本機(jī)的keepalived服務(wù)。
3)編輯keepalived.conf
在A機(jī)(即主機(jī))上keepalived.conf內(nèi)容如下:

! Configuration File for keepalived
#全局配置
global_defs {
? ? #提醒郵件收件人列表
? ? notification_email {
? ? ? ? xxxx@163.com
? ? ? ? yyyy@126.com
? ? }
? ? #提醒郵件發(fā)件人地址、smtp服務(wù)器
????notification_email_from zzz@sina.com
? ? smtp_server mail.sina.com
? ? smtp_connect_timeout 30
? ? #機(jī)器標(biāo)識(shí),通??稍O(shè)為hostname。在郵件中起到標(biāo)識(shí)本集群的作用?
? ? router_id? KeepLiveRouter
}
#VRRP腳本定義
vrrp_script chk_nginx {
? ? #檢測(cè)腳本位置(絕對(duì)路徑)
? ? script "/etc/keepalived/check_nginx.sh"
? ? #每2秒檢測(cè)一次
? ? interval 2
? ???#檢測(cè)失敗(腳本返回非0值)則優(yōu)先級(jí) -5?
? ? weight -5
? ? ? #檢測(cè)連續(xù) 3 次失敗才算確定是真失敗。會(huì)用weight減少優(yōu)先級(jí)(1-255之間)
? ? fall 3?
? ? ? #檢測(cè) 2次成功就為成功。但不修改優(yōu)先級(jí)
? ? rise 2
}
#VRRP實(shí)例定義
vrrp_instance VI_1 {
? ? #指定初始狀態(tài),主機(jī)指定為MASTER ,備機(jī)指定為BACKUP,實(shí)際主備與否要比較priority的值
? ? state MASTER
? ? #網(wǎng)卡名稱
? ? interface eth0
? ? #本機(jī)IP
? ? mcast_src_ip 192.168.56.30
? ? #同一集群中的機(jī)器,virtual_router_id?需配置同一個(gè)值
? ? virtual_router_id 51
? ? #優(yōu)先級(jí),主節(jié)點(diǎn)大于從節(jié)點(diǎn)
? ? priority 101
? ? #檢查間隔,控制主機(jī)定期發(fā)送工作正常廣告報(bào)文
? ? advert_int 2
? ? #認(rèn)證配置塊(主從要一致)
? ? authentication {
? ? ? ? #設(shè)置認(rèn)證方式為密碼認(rèn)證
? ? ? ? auth_type PASS
? ? ? ? #設(shè)置密碼
? ? ? ? auth_pass 1111
? ? }
? ? #虛擬IP地址
? ? virtual_ipaddress {
? ? ? ? 192.168.56.32
? ? }
? ? #觸發(fā)腳本
? ? track_script {
? ? ? ? #引用上面定義的?VRRP腳本?的名稱
? ? ? ?chk_nginx
? ? }
}

在B機(jī)(即備機(jī))上keepalived.conf內(nèi)容差異部分如下:

……
vrrp_instance VI_2 {
? ??state?BACKUP
? ? ……
????mcast_src_ip 192.168.56.31
? ? ……
????priority 100
? ? ……

4)啟動(dòng)keepalived?
# service? keepalived restart
5)兩臺(tái)Nginx配置保持一致。

2、實(shí)現(xiàn)keepalived主主模型
雙主模型與第1題有些不同,相同部分不再寫出。
1)A機(jī)配置/etc/keepalived/keepalived.conf文件;

vrrp_instance VI_1 {
? ? state MASTER? ?#A機(jī)在VI_1中為 ?MASTER
? ? interface ens34
? ? virtual_router_id 11? ?#在VI_1中這項(xiàng)兩機(jī)保持一致
? ? priority 100? ? ? ? ? ? #A機(jī)在VI_1中這值較大
? ? advert_int 1
? ? authentication {
? ? ? ? auth_type PASS
? ? ? ? auth_pass?aaaa? # VI_1?中兩機(jī)密碼一致
? ? }
? ? virtual_ipaddress {
? ? ? ? 192.168.70.30
? ? }
}
再設(shè)置一個(gè)VI2
vrrp_instance VI_2 {
? ? state BACKUP? ? ?#A機(jī)在VI_2中為?? BACKUP
? ? interface ens34
? ? virtual_router_id 12? ? #在VI_2中這項(xiàng)兩機(jī)保持一致?但與前面的VI_1不一樣
? ? priority 95? ? ?? #A機(jī)在VI_2中這值較小
? ? advert_int 1
? ? authentication {
? ? ? ? auth_type PASS
? ? ? ? auth_pass bbbb?? #?VI_2 中兩機(jī)密碼一致 , 但與前面的VI_1不一樣
? ? }
? ? virtual_ipaddress {
? ? ? ? ? 192.168.70.31
? ? }
}

2)B機(jī)配置/etc/keepalived/keepalived.conf文件差異之處;

vrrp_instance VI_1 {? ??
????state BACKUP? ??#B機(jī)在VI_1中為?BACKUP
? ? ……
? ??? priority 95? ? ???#B機(jī)在VI_1中這值較小
? ? ……
}
vrrp_instance VI_2 {
?????state MASTER? ?#B機(jī)在VI_2中為?MASTER?
? ? ……
????priority 100? ? ? ? ? ? #B機(jī)在VI_2中這值較大
????……
}

3、采用varnish為nginx實(shí)現(xiàn)緩存加速
1)編譯安裝varnish
wget?http://varnish-cache.org/_downloads/varnish-6.0.3.tgz
tar zxvf varnish-6.0.3.tgz
cd varnish-6.0.3
./configure --prefix=/usr/local/varnish
make && make install
2)創(chuàng)建配置文件
vi /usr/local/varnish/vcl.conf

#定義后端Nginx服務(wù)器的IP和端口
backend?nginxserver {?
????set backend.host = "192.168.65.73";?
????set backend.port = "80";?
}
#?定義一個(gè)IP組,組名為?purge,目的是在后續(xù)配置中使用,已達(dá)到僅允許本機(jī)進(jìn)行緩存清除操作。
acl purge { ? ? ?
?????"localhost"; ? ? ? ?
????"127.0.0.1"; ? ? ? ?
}
#vcl_recv函數(shù), 用于接收用戶請(qǐng)求,當(dāng)成功接收用戶請(qǐng)求后被調(diào)用。
sub vcl_recv { ? ? ? ?
? ? #當(dāng)收到請(qǐng)求為 PURGE?方法時(shí)
????if (req.request == "PURGE") { ? ? ? ? ? ? ? ?
? ? ? ? #如果客戶端IP不屬于purge組中
????????if (!client.ip ~ purge) { ? ? ? ? ? ? ?
?????????????#返回錯(cuò)誤代碼和錯(cuò)誤提示信息給客戶端并丟棄該請(qǐng)求。 ? ? ? ? ??
????????????error 405 "Not allowed."; ? ? ? ? ? ? ? ?
????????} ? ? ? ? ? ? ? ?
? ???????#表示在緩存中查找請(qǐng)求的對(duì)象。并根據(jù)查找的結(jié)果將請(qǐng)求控制權(quán)交給vcl_hit或vcl_miss函數(shù)。
????????lookup; ? ? ?
?????}
? ? ? #如果請(qǐng)求中的遠(yuǎn)程主機(jī)名為 www.test.com?開頭
? ?? ?if (req.http.host ~ "^www.test.com") {
? ? ? ? ? ? ? ? #設(shè)置這類請(qǐng)求轉(zhuǎn)發(fā)到后端服務(wù)器,名稱在之前用 backend? 進(jìn)行定義
? ? ? ? ? ? ? ? set req.backend = nginxserver ;
? ? ? ? ? ? ? ? #如果請(qǐng)求不是GET和HEAD,比如POST請(qǐng)求,則直接透過,讓其直接訪問后端Web服務(wù)器
? ? ? ? ? ? ? ? ?if (req.request != "GET" && req.request != "HEAD") {
? ? ? ? ? ? ? ? ? ? ? ? # 表示請(qǐng)求不再本地緩存中查找,且進(jìn)入pipe模式,并將請(qǐng)求控制權(quán)交給vcl_pipe函數(shù)。
? ? ? ? ? ? ? ? ? ? ? ? #此模式下不會(huì)對(duì)客戶端做任何的檢查或操作,而是在客戶端和后端服務(wù)器直接建立管道,并將數(shù)據(jù)直接在這個(gè)管道中傳輸。
? ? ? ? ? ? ? ? ? ? ? ? pipe; ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ?} ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ?else {
? ? ? ? ? ? ? ? ? ? ? ? #對(duì)于GET和HEAD請(qǐng)求查找緩存內(nèi)容。
? ? ? ? ? ? ? ? ? ? ? ? lookup;
? ? ? ? ? ? ? ? }
? ? ? } ? ? ? ?
????????else { ?
? ? ? ? ? ? ? ? #否則顯示404錯(cuò)誤碼,并提示這是緩存服務(wù)器 ? ? ? ? ? ? ?
????????????????error 404 "my Cache Server"
? ? ? ? ? ? ? ? ?lookup; ? ? ? ?
????????}
}
#? vcl_hit? 函數(shù)在執(zhí)行l(wèi)ookup命令后,如果在緩存中找到請(qǐng)求數(shù)據(jù),則自動(dòng)調(diào)用該函數(shù)。
sub vcl_hit {
? ? ? ? ?#當(dāng)收到請(qǐng)求為?PURGE?方法時(shí)
? ? ? ? if (req.request == "PURGE") {
? ? ? ? ? ? ? ? #找到對(duì)象,設(shè)置對(duì)象的TTL為0s,達(dá)到清除緩存的目的
? ? ? ? ? ? ? ? set obj.ttl = 0s; ? ? ? ? ?
? ? ? ? ? ? ? ? #返回代碼200,并顯示為已清滁? ? ??
????????????????error 200 "Purged."; ? ? ? ?
????????}
}
# vcl_miss? 函數(shù)在執(zhí)行l(wèi)ookup命令后,如果在緩存中沒有找到請(qǐng)求數(shù)據(jù),則自動(dòng)調(diào)用該函數(shù)
sub vcl_miss {
? ?????? #當(dāng)收到請(qǐng)求為?PURGE?方法時(shí)?
? ? ? ?if (req.request == "PURGE") {
? ? ? ? ? ? ? ? #沒有找到對(duì)象,返回代碼404,并顯示對(duì)象不在緩存中
? ? ? ? ? ? ? ?error 404 "Not in cache.";
? ? ? ?}
}
# 當(dāng)想從后端服務(wù)器獲取數(shù)據(jù)或更新緩存時(shí) vcl_fetch 函數(shù)被調(diào)用
sub vcl_fetch {
? ????? #當(dāng)收到請(qǐng)求為Get方法時(shí),并且請(qǐng)求地址url是以.js結(jié)尾時(shí),設(shè)置緩存時(shí)長為1小時(shí)
? ? ? ? if (req.request == "GET" && req.url ~ "\.js$") {
? ? ? ? ? ? ? ? set obj.ttl = 3600s; ? ? ? ?
????????} ? ? ? ?
????????else {
? ? ? ? #其它設(shè)置時(shí)長為30天 ? ? ? ? ? ? ??
????????????????set obj.ttl = 30d;
? ? ? ? }
}

3) 啟動(dòng)Varnish
/usr/local/varnish/sbin/varnishd -n /var/vcache -f /usr/local/varnish/vcl.conf -a 0.0.0.0:80
-n表示緩存目錄,需要事先創(chuàng)建,可讀可寫
-f?表示配置文件
-a?表示使用哪個(gè)端口接受 HTTP 請(qǐng)求
4)查看Varnish服務(wù)器連接數(shù)與命中率:
/usr/local/varnish/bin/varnishstat

4、LNMP結(jié)合varnish實(shí)現(xiàn)動(dòng)靜分離
需要三臺(tái)服務(wù)器:
A機(jī):Varnish服務(wù)器 (192.168.65.30);?
B機(jī):靜態(tài)文件WEB服務(wù)器(192.168.65.31)
C機(jī):動(dòng)態(tài)程序WEB服務(wù)器(192.168.65.32)
1)在A機(jī)上安裝varnish服務(wù),步驟見上一題
2)在A機(jī)上創(chuàng)建配置文件
vi /usr/local/varnish/vcl.conf

#定義后端服務(wù)器
#定義靜態(tài)文件WEB服務(wù)器
backend webB{
? ?.host=" 192.168.65.31";
? ?.port="80";
}
#定義 動(dòng)態(tài)程序 WEB服務(wù)器
backend webC{
? ?.host=" 192.168.65.32";
? ?.port="80";
}
#只允許本機(jī)使用purgers請(qǐng)求方法清除緩存
acl purgers {
? ?"127.0.0.1";
? ? "localhost";
? ?"192.168.65.30";
}
sub vcl_recv {
? ? #對(duì)于 PURGE?請(qǐng)求,
? if(req.request=="PURGE"){
? ???#對(duì)于非purgers組中定義的IP,
? ? ? if(!client.ip~purgers) {
? ? ? ? #返回錯(cuò)誤代碼,不許訪問
? ? ? ? ?error 405 "Mothod not allow";
? ? ? }
? ?}
? #靜態(tài)資源交給webB服務(wù)器
? ? #如果請(qǐng)求的url中包含.html png等靜態(tài)資源
? ?if(req.url ~ "\.(html|htm|shtml|css|js|jpg|png|gif|jpeg)"){
? ? ? set req.backend=webB;
? ?}
????#php頁面交給webC服務(wù)器,并跳過緩存
? ? #如果請(qǐng)求url中包含.php
? ? if(req.url ~ "\.php") {
? ? ? ? set req.backend=webC;
????? ? ? return(pass);
? ?}
? ? #其余的查找本地緩存
? ? return(lookup);
}
# 如果請(qǐng)求清除的資源 在緩存列表中 ,將清除
sub vcl_hit {
? if (req.request == "PURGE") {
? ? purge;
? ? error 200 "Purged OK";
? }
}
#如果請(qǐng)求清除的資源不在緩存列表中,返回404狀態(tài)
sub vcl_miss {
? if (req.request == "PURGE") {
? ??? ? error 404 "Not in cache";
? }
}
#如果請(qǐng)求清除的資源是一個(gè)不可緩存的資源,返回502狀態(tài)
sub vcl_pass {
? if (req.request == "PURGE") {
? ? error 502 "Purged on a passed object.";
? }
}
#緩存對(duì)象存活時(shí)間2個(gè)小時(shí)
sub vcl_fetch {
? ? ? ?if(req.url ~ "\.(html|htm|shtml|css|js|jpg|png|gif|jpeg)"){
? ? ? set beresp.ttl=7200s;
? ?}
}
#將結(jié)果返回給客戶端并在響應(yīng)頭部添加兩字段,顯示命中與否,并顯示后端響應(yīng)的web服務(wù)器
sub vcl_deliver {
? ?if(obj.hits > 0) {
? ? ? set resp.http.X-Cache="HIT from? ?" + server.ip;
? ?}else{
? ? ? set resp.http.X-Cache="MISS";
? ?}
? ?set resp.http.Backend-IP=req.backend;
}

3)啟動(dòng)Varnish
# /usr/local/varnish/sbin/varnishd -n /var/vcache -f /usr/local/varnish/vcl.conf -a 0.0.0.0:80

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容