来自:MrLinFeng - 博客园
链接:www.cnblogs.com/mrlinfeng/p/6146866.html
相关知识自行搜索,直接上干货。。。
使用的资源:
nginx 主服务器一台,nginx 备服务器一台,使用 keepalived 进行宕机切换。
tomcat 服务器两台,由 nginx 进行反向代理和负载均衡,此处可搭建服务器集群。
redis 服务器一台,用于 session 的分离共享。
nginx 主服务器:192.168.50.133
nginx 备服务器:192.168.50.135
tomcat 项目服务器 1:192.168.50.137
tomcat 项目服务器 2:192.168.50.139
redis 服务器:192.168.50.140
注意访问时需要配置防火墙规则,或者关闭防火墙
首先进行的通用安装:
总的需要模拟五台服务器,使用 vmware,全部使用 centos 6.5 64 位,五台服务器全部安装 jdk,我使用的是 jdk1.8.
1、安装 VMware 虚拟机,安装 linux 系统,此处使用 centOS6.5 64 位,安装 linux 命令行工具,上传文件工具,此处使用 SecureCRT,SecureFX 。安装教程不再赘述,百度一大堆 ... ...
这步有问题请使劲点:www.baidu.com
2、在 linux 上安装 jdk:
安装 jdk:卸载 openjdk 版本,上传解压 jdk,配置环境变量 ---- 参考:http://jingyan.baidu.com/article/ab0b56308966acc15afa7d18.html
一、Nginx反向代理与负载均衡:
架构图此时需要用到三台服务器,一台 nginx 服务器,两台正式部署项目的服务器:选择的是 192.168.50.133 主 nginx 和 192.168.50.137,192.168.50.139 两台 tomcat 服务器
首先在两台服务器上安装 tomcat:这个也是简单,不多说
安装 tomcat:上传解压即可使用,bin 目录下 startup.sh 启动,shutdown.sh 关闭
配置防火墙端口:vim /etc/sysconfig/iptables 编辑,开放 8080 端口,80 端口等一些常用端口,当然后边有用到一些端口都是需要配置开放的,不建议关闭防火墙
编辑好后 service iptables restart 重新加载防火墙配置
如果是自己测试嫌配置麻烦,关闭防火墙: service iptables stop 重启后防火墙打开,即在此次开机状态下有效,完全关闭再使用 chkconfig iptables off , 即会在重启后也关闭防火墙,注意有时候服务都起了但访问出错,可能就是防火墙问题哦
启动 tomcat 访问:192.168.50.137:8080,192.168.50.139:8080,打开 tomcat 首页即成功。
然后编写测试项目,部署到两台 tomcat 上,eclipse 新建 web 项目,项目名为 testproject,在 webapp 下新建一个 jsp 页面为 index.jsp, 添加如下内容
将项目中 web.xml 中的访问顺序 <welcome-file>index.jsp</welcome-file >
上移到第一个访问
然后右键导出为 war 包,testproject.war,将该 war 包上传到两台服务器的 tomcat 的 webapps 中
然后修改 tomcat 的 server.xml 文件,在 tomcat conf 目录中:可以使用 notepad++ 的插件 NppFTP 直接连上 linux,然后使用 notepad++ 修改文件哦,保存记得使用 UTF-8 无 BOM 格式,具体去百度吧,哈哈
修改 Engine 标签中,添加 jvmRoute,用于标识 nginx 访问的是哪个服务器 tomcat,137 服务器标识为 137Server1,139 服务器标识为 139Server2
在两台 tomcat 的 server.xml 文件,Host 标签中添加:<Context path=""docBase="testproject"/>
,path 标识访问路径,docBase 为项目名,表示访问项目
此时,重新启动 tomcat,访问 192.168.50.137:8080,192.168.50.139:8080, 显示 index.jsp 内容:两台服务器访问显示如下
server 1 server 2至此,两台 tomcat 服务器搭建完成。
在 nginx 主机 192.168.50.133 上安装 nginx:
- 先使用 yum 命令安装 gcc,安装 pcre,zlib,openssl:
yum install -y gcc
yum install -y pcre pcre-devel
yum install -y zlib zlib-devel
yum install -y openssl openssl-develplain
- 在 / usr/local / 目录下新建 nginx-src 目录,将 nginx-1.8.0.tar.gz 放到此处,解压
tar -zxvf nginx-1.8.0.tar.gz
进入解压后目录
依次执行命令:
./configure
make
mkae install
此时 nginx 安装完毕,安装目录是 / usr/local/nginx,nginx 默认占用 80 端口
其中,sbin 目录为 nginx 执行命令,conf 目录下的 nginx.conf 为默认加载的配置文件
启动 nginx:
./sbin/nginx
关闭 nginx:
./sbin/nginx -s stop
启动 nginx 后访问 192.168.50.133:80 即可访问 nginx:显示 nginx 欢迎页
欢迎页至此,nginx 安装完毕。
3、反向代理与负载均衡配置
现有两台服务器,一台为 192.168.50.137,一台为 192.168.50.139,服务器上各有一台 tomcat,端口均为 8080,在 192.168.50.133 上有 nginx,经过配置 nginx,当访问 192.168.50.133:80 时,即可访问 192.168.50.137:8080,192.168.50.139:8080 中随机一台,此时 192.168.50.133:80 被 nginx 监听,当有请求时,代理到 192.168.50.137:8080,192.168.50.139:8080 随机一台即可,即为 nginx 反向代理功能,同时此时可以通过 nginx 将请求进行转发,保证了一个入口,将所有请求转发到两台服务器上也减轻了任何一台的负载压力,当有大量请求时,可以搭建大量服务器,在入口代理服务器上使用 nginx 进行转发,即是负载均衡功能。
配置即是配置 nginx 安装目录中 conf 目录下的 nginx.conf 文件即可:具体配置如下,重点是红色部分
#Nginx所用用户和组
#user niumd niumd;
#工作的子进程数量(通常等于CPU数量或者2倍于CPU)
worker_processes 2;
#错误日志存放路径
#error_log logs/error.log;
#error_log logs/error.log notice;
error_log logs/error.log info;
#指定pid存放文件
pid logs/nginx.pid;
events {
#使用网络IO模型linux建议epoll,FreeBSD建议采用kqueue
#use epoll;
#允许最大连接数
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#定义日志格式
#log_format main '$remote_addr - $remote_user [$time_local] $request '
# '"$status" $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log off;
access_log logs/access.log;
client_header_timeout 3m;
client_body_timeout 3m;
send_timeout 3m;
client_header_buffer_size 1k;
large_client_header_buffers 4 4k;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
#fastcgi_intercept_errors on;
error_page 404 /404.html;
#keepalive_timeout 75 20;
gzip on;
gzip_min_length 1000;
gzip_types text/plain text/css application/x-javascript;
#配置被代理的服务器
upstream blank {
#ip_hash;
server 192.168.50.137:8080;
server 192.168.50.139:8080;
}
server {
#nginx监听80端口,请求该端口时转发到真实目标
listen 80;
#配置访问域名
server_name 192.168.11.133;
location / {
#这里配置代理是指上面定义的两个被代理目标,blank名字必须一致
proxy_pass http://blank;
#proxy_redirect off;
#非80端口使用,目的是将代理服务器收到的用户的信息传到真实服务器上,我也不是很理解
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
add_header Access-Control-Allow-Origin *;
}
#此处定义500 502 503 504的错误页面
error_page 500 502 503 504 /50x.html;
#错误页面位置
location = /50x.html {
#root表示路径 html为nginx安装目录中的html文件夹
#位于/usr/local/nginx/html/下
root html;
}
}
}
启动两台 tomcat,重新启动 nginx:
访问 192.168.50.133:80 将会随机访问 192.168.50.137:8080 和 192.168.50.139:8080 其中一台。(问题:每次刷新 nginx 服务器地址 sessionid 会变,session 不能共享。)
nginx 轮询策略:
nginx 负载均衡到多台服务器上时,默认采用轮询策略:
常见策略:
1、轮询
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器 down 掉,能自动剔除。
2、weight
指定轮询几率,weight 和访问比率成正比,用于后端服务器性能不均的情况,数字越大命中率越高。
例如:轮询几率是 2:1
upstream bakend {
server 192.168.0.14 weight=2;
server 192.168.0.15 weight=1;
}
2、ip_hash
每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决 session 的问题。
例如:
upstream bakend {
ip_hash;
server 192.168.0.14:88;
server 192.168.0.15:80;
}
其他策略可以自行查询学习, nginx 还有很多其他可配置项,静态资源缓存,重定向等。
想深入的童鞋请自行学习 nginx 配置详解:http://blog.csdn.net/tjcyjd/article/details/50695922
实际问题:虽然解决了,但是不是很理解,记录一下
其中 192.168.50.133:80 是有外网映射的,外网 55.125.55.55:5555 映射到 192.168.50.133:80 上,此时使用 55.125.55.55:5555 访问,会映射到 192.168.50.133:80 上,然后会被转发到 192.168.50.137:8080 或 192.168.50.139:8080,但是此时却出现图片,js,css 等静态文件无法访问的情况,通过两种方法解决。
<1>. 映射非 80 端口
让 55.125.55.55:5555 映射 192.168.50.133 的非 80 端口,例如 55.125.55.55:5555 映射 192.168.50.133:5555,然后再在 nginx 配置文件中配置如下,注意红色加大部分:这地方不理解
........ upstream blank {
#ip_hash;
server 192.168.50.137:8080;
server 192.168.50.139:8080;
}
server {
#nginx监听5555端口,请求该端口时转发到真实目标
listen 5555;
#配置访问域名
server_name 192.168.11.133;
location / {
#这里配置代理是指上面定义的两个被代理目标,blank名字必须一致
proxy_pass http://blank;
#proxy_redirect off;
#非80端口使用,目的是将代理服务器收到的用户的信息传到真实服务器上
proxy_set_header Host $host:5555;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
add_header Access-Control-Allow-Origin *;
}........
此时访问 55.125.55.55:5555,映射到 192.168.50.133:5555 上,然后转发到 192.168.50.137:8080 或 192.168.50.139:8080 上,此时静态文件均能访问。
<2>. 使用域名在外网服务器上使用 nginx 进行转发
将 55.125.55.55 绑定域名为 test.baidubaidu.com,此时在 55.125.55.55 服务器上使用 nginx,
........location / {
#加入判断,如果域名为test.baidubaidu.com,转发到192.168.50.133:80,然后再进行转发,注意,此处未进行测试,貌似是这么写的,$hostname为nginx变量,可以获取域名
if($hostname = "test.baidubaidu.com" ){
proxy_pass http://192.168.50.133:80;
}
#proxy_redirect off;
#非80端口使用,目的是将代理服务器收到的用户的信息传到真实服务器上,我也不是很理解
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
add_header Access-Control-Allow-Origin *;
}........
以上即 nginx 反向代理与负载均衡介绍,经过此次学习,发现 nginx 确实是博大精深,一个配置文件搞得我不要不要的。。。
二、session 共享问题:
由于 nginx 是随机分配请求,假设一个用户登录时访问网站登录时被分配到 192.168.50.137:8080 上,然后进行了登录操作,此时该服务器上就会有该用户登录的 session 信息,然后登陆后重定向到网站首页或个人中心时,此时如果被分配到 192.168.50.139:8080 上,那么这台服务器上没有该用户 session 信息,于是又会变成未登录状态,所以由于 nginx 的负载均衡会导致 session 共享的问题。
解决方法:
-
nginx 提供了 ip_hash 策略,可以保持用户 ip 进行 hash 值计算固定分配到某台服务器上,然后只要是该 ip 则会保持分配到该服务器上,保证用户访问的是同一台服务器,那么 session 问题就不存在了。这也是解决 session 共享的一种方式,也称为黏性 session。但是假设一台 tomcat 服务器挂了的话,那么 session 也会丢失。所以比较好的方案是抽取 session。
-
session 存在 memcache 或者 redis 中,以这种方式来同步 session,把 session 抽取出来,放到内存级数据库里面,解决了 session 共享问题,同时读取速度也是非常之快。
本例中:
Redis 解决 session 共享:
在 redis 服务器 192.168.50.140 上搭建 redis,redis 默认端口为 6379
Redis 搭建:
redis 依赖 gcc,先安装:
yum install -y gcc-c++
下载 redis,我使用的是 redis-3.2.1.tar.gz,上传至 linux /usr/local/redis-src / 中,解压
进入解压后目录 redis-3.2.1,执行 make 命令进行编译
安装到目录 / usr/local/redis
执行:
make PREFIX=/usr/local/redis install
安装完成之后将 redis 配置文件拷贝到安装目录下,redis.conf 是 redis 的配置文件,redis.conf 在 redis 源码目录, port 默认 6379。
执行命令:
cp /usr/local/redis-src/redis-3.2.1/redis.conf /usr/local/redis/
在 redis 安装目录启动和关闭 redis:
启动:
这种启动方式叫做前端启动,必须保持在当前窗口,如果 ctrl + c 退出,那么 redis 也就退出了,不建议使用
那么后端启动:
首先修改 redis.conf 中 daemonize 的值,打开可以看到默认是 no,修改为 daemonize yes,启动即可。也可以在该配置文件中修改 redis 默认端口 6379 为其他值。
关闭 redis:
./bin/redis-cli shutdown
至此,redis 服务器搭建完成。
tomcat 与 redis 集成实现 session 共享:
- 环境为 tomcat7 + jdk1.6 的话:
在所有需要共享 session 的服务器的 tomcat 中目录下:
lib 目录中添加以下三个 jar 包,注意版本最好一致,不然极容易出现错误,下边的测试是可用的:
conf 目录中 content.xml 中加入:配置 redis 服务
<Valve className="com.radiadesign.catalina.session.RedisSessionHandlerValve"/>
<Manager className="com.radiadesign.catalina.session.RedisSessionManager"
host="192.168.50.140"
port="6379"
database="0"
maxInactiveInterval="60" />
- 环境为 tomcat7 + jdk1.7 或 1.8 的话:
在所有需要共享 session 的服务器的 tomcat 中目录下:
lib 目录中添加以下三个 jar 包,测试通过:
conf 目录中 content.xml 中加入:配置 redis 服务
<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />
<Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
host="192.168.50.140"
port="6379"
database="0"
maxInactiveInterval="60"/>
根据我这测试,是 jkd1.8+tomcat7,在 137 和 139 两台 tomcat 中加入 jar 包且进行如上配置:
上传 jar 包
修改 content.xml
启动 redis 服务,重新启动所有 tomcat,启动 nginx,刷新 nginx 页面, 两台 tomcat 页面可以看到 sessionid 值不变,关闭某台 tomcat,nginx 中 sessionid 不变,说明 session 是共享的。
问题:
有可能此时访问会报错,redis 无法访问,这是由于 redis 的安全机制,默认只有 127.0.0.1 才能访问,在 redis.conf 中可以找到 bind 127.0.0.1,你可以将此 ip 改为访问者 ip,
如果有多个访问者,也可以把 bind 127.0.0.1 注释掉,然后在配置文件中找到 protected-mode,修改 protected-mode yes 改为 protected-mode no 关闭 redis 保护模式即可
详细可以参考这:http://www.cnblogs.com/liusxg/p/5712493.html
请注意!!!!
context.xml 配置说明:
<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />
<Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
//这里是redis服务器地址
host="192.168.50.140"
//这里是redis端口,redis默认端口是6379
port="6379"
//这里是redis数据库中的标识,标识第0个,默认使用0即可
database="0"
//需要注意的是这里由于redis过期时间默认设置为60,单位是秒,session过期时间为30分钟,所以需要设置为1800对应30分钟
maxInactiveInterval="1800"/>
三、keepalived 高可用:
架构图上图画的不对称好难看,将就下吧
根据上边一路走来,已经是搭好了从 nginx 主到服务器的这条线的,那么同理,使用 nginx 备机 192.168.50.135 上再搭建 nginx,也是代理 192.168.137 和 139 两台服务器。搞了一次之后也就简单了
在 192.168.50.135 上安装 nginx,配置 nginx 配置即可,不再赘述,nginx 备机配置如下:
配置和上边的是一样的,只不过监听的地方的 ip 了而已
........upstream blank {
#ip_hash;
server 192.168.50.137:8080;
server 192.168.50.139:8080;
}
server {
listen 80;
server_name 192.168.50.135;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
proxy_pass http://blank;
root html;
index index.html index.htm;
}........
那么现在就是相当于有两套 nginx 了,代理的服务器是一样的,为什么要搞两套?
假设只有一台 nginx 的话,这个 nginx 服务器挂了。那怎么办?
所以需要一台备份 nginx。
正常情况下,主 nginx 作为反向代理服务器即可,假设 nginx 服务器挂了的话,能够立即切换到备份机上,保证用户可以访问,然后运维人员把主 nginx 服务器故障修好之后,又能够自动切换到主 nginx 提供服务。通过 keepalived 来监测两台服务器,正常情况时,将 nginx 主服务器 ip(192.168.50.133)绑定到 keepalived 定义的一个虚拟 ip(我设置为 192.168.50.88)上,通过这个虚拟 IP 可以访问 nginx,然后备机(192.168.50.135)啥事不干,就是每隔一小段时间(设置为 1 秒)keepalived 会告诉备机,你不用管,我还活着呢,如果突然主机死了,那么就会超过一秒备机没有收到主机或者的消息,那么备机马上接管主机,keeplived 将虚拟 ip 绑定到备机身上,网站继续提供服务。
突然主机又复活了(运维人员排除故障了),那么备机又将收到主机的活着的消息,于是将管理权交回给主机,虚拟 ip 又绑到主机上,大概就是这么个过程,个人理解。
__ 先在两台 nginx 服务器(主备)上都装上 keepalived:__
下载:这里使用 rpm 安装,是区分 32,64 位的,不要搞错了哦
keepalived-1.2.7-3.el6.x86_64.rpm
openssl-1.0.1e-30.el6_6.4.x86_64.rpm
要求必须是 openssl-1.0.1e 或以上才行、如果版本已经符合(因为安装 nginx 时已经安装 openssl,使用 yum 安装应该是符合的)、不用再安装 openssl,使用 rpm -q openssl 查看当前 openssl 版本,我这已经是 1.0.1e 48 的,所以就不安装了
将两个 rpm 安装包上传到两台 nginx 服务器,进入上传到的目录,运行以下命令安装:--nodeps 是忽略依赖包,当然最好是把依赖包装上,去掉 --nodeps 可以看到错误,需要哪些依赖包
如果需要安装 openssl
rpm –Uvh --nodeps ./openssl-1.0.1e-30.el6_6.4.x86_64.rpm
安装 keepalived:
rpm -Uvh --nodeps ./keepalived-1.2.7-3.el6.x86_64.rpm
安装完毕后再 / etc/keepalived / 目录下有个文件 keepalived.conf 即是本台服务器 keepalived 的核心配置文件了:
重点:keepalived 配置,配置文件上边部分按照下面的配置就行了,配置文件后面的内容可以不用管,还没有去研究其他部分
先配置主机 192.168.50.133 的 keepalived,按下边进行配置
! Configuration File for keepalived
#这是全局配置
global_defs {
#指定keepalived在发生切换时需要发送email到的对象,一行一个
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
#指定发件人
notification_email_from Alexandre.Cassen@firewall.loc
#指定smtp服务器地址
#smtp_server 192.168.200.1
#指定smtp连接超时时间
#smtp_connect_timeout 30
#运行keepalived机器的一个标识
router_id LVS_DEVEL
}
#主备配置
vrrp_instance VI_1 {
#标示状态为MASTER 备份机为BACKUP
state MASTER
#设置keepalived实例绑定的服务器网卡,一般为eth0,linux使用ifconfig命令可查看当前服务器网卡标识名
interface eth0
#同一实例下(即同一组主备机下)virtual_router_id必须相同
virtual_router_id 51
#MASTER权重要高于BACKUP,MASTER为100则BACKUP最大为99
priority 100
#MASTER与BACKUP负载均衡器之间同步检查的时间间隔,单位是秒,设置为1秒
advert_int 1
#设置认证
authentication {
#主从服务器验证方式,PASS为明文密码验证
auth_type PASS
#密码
auth_pass 1111
}
#设置虚拟IP,与我们的主备机在同一网段下,最后一位随便给就是拉,可以设置多个,换行即可
virtual_ipaddress {
192.168.50.88
}
}
备机 192.168.50.135 的 keepalived 配置:
备机配置注意的地方:需要修改 state 为 BACKUP , priority 比 MASTER 低,virtual_router_id 和 master 的值一致
! Configuration File for keepalived
#这是全局配置
global_defs {
#指定keepalived在发生切换时需要发送email到的对象,一行一个
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
#指定发件人
notification_email_from Alexandre.Cassen@firewall.loc
#指定smtp服务器地址
#smtp_server 192.168.200.1
#指定smtp连接超时时间
#smtp_connect_timeout 30
#运行keepalived机器的一个标识
router_id LVS_DEVEL
}
#主备配置
vrrp_instance VI_1 {
#备机为BACKUP
state BACKUP
#备机网卡标识,一般都是eth0,先查询一下
interface eth0
#virtual_router_id必须与主机相同
virtual_router_id 51
#权重,备机必须比主机小
priority 99
#MASTER与BACKUP负载均衡器之间同步检查的时间间隔,单位是秒,设置为1秒
advert_int 1
#认证,与主机一致
authentication {
auth_type PASS
auth_pass 1111
}
#虚拟IP,绑定的虚拟ip与主机一致
virtual_ipaddress {
192.168.50.135
}
}
酱紫,keepalived 就配置完成了。
keeplived 启动关闭命令:
service keepalived start
service keepalived stop
启动两台 nginx,启动主机 keepalived,启动备机 keepalived 服务。
这时,nginx 主机在提供服务,备机是闲着的,虚拟 ip 是 192.168.50.88,在主机和备机上使用命令
ip addr
可以发现:
主机:可以看到,192.168.50.133 带有虚拟 ip192.168.50.88,在浏览器中输入 192.168.50.88,即可访问到主 nginx192.168.50.133. 然后转发到 tomcat 服务器上
浏览器访问虚拟 ip:192.168.50.88,效果如下
备机:ip addr 命令执行:可以看到,备机 nginx 没有绑定虚拟 ip
以上是初始状态下的情况,也是正常服务的情况。
现在测试高可用,假设主机 nginx 服务器挂了,模拟为关闭 nginx 主机或者将 keepalived 服务停止,那么主机上 keepalived 死了就没办法告诉备机自己活着,而备机超过 1 秒没有接收到主机给自己的消息,马上接管虚拟 ip,同时在配置文件中配置切换主备机时发送邮件,此时开发团队收到邮件即知道主机挂了,马上去排除主机的故障
将主机上的 keepalived 服务停止,service keepalived stop , 然后查看虚拟 ip 绑定情况,
主机挂了:可以看到虚拟 ip 就没有绑在主机上
备机情况:虚拟 ip 已经绑定到备机,此时主机虽然挂了,但是切换到备机上了(发现故障和切换的时间差最大也就是 1 秒),虚拟 ip 也绑到备机上了,访问虚拟 ip,就会请求备机 nginx 然后转发到 web 服务器实现高可用。
__ 运维人员收到邮件后就去排除主机故障了,搞定之后(模拟为 keepalived 服务启动),这时主机告诉备机,我又活了,于是备机将管理权又交给主机(切换为主机 nginx 提供服务):__
主机 keepalived 服务启动后,即吧主机维护好之后:可以看到,虚拟 ip 又自动绑到了主机上
备机情况,主机活了之后,备机转交管理权,虚拟 ip 切换到主机上,备机不绑定虚拟 ip, 貌似启动 keepalived 服务之后并不能马上切回,应该是起服务需要点时间吧,但是不影响,这段时间还是备机绑定虚拟 IP 的
这就是 keepalived 高可用的模拟。
注意问题:
主机挂了之后,主机 nginx 恢复时,一定要将 nginx 也启动,否则即使虚拟 ip 切换到了主机上,但是主机 nginx 没起那也是没法转发的。所以要把 nginx 启动要加在开机启动中。
四、Nginx 服务开机自启动:
在 linux 系统的 /etc/init.d / 目录下创建 nginx 文件,使用如下命令:(vim 命令不会的自己去学吧哈哈)
vi /etc/init.d/nginx
将如下内容搞到该文件中: 注意红色部分修改成你的路径即可,nginxd
值是启动 nginx 的 nginx 路径,nginx_config
值是 nginx 配置文件 nginx.conf 路径,nginx_pid
值是 nginx.pid 所在路径,如果按照我方法安装的话,是在 nginx 安装目录的 logs 里边的
#!/bin/bash
# nginx Startup script for the Nginx HTTP Server
# it is v.0.0.2 version.
# chkconfig: - 85 15
# description: Nginx is a high-performance web and proxy server.
# It has a lot of features, but it's not for everyone.
# processname: nginx
# pidfile: /usr/local/nginx/logs/nginx.pid
# config: /usr/local/nginx/conf/nginx.conf
nginxd=/usr/local/nginx/sbin/nginx
nginx_config=/usr/local/nginx/conf/nginx.conf
nginx_pid=/usr/local/nginx/logs/nginx.pid
RETVAL=0
prog="nginx"
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ ${NETWORKING} = "no" ] && exit 0
[ -x $nginxd ] || exit 0
# Start nginx daemons functions.
start() {
if [ -e $nginx_pid ];then
echo "nginx already running...."
exit 1
fi
echo -n $"Starting $prog: "
daemon $nginxd -c ${nginx_config}
RETVAL=$?
echo
[ $RETVAL = 0 ] && touch /var/lock/subsys/nginx
return $RETVAL
}
# Stop nginx daemons functions.
stop() {
echo -n $"Stopping $prog: "
killproc $nginxd
RETVAL=$?
echo
[ $RETVAL = 0 ] && rm -f /var/lock/subsys/nginx /var/run/nginx.pid
}
# reload nginx service functions.
reload() {
echo -n $"Reloading $prog: "
#kill -HUP `cat ${nginx_pid}`
killproc $nginxd -HUP
RETVAL=$?
echo
}
# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
reload)
reload
;;
restart)
stop
start
;;
status)
status $prog
RETVAL=$?
;;
*)
echo $"Usage: $prog {start|stop|restart|reload|status|help}"
exit 1
esac
exit $RETVAL
然后设置该文件的访问权限:执行以下命令,意为所有用户可访问
chmod a+x /etc/init.d/nginx
最后将 ngix 加入到 rc.local 文件中,这样开机的时候 nginx 就默认启动了
vi /etc/rc.local
添加
/etc/init.d/nginx start
保存并退出,下次重启就会生效,nginx 的开机自启动。测试无误的。
五、解决 nginx 进程和 keepalived 不同时存在问题:
keepalived 是通过检测 keepalived 进程是否存在判断服务器是否宕机,如果 keepalived 进程在,但是 nginx 进程不在了,那么 keepalived 是不会做主备切换。因为是 nginx 挂了,然后无法做代理,keepalived 还在不会切换到备机。
所以一直检测 nginx 是否还在,如果不在,那么让 keepalived 也停止,同生共死。
注:只需要在主机上搞就行了,备机没必要检测 nginx,因为基本是主机在服务。
解决:写个脚本来监控 nginx 进程是否存在,如果 nginx 不存在就将 keepalived 进程杀掉。
注:keepalived 不需要开机启动,假如开机自启的话,如果 keepalived 比 nginx 更快启动的话,脚本检测会把 keepalived 停掉的,所以没必要,只需要 nginx 开机启动,启动主机后自行手动的把 keepalived 服务启动即可。
在主 nginx 上编写 nginx 进程检测脚本(check_nginx_dead.sh), 在 keepalived 配置文件目录下创建脚本:
vi /etc/keepalived/check_nginx_dead.sh
把下边这些内容搞到脚本文件中,内容如下:
#!/bin/bash
# 如果进程中没有nginx则将keepalived进程kill掉
A=`ps -C nginx --no-header |wc -l` ## 查看是否有 nginx进程 把值赋给变量A
if [ $A -eq 0 ];then ## 如果没有进程值得为 零
service keepalived stop ## 则结束 keepalived 进程
fi
给访问权限:不然不行哦,这里卡了我半小时
chmod a+x /etc/keepalived/check_nginx_dead.sh
先测试一下脚本:
把 nginx 停了,此时 keepalived 还在运行,所以不会切换,虚拟 ip 无法访问到 web 服务器
然后执行脚本:
主机脚本检测 nginx 不在了,把 keepalived 停掉,从输出可以看到确实停止了,主机虚拟没有绑定虚拟 ip
备机:成功绑定虚拟 ip
所以,只需要让该脚本一直执行,即一直检测 nginx 进程是否在,如果没得了,那么直接停止主机 keepalived,切换备机,保证能够访问 web 服务器。
按如下修改 keepalived 配置文件 keepalived.conf,添加脚本定义检测:
只需要在正确的位置添加红色部分即可:那么脚本则是两秒执行一次,一旦发现主机 nginx 不在了,keepalived 停止,切换备机
! Configuration File for keepalived
#这是全局配置
global_defs {
#指定keepalived在发生切换时需要发送email到的对象,一行一个
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
#指定发件人
notification_email_from Alexandre.Cassen@firewall.loc
#指定smtp服务器地址
#smtp_server 192.168.200.1
#指定smtp连接超时时间
#smtp_connect_timeout 30
#运行keepalived机器的一个标识
router_id LVS_DEVEL
}
vrrp_script check_nginx_dead {
##监控脚本路径
script "/etc/keepalived/check_nginx_dead.sh"
##时间间隔,2秒
interval 2
##权重
weight 2
}
#主备配置
vrrp_instance VI_1 {
#标示状态为MASTER 备份机为BACKUP
state MASTER
#设置keepalived实例绑定的服务器网卡,一般为eth0,linux使用ifconfig命令可查看当前服务器网卡标识名
interface eth0
#同一实例下(即同一组主备机下)virtual_router_id必须相同
virtual_router_id 51
#MASTER权重要高于BACKUP,MASTER为100则BACKUP最大为99
priority 100
#MASTER与BACKUP负载均衡器之间同步检查的时间间隔,单位是秒,设置为1秒
advert_int 1
#设置认证
authentication {
#主从服务器验证方式,PASS为明文密码验证
auth_type PASS
#密码
auth_pass 1111
}
track_script {
#监控脚本
check_nginx_dead
}
#设置虚拟IP,与我们的主备机在同一网段下,最后一位随便给就是拉,可以设置多个,换行即可
virtual_ipaddress {
192.168.50.88
}
}
保存后,重新启动主机 keepalived 服务即可。
测试:
回到负载均衡高可用的初始状态,保证主、备上的 keepalived、nginx 全部启动。
停止主 nginx 服务:
主机查看 keepalived 进程,发现没有,说明已经停止了,虚拟 ip 也没有绑在主机上
备机:绑定虚拟 ip,切换成功。
测试通过,如果主机 nginx 挂了之后,keepalived 也会随着挂掉,然后切换备机。
以上所有过程均是经过测试的,所以除去一些其他因素,例如人品,应该都是可以成功的。
网友评论