Nginx+Tomcat+Memcached集群

部署环境

系统:Centos
软件及依赖包:
Nginx:
nginx-1.6.2.tar.gz
(http://nginx.org/download/nginx-1.6.2.tar.gz)
pcre-8.36.tar.gz (ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.36.tar.gz)
zlib-1.2.8.tar.gz(http://zlib.net/zlib-1.2.8.tar.gz)

memcached:
memcached-1.4.22.tar.gz(http://memcached.org/files/memcached-1.4.22.tar.gz)
libevent-2.0.22-stable.tar.gz(http://libevent.org/)

memcached-session-manager:
下载地址

Tomcat:
apache-tomcat-7.0.59.tar.gz (http://mirrors.cnnic.cn/apache/tomcat/tomcat-7/v7.0.59/bin/apache-tomcat-7.0.59.tar.gz)
jdk-7u72-linux-x64.tar.gz

jar包:
我采用的是截止目前最新的版本,其中序列化方式是可选的。
序列化方式使用kryo时,jar包:下载地址
此处输入图片的描述

序列化方式使用javolution时,jar包:下载地址
此处输入图片的描述

了解到kryo序列化方式效率最高。

相关序列方式,所需不同jar包,可参考官方文档

Nginx安装

安装gcc-c++

1
yum -y install gcc-c++

安装pcre库

pcre库是为了使nginx支持http rewrite模块

1
2
3
4
5
6
7
cd /usr/local/src/
wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.36.tar.gz
tar -xzvf pcre-8.36.tar.gz
cd pcre-8.36
./configure
make
make install

安装zlib库

zlib库是为了使nginx支持gzip压缩

1
2
3
4
5
6
7
cd /usr/local/src
wget http://zlib.net/zlib-1.2.8.tar.gz
tar -xzvf zlib-1.2.8.tar.gz
cd zlib-1.2.8
./configure
make
make install

安装Nginx

1
2
3
4
5
6
7
cd /usr/local/
wget http://nginx.org/download/nginx-1.6.2.tar.gz
tar -zxvf nginx-1.6.2.tar.gz
cd nginx-1.6.2
./configure --prefix=/usr/local/nginx --with-pcre=/usr/local/src/pcre-8.36 --with-zlib=/usr/local/src/zlib-1.2.8
make
make install

配置nginx.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
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 logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
gzip on;
#配置后端服务器群组信息
upstream web_server {
server localhost:8080;
server localhost:8081;
}
server {
listen 80;
server_name localhost;
charset utf-8;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
#代理设置
proxy_pass http://web_server;
proxy_set_header X-Real-IP $remote_addr;
client_max_body_size 100m;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}

安装memcached

先安装libevent-2.0.22-stable.tar.gz依赖包

1
2
3
4
5
tar zxvf libevent-2.0.22-stable.tar.gz
cd libevent-2.0.22-stable
./configure --prefix=/usr/local/libevent-2.0.22
make
make install

再安装memcached-1.4.22.tar.gz

1
2
3
4
5
6
7
8
9
10
11
12
tar zxvf memcached-1.4.22.tar.gz
cd memcached-1.4.22
./configure --prefix=/usr/local/memcached-1.4.22 --with-libevent=/usr/local/libevent-2.0.22/
make
make install
#以守护进程的方式启动,监听于 127.0.0.111211端口,使用root用户,最大使用512M内存,日志输出到/tmp/memcached.log
/usr/local/memcached-1.4.22/bin/memcached -d -m 512 -l 127.0.0.1 -p 11211 -u root -vv >> /tmp/memcached.log 2>&1
#启动后,可以telnet上去看下状态
telnet 127.0.0.1 11211
stats

安装tomcat

安装JDK 环境

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#查询是否安装java
rpm -qa | grep java
#卸载openjdk
rpm -e java-1.6.0-openjdk-1.6.0.0-1.45.1.11.1.el6.x86_64
rpm -e tzdata-java-2012c-1.el6.noarch
#安装java
mkdir /usr/java
cd /usr/java
wget http://.../jdk-7u72-linux-x64.tar.gz
tar -xzvf jdk-7u72-linux-x64.tar.gz
#修改系统环境变量文件
vi /etc/profile
#添加如下内容
#Set java JDK
JAVA_HOME=/usr/local/jdk1.7.0_72
JRE_HOME=/usr/local/jdk1.7.0_72/jre
PATH=$PATH:$JAVA_HOME/bin:$JRE_home/bin
CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar
export JAVA_HOME
export JRE_HOME
export PATH
export CLASSPATH
#使修改马上生效
source /etc/profile
#验证是否安装成功
java -version

安装Tomcat应用服务器

1
2
3
4
5
cd /usr/local
wget http://.../apache-tomcat-7.0.56.tar.gz
tar -xzvf apache-tomcat-7.0.56.tar.gz
mv apache-tomcat-7.0.56 tomcat1
cp -R tomcat1 tomcat2

配置Tomact的server.conf

8080端口实例的tomcat1配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<Server port="8005" shutdown="SHUTDOWN">
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">
...
<Context path="" docBase="/home/imcc/web" debug="0" reloadable="true" crossContext="true">
<Manager
className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:localhost:11211"
requestUriIgnorePattern=".*\.(png|gif|jpg|css|js|ico|jpeg|htm|html)$"
sessionBackupAsync="false"
sessionBackupTimeout="100"
copyCollectionsForSerialization="false"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory" />
</Context>

8081端口实例的tomcat1配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<Server port="8006" shutdown="SHUTDOWN">
<Connector port="8081" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
<Connector port="9009" protocol="AJP/1.3" redirectPort="8443" />
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat2">
...
<Context path="" docBase="/home/imcc/web" debug="0" reloadable="true" crossContext="true">
<Manager
className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:localhost:11211"
requestUriIgnorePattern=".*\.(png|gif|jpg|css|js|ico|jpeg|htm|html)$"
sessionBackupAsync="false"
sessionBackupTimeout="100"
copyCollectionsForSerialization="false"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory" />
</Context>

备注:

Manager标签属性说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
className 必须
类名:de.javakaffee.web.msm.MemcachedBackupSessionManager
memcachedNodes 必须
memcached节点:此属性应该包含所有运行的memcached节点或者membase bucket的uri地址,每一个memcached节点的属性定义格式为<id>:<host>:<port>,多个节点定义直接使用空格或者逗号分隔,形如:memcachedNodes="n1:app01:11211,n2:app02:11211",如果只有单个的memcached节点,则<id>是可选项,只需配置<host>:<port>即可,形如:memcachedNodes="localhost:11211"
如果我们配置的是membase,那么从1.6.0版本开始,我们可以配置指定一个或者多个membase bucket uris,形如:http://host1:8091/pools,http://host2:8091/pools。Bucket 名称和密码通过属性username,password来定义。membase buckets连接需要遵循memcached协议,传输数据通过二进制流方式。
failoverNodes 可选项
故障转移节点:可选项,对非黏性session不可用,属性必须包含memcached节点集群的所有ids。节点id之间用空格或者逗号分隔。
username 可选项
1.6.0版开始使用,并且是可选的。用来进行membase bucket或者SASL验证,密码可以为空。
password 可选项
1.6.0版开始使用,并且是可选的。用来进行membase bucket或者SASL验证,密码可以为空。
memcachedProtocol 可选项
定义memcached协议,默认使用text文本,出属性指明memcached使用的存储协议。只支持text或者binary。
sticky 可选项
定义session方式为黏性或非黏性,默认为true,多个tomcat时需使用非黏性
lockingMode 可选项
只有非黏性session才使用,默认值为none
none: 从不对session进行锁定
all: session将一直被锁定,直到请求结束
auto: 对于只读请求,session将不会被锁定,如果是非只读请求,则session会被锁定
uriPattern:<regexp>: 通过正则表达式的方式来对请求uri以及查询字符串进行匹配,只有匹配上的才会被锁定。
requestUriIgnorePattern 可选项
此属性是那些不能改备份Session的请求的正则表达式。如果像css,javascript,图片等静态文件被同一个Tomcat和同一个应用上下文来提供,这些请求也会通过memcached-session-manager。但是这些请求在一个http会话中几乎没什么改变,所以他们没必要触发Session备份。所以那些静态文件没必要触发Session备份,你就可以使用此属性定义。此属性必须符合java regex正则规范。
如:".*\.(png|gif|jpg|css|js)$"
sessionBackupAsync 可选项
指定Session是否应该被异步保存到Memcached中。 如果被设置为true,backupThreadCount设置起作用,如果设置false,通过sessionBackupTimeout设置的过期时间起作用。
backupThreadCount 可选项
用来异步保存Session的线程数,(如果sessionBackupAsync="true")。默认值为cup的内核数。
sessionBackupTimeout 可选项
设置备份一个Session所用的时间,如果操作超过时间那么保存失败。此属性只sessionBackupAsync="false"是起作用。默认100毫秒
operationTimeout 可选项
1.6.0版开始使用, 默认值为1000
sessionAttributeFilter 可选项
此属性是用来控制Session中的那个属性值保存到Memcached中的正则表达式。正则表达式被用来匹配Session中属性名称。如sessionAttributeFilter="^(userName|sessionHistory)$" 指定了只有"userName""sessionHistory"属性保存到Memcached中。依赖于选择的序列化策略。
transcoderFactoryClass 可选项
此属性值是创建序列化和反序列化保存到Memcached中的Session的编码转换器的工厂类名。这个指定的类必须实现了de.javakaffee.web.msm.TranscoderFactory和提供一个无参的构造方法。例如其他的有效的实现在其他packages/jars中提供如:msm-kryo-serializer,msm-xstrea-serializer和msm-javolution-serializer.
默认为 de.javakaffee.web.msm.JavaSerializationTranscoderFactory
copyCollectionsForSerialization 可选项
默认值为false。
customConverter 可选项
自己定义特殊的类注册到kryo自定义转换器中,实现序列化
enableStatistics 可选项
用来指定是否进行统计。 默认值为true。
enabled 可选项
指定Session保存到Memcached中是否可用和是否可以通过JMX进行改变。只用于粘性Session。 默认值为true。

添加memcached-session-manager的依赖包到$TOMCATHOME/lib目录下

测试

添加测试页面/home/imcc/web/index.jsp

1
2
3
4
5
6
7
8
SessionID:<%=session.getId()%>
<BR>
SessionIP:<%=request.getServerName()%>
<BR>
SessionPort:<%=request.getServerPort()%>
<%
out.println("This is Tomcat Server!");
%>

通过浏览器访问,并刷新:
此处输入图片的描述
此处输入图片的描述

查看memcached日志:
此处输入图片的描述
通过观察SessionID没有发生变化,证明session共享成功。

参考:
MSM–Memcached_Session_Manager介绍及使用
交易系统架构之会话篇:tomcat msm部署
Nginx+Tomcat+Memcached集群Session共享
利用nginx+tomcat+memcached组建web服务器负载均衡
Nginx+Tomcat+Memcached集群