tomcat session server
此前已经进行过Tomcat的其他配置信息,这里不再进行重复的描述,会把重要的地方写上,不会影响实验
要想能够实现追踪有状态的web apps,对应的状态信息,有三种方式
session sticky
session replication cluster
session server
这里实现session server的实现方式
memcached可以借助于第三方的项目所提供的功能,实现使用memcached保存用户的session信息,项目称为MSM,工作方式:
例如有两台Tomcat主机,Tomcat拥有所谓的会话管理器,PersistentManager和deltaManager。MSM可以引入另外一个Manager,一个新的会话。
会话是靠Tomcat内部的类实现的,因此MSM有新增了一个会话管理器类,这个会话管理器,在管理本地会话时,可以在Tomcat级别,不是应用程序级别,而是Tomcat这个程序级别,把需要管理保存的用户会话,直接通过memcached协议,连接至memcached存储系统,予以保存。每一个主机只要配置指定了同样的位置,就能通过同一个位置,读取,或者是写入数据。如果memcached宕机了,所有会话就会丢失,而memcached自身不具备冗余能力,因此就在程序级,实现memcached的冗余,所以支持直接配置两台memcached主机,写数据的时候直接写两个节点,读取的时候,可以只从一个节点读,另外一个就是热备。每一个Tomcat都直接写2个节点,读的时候只从一个节点读。如果默认读的节点1宕机了,另外一台主机就会转为主动模式,回头坏掉的修复了再重新上线。能够把数据重新拿回来一份,就是客户端参与从一个节点上读出来,dump出来,导入到第二个节点上去。这就是MSM
MSM托管在GitHub中
在GitHub中搜索:memcached session manager
讲述了如何安装配置和使用MSM
支持的系统,Redis和couchbase是后期的事
- Configure memcached-session-manager as Manager
- Example for sticky sessions + kryo
- Example for non-sticky sessions + kryo
- Example for non-sticky sessions + kryo + Redis
- Example for non-sticky sessions with couchbase + kryo
- Example for multiple contexts sharing the same session id
kryo:
Decide which serialization strategy to use 决定使用哪一个序列化的策略
There are several session serialization strategies available, as they are described on SerializationStrategies. The default strategy uses java serialization and is already provided by the memcached-session-manager jar. Other strategies are provided by separate jars, in the section below you‘ll see which jars are required for which strategy.
序列化指的就是数据流式化,Tomcat是对象式编程语言而且是完全面向对象的,所以内部的所有的数据结构,都是对象,包括会话,而对象通常都有特定结构和元数据的,在内存中有结构,利用内存中存储系统专门去存储的。这种数据有特别诡异的地方是:
在内存中存好,同步到磁盘上去保存,都得流式化,只要通过网络传输,就一定要拆成0101代码发送出去,都需要流式化,往磁盘上发送也是一样,内部总线也是0101发出去的,往磁盘上存储都需要流式化,网络发送也要流式化。因此,像这种会话信息,想保存到memcached中,memcached本来就只能存储流式化数据,第一步就需要把会话流式化,然后才能存下来。流式化就需要流式化的工具,进行辅助实现。对memcached而言,流式化工具有很多
Add custom serializers to your webapp (optional) 定制使用serializers
要想使用Tomcat+MSM,需要的组件:Tomcat、memcached、二者之间加serializers(序列化工具、流式化工具)
流式化工具Tomcat内键的已经有可以直接使用,早些时候是必须要添加的,如果不想使用内键的,想调用外部的第三方的(可能会有更好的性能),就需要自己去定义
Add custom serializers to your webapp (optional) 添加自动以流式化工具
If you want to use java‘s built in serialization nothing more has to be done. If you want to use a custom serialization strategy (e.g. because of?better performance) this has to be deployed with your webapp so that they‘re available in?WEB-INF/lib/. #类库的存放位置,把下载的类库放进去
As msm is available in maven central (under groupId?de.javakaffee.msm) you can just pull it in using the dependency management of your build system. With maven you can use this dependency definition for the kryo-serializer:
<dependency> #自定义使用流式化工具
<groupId>de.javakaffee.msm</groupId>
<artifactId>msm-kryo-serializer</artifactId>
<version>1.9.7</version>
<scope>runtime</scope>
</dependency>
For javolution the artifactId is?msm-javolution-serializer, for xstream?msm-xstream-serializerand for flexjson it‘s?
msm-flexjson-serializer
.If you‘re not using a dependency management based on maven repositories these are the jars you need for the different serializers:
不同的流式化工具
- kryo-serializer:?msm-kryo-serializer,?kryo-serializers-0.34+,?kryo-3.x,?minlog,?reflectasm,?asm-5.x,?objenesis-2.x
- javolution-serializer:?msm-javolution-serializer,?javolution-5.4.3.1
- xstream-serializer:?msm-xstream-serializer,?xstream,?xmlpull,?xpp3_min
- flexjson-serializer:?msm-flexjson-serializer,?flexjson
要放的类库,这是四款流式化工具,放一个就可以了(下载下来)
如果要使用kryo-serializer,需要把对应的jar文件,下载下来,放到WEB-INF/lib/.目录中
配置的时候可以使用的模型
Configure memcached-session-manager as?<Context>Manager
- Example for sticky sessions + kryo
- Example for non-sticky sessions + kryo
- Example for non-sticky sessions + kryo + Redis 非粘性会话 + Redis
这里通过使用Example for sticky sessions + kryo方式进行构建
Example for non-sticky sessions + kryo
The following example shows a configuration for non-sticky sessions. In this case there‘s no need for?failoverNodes, as sessions are served by all tomcats round-robin and they‘re not bound to a single tomcat. For non-sticky sessions the configuration (for both/all tomcats) would look like this:
<Context>
...
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:host1.yourdomain.com:11211,n2:host2.yourdomain.com:11211"
sticky="false"
sessionBackupAsync="false"
lockingMode="uriPattern:/path1|/path2"
requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
/>
</Context>
实现使用memcached保存用户的session信息
版本要是一样的
[[email protected] /etc/tomcat]# rpm -q tomcat
tomcat-7.0.76-3.el7_4.noarch
[[email protected] /etc/tomcat]# rpm -q tomcat
tomcat-7.0.76-3.el7_4.noarch
准备Tomcat7专用的类
Add memcached-session-manager jars to tomcat
Independent of the chosen serialization strategy you always need the?memcached-session-manager-${version}.jar
?and either?memcached-session-manager-tc6-${version}.jar
?for tomcat6,?memcached-session-manager-tc7-${version}.jar
?for tomcat7 (attention: tomcat 7.0.23+),?memcached-session-manager-tc8-${version}.jar
?for tomcat8 or?memcached-session-manager-tc9-${version}.jar
?for tomcat9.If you‘re using
memcached
, you also need the?spymemcached-${version}.jar
. Tested up to v2.12.3.
If you‘re using couchbase, you need additionally these jars:?couchbase-client-1.4.0.jar
?jettison-1.3.jar
,?commons-codec-1.5.jar
,?httpcore-4.3.jar
,?httpcore-nio-4.3.jar
,?netty-3.5.5.Final.jar
.
If you‘re using Redis, you need the?jedis-2.9.0.jar.
Please download the appropriate jars and put them in?$CATALINA_HOME/lib/.
下载和序列化相关的jar文件,因为示例写的是keyo,不再进行修改,直接使用kryo,也可以修改为其他的流式化工具
kryo-serializer:?msm-kryo-serializer,?kryo-serializers-0.34+,?kryo-3.x,?minlog,?reflectasm,?asm-5.x,?objenesis-2.x
要把下载的jar包放到WEB-INI/lib目录下
下载各个包完成
查看Tomcat把库文件存放在什么位置
[[email protected] /app]# rpm -ql tomcat-lib/usr/share/java/tomcat
复制主要的jar文件
[[email protected] /app]# cp memcached-session-manager-* pymemcached-2.12.3.jar/usr/share/java/tomcat
把jar包复制到另一台机器
[[email protected] /app]# scp memcached-session-manager-* spymemcached-2.12.3.jar 192.168.111.102:/usr/share/java/tomcat
*memcached-session-manager- spymemcached-2.12.3.jar 是必须的jar包**
查看
[[email protected] /app]# ls /usr/share/java/tomcat
修改配置文件的配置,根据配置文件中的说明配置session manager
修改配置文件的配置,根据配置文件中的说明配置session manager
<Context>Manager
作为<Context>内部使用的Manager,也就意味着丢到<Context>内部
<Context>是定义application的
Configure memcached-session-manager as?<Context>Manager
Example for sticky sessions + kryo
The following example shows the configuration of the first tomcat, assuming that it runs on host1, together with memcached "n1". The attribute?failoverNodes="n1"?tells msm to store sessions preferably in memcached "n2" and only store sessions in "n1"(running on the same host/machine)
if no other memcached node (here only n2) is available (even if host1 goes down completely, the session is still available in memcached "n2" and could be served by the tomcat on host2). For the second tomcat (on host2) you just need to change the failover node to "n2", so that it prefers the memcached "n1". Everything else should be left unchanged.
<Context> # contest是定义application的
...
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
`memcachedNodes`="n1:host1.yourdomain.com:11211,n2:host2.yourdomain.com:11211"
`failoverNodes`="n1"
`requestUriIgnorePattern`=".*\.(ico|png|gif|jpg|css|js)$"
`transcoderFactoryClass`="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
/>
</Context>
使用的类是MemcachedBackupSessionManager
- memcachedNodes 指定memcached的节点
- n1 是标识,memcached节点的主机名或者IP地址都可
- failoverNodes 标识n1是什么,这里标识备用节点,是故障转移节点。意味着n2是主节点,把n1当做故障转移节点
- requestUriIgnorePattern 如果是这台主机上的session,就不用保存了,和图片有关的,cookie、session都没有用,所以,静态内容,都进行了忽略
- transcoderFactoryClass 如果需要把session保存在memcached中,使用什么序列化工具,这里使用的是KryoTranscoderFactory,就是刚才下载的一大堆的jar包,被这个指令全部调用完了
这是sticky sessions + kryo形式的
sticky sessions + kryo并不是绑定主机的, 绑定的只是sticky本身,一个用户访问的请求,始终是绑定在同一个session上
对于non-sticky session多出的内容
- sticky="false"
- sessionBackupAsync="false" session备份使用异步模式是被拒绝的。
- lockingMode="uriPattern:/path1/path2" 锁模型为"uriPattern:/path1/path2",使用url进行定义,这个就麻烦了
使用sticky sessions + kryo形式的
[[email protected] /etc/tomcat]# vim server.xml
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Context path="/myapp" docBase="myapp" reloadable="" >
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:192.168.111.102:11211,n2:192.168.111.103:11211"
failoverNodes="n1" 故障转移节点
requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$" 这些session不进行保存
transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
/>
</Context>
reloadable=""是否可以重写,默认没有定义
复制到另外一个节点上
[[email protected] /etc/tomcat]# scp server.xml 192.168.111.103:/etc/tomcat
准备memcached(就使用本机的不然还需要别的虚拟机)
[[email protected] /etc/tomcat]# systemctl start memcached
[[email protected] /etc/tomcat]# ss -ntl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:11211 *:*
[[email protected] ~]# yum -y install memcached
[[email protected] ~]# systemctl start memcached
[[email protected] ~]# ss -ntl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 :11211 :*
启动Tomcat
[[email protected] /etc/tomcat]# systemctl start tomcat
[[email protected] /etc/tomcat]# systemctl status tomcat
● tomcat.service - Apache Tomcat Web Application Container
Loaded: loaded (/usr/lib/systemd/system/tomcat.service; disabled; vendor preset: disabled)Active: active (running)
[[email protected] /app]# systemctl start tomcat
访问(可以访问主页面,无法访问myapp)http://192.168.111.102:8080/
把所有的jar包复制到tomcat的jab目录中
[[email protected] /app]# cp * /usr/share/java/tomcat/
cp: overwrite ‘/usr/share/java/tomcat/memcached-session-manager-2.3.0.jar’? y
cp: overwrite ‘/usr/share/java/tomcat/memcached-session-manager-tc7-2.3.0.jar’? y
cp: overwrite ‘/usr/share/java/tomcat/spymemcached-2.12.3.jar’? y
[[email protected] /app]# systemctl restart tomcat
访问
把jar包复制到目录中访问,正常
把所有的包都扔进目录中
[[email protected] /app]# scp * 192.168.111.102:/usr/share/java/tomcat/
[[email protected] /etc/tomcat]# systemctl restart tomcat
查看前端代理配置
[[email protected] /etc/nginx]# vim nginx.conf
http {
upstream tcsrvs{
server 192.168.111.102:8080;
server 192.168.111.103:8080;
}
server {
location / {
proxy_pass http://tcsrvs;
index index.jsp index.html;
}
访问前端代理
做了session sticky,刷新,主机会变,但是session信息不会变。
但页面信息确实是对应的主机提供的服务。
这就是session sticky
如果是下载的rpm包的方式安装的Tomcat,需要把对应的jar包放在/usr/local/tomcat/lib 目录中
把jar包扔进去以后,就可以使用msm的session-manager
修改配置文件使用session-manager,放在context或者host中
多数情况下session管理是分应用程序单独管理的,所以把它放在配置文件的contest中,而后启动Tomcat就可以了
宕机memcached看会不会执行
[[email protected] /app]# systemctl stop memcached
刷新
所以,可以实现故障转移了
现在把memcached启动起来
[[email protected] /app]# systemctl start memcached
每一次转移,换一个节点,都是有成本的,所以是不会移来移去的,除非定义了failed back
故障转移有两个盖面,fill lower,自己故障了,转到备用节点上去,原来的节点重新上线以后,无论备用节点坏还是不坏,都要回来,这叫fill back。如果没有定义fill back,就意味着转过去之后,至于对方坏了才会转回来。过去之后,自己就是备用的了,重新转回来的时候自己才是主。
这就是讲到的session server
memcached没有持久功能,如果停电,所有的session就全没了。这是很悲剧的。所以,建议使用Redis,做session server
If you‘re using
Redis
, you need the?jedis-2.9.0.jar
.Example for non-sticky sessions + kryo + Redis
The following example shows a configuration which uses a Redis server at the URL "redis.example.com" for session storage for non-sticky sessions. Here the configuration (for both/all tomcats) would look like this:
<Context>
...
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="redis://redis.example.com"
sticky="false"
sessionBackupAsync="false"
lockingMode="uriPattern:/path1|/path2"
requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
/>
</Context>
其他的信息都不变,换jar包就行了。
redis支持主从,所以这里没有备用。
配置redis以主从模式工作就没问题。
这里使用主机名的好处是,使用主机名,万一主节点宕机了,redis会自动切换另外一个节点成为主节点,但是IP变了怎么办?要么使用vip提供服务,去转移vip,要么是使用主机名解析它,修改解析记录。使用keepalived要好一点。
原文地址:http://blog.51cto.com/13335066/2113392