Nginx集群配置与redis的session共享策略
一.什么是Nginx?
Nginx (engine x) 是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,第一个公开版本0.1.0发布于2004年10月4日。

Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好,中国大陆使用Nginx的网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。
二.为什么要用Nginx?
提及Nginx,我们就需要了解下web应用服务器。在此,我们暂且以tomcat这款应用服务器为例来介绍。
Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache、Sun 和其他一些公司及个人共同开发而成。由于有了Sun 的参与和支持,最新的Servlet 和JSP 规范总是能在Tomcat 中得到体现,Tomcat 5支持最新的Servlet 2.4 和JSP 2.0 规范。由于Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web 应用服务器。
Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。实际上Tomcat是Apache 服务器的扩展,但运行时它是独立运行的,所以当你运行tomcat 时,它实际上作为一个与Apache 独立的进程单独运行的。
一般来说,用单机tomcat搭建的网站,在比较理想的状态下能够承受的并发访问量在150到200左右。按照并发访问量占总用户数量的5%到10%这样计算,单点tomcat网站的用户人数在1500到4000左右。对于一个为全国范围提供服务的网站显然是不够用的。
在互联网飞速发展的今天,大用户量高并发已经成为互联网的主体.怎样能让一个网站能够承载几万个或几十万个用户的持续访问呢?这是一些中小网站急需解决的问题。
为了解决这个问题,我们引入了负载均衡方法。负载均衡就是一个web服务器解决不了的问题可以通过多个web服务器来平均分担压力来解决,并发过来的请求被平均分配到多个后台web服务器来处理,这样压力就被分解开来。
目前,负载均衡服务器主要分为两种,一种是通过硬件实现的负载均衡服务器,简称硬负载,例如f5;另一种是通过软件来实现的负载均衡,简称软负载,例如apache和nginx。硬负载和软负载相比,前者作用的网络层次比较多,可以作用到socket接口的数据链路层,并且对发出的请求进行分组转发,但是价格成本也随之较贵;而软负载作用的层次在http协议层之上,可以对http请求进行分组转发,并且由于是开源的,所以几乎是0成本,当前,阿里巴巴,京东等电商网站使用的也是Nginx服务器。
我们接下来以一副示意图演示Nginx对tomcat的负载均衡配置:

三.tomcat如何配置首个启动工程?
在讲述Nginx负载均衡之前,我们先熟悉tomcat的配置。
以win7系统为例,我们平时在电脑上开启tomcat应用后,通过浏览器访问,会访问到tomcat的系统默认首页。那么,如何修改tomcat的首个启动工程呢?
以tomcat7为例,我们将一个名称为Demo1的java web项目导出为一个war文件,然后放在tomcat的webapps文件夹下,接着打开tomcat的conf文件夹下的server.xml文件,在<Host></Host>中加入
<Context docBase="E:\nginx\tomcatA\webapps\Demo1" path="" reloadable="true" crossContext="true"/>
然后重启tomcat,并在浏览器地址栏里输入http://localhost:8080,这时就会发现tomcat的默认首个启动工程变为Demo1。
四.如何在同一个tomcat上配置多个虚拟主机?
接下来,我们再看如何在一台服务器上设置多个域名,从而使得用户访问多个域名时,可以分别指向同一个tomcat应用服务器中配置的不同web工程。
首先,我们按照C:\Windows\System32\drivers\etc路径,打开该路径下的hosts文件,在里面配置下域名映射信息,如下:
127.0.0.1 www.baidudu.com
127.0.0.1 www.taobaobao.com
接着,我们另建两个java web项目,分别是Demo1和Demo2,然后再打开tomcat中的server.xml文件,在里面配置两个服务器主机信息,如下所示:
<Host name="www.baidudu.com" appBase="webapps" autoDeploy="true" unpackWARs="true">
<Context docBase="E:\nginx\tomcatA\webapps\Demo2" path="" reloadable="true" crossContext="true"/>
</Host>
<Host name="www.taobaobao.com" appBase="webapps" autoDeploy="true" unpackWARs="true">
<Context docBase="E:\nginx\tomcatA\webapps\Demo3" path="" reloadable="true" crossContext="true"/>
</Host>
配置完毕后,我们再重启tomcat,分别访问新配置的两个域名,发现它们会各自指向相应的web工程,从而实现了用一个tomcat配置多个虚拟主机。
五.如何通过Nginx实现tomcat集群配置与负载均衡?
我们接下来看通过Nginx对多个tomcat进行集群配置。在这里,我暂且在一台电脑上用两个tomcat做下演示,同时将这两个tomcat分别命名为tomcatA和tomcatB。为了避免同一台电脑上开启多个tomcat引起端口冲突,我将tomcatA的http访问端口配置为8081,将tomcatB的http访问端口配置为8082,为了显示不同tomcat的访问区别,我暂且让tomcatA的默认首个启动工程为Demo1,让tomcatB的默认首个启动工程为Demo3。
接着,我们双击ningx中的nginx.exe文件,从而启动nginx服务。当然,我们这里还需要对nginx中的配置文件进行一番配置,所以,如果nginx处于开启状态,则暂且在DOS窗口中关闭nginx服务。如图所示:

接下来,我们打开nginx中的conf文件夹下的nginx.conf文件,我们在里面加入要配置的tomcat集群,同时,考虑到不同的服务器性能差别,可以配置相应的权重,从而实现服务器的负载均衡。如下图所示:

上图中,标注红框的部分是关键配置,然后,我们在浏览器的地址栏中输入localhost,会发现tomcatA和tomcatB的所承担的访问任务比重约为5:1,从而实现了nginx对tomcat的负载均衡配置。
六.如何处理Nginx负载均衡中的session会话信息丢失问题?
我们在通过nginx完成了对tomcat的集群与负载均衡配置后,还面临着一个关键问题,那就是如何解决session会话信息的共享问题。解决方法也很简单,需要两个步骤:
步骤一:在每个tomcat的server.xml中找到标签:
<Engine name="Catalina" defaultHost="localhost">
#....
#....
#....
</Engine>
在上面的<Engine></Engine>标签中加入下述代码,注意不要做任何更改:
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
channelSendOptions="8">
<Manager className="org.apache.catalina.ha.session.DeltaManager"
expireSessionsOnShutdown="false"
notifyListenersOnReplication="true"/>
<Channel className="org.apache.catalina.tribes.group.GroupChannel">
<Membership className="org.apache.catalina.tribes.membership.McastService"
address="228.0.0.4"
port="45564"
frequency="500"
dropTime="3000"/>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="auto"
port="4000"
autoBind="100"
selectorTimeout="5000"
maxThreads="6"/> <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
<Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
</Sender>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
</Channel>
<Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
filter=""/>
<Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
<Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
tempDir="/tmp/war-temp/"
deployDir="/tmp/war-deploy/"
watchDir="/tmp/war-listen/"
watchEnabled="false"/>
<ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>
步骤二:在web项目的web.xml文件中,添加节点<distributable/>就可以了,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<distributable/>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
到此,我们就解决了Nginx在tomcat集群配置中的session共享问题。这是基于tomcat自身的广播机制完成,虽然在功能上实现了session共享,但是运行效率相对较低。
为此,我们再介绍一种企业级解决方案,那就是引入redis缓存完成session共享。
那么,什么是redis呢?为此,我们要对NoSql有所了解。NoSql叫非关系型数据库,它的全名Not only sql,它不能替代关系型数据库,只能作为关系型数据库的一个良好补充。它是为了解决高并发、高可用、高可扩展,大数据存储等一系列问题而产生的数据库解决方案。
NoSql可以有多种分类,如根据键值对(Key-Value)存储数据的数据库(如Redis),列存储型数据库(如Hbase),文档型数据库(如MongoDB),图形(Graph)数据库等。我们在这里用到的Redis就是NoSql数据库中的一种。Redis可以将数据储存在缓存中,极大地提高了访问数据的效率,还可以根据需要对数据进行持久化存储。
Redis中可以储存5种类型的数据,分别是:
String
hash
list
set
zset
言归正传,我们继续介绍运用Redis实现session共享。
首先,我们可以根据自己所用电脑的操作系统下载Redis文件,如下图所示:

我们以Windows系统为例,上面分别对应32位和64位的win7操作系统,我们选择对应的压缩文件,解压到电脑中的一个位置,如下图所示:

在上图中,我们可以对redis的配置做下修改,如设置数据持久化策略,配置端口号等,为了方便启动redis服务器,我们还可以写个批处理文件,通过双击该批处理文件即可启动redis。上图中的“启动redis服务器.bat”文件内容如下:
C:
cd C:\Users\Administrator\Desktop\work\redis
redis-server redis.windows.conf
接下来,为了便于更好地模拟nginx集群配置tomcat时解决session共享的问题,我们先下载好nginx和两个tomcat,如下图所示:

然后,我们在每个tomcat中的server.xml里,删除原先通过tomcat广播机制配置的代码块,如下图所示:

然后,我们继续在server.xml中,找到<Context />标签,将其改成<Context></Context>,根据需要,在该标签中加入下面的信息:
<Context docBase="E:\nginx\tomcatB\webapps\Demo" path="" reloadable="true" crossContext="true">
<!--redis配置session共享-->
<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />
<Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
host="127.0.0.1"
port=""
maxInactiveInterval=""
<!--
database="" #optional: defaults to ""
sessionPersistPolicies="PERSIST_POLICY_1,PERSIST_POLICY_2,.." #optional
sentinelMaster="SentinelMasterName" #optional
sentinels="sentinel-host-1:port,sentinel-host-2:port,.." /> # optional
-->
/>
</Context>
我们要在做集群配置的tomcat的server.xml中均做如上配置,同时确保在web项目的web.xml中添加上<distributable/>标签。
接着,我们把三个jar包放入每个tomcat根目录下的lib文件中,三个jar包如下图所示(您可以在网上download,如果找不到请给我留言,并留下您的邮箱,我会发给您):

至此,我们就运用redis技术做好了nginx集群配置tomcat中面临的session共享问题。
最后,我们依次开启tomcat,nginx,以及redis,就会发现session已经实现了共享。
Nginx集群配置与redis的session共享策略的更多相关文章
- Nginx集群之基于Redis的WebApi身份验证
目录 1 大概思路... 1 2 Nginx集群之基于Redis的WebApi身份验证... 1 3 Redis数据库... 2 4 Visualbox ...
- Spring Boot+redis存储session,满足集群部署、分布式系统的session共享
本文讲述spring-boot工程中使用spring-session机制进行安全认证,并且通过redis存储session,满足集群部署.分布式系统的session共享. 原文链接:https://w ...
- Nginx+Memcached+Tomcat集群配置实践(Sticky Session)
准备工作 创建一个简单的web应用,名为session.其中有两个页面,分别如下所示: 页面login.jsp <%@ page language="java" conten ...
- nginx集群配置
一.nginx集群目标 以nginx作为代理服务器,分别在两台部署web站点的机器上面轮询访问. 3台机器IP地址分别为: 1)192.168.189.133 (nginx代理服务器) 2)192 ...
- 集群中用Memcached来实现session共享
这几天在实现nginx集群的过程中,发现session使用存在问题,登录页面后有时候需要重复登录,和开发部沟通后,决定采用memcached来实现session的共享,这也是各大型网站推荐的方式.开发 ...
- 【原创】搭建Nginx(负载均衡)+Redis(Session共享)+Tomcat集群
为什么移除首页?哪里不符合要求?倒是回我邮件啊! 一.环境搭建 Linux下Vagrant搭建Tomcat7.Java7 二.Nginx的安装配置与测试 *虚拟机下转至root sudo -i 1)下 ...
- 搭建Nginx(负载均衡)+Redis(Session共享)+Tomcat集群
一.环境搭建 Linux下Vagrant搭建Tomcat7.Java7 二.Nginx的安装配置与测试 *虚拟机下转至root sudo -i 1)下载并解压(目前官网最新版本) 创建安装目录:mkd ...
- Nginx+ 多个Memcached+ 多个Tomcat集群配置来实现 sticky Session
假如有 大于2 台的Tomcat servers,如何实现sticky session特点的高可靠web 服务? 方案设计: 前端使用nginx(最好是淘宝的 tengine)作为we 流量分发器,向 ...
- Redis-3.2.0集群配置(redis cluster)
版本:redis-3.0.5 redis-3.2.0 redis-3.2.9 redis-4.0.11 参考:http://redis.io/topics/cluster-tutorial. 目录 ...
随机推荐
- BZOJ3673 & BZOJ3674 & 洛谷3402:可持久化并查集——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=3673 https://www.lydsy.com/JudgeOnline/problem.php? ...
- 函数strcat实现
1.函数原型 extern char *strcat(char *dest,const char *src); 注:在C++中,则存在于<cstring>头文件中. 2.函数功能: str ...
- HDOJ(HDU).1016 Prime Ring Problem (DFS)
HDOJ(HDU).1016 Prime Ring Problem (DFS) [从零开始DFS(3)] 从零开始DFS HDOJ.1342 Lotto [从零开始DFS(0)] - DFS思想与框架 ...
- 页面元素的CSS渲染优先级
样式的优先级 多重样式(Multiple Styles):如果外部样式.内部样式和内联样式同时应用于同一个元素,就是使多重样式的情况. 一般情况下,优先级如下:(外部样式)External style ...
- 探讨JavaScript的事件冒泡
JavaSciprt事件中有两个很重要的特性:事件冒泡以及目标元素. 当一个元素上的事件被触发的时候,比如说鼠标点击了一个按钮,同样的事件将会在那个元素的所有祖先元素中被触发.这一过程被称为事件冒泡: ...
- qt4+vs2010 环境搭建
1.安装开发所需的软件: vs2010(包括VS2010SP1dvd1,Visual_Assist_X_10.9.2062.0_Crack等) QT: qt-win-opensource-4.8.5- ...
- Android 悬浮窗口
Android 悬浮窗口 一.创建悬浮窗口步骤 1.实现一个ViewGroup类,作为悬浮窗口的界面类,以便在里面重写onInterceptTouchEvent和onTouchEvent方法,实 ...
- FreeRTOS - 如何根据FreeRTOS提供的功能(信号量、任务通知、队列等)设计程序
原文地址:http://www.cnblogs.com/god-of-death/p/6917837.html 1.二值信号量 就像一个标志位,事件产生置一,事件处理后直零 用于任务之间的同步,即一个 ...
- [洛谷P2597] [ZJOI2012]灾难
洛谷题目链接:[ZJOI2012]灾难 题目描述 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引 ...
- jsp04状态管理
1.http 协议的无状态性 无状态是指,当浏览器发送请求给服务器的时候,服务器会响应.但当同一个浏览器再次发送请求时,服务器不会知道是刚才那个浏览器. 简单说,服务器[不会保存用户状态],不会记得客 ...