(第十六周作业)
1、Nginx+Keepalived实现站点高可用
需要两台centos服务器,A机B机,A机是主机,B机是备机,两机都关闭SeLinux,配置防火墙开放合适的端口,时间同步
1)在A机和B机,安装Nginx和keepalived工具
yum -y install nginx
yum -y install keepalived
2)在A机和B机,编写Nginx服务检测脚本:/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表示使用进程名称进行选择 --no-headers显示结果中不显示没有标题,后面用wc -l进行统计nginx进程数量。
如果进程数量为0,则使用/usr/local/bin/nginx进行重启nginx,等待2秒等待重启完成,然后再一次统计nginx进程数量,
如果数量还是为0,则停止本机的keepalived服务。
3)编辑keepalived.conf
在A机(即主机)上keepalived.conf内容如下:
! Configuration File for keepalived
#全局配置
global_defs {
#提醒邮件收件人列表
notification_email {
xxxx@163.com
yyyy@126.com
}
#提醒邮件发件人地址、smtp服务器
notification_email_from zzz@sina.com
smtp_server mail.sina.com
smtp_connect_timeout 30
#机器标识,通常可设为hostname。在邮件中起到标识本集群的作用
router_id KeepLiveRouter
}
#VRRP脚本定义
vrrp_script chk_nginx {
#检测脚本位置(绝对路径)
script "/etc/keepalived/check_nginx.sh"
#每2秒检测一次
interval 2
#检测失败(脚本返回非0值)则优先级 -5
weight -5
#检测连续 3 次失败才算确定是真失败。会用weight减少优先级(1-255之间)
fall 3
#检测 2次成功就为成功。但不修改优先级
rise 2
}
#VRRP实例定义
vrrp_instance VI_1 {
#指定初始状态,主机指定为MASTER ,备机指定为BACKUP,实际主备与否要比较priority的值
state MASTER
#网卡名称
interface eth0
#本机IP
mcast_src_ip 192.168.56.30
#同一集群中的机器,virtual_router_id 需配置同一个值
virtual_router_id 51
#优先级,主节点大于从节点
priority 101
#检查间隔,控制主机定期发送工作正常广告报文
advert_int 2
#认证配置块(主从要一致)
authentication {
#设置认证方式为密码认证
auth_type PASS
#设置密码
auth_pass 1111
}
#虚拟IP地址
virtual_ipaddress {
192.168.56.32
}
#触发脚本
track_script {
#引用上面定义的 VRRP脚本 的名称
chk_nginx
}
}
在B机(即备机)上keepalived.conf内容差异部分如下:
……
vrrp_instance VI_2 {
state BACKUP
……
mcast_src_ip 192.168.56.31
……
priority 100
……
4)启动keepalived
# service keepalived restart
5)两台Nginx配置保持一致。
2、实现keepalived主主模型
双主模型与第1题有些不同,相同部分不再写出。
1)A机配置/etc/keepalived/keepalived.conf文件;
vrrp_instance VI_1 {
state MASTER #A机在VI_1中为 MASTER
interface ens34
virtual_router_id 11 #在VI_1中这项两机保持一致
priority 100 #A机在VI_1中这值较大
advert_int 1
authentication {
auth_type PASS
auth_pass aaaa # VI_1 中两机密码一致
}
virtual_ipaddress {
192.168.70.30
}
}
再设置一个VI2
vrrp_instance VI_2 {
state BACKUP #A机在VI_2中为 BACKUP
interface ens34
virtual_router_id 12 #在VI_2中这项两机保持一致 但与前面的VI_1不一样
priority 95 #A机在VI_2中这值较小
advert_int 1
authentication {
auth_type PASS
auth_pass bbbb # VI_2 中两机密码一致 , 但与前面的VI_1不一样
}
virtual_ipaddress {
192.168.70.31
}
}
2)B机配置/etc/keepalived/keepalived.conf文件差异之处;
vrrp_instance VI_1 {
state BACKUP #B机在VI_1中为 BACKUP
……
priority 95 #B机在VI_1中这值较小
……
}
vrrp_instance VI_2 {
state MASTER #B机在VI_2中为 MASTER
……
priority 100 #B机在VI_2中这值较大
……
}
3、采用varnish为nginx实现缓存加速
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)创建配置文件
vi /usr/local/varnish/vcl.conf
#定义后端Nginx服务器的IP和端口
backend nginxserver {
set backend.host = "192.168.65.73";
set backend.port = "80";
}
# 定义一个IP组,组名为 purge,目的是在后续配置中使用,已达到仅允许本机进行缓存清除操作。
acl purge {
"localhost";
"127.0.0.1";
}
#vcl_recv函数, 用于接收用户请求,当成功接收用户请求后被调用。
sub vcl_recv {
#当收到请求为 PURGE 方法时
if (req.request == "PURGE") {
#如果客户端IP不属于purge组中
if (!client.ip ~ purge) {
#返回错误代码和错误提示信息给客户端并丢弃该请求。
error 405 "Not allowed.";
}
#表示在缓存中查找请求的对象。并根据查找的结果将请求控制权交给vcl_hit或vcl_miss函数。
lookup;
}
#如果请求中的远程主机名为 www.test.com 开头
if (req.http.host ~ "^www.test.com") {
#设置这类请求转发到后端服务器,名称在之前用 backend 进行定义
set req.backend = nginxserver ;
#如果请求不是GET和HEAD,比如POST请求,则直接透过,让其直接访问后端Web服务器
if (req.request != "GET" && req.request != "HEAD") {
# 表示请求不再本地缓存中查找,且进入pipe模式,并将请求控制权交给vcl_pipe函数。
#此模式下不会对客户端做任何的检查或操作,而是在客户端和后端服务器直接建立管道,并将数据直接在这个管道中传输。
pipe;
}
else {
#对于GET和HEAD请求查找缓存内容。
lookup;
}
}
else {
#否则显示404错误码,并提示这是缓存服务器
error 404 "my Cache Server"
lookup;
}
}
# vcl_hit 函数在执行lookup命令后,如果在缓存中找到请求数据,则自动调用该函数。
sub vcl_hit {
#当收到请求为 PURGE 方法时
if (req.request == "PURGE") {
#找到对象,设置对象的TTL为0s,达到清除缓存的目的
set obj.ttl = 0s;
#返回代码200,并显示为已清滁
error 200 "Purged.";
}
}
# vcl_miss 函数在执行lookup命令后,如果在缓存中没有找到请求数据,则自动调用该函数
sub vcl_miss {
#当收到请求为 PURGE 方法时
if (req.request == "PURGE") {
#没有找到对象,返回代码404,并显示对象不在缓存中
error 404 "Not in cache.";
}
}
# 当想从后端服务器获取数据或更新缓存时 vcl_fetch 函数被调用
sub vcl_fetch {
#当收到请求为Get方法时,并且请求地址url是以.js结尾时,设置缓存时长为1小时
if (req.request == "GET" && req.url ~ "\.js$") {
set obj.ttl = 3600s;
}
else {
#其它设置时长为30天
set obj.ttl = 30d;
}
}
3) 启动Varnish
/usr/local/varnish/sbin/varnishd -n /var/vcache -f /usr/local/varnish/vcl.conf -a 0.0.0.0:80
-n表示缓存目录,需要事先创建,可读可写
-f 表示配置文件
-a 表示使用哪个端口接受 HTTP 请求
4)查看Varnish服务器连接数与命中率:
/usr/local/varnish/bin/varnishstat
4、LNMP结合varnish实现动静分离
需要三台服务器:
A机:Varnish服务器 (192.168.65.30);
B机:静态文件WEB服务器(192.168.65.31)
C机:动态程序WEB服务器(192.168.65.32)
1)在A机上安装varnish服务,步骤见上一题
2)在A机上创建配置文件
vi /usr/local/varnish/vcl.conf
#定义后端服务器
#定义静态文件WEB服务器
backend webB{
.host=" 192.168.65.31";
.port="80";
}
#定义 动态程序 WEB服务器
backend webC{
.host=" 192.168.65.32";
.port="80";
}
#只允许本机使用purgers请求方法清除缓存
acl purgers {
"127.0.0.1";
"localhost";
"192.168.65.30";
}
sub vcl_recv {
#对于 PURGE 请求,
if(req.request=="PURGE"){
#对于非purgers组中定义的IP,
if(!client.ip~purgers) {
#返回错误代码,不许访问
error 405 "Mothod not allow";
}
}
#静态资源交给webB服务器
#如果请求的url中包含.html png等静态资源
if(req.url ~ "\.(html|htm|shtml|css|js|jpg|png|gif|jpeg)"){
set req.backend=webB;
}
#php页面交给webC服务器,并跳过缓存
#如果请求url中包含.php
if(req.url ~ "\.php") {
set req.backend=webC;
return(pass);
}
#其余的查找本地缓存
return(lookup);
}
# 如果请求清除的资源 在缓存列表中 ,将清除
sub vcl_hit {
if (req.request == "PURGE") {
purge;
error 200 "Purged OK";
}
}
#如果请求清除的资源不在缓存列表中,返回404状态
sub vcl_miss {
if (req.request == "PURGE") {
error 404 "Not in cache";
}
}
#如果请求清除的资源是一个不可缓存的资源,返回502状态
sub vcl_pass {
if (req.request == "PURGE") {
error 502 "Purged on a passed object.";
}
}
#缓存对象存活时间2个小时
sub vcl_fetch {
if(req.url ~ "\.(html|htm|shtml|css|js|jpg|png|gif|jpeg)"){
set beresp.ttl=7200s;
}
}
#将结果返回给客户端并在响应头部添加两字段,显示命中与否,并显示后端响应的web服务器
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)启动Varnish
# /usr/local/varnish/sbin/varnishd -n /var/vcache -f /usr/local/varnish/vcl.conf -a 0.0.0.0:80