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

使用的资源:

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 。安装教程不再赘述,百度一大堆……….

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中的访问顺序index.jsp上移到第一个访问

然后右键导出为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标签中添加:,path标识访问路径,docBase为项目名,表示访问项目

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

至此,两台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 ‘ remoteaddr r e m o t e a d d r − remote_user [ timelocal] t i m e l o c a l ] request ’
# ‘” status" s t a t u s " body_bytes_sent “http_referer” ’  
   #                  ‘”
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轮询策略:

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,然后再进行转发,注意,此处未进行测试,貌似是这么写的, hostnginxif( h o s t 为 n g i n x 变 量 , 可 以 获 取 域 名 i f ( 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共享问题,同时读取速度也是非常之快。

本例中:

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

这种启动方式叫做前端启动,必须保持在当前窗口,如果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服务


!/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
{NETWORKING} = “no” ] && exit 0  [ -x
nginxd ] || exit 0

Start nginx daemons functions.

start() {
if [ -e nginxpid];thenechonginxalreadyrunning.exit1fiechon n g i n x p i d ] ; t h e n e c h o “ n g i n x a l r e a d y r u n n i n g … . ” e x i t 1 f i e c h o − n "Starting prog:daemon p r o g : ” d a e m o n nginxd -c nginxconfigRETVAL= n g i n x c o n f i g R E T V A L = ?
echo
[ RETVAL = 0 ] && touch /var/lock/subsys/nginx  
  return
RETVAL = 0 ] && touch /var/lock/subsys/nginx    return
RETVAL
}

Stop nginx daemons functions.

stop() {
echo -n "Stopping " S t o p p i n g prog: ”
killproc nginxdRETVAL= n g i n x d R E T V A L = ?
echo
[ $RETVAL = 0 ] && rm -f /var/lock/subsys/nginx /var/run/nginx.pid
}

reload nginx service functions.

reload() {
echo -n "Reloading " R e l o a d i n g prog: ”
#kill -HUP cat ${nginx_pid}
killproc nginxdHUPRETVAL= n g i n x d − H U P R E T V A L = ?
echo
}

See how we were called.

case “ 1instart)start;;stop)stop;;reload)reload;;restart)stopstart;;status)status 1 ” i n s t a r t ) s t a r t ; ; s t o p ) s t o p ; ; r e l o a d ) r e l o a d ; ; r e s t a r t ) s t o p s t a r t ; ; s t a t u s ) s t a t u s prog
RETVAL= ?;;)echo ? ; ; ∗ ) e c h o "Usage: progstart|stop|restart|reload|status|helpexit1esacexit p r o g s t a r t | s t o p | r e s t a r t | r e l o a d | s t a t u s | h e l p ” e x i t 1 e s a c e x i t 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也会随着挂掉,然后切换备机。

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值