一、tomcat介绍

Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。(Tomcat 不太适合高并发,解决方法,增加后端数量)

tomcat 启动前需要配置JDK环境变量,如果没有配置JDK的环境变量,那么tomcat启动的时候就会报错,也就是无法启动。

JDK 是 Java 语言的软件开发工具包,主要用于移动设备、嵌入式设备上的java应用程序。JDK是整个java开发的核心,它包含了JAVA的运行环境(JVM+Java系统类库)和JAVA工具。

二、nginx结合tomcat

Tomcat和Nginx的区别:

tomcat一般做动态解析才会用得到,支持jsp的解析,需要配置JDK支持。

nginx,则一般是做静态,本身不具备动态解析功能,需要配置其他插件或通过其他软件协同才具备动态功能,比如php,tomcat,或者proxypass到win2008的iis服务器做ASP的动态链接等,但nginx在静态上的功能非常强大,也可做访问控制,而且可以做成各种协议负载服务器。

动态静态资源分离:
之前开发web方面的程序时候我们习惯将html、css等资源文件也放置于Tomcat中,用户访问后tomcat需要将请求的这些静态资源文件一并返回给用户。再者如果有多台同业务逻辑的tomcat服务器的话,同样的资源还需要在每个服务器上放一份,同时也增加了tomcat服务器的网络IO。

如果我们只讲JSP之类的请求交给tomcat,在代理服务器上存放静态资源,当用户的请求非动态资源的时候,我们完全可以将代理服务器的静态资源直接返回给用户,而不去增大Tomcat的压力,tomcat只需要负责逻辑处理动态资源的加载就可以了。

同时,Tomcat的高并发性能很弱,所以在处理静态请求的时候,我们就抛给Nginx处理,而Tomcat专门处理动态请求。

Nginx和Tomcat结合方式

  1. 将所有静态页面交给nginx,动态请求交给后端tomcat处理。
  2. 将所有请求交给后端tomcat服务器处理,只利用Nginx自身的负载均衡功能进行多台tomcat服务器调度流。

三、tomcat结合memcached

为了实现tomcat集群之间的session同步:利用memcached实现(MSM工具)。memcached存储session,并把多个tomcat的session集中管理,前端在利用nginx负载均衡和动静态资源分离,在兼顾系统水平扩展的同时又能保证较高的性能。即通过MSM工具把Tomcat的Session序列化后保存到Memcached里面,从而实现Session共享.

MSM介绍:

MSM是一个高可用的Tomcat Session共享解决方案,除了可以从本机内存快速读取Session信息(仅针对黏性Session)外,还可使用Memcached存取Session,以实现高可用。
传统tomcat集群,会话复制随着结点数增多,扩展性成为瓶颈。MSM使用memcached完成统一管理tomcat会话,避免tomcat结点间过多会话复制。

MSM利用Value(Tomcat 阀)对Request进行跟踪。Request请求到来时,从memcached加载session,Request请求结束时,将tomcat session更新至memcached,以达到session共享之目的, 支持sticky和non-sticky模式:

sticky : 会话粘连模式(黏性session)。客户端在一台tomcat实例上完成登录后,以后的请求均会根据IP直接绑定到该tomcat实例。
no-sticky:会话非粘连模式(非粘性session)。客户端的请求是随机分发,多台tomcat实例均会收到请求。

下面给出一个黏性session模式的设置示例,此实例中安装了2个tomcat以及2个memcached。

交叉存储:Tomcat-1(t1)的首要选择是把session存储在memcached-2 (m2)上(m2是t1的一个普通节点),而m2是运行在另外的一台机器上。只有当m2不可用(宕机或无法访问)时,t1才会把session存储到memcached-1(m1,m1是t1的故障转移节点)上。使用这种配置,即使机器1宕机了session也不会丢失。具体如下图所示: 

jar包和nginx_服务器

 

四、nginx+tomcat结合memcache

此时我们关闭上文中openresty里的nginx,更改为源生的nginx:

jar包和nginx_服务器_02

 将后台的两个server端的apache服务关闭。

软件下载:https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/src/master/
拷贝jar包到/usr/local/tomcat/lib目录
配置tomcat:
#  vim /usr/local/tomcat/conf/context.xml
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:172.25.0.3:11211,n2:172.25.0.4:11211"
failoverNodes="n1"
requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
/>

首先在后端两个server上下载apache-tomcat和源生的jdk:

jar包和nginx_tomcat_03

 将apache-tomcat解压到/usr/local/下,并做一个软连接:

jar包和nginx_jar包和nginx_04

 进入目录将tomcat启动起来:

jar包和nginx_tomcat_05

 同样的操作在server3上再操作一遍:

jar包和nginx_nginx_06

tomcat占用的是8080端口。此时在server1上设置nginx,编辑nginx.conf:

 

jar包和nginx_大数据_07

 

jar包和nginx_tomcat_08

 检测语法没问题后开启:

jar包和nginx_大数据_09

此时访问172.25.254.2:8080可以访问到tomcat 页面;

jar包和nginx_nginx_10

问题1:我们在server1上配置了tomcat负载均衡器,此时访问172.25.254.1/index.jsp应该链接到后端的8080端口,但是访问后是以下页面:

jar包和nginx_大数据_11

解析:这是由于nginx和tomcat默认发布目录不一样,此处最好做一个重定向,将所有请求都交给后端的tomcat。因为此时nginx配置文件的逻辑是所有后缀为jsp的文件交给后端tomcat处理,但是图片的后缀不是jsp,所以图片会加载不出来。

解决:此时,我们在后端server上设置,进入tomcat默认发布目录,创建一个test.jsp(此文件的功能是记录session列表的信息)

jar包和nginx_jar包和nginx_12

 

jar包和nginx_jar包和nginx_13

 此时我们访问172.25.254.1/test.jsp:

jar包和nginx_jar包和nginx_14

 此时,我们停掉server2的tomcat来假设server2宕掉了。

 

jar包和nginx_nginx_15

我们再访问172.25.254.1/test.jsp:

jar包和nginx_服务器_16

我们发现此时后端已经被server3接管了,这是因为nginx对后端有健康检测,但是sesison却丢失了,这表示后端的session信息并不共享。

解决方式:nginx+tomcat+memcached交叉式存储。

jar包和nginx_jar包和nginx_17

 工作原理:tomcat1和memcache1在后端server2上,tomcat2和memcache2在后端server3上。nginx只对后端的两个tomcat进行健康检测,不对memcache进行健康检测。从nginx传过来的session信息会先在tomcat1上存储,再在memcache2上存储一份,tomcat2同理。若tomcat1挂掉之后,tomcat2接管后端服务器,同时从memcache2上获取之前tomcat1上存储的session信息。若tomcat1整个节点同时宕掉,由于tomcat1之前的信息都是存在memcache2上的,所以信息不会丢失;memcache1挂掉后,tomcat2可以把自身处理的信息再在memcache2上再存储一份,也不会丢失。这种方式下,任何一个节点或者服务宕掉,整个集群都可以进行高可用和自动冗余。注:memcache只是临时存储,并没有持久化保存。

具体操作: 首先把后端两个服务器的tomcat停掉,更改配置文件

/usr/local/tomcat/conf/context.xml  添加以下内容:

jar包和nginx_大数据_18

节点2失效n2。

 由于刚刚配置文件调用了相关的类,我们需要把相应的包放到tomcat/lib下:(注意:相应的jar包要和tomcat对应起来)

jar包和nginx_tomcat_19

 

jar包和nginx_jar包和nginx_20

注:版本对应非常重要,一个对应不上就会报错。此套jar包经本人亲测和tomcat8.5.24匹配。



 此时在后端两个服务器安装memcached客户端:

jar包和nginx_jar包和nginx_21

 两个服务器都设置好tomcat+memcache后,开启memcached服务,此时后端的tomcat+memcache交叉存储就设置好了(同时解决了高可用和session共享问题)。

测试:

此时再登陆服务器的test.jsp会出现一个ID号,

jar包和nginx_tomcat_22

 可以看待此时我们添加的数据通过server2添加到了server3的memcache上。

jar包和nginx_tomcat_23

 我们可以通过安装工具telnet来查看我们缓存的信息:

jar包和nginx_nginx_24

 可以看到我们存储的信息是在server3上的。因为此时是server2的tomcat在接管服务器,所以我们先把server2的tomcat停掉:

jar包和nginx_大数据_25

 此时我们再提交seission数据,可以看到数据没有丢失,对于客户端来说是透明的,但是此时的服务器已经切到了server3,数据则存在server2的memcache上:

jar包和nginx_jar包和nginx_26

由于此时使用的是server3上的memcache存储的数据,我们关闭server3上的memc,发现此时的memc服务器又切回到了server2上的memc

jar包和nginx_服务器_27

注:如果某个后端服务器宕掉,重新开启服务器后,要手动切换到交叉存储,不然如果tomcat和memc在同一个服务器上的话,如果这个服务器宕掉数据就丢失了)