89233956 2011-09-15
说明
所有的配置以及软件都是在windows环境下进行的,都是用自己的电脑做服务器。
要解决的问题
在tomcat集群环境下的session共享、缓存共享、负载均衡。
解决方案的选择
多个tomcat要一起协同工作有几种办法,可以考虑的方案有以下几个:
1.使用tomcat自带的cluster方式,多个tomcat间自动实时复制session信息,配置起来很简单。但这个方案的效率比较低,在大并发下表现并不好。
2.利用nginx的基于访问ip的hash路由策略,保证访问的ip始终被路由到同一个tomcat上,这个配置更简单。但是我们的应用很可能是某一个局域网大量用户同时登录,这样负载均衡就没什么作用了。
3.利用memcached把多个tomcat的session集中管理,这是最直接的解决方案,但是操作起来也最为复杂。
我们的系统既要求性能,又要比较好的利用上负载均衡,所以第3个方案是首选(我采取的第三种方案)。接下来就是安装搭建之路了。
参考资料:http://hi.baidu.com/dqgdeng/blog/item/32e3d53af100eae9b311c745.html
采取的方案
解决缓存共享:
Memcached是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。可以使用Memcached。
解决Session共享:
主要是利用memcached-session-manager(http://code.google.com/p/memcached-session-manager/下面简称msm)开源tomcat插件改变tomcat原始的session存储机制,将session的存储放到分布式缓存memcache中,从而实现对session的共享。
解决负载均衡:
利用nginx+tomcat+memcached组建web服务器负载均衡。
实现的整体步骤
一:安装memcached,测试其是否好用。
二:安装两个tomcat
三:配置msm。
四:安装nginx,实现负载均衡。
一下是我走的弯路:希望大家不要和我走一样的路
我开始弄这个的时候,思路是下面这样的:
一:安装memcached,测试其是否好用。
二:两个tomcat集群。(配置tomcat集群,找了一些资料)
三:配置msm。
四:安装nginx,实现负载均衡。
按照这个思路配置完成后,发现session、缓存都共享了,也实现了负载均衡,以为问题解决了。我写了配置过程的一个文档。
之后一位架构师看了我写的文档,发现有问题,这我才知道我之前的思路有点问题。因为我既使用了tomcat集群实时的复制session,又使用了msm来存储session。我之前之所以能session共享,是因为我配置的tomcat集群起得作用,而我配置的msm有问题,但我没发现。
弄清楚这点就可以:使用tomcat集群实现session共享和使用msm将session存储放到分布式缓存memcache中实现session是两种不同的解决方案。后者更有优势。
第一步:安装memcached
1.下载memcached服务端memcached-1.2.6-win32-bin.zip,地址:http://code.jellycan.com/memcached/
2.下载java版客户端java_memcached-release_2.6.1.zip
3.解压缩memcached-1.2.6-win32-bin.zip到指定目录,例如:D:\memcached-1.2.6-win32,
在终端(即cmd命令行界面),执行'D:\memcached-1.2.6-win32\memcached.exe-dinstall'
安装,再执行:'D:\memcached\memcached.exe-dstart'启劢,这样memcache就会作为windows系统服务在每次开机时启劢memcache服务。
4.将客户端jar包放到web的lib下面,测试其是否好用。
5.测试类如下:
publicclassTestMemCached{
protectedstaticMemCachedClientmcc=newMemCachedClient();
static{
String[]servers={"localhost:11211"};
Integer[]weights={3};
//创建一个实例对象SockIOPool
SockIOPoolpool=SockIOPool.getInstance();
//settheserversandtheweights
//设置MemcachedServer
pool.setServers(servers);
pool.setWeights(weights);
//setsomebasicpoolsettings
//5initial,5min,and250maxconns
//andsetthemaxidletimeforaconn
//to6hours
pool.setInitConn(5);
pool.setMinConn(5);
pool.setMaxConn(250);
pool.setMaxIdle(1000*60*60*6);
//setthesleepforthemaintthread
//itwillwakeupeveryxsecondsand
//maintainthepoolsize
pool.setMaintSleep(30);
//Tcp的规则就是在发送一个包之前,本地机器会等待远程主机
//对上一次发送的包的确认信息到来;这个方法就可以关闭套接字的缓存,
//以至这个包准备好了就发;
pool.setNagle(false);
//连接建立后对超时的控制
pool.setSocketTO(3000);
//连接建立时对超时的控制
pool.setSocketConnectTO(0);
//initializetheconnectionpool
//初始化一些值并与MemcachedServer段建立连接
pool.initialize();
//letssetsomecompressiononfortheclient
//compressanythinglargerthan64k
//mcc.setCompressEnable(true);
//mcc.setCompressThreshold(64*1024);
}
publicstaticvoidbulidCache(){
//set(key,value,Date),Date是一个过期时间,如果想让这个过期时间生效的话,这里传递的newDate(long
//date)中参数date,需要是个大于或等于1000的值。
//因为javaclient的实现源码里是这样实现的expiry.getTime()/1000,也就是说,如果
//小于1000的值,除以1000以后都是0,即永不过期
TMembert=newTMember();
t.setId("123456789");
t.setName("yangliang");
mcc.set("test",t,newDate(100000));//十秒后过期
}
publicstaticvoidoutput(){
//从cache里取值
TMembervalue=(TMember)mcc.get("test");
System.out.println(value.getId());
System.out.println(value.getName());
//Stringvalue=(String)mcc.get("test");
//System.out.println(value);
}
publicstaticvoidmain(String[]args){
bulidCache();
output();
}
}
输出结果为:123456789
yangliang
第二步:安装tomcat
1.安装两个tomcat6,如果不在myEclipse等集成环境下,需要先安装JDK.注意修改两个tomcat的端口号(server.xml中要修改三个端口:8005,8080,8009,把这三个改成没有在用的端口就可以了)。
2.启动两个tomcat看是否能成功启动。如果不能同时启动,很可能就是端口冲突。
第三步:配置msm
1.准备jar包
msm要用的包有:
javolution-5.4.3.1.jar
memcached-2.5.jar
memcached-session-manager-1.3.0.jar
msm-javolution-serializer-1.3.0.jar
msm-javolution-serializer-cglib-1.3.0.jar
msm-javolution-serializer-jodatime-1.3.0.jar
将这些包考到tomcat的lib下即可
•javolution-5.4.3.1.jar(442.1KB)
•memcached-2.5.jar(260.9KB)
•memcached-session-manager-1.3.0.jar(79.1KB)
•msm-javolution-serializer-1.3.0.jar(61KB)
•msm-javolution-serializer-cglib-1.3.0.jar(3.7KB)
•msm-javolution-serializer-jodatime-1.3.0.jar(5KB)
官方下载:http://code.google.com/p/memcached-session-manager/downloads/list
2.修改配置文件context.xml
Xml代码
加入
<Managerclassname="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:localhost:11211"
requestUriIgnorePattern=".*/.(png|gif|jpg|css|js)$"
sessionBackupAsync="false"
sessionBackupTimeout="100"
transcoderFactoryclass="de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoderFactory"
copyCollectionsForSerialization="false"
/>
这里的memcachedNodes是填写memcached节点,多个节点时可以以空隔分开,如:
n1:localhost:11211n2:localhost:11212
sessionBackupTimeout的单位为分钟
参考资料:http://blog.csdn.net/small_love/article/details/6662686
Ok!修改后重启两个TOMCAT即可,这个时候已经解决SESSION的共享问题.
3.可以测试一下session是否共享了,测试缓存是否可以共享了。
我的思路是这样的:登录后将sessionId作为key,value就是要保存的值,存放到session中,做一个过滤器,只要登录了就可以通过当前session的id获得到保存的值。
关于缓存的测试可以这样:修改部署在两个tomcat的web工程中缓存相关的信息,在一个工程中往memcached服务器中保存信息,在另外一个工程中看能否取到。
第四步:安装nginx,实现负载均衡
1下载nginx的jar包。地址:http://nginx.org/en/download.html
2解压nginx-1.0.6.zip包到你喜欢的根目录,并将目录名改为nginx。
然后,执行下列操作:
cdnginx
startnginx
这样,nginx服务就启动了(也可以直接双击打开)。打开任务管理器,查看nginx.exe进程,有二个进程会显示,占用系统资源,那是相当的少。然后再打开浏览器,输入http://127.0.0.1/就可以看到nginx的欢迎页面了,非常友好
nginx-sstop//停止nginx
nginx-sreload//重新加载配置文件
nginx-squit//退出nginx
3修改配置文件nginx\conf\nginx.conf
1)、找到内容server{
在它的上面加入如下内容:
upstream192.168.2.182{
ip_hash;----#ip_hash策略将同一IP的所有请求都转发到同一应用服务器
server192.168.2.182:8087;---------我的tomcat端口号
server192.168.2.182:8012;
}
(这是负载切换使用的服务器网站IP)
2)、找到location/{
roothtml;
indexindex.htmlindex.htm;
}
把内容更改如下:
location/{
proxy_passhttp://192.168.2.182;
proxy_redirectdefault;
proxy_connect_timeout10;addedbyme(跟代理服务器连接的超时时间,必须留意这个timeout时间不能超过75秒.当一台服务器当掉时,过10秒转发到另外一台服务器)
}
3)、找到server{
listen80;
server_namelocalhost;
把内容改成如下:
server{
listen80;
server_name192.168.2.182;
(这是监听访问域名绑定那台服务器80端口的请求)
好,在这里就这么简单配置好了,下面看下以上3步配置的图:
4参考资料:http://wenku.baidu.com/view/53b4640003d8ce2f0066233a.html
关于nginx的配置说明参考资料:http://wiki.nginx.org/NginxChs
5测试负载均衡是否好用。启动两个tomcat,之后断掉一个tomcat,看能否成功访问。
------------------------以上是我的配置过程,希望大家多提提宝贵意见,一起进步,谢谢。