本文将使用Nginx+Tomcat的工具配置一个分布式集群环境,作为企业级开发最常见的集群搭建方式,Nginx+Tomcat由于简单方便,性能优秀,深受很多人的喜爱。为了方便起见,我暂时将集群搭建在本机的Windows系统上,一般企业级应用都是搭建在Linux,建议大家将环境搭建在Linux,来获得更好的性能。
一.搭建环境
操作系统:windows server 2008 64位
JDK 1.7
tomcat 7和 tomcat6 (下载地址:http://tomcat.apache.org/download-70.cgi)
Nginx1.8.0(下载地址:http://nginx.org/en/download.html ,下载nginx/Windows-1.8.0)
二.软件安装
1.安装JDK,jdk的安装过程网上有很多,随便搜一下就知道了,这里就不再重复;
2.安装Tomcat,建议大家不要下载安装包,下载zip版的,直接解压到一个目录下,如E:/web/server目录下,tomcat6和7各复制一份,一共形成4个tomcat组成集群,随便找一个的bin目录下点击startup.bat,启动后在浏览器上输入 http://localhost:8080 ,如果出现下面页面
,则说明安装成功!
3.安装Nginx,下载后得到一个zip的压缩包,解压缩放在一个文件夹下就行,这里我放在了E:/web文件夹下,nginx的目录结构为:
点击nginx.exe就启动了nginx服务器了,在浏览器上输入localhost,如果出现如下页面
就说明安装成功了。
三.集群配置
在nginx1.8.0目录下有一个conf文件夹,conf下面有一个nginx.conf文件,进行集群配置就是要在这个文件中进行:
#user nobody; #工作进程,一般小于等于cpu核心数量 worker_processes 1; #进程绑定到cpu的位置 #worker_cpu_affinity 0001 0010; events { #每个进程允许的同时最大连接数 worker_connections 200000; #Windows上没有非阻塞模式 #use epoll } http { include mime.types; default_type application/octet-stream; #启动内核复制模式,提高io效率 sendfile on; #每个连接alive存活的最长时间 keepalive_timeout 65; #启动内容压缩 gzip on; #内容大于多少才压缩 gzip_min_length 1000; #压缩基本 gzip_comp_level 4; #压缩内容类别 gzip_types text/plain text/css application/json application/x-javascript text/xml; #静态文件缓存 open_file_cache max=655350 inactive=20s; open_file_cache_valid 30s; open_file_cache_min_uses 2; upstream dunquan-tomcat { server 127.0.0.1:8080 weight=5; server 127.0.0.1:8081 weight=3; } server { listen 80; server_name localhost; charset utf-8; location / { #root html; proxy_pass http://dunquan-tomcat; proxy_set_header X-Real-IP $remote_addr; index index.html index.htm; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } }这是一个比较简单的配置,
upstream dunquan-tomcat { server 127.0.0.1:8080 weight=5; server 127.0.0.1:8081 weight=3; }这里是设置一个简单的多个服务器的集群,你自己可以加多个服务器,weight是每个服务器的加权权重,这里是使用的加权轮询的方式进行负载均衡的,就是如果每来了8个请求,则5个分配给上面的服务器,3个分配给下面的服务器,此外,还有其他几种服务器分配算法,下面再介绍;
注意你如果多个服务器是在一个主机上,在tomcat的配置文件里你需要把tomat的几个监听端口设置成不同的,如:
<Server port="8006" shutdown="SHUTDOWN">
<Connector port="8081" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
<Connector port="8011" protocol="AJP/1.3" redirectPort="8443" />
nginx是使用反向代理的模式来处理请求的,每个请求需要发给nginx服务器,然后nginx服务器代理发送到具体的应用服务器,而且现在浏览器都是建立两条链路来发送请求,所以真正nginx最大同时连接数是 : worker_processes * worker_connections / 4
还有一点是:
#Windows上没有非阻塞模式 #use epoll由于Linux上io处理的方式是非阻塞模式的,一般使用epoll模式,这种模式对网络io的处理具有非常好的性能,而Windows上没有epoll这种非阻塞模式的,所以nginx在Windows上面部署的性能远远没有Linux性能好,所以我建议大家在Linux上面搭建环境。
四.Session处理方式
session是储存在服务器端的会话,Session 对象存储特定用户会话所需的信息。这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。
由此可知,session是存储在服务器端的,也就是tomcat服务器上,其实我们如果解析tomcat的源码,就可以发现tomcat服务器有一个专门的线程来维持session信息的,关于tomcat具体解析的问题我在另外一篇博客详细解析了,感兴趣的可以去看看。
session存储在tomcat端,这样的话假如我一个用户在服务器A登录了,A服务器中就有session信息,然后我下次请求nginx给我分配到B服务器,但是B服务器中没有我们session信息,这时就有问题了。
我们知道问题是如何出现的,那么问题的解决方案就也很清晰了:
方案一,既然A服务器中有某个用户的信息,那么就让这个用户一直访问A服务器就行了啊,所以通过ip得到一个hash值,根据hash值来转发到对应的服务器即可:
upstream dunquan-tomcat {
ip_hash; server 127.0.0.1:8080; server 127.0.0.1:8081; }
这样就可以实现一个比较简单的session处理方案,但是这个方案可能有一个问题是如果服务器A挂掉了,那么这个服务器上的session信息就丢失了,可能会出现问题;
方案二 是既然各个服务器上的session信息不同步,那就让它同步好了,在tomcat上进行配置,如果一个服务器上的session状态发生任何改变,通知所有服务器上的session同时改变,这样也可以达到目的,且一台服务器挂掉对其他没有影响,但是让所有服务器维持所有session的状态,会导致服务器的性能有所下降;
方案三 是把session信息专门存放在另外的一个地方,如memcached缓存中,当某台服务器的session状态发生改变时,同步只用改变memcached的session信息就行,取也是直接到memcached中取,这样就比较好的解决了服务器挂掉session出问题和性能问题。由于在Windows上安装memcached比较麻烦,这里就不具体演示了。
五.其他
最后,当我们在tomcat上开启具体的项目,然后在浏览器中输入localhost/stuallList时(这是我的请求和页面,你的是你自己的项目),我们能观察到
就说明我们的负载均衡成功了。
还有一些需要注意的是由于nginx使用了反向代理,所以request.getRemoteAddr()这个方法获取的ip地址是nginx的地址,如果需要获取具体的用户ip地址,需要在nginx.conf文件中设置
proxy_set_header X-Real-IP $remote_addr;
然后在项目中使用request.getHeader("X-Real-IP")方式来获取用户ip。