最近出于好奇心,研究了一下tomcat集群配置,并整合nginx,实现负载均衡,session共享,写篇记录,防止遗忘。---------菜鸡的自我修炼。
说明:博主采用一个web项目同时部署到两台tomcat下,(tomcat-A,tomca-B),使用nginx做反向代理,按照设置的权值,将请求分发到后台的tomcatA/tomcat-B,并且实现session共享。
配置好本地域名指向:修改host文件:添加 127.0.0.1 www.domain.com.cn
新建项目:tiny-demo-operation 采用springmvc 配置好springmvc.xml配置文件
建立SessionShareSetController和SessionShareGetController
目录如下:
SessionShareSetController代码:
1 package com.tiny.session.share.controller; 2 3 import javax.servlet.http.HttpServletRequest; 4 import javax.servlet.http.HttpServletResponse; 5 import javax.servlet.http.HttpSession; 6 7 import org.springframework.stereotype.Controller; 8 import org.springframework.web.bind.annotation.RequestMapping; 9 10 @Controller 11 @RequestMapping("/sessionShare") 12 public class SessionShareSetController { 13 14 @RequestMapping("/sessionSet") 15 public String sessionSet(HttpServletRequest request, 16 HttpServletResponse response) throws Exception { 17 18 HttpSession session = request.getSession(); 19 String name = "tinyseven-demo-operation"+"---"; 20 String remote = request.getRemoteHost() + "---" 21 + request.getRemoteAddr() + "---" + request.getRemotePort() 22 + "---"; 23 String local = request.getLocalName() + "---" + request.getLocalAddr() 24 + "---" + request.getLocalPort() + "---"; 25 String server = request.getServerName() + "---" 26 + request.getServerPort() + "---"; 27 request.setAttribute("name", name); 28 request.setAttribute("remote", remote); 29 request.setAttribute("local", local); 30 request.setAttribute("server", server); 31 32 session.setAttribute("name", name); 33 return "sessionshare/sessionSet"; 34 } 35 36 }
SessionShareGetController代码:
1 package com.tiny.session.share.controller; 2 3 import javax.servlet.http.HttpServletRequest; 4 5 import org.springframework.stereotype.Controller; 6 import org.springframework.web.bind.annotation.RequestMapping; 7 8 @Controller 9 @RequestMapping("/sessionShare") 10 public class SessionShareGetController { 11 12 @RequestMapping("/sessionGet") 13 public String sessionGet(HttpServletRequest request) throws Exception { 14 15 String name = (String) request.getSession().getAttribute("name") 16 + "---"; 17 String remote = request.getRemoteHost() + "---" 18 + request.getRemoteAddr() + "---" + request.getRemotePort() 19 + "---"; 20 String local = request.getLocalName() + "---" + request.getLocalAddr() 21 + "---" + request.getLocalPort() + "---"; 22 String server = request.getServerName() + "---" 23 + request.getServerPort() + "---"; 24 request.setAttribute("name", name); 25 request.setAttribute("remote", remote); 26 request.setAttribute("local", local); 27 request.setAttribute("server", server); 28 return "sessionshare/sessionGet"; 29 30 } 31 }
新建jsp页面:
目录如下:
sessionSet.jsp部分代码:
<body> 当前用户设置session--server-->>${server}</br> 当前用户设置session--remote-->>${remote}</br> 当前用户设置session--local-->>${local}</br> 当前用户设置session--name-->>${name}</br> </body>
sessionGet.jsp部分代码:
1 <body> 2 当前用户请求的server-->>${server}</br> 3 当前用户请求的remote-->>${remote}</br> 4 当前用户请求的local-->>${local}</br> 5 当前用户请求的name-->>${name}</br> 6 </body>
一、准备两台tomcat,建立起tomcat集群。
博主使用 apache-tomcat-6.0.37
路径分别为:E:\Server\apache-tomcat-6.0.37-node-A
E:\Server\apache-tomcat-6.0.37-node-B
分别修改A/B的server.xml保证两台tomcat可以正常启动,避免端口冲突,并且建立起两台tomcat的集群。
1.修改A的server.xml,在所有port前面加1,例如(<Server port="8005" shutdown="SHUTDOWN">修改成<Server port="18005" shutdown="SHUTDOWN">其他类似)
修改<Engine name="Catalina" defaultHost="localhost" >为<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">
2.修改B的server.xml,在所有port前面加2,例如(<Server port="8005" shutdown="SHUTDOWN">修改成<Server port="28005" shutdown="SHUTDOWN">其他类似)
修改<Engine name="Catalina" defaultHost="localhost" >为<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat2">
此时两台tomcat应该都可以成功启动了。
3.建立起两台tomcat的集群服务。
分别取消掉A/B server.xml文件中
<!--
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
-->
的注释。
重新启动A、B tomcat(运行bin中的startup.bat)发现这次启动比上次多了以下信息,表示两个tomcat节点已经建立起了关联。
二、发布项目到tomcatA、tomcatB下,并且配置session共享。
1.修改tomcaA、tomcatB的server.xml文件。
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
<!-- SingleSignOn valve, share authentication between web applications
Documentation at: /docs/config/valve.html -->
<!--
<Valve className="org.apache.catalina.authenticator.SingleSignOn" />
-->
<!-- Access log processes all example.
Documentation at: /docs/config/valve.html -->
<!--
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log." suffix=".txt" pattern="common" resolveHosts="false"/>
-->
<Context docBase="E:\javaWorkspace\tiny-demo-operation\WebRoot" reloadable="true" path="/tiny-demo-operation" crossContext="true" source="org.eclipse.jst.jee.server:tiny-demo-operation"/> 此处为添加内容
</Host>
2、修改所发布项目的web.xml文件
在web.xml文件的</web-app>之前添加
<!-- session共享配置 -->
<distributable />
此时当前项目在两台tomcat可以做到session共享了,效果如下:
访问tomcatA下的项目,设置session:
访问tomcatB下的项目,获取session:
三、整合nginx,实现请求分发。此处使用的是nginx1.5.0版本
1.修改nginx.conf 修改后
1 #Nginx所用用户和组,window下不指定 2 #user niumd niumd; 3 #工作的子进程数量(通常等于CPU数量或者2倍于CPU) 4 5 worker_processes 2; 6 7 #错误日志存放路径 8 #error_log logs/error.log; 9 #error_log logs/error.log notice; 10 11 error_log logs/error.log info; 12 13 #指定pid存放文件 14 15 pid logs/nginx.pid; 16 17 events { 18 #使用网络IO模型linux建议epoll,FreeBSD建议采用kqueue,window下不指定。 19 #use epoll; 20 #允许最大连接数 21 worker_connections 2048; 22 } 23 24 http { 25 26 include mime.types; 27 default_type application/octet-stream; 28 #定义日志格式 29 #log_format main ‘$remote_addr - $remote_user [$time_local] $request ‘ 30 # ‘"$status" $body_bytes_sent "$http_referer" ‘ 31 # ‘"$http_user_agent" "$http_x_forwarded_for"‘; 32 #access_log off; 33 access_log logs/access.log; 34 client_header_timeout 3m; 35 client_body_timeout 3m; 36 send_timeout 3m; 37 client_header_buffer_size 1k; 38 large_client_header_buffers 4 4k; 39 sendfile on; 40 tcp_nopush on; 41 tcp_nodelay on; 42 #keepalive_timeout 75 20; 43 include gzip.conf; 44 include proxy.conf; 45 46 upstream localhost { 47 #根据ip计算将请求分配各那个后端tomcat,许多人误认为可以解决session问题,其实并不能。 48 #同一机器在多网情况下,路由切换,ip可能不同 49 #ip_hash; 50 #weigth参数表示权值,权值越高被分配到的几率越大 51 server localhost:18080 weight=5; 52 server localhost:28080 weight=5; 53 54 } 55 56 server { 57 58 listen 80; 59 server_name localhost; 60 61 location / { 62 root E:/javaWorkspace/tiny-demo-operation/WebRoot; 63 index index.html index.htm; 64 65 } 66 67 location ~ \.(html|js|css|png|gif)$ { 68 root E:/javaWorkspace/tiny-demo-operation/WebRoot; 69 } 70 71 location ~ \.(jsp|action)$ { 72 proxy_connect_timeout 3; 73 proxy_send_timeout 30; 74 proxy_read_timeout 30; 75 proxy_pass http://localhost; 76 } 77 } 78 }
2.重新启动nginx
访问虚拟主机下的当前项目,nginx自动实现请求分发,效果如下:
分发到tomcatB下的tiny-demo-operation,设置session中的属性值name。
分发tomcatA下的tiny-demo-operation,获取session中的属性值name。
至此,简单实现了nginx整合tomcat集群,实现负载均衡,session共享的测试案例。