tomcat 集群
当前tomcat集群,用得比较多的几种方法就是apache+tomcat、nginx+memcache+tomcat以及Hyproxy+tomcat。
做对比的也比较多,总得来说,apache的方式已经用得比较少了。其中在nginx 和 hyproxy的对比比较多。起始Hybroxy出来的时间比较晚,很多东西也做得比较完善了,可以使用。由于前面都是使用的nginx,所以这里先用这个来搭建并做一下相关记录。
大概原理
nginx+memcache+tomcat集群的大概原理是使用nginx做负载分担,多个tomcat在后端做服务集群。然后使用memcache在里面做session的共享。
同时memcache还可以做后端mysql的缓存,不过这个就需要单独拿出来做了,在这里不涉及。
安装
安装nginx、tomcat、memcache在这里就不过多涉及了。
配置nginx的负载均衡
nginx的主备也不在这里过多描述了,可以参考前面的博。
配置nginx的负载均衡:
upstream myClusterServer1 {
server 192.168.11.135:8080 weight=5;
server 192.168.11.136:8080 weight=5;
server 192.168.11.137:8080 weight=5;
}
server {
listen 80;
server_name localhost;
#charset koi8-r;
charset utf-8;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
proxy_pass http://myClusterServer1;
proxy_redirect off;
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 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
这里整理了三台主机的负载均衡
配置完成后进行/usr/local/nginx/sbin/nginx -s reload
重启nginx即可
此时访问测试工程就可以发现,负载分担已经起作用了。
配置memcached
启动memcached
/usr/bin/memcached -m 64 -d -u memcache -p 11211 -l 192.168.11.141
不要使用默认的启动,默认的启动会绑定到127.0.0.1上,这样其他服务是不能访问的
在第二台上配置启动:
/usr/bin/memcached -m 64 -d -u memcache -p 11211 -l 192.168.11.142
启动完成后就可以进行memcache共享了
tomcat配置
配置测试工程
测试工程中加一个jsp文件就可以了
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Tomcat+memcached共享session测试</title>
</head>
<body>
SessionID:<%=session.getId()%>
<BR>
SessionIP:<%=request.getServerName()%>
<BR>
SessionPort:<%=request.getServerPort()%>
<BR>
<%
out.println("This is Tomcat Server 8081.");
%>
</body>
</html>
配置tomcat目录
使用memcache需要使用的jar包有
asm-3.2.jar
commons-codec-1.5.jar
couchbase-client-1.4.0.jar
httpcore-4.3.jar
httpcore-nio-4.3.jar
javolution-5.4.3.1.jar
jettison-1.3.jar
kryo-1.04.jar
kryo-serializers-0.10.jar
memcached-session-manager-1.7.0.jar
memcached-session-manager-tc7-1.7.0.jar
minlog-1.2.jar
msm-kryo-serializer-1.6.3.jar
netty-3.5.5.Final.jar
reflectasm-0.9.jar
spymemcached-2.11.1.jar
这些包不要放到工程里面,而是放到tomcat的lib目录中,ubuntu中在/usr/share/tomcat7/lib/
中,mac在 /Library/tomcat/apache-tomcat-7.0.42/
中。 否则可能会出现类无法找到的问题。
配置tomcat配置文件
配置context.xml ,这个文件在/var/lib/tomcat7/webapps/conf
中
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:192.168.11.141:11211 n2:192.168.11.142:11211"
sticky="false"
requestUriIgnorePattern=".*\.(png|gif|jpg|css|js|ico|jpeg)$"
sessionBackupAsync="false"
sessionBackupTimeout="100"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"/>
配置server.xml ,这个文件同样在/var/lib/tomcat7/webapps/conf
中
Engine中添加
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcatRoute1">
配置多个memcache节点中间加空格,session会在多个memcache节点中共享,就算某个memcache挂掉也可以从另外的节点继续获取session。
完成
这些都配置完成后,可以再通过负载均衡来访问,可以看到相关的session访问也一样了。如果没有配的时候,每次访问到不同的节点上会新增一个新的session。
问题
大多数走到这一步都完了,但是存在一些问题。现在nginx、tomcat、memcache、mysql都集群了,对于nginx、memcache、mysql挂掉之后都可以由其他的拉起来。
简单的tomcat服务down机等,可以通过nginx的配置 proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
来进行完成。后面也会详细说明一下这些配置
但是现在如果某一台tomcat异常,但是请求未挂掉的时候,(比如内存溢出等),实际上是不能提供服务的,但是nginx还是会将映射找到这台挂掉的tomcat上,这是这个请求无法达成,后面所有的到这个服务器的请求都将出错。所以必须有检查错误的剔除机制。 —— 想到的简单解决方案是在当前本机上或者在核心上监控,如果这台服务器的服务无法提供,就直接把tomcat给停掉。
90秒是否过长了,对于某些服务可能需要降低错误时间。
参考
可以参考的几个网站:
http://www.cnblogs.com/phirothing/archive/2013/12/05/3459814.html —— 这个写的比较清晰,适合配置使用
http://www.2cto.com/os/201109/104650.html ——写得不是那么清晰,但是是在ubuntu下面的
http://blog.csdn.net/zht666/article/details/38515147 —— 有些写的比价细,但是有些有bug
nginx的一些超时配置
client_header_timeout
语法 client_header_timeout time
默认值 60s
上下文 http server
说明 指定等待client发送一个请求头的超时时间(例如:GET / HTTP/1.1).仅当在一次read中,没有收到请求头,才会算成超时。如果在超时时间内,client没发送任何东西,nginx返回HTTP状态码408(“Request timed out”)
client_body_timeout
语法 client_body_timeout time
默认值 60s
上下文 http server location
说明 该指令设置请求体(request body)的读超时时间。仅当在一次readstep中,没有得到请求体,就会设为超时。超时后,nginx返回HTTP状态码408(“Request timed out”)
keepalive_timeout
语法 keepalive_timeout timeout [ header_timeout ]
默认值 75s
上下文 http server location
说明 第一个参数指定了与client的keep-alive连接超时时间。服务器将会在这个时间后关闭连接。可选的第二个参数指定了在响应头Keep-Alive: timeout=time中的time值。这个头能够让一些浏览器主动关闭连接,这样服务器就不必要去关闭连接了。没有这个参数,nginx不会发送Keep-Alive响应头(尽管并不是由这个头来决定连接是否“keep-alive”)
两个参数的值可并不相同
注意不同浏览器怎么处理“keep-alive”头
MSIE和Opera忽略掉"Keep-Alive: timeout=" header.
MSIE保持连接大约60-65秒,然后发送TCP RST
Opera永久保持长连接
Mozilla keeps the connection alive for N plus about 1-10 seconds.
Konqueror保持长连接N秒
lingering_timeout
语法 lingering_timeout time
默认值 5s
上下文 http server location
说明 lingering_close生效后,在关闭连接前,会检测是否有用户发送的数据到达服务器,如果超过lingering_timeout时间后还没有数据可读,就直接关闭连接;否则,必须在读取完连接缓冲区上的数据并丢弃掉后才会关闭连接。
resolver_timeout
语法 resolver_timeout time
默认值 30s
上下文 http server location
说明 该指令设置DNS解析超时时间
proxy_connect_timeout
语法 proxy_connect_timeout time
默认值 60s
上下文 http server location
说明 该指令设置与upstream server的连接超时时间,有必要记住,这个超时不能超过75秒。
这个不是等待后端返回页面的时间,那是由proxy_read_timeout声明的。如果你的upstream服务器起来了,但是hanging住了(例如,没有足够的线程处理请求,所以把你的请求放到请求池里稍后处理),那么这个声明是没有用的,由于与upstream服务器的连接已经建立了。
proxy_read_timeout
语法 proxy_read_timeout time
默认值 60s
上下文 http server location
说明 该指令设置与代理服务器的读超时时间。它决定了nginx会等待多长时间来获得请求的响应。这个时间不是获得整个response的时间,而是两次reading操作的时间。
proxy_send_timeout
语法 proxy_send_timeout time
默认值 60s
上下文 http server location
说明 这个指定设置了发送请求给upstream服务器的超时时间。超时设置不是为了整个发送期间,而是在两次write操作期间。如果超时后,upstream没有收到新的数据,nginx会关闭连接
proxy_upstream_fail_timeout(fail_timeout)
语法 server address [fail_timeout=30s]
默认值 10s
上下文 upstream
说明 Upstream模块下 server指令的参数,设置了某一个upstream后端失败了指定次数(max_fails)后,该后端不可操作的时间,默认为10秒