Nginx反向代理,负载均衡,redis session共享,keepalived高可用

Stella981
• 阅读 725

点击上方“Java知音”,选择“置顶公众号”

技术文章第一时间送达!


本文作者:MrLinFeng;

**原文:http://www.cnblogs.com/****mrlinfeng/p/6146866.html**

知音专栏:

JavaWeb练手项目源码下载

常用的设计模式完整总结篇

近几年的java面试题总结汇总

相关知识自行搜索,直接上干货。。。

使用的资源:

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,全部使用centos6.5 64位,五台服务器全部安装jdk,我使用的是jdk1.8.

1、安装VMware虚拟机,安装linux系统,此处使用centOS6.5 64位,安装linux命令行工具,上传文件工具,此处使用SecureCRT,SecureFX 。安装教程不再赘述,百度一大堆..........

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

2、在linux上安装jdk:

安装jdk:卸载openjdk版本,上传解压jdk,配置环境变量----参考:http://jingyan.baidu.com/article/ab0b56308966acc15afa7d18.html

一、Nginx反向代理与负载均衡:

架构图:

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

此时需要用到三台服务器,一台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端口等一些常用端口,当然后边有用到一些端口都是需要配置开放的,不建议关闭防火墙

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

编辑好后 service iptables restart 重新加载防火墙配置

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

如果是自己测试嫌配置麻烦,关闭防火墙: 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,添加如下内容

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

将项目中web.xml中的访问顺序 index.jsp 上移到第一个访问

然后右键导出为war包,testproject.war,将该war包上传到两台服务器的tomcat的webapps中

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

然后修改tomcat的server.xml文件,在tomcat conf目录中:可以使用notepad++的插件NppFTP直接连上linux,然后使用notepad++修改文件哦,保存记得使用UTF-8无BOM格式,具体去百度吧,哈哈

修改Engine标签中,添加jvmRoute,用于标识nginx访问的是哪个服务器tomcat,137服务器标识为137Server1,139服务器标识为139Server2

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

在两台tomcat的server.xml文件,Host标签中添加: ,path标识访问路径,docBase为项目名,表示访问项目

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

此时,重新启动tomcat,访问192.168.50.137:8080,192.168.50.139:8080,显示index.jsp内容:两台服务器访问显示如下

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

至此,两台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

进入解压后目录

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

依次执行命令:

./configure   make   mkae install

此时nginx安装完毕,安装目录是/usr/local/nginx,nginx默认占用80端口

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

其中,sbin目录为nginx执行命令,conf目录下的nginx.conf为默认加载的配置文件

启动nginx:

./sbin/nginx

关闭nginx:

./sbin/nginx -s stop

 启动nginx后访问192.168.50.133:80即可访问nginx:显示nginx欢迎页

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

 至此,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  localhost;                                      location / {                #这里配置代理是指上面定义的两个被代理目标,blank名字必须一致                proxy_pass http://blank;                                #proxy_redirect          off;                #如果是非80端口,配置为Host $host:端口号,目的是将代理服务器收到的用户的信息传到真实服务器上                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反向代理,负载均衡,redis session共享,keepalived高可用

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;}

3、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:$server_port;        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,然后再进行转发,注意,此处未进行测试,貌似是这么写的,$host为nginx变量,可以获取域名            if($host = "test.baidubaidu.com" ){          proxy_pass http://192.168.50.133:80;        }                         #proxy_redirect          off;        #非80端口使用,目的是将代理服务器收到的用户的信息传到真实服务器上,我也不是很理解        proxy_set_header        Host $host:$server_port;        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共享的问题。

解决方法:

1、nginx提供了ip_hash策略,可以保持用户ip进行hash值计算固定分配到某台服务器上,然后只要是该ip则会保持分配到该服务器上,保证用户访问的是同一台服务器,那么session问题就不存在了。这也是解决session共享的一种方式,也称为黏性session。但是假设一台tomcat服务器挂了的话,那么session也会丢失。所以比较好的方案是抽取session。

2、session存在memcache或者redis中,以这种方式来同步session,把session抽取出来,放到内存级数据库里面,解决了session共享问题,同时读取速度也是非常之快。

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

本例中:

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

Redis解决session共享:

在redis服务器192.168.50.140上搭建redis,redis默认端口为6379

Redis搭建:

redis依赖gcc,

1,先安装:

yum install -y gcc-c++

2,下载redis,我使用的是redis-3.2.1.tar.gz,上传至linux /usr/local/redis-src/中。

3,解压。

4,进入解压后目录redis-3.2.1,执行make命令进行编译。

5,安装到目录/usr/local/redis。

6,执行:

make PREFIX=/usr/local/redis install

安装完成之后将redis配置文件拷贝到安装目录下,redis.conf是redis的配置文件,redis.conf在redis源码目录,port默认6379。

7,执行命令:

cp /usr/local/redis-src/redis-3.2.1/redis.conf /usr/local/redis/

在redis安装目录启动和关闭redis:

启动:

./bin/redis-server ./redis.conf

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

这种启动方式叫做前端启动,必须保持在当前窗口,如果ctrl + c 退出,那么redis也就退出了,不建议使用

那么后端启动:

首先修改redis.conf中daemonize的值,打开可以看到默认是no,修改为daemonize yes,启动即可。也可以在该配置文件中修改redis默认端口6379为其他值。

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

关闭redis:

./bin/redis-cli shutdown

 至此,redis服务器搭建完成。

tomcat与redis集成实现session共享:

环境为tomcat7 + jdk1.6的话:

在所有需要共享session的服务器的tomcat中目录下:

lib目录中添加以下三个jar包,注意版本最好一致,不然极容易出现错误,下边的测试是可用的:

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

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包,测试通过:

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

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包

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

 修改content.xml

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

启动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

经过大牛指点:添加两个注意点:

1、按照如上配置,使用redis数据库,放入session中的对象必须要实现java.io.Serializable接口,使用memcache的可以不用实现Serializable接口

原因是:因为tomcat里使用的将session放置redis使用的工具类,是使用的jdk序列化模式存储的,这一点也是很容易理解的,session.setAttribute(String key, Object value),存储Object类型。

object放入redis中又要能取出来,只能是序列化进行存储了,然后取出的时候进行反序列化。

所以我们在session中存储的任何对象,都必须实现序列化接口。

2、按照如上配置,使用redis做session存储空间时,web应用的session-time的时间单位会变成[秒],而不是原本的[分]

原因是:因为tomcat里使用的将session放置redis使用的工具类,在存储时为对tomcat容器时间做转换。

在redis中设置过期时间是使用秒作为单位的,有个命令叫expire可以设置redis键值过期时间,所以在context.xml配置文件中我们需要制定session过期时间(默认是60秒,配成1800即30分钟),这一点很重要。

请注意!!!!

context.xml配置说明:

<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />      <Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"//这里是redis服务器地址host="192.168.50.140"//这里是redis端口,redis默认端口是6379port="6379"//这里是redis数据库中的标识,标识第0个,默认使用0即可database="0"            //需要注意的是这里由于redis过期时间默认设置为60,单位是秒,session过期时间为30分钟,所以需要设置为1800对应30分钟maxInactiveInterval="1800"/>

三、keepalived高可用:

架构图:

Nginx反向代理,负载均衡,redis session共享,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  localhost;         #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反向代理,负载均衡,redis session共享,keepalived高可用

 先在两台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的,所以就不安装了

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

将两个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,按下边进行配置

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

备机192.168.50.135的keepalived配置:

备机配置注意的地方:需要修改state为BACKUP , priority比MASTER低,virtual_router_id和master的值一致

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

酱紫,keepalived就配置完成了。

keeplived启动关闭命令:

service keepalived start   service keepalived stop 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服务器上

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

浏览器访问虚拟ip:192.168.50.88,效果如下

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

备机:ip addr命令执行:可以看到,备机nginx没有绑定虚拟ip

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

以上是初始状态下的情况,也是正常服务的情况。

现在测试高可用,假设主机nginx服务器挂了,模拟为关闭nginx主机或者将keepalived服务停止,那么主机上keepalived死了就没办法告诉备机自己活着,而备机超过1秒没有接收到主机给自己的消息,马上接管虚拟ip,同时在配置文件中配置切换主备机时发送邮件,此时开发团队收到邮件即知道主机挂了,马上去排除主机的故障。

将主机上的keepalived服务停止,service keepalived stop ,然后查看虚拟ip绑定情况,主机挂了:可以看到虚拟ip就没有绑在主机上

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

备机情况:虚拟ip已经绑定到备机,此时主机虽然挂了,但是切换到备机上了(发现故障和切换的时间差最大也就是1秒),虚拟ip也绑到备机上了,访问虚拟ip,就会请求备机nginx然后转发到web服务器实现高可用。

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

运维人员收到邮件后就去排除主机故障了,搞定之后(模拟为keepalived服务启动),这时主机告诉备机,我又活了,于是备机将管理权又交给主机(切换为主机nginx提供服务):

主机keepalived服务启动后,即吧主机维护好之后:可以看到,虚拟ip又自动绑到了主机上

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

备机情况,主机活了之后,备机转交管理权,虚拟ip切换到主机上,备机不绑定虚拟ip,貌似启动keepalived服务之后并不能马上切回,应该是起服务需要点时间吧,但是不影响,这段时间还是备机绑定虚拟IP的

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

这就是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.confnginxd=/usr/local/nginx/sbin/nginxnginx_config=/usr/local/nginx/conf/nginx.confnginx_pid=/usr/local/nginx/logs/nginx.pidRETVAL=0prog="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 1fi   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" instart)        start        ;;stop)        stop        ;;reload)        reload        ;;restart)        stop        start        ;;status)        status $prog        RETVAL=$?        ;;*)        echo $"Usage: $prog {start|stop|restart|reload|status|help}"        exit 1esacexit $RETVAL

然后设置该文件的访问权限:执行以下命令,意为所有用户可访问

chmod a+x /etc/init.d/nginx

 最后将ngix加入到rc.local文件中,这样开机的时候nginx就默认启动了

vi /etc/rc.local

添加

/etc/init.d/nginx start

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

保存并退出,下次重启就会生效,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进程 把值赋给变量Aif [ $A -eq 0 ];then                    ## 如果没有进程值得为 零       service keepalived stop                 ## 则结束 keepalived 进程fi

给访问权限:不然不行哦,这里卡了我半小时

chmod a+x /etc/keepalived/check_nginx_dead.sh

先测试一下脚本:

把nginx停了,此时keepalived还在运行,所以不会切换,虚拟ip无法访问到web服务器

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

然后执行脚本:

主机脚本检测nginx不在了,把keepalived停掉,从输出可以看到确实停止了,主机虚拟没有绑定虚拟ip

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

备机:成功绑定虚拟ip

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

所以,只需要让该脚本一直执行,即一直检测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也没有绑在主机上

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

备机:绑定虚拟ip,切换成功。

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

 测试通过,如果主机nginx挂了之后,keepalived也会随着挂掉,然后切换备机。

以上所有过程均是经过测试的,所以除去一些其他因素,例如人品,应该都是可以成功的。

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

本文分享自微信公众号 - Java知音(Java_friends)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Stella981 Stella981
3年前
Docker 部署SpringBoot项目不香吗?
  公众号改版后文章乱序推荐,希望你可以点击上方“Java进阶架构师”,点击右上角,将我们设为★“星标”!这样才不会错过每日进阶架构文章呀。  !(http://dingyue.ws.126.net/2020/0920/b00fbfc7j00qgy5xy002kd200qo00hsg00it00cj.jpg)  2
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这