首页 > 代码库 > Nginx+Tomcat服务器负载均衡实践方案
Nginx+Tomcat服务器负载均衡实践方案
1. 为何选择Nginx+Tomcat做负载均衡?
1.1. Nginx是什么?
Nginx(发音同 engine x)是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。由俄罗斯的程序设计师Igor Sysoev所开发,供俄国大型的入口网站及搜索引擎Rambler(俄文:Рамблер)使用。其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:新浪、网易、 腾讯等。
1.2. Nginx特点
Nginx是一款面向性能设计的HTTP服务器,相较于Apache、lighttpd具有占有内存少,稳定性高等优势。与旧版本(<=2.2)的Apache不 同,nginx不采用每客户机一线程的设计模型,而是充分使用异步逻辑,削减了上下文调度开销,所以并发服务能力更强。整体采用模块化设计,有丰富的模块 库和第三方模块库,配置灵活。 在Linux操作系统下,nginx使用epoll事件模型,得益于此,nginx在Linux操作系统下效率相当高。同时Nginx在OpenBSD或FreeBSD操作系统上采用类似于epoll的高效事件模型kqueue。
1.3. Nginx可大量平行处理
Nginx在官方测试的结果中,能够支持五万个平行连接,而在实际的运作中,是可以支持二万至四万个平行链接。
1.4. nginx 的模块
整体采用模块化设计是nginx的一个重大特点,甚至http服务器核心功能也是一个模块。要注意的是:nginx的模块是静态的,添加和删除模块都要对nginx进行重新编译,这一点与Apache的动态模块完全不同。
1.5. Nginx与PHP的集成
自PHP-5.3.3起,PHP-FPM加入到了PHP核心,编译时加上--enable-fpm即可提供支持。 PHP-FPM以守护进程在后台运行,Nginx响应请求后,自行处理静态请求,PHP请求则经过fastcgi_pass交由PHP-FPM处理,处理 完毕后返回。 Nginx和PHP-FPM的组合,是一种稳定、高效的PHP运行方式,效率要比传统的Apache和mod_php高出不少。
PHP-FPM不支持Windows平台,由于没有fastcgi进程管理器管理php-cgi.exe,因此一旦php-cgi.exe崩溃退 出,前端将失去响应,这时Nginx会返回“The page you are looking for is temporarily unavailable. Please try again later.”的错误信息。 因此在Windows上用Nginx和php-cgi.exe组合来运行PHP的方式并不可靠,稳定性有待提高。
1.6. Tomcat与Nginx性能对比
Tomcat 服务器作为一个 Web 服务器,其并发数在 300-500 之间,如果有超过 500的并发数便会出现 Tomcat 不能响应新的请求的情况,严重影响网站的运行。另外,在访问量大的情况下,Tomcat 的线程数会不断增加。由于Tomcat 自身对内存的占用有控制,当对内存的占用达到最大值时便会出现内存溢出,对网站的访问严重超时等现象,这时便需要重新启动 Tomcat 以释放占用的内存,这样做便会阻断网站运行。所以对 Tomcat 做负载均衡便很有必要。目前可以和 Tomcat 做负载均衡的主流服务器是 Apache ,但是 Nginx 由于功能多、配置简单等优点逐渐成为很多负载均衡服务器的首选。 Nginx 的并发数可达到50000 ,所以理论上可以和Tomcat 以 1:100 的比例来配置,这样便可以很好的解决网站并发瓶颈问题。
2. Nginx+Tomcat负载均衡方案实施
2.1. 环境及软件安装工具准备
2.1.1.下载JDK7
在官网(http://www.oracle.com/us/sun/index.htm)上下载JDK即可,下载地址:
http://java.com/zh_CN/download/index.jsp
2.1.2.下载Nginx
根据自己的需要下载合适的系统版本,目前官方对Windows系列平台只提供Windows 32bit的下载,下载地址:http://nginx.org/en/download.html
2.1.3.下载Tomcat7
Tomcat需要JDK运行环境支持,由于我们下载的是JDK7所以选择对应的Tomcat也是7。建议下载最新的Tomcat7版本,下载地址:http://tomcat.apache.org/download-70.cgi
注:下载Binary版本,没有必要下载Resource版本。
2.2. 安装JDK并设置Tomcat和Nginx
2.2.1.安装JDK
下载完成后,系统会自动弹出安装文件提示用户安装。直接点击“同意协议”,然后直接默认安装JDK路径,点“下一步”知道完成为止(对于JDK安装这个没多大的技术难度,JDK怎么安装已经在多处文档中写过了,故不再详述),记得验证安装是否成功。 参见文档:《WEB应用打包部署》。
2.2.2.解压Tomcat
将下载的Tomcat服务器包解压到任意路径下,如:D:\BALANCE_TOMCAT__NGINX由于我已经下载Tomcat7,就用我本机的apache-tomcat-7.0.47作为示例。解压两个Tomcat分别命名为apache-tomcat-7.0.47-1何apache-tomcat-7.0.47-2.解压后如图所示:
2.2.3.启动Nginx
之所以不以安装为名是因为Nginx本身是控制台程序而并未做出Windows服务;将下载的Nginx1.6.0解压至与Tomcat相同的D:\BALANCE_TOMCAT__NGINX路径下。切换文件夹路径找到D:\BALANCE_TOMCAT__NGINX\nginx-1.6.0:
在控制台“cmd”,执行“start nginx”命令启动上图中的exe程序。
启动后会看到控制台闪一下;这时查看系统进程中有两个nginx.exe的进程,说明启动完成。
2.2.4.负载均衡设置
2.2.4.1. 修改Tomcat设置
这里需要修改两个Tomcat的server.xml文件:
apache-tomcat-7.0.47-1配置:
1、<Server port="18080" shutdown="SHUTDOWN">
2、 <Connector port="18080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="18443" />
3、 <Connector port="18009" protocol="AJP/1.3" redirectPort="18443" />
4、 <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">
5、 另外<Host>中添加<Content>设置:
<Context path="/nginx" reloadable="false" docBase="D:/DEVELOPER_WORKSPACE_AJX/workspace/nginx/WebRoot"> </Context>
注:docBase是项目物理路径。
apache-tomcat-7.0.47-2配置:
2、<Server port="28080" shutdown="SHUTDOWN">
2、 <Connector port="28080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="28443" />
6、 <Connector port="28009" protocol="AJP/1.3" redirectPort="28443" />
7、 <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat2">
8、 另外<Host>中添加<Content>设置:
<Context path="/nginx" reloadable="false" docBase="D:/DEVELOPER_WORKSPACE_AJX/workspace/nginx/WebRoot"> </Context>
注:docBase是项目物理路径。
2.2.4.2. 修改Nginx设置
打开Nginx1.6.0/conf/nginx.conf进行修改,nginx.conf内容如下:
#user nobody; #此参数修改为与CPU个数一致 worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; pid logs/nginx.pid; #后添的 worker_rlimit_nofile 51200; events { worker_connections 51200; } 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; server_names_hash_bucket_size 128; client_header_buffer_size 32k; large_client_header_buffers 4 32k; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 60; tcp_nodelay on; #gzip on; upstream abc.tomcats.com { #ip_hash; server 192.168.1.147:18080 weight=1; server 192.168.1.147:28080 weight=2; } server { listen 80; server_name abc.tomcats.com; proxy_redirect off; access_log logs/abc.tomcats.com.log combined; #charset koi8-r; #access_log logs/host.access.log main; #充许客户端请求的最大单个文件字节数 client_max_body_size 10m; client_body_buffer_size 128k; #跟后端服务器连接的超时时间 proxy_connect_timeout 600; #连接成功后等候后端服务器响应时间 proxy_read_timeout 600; #后端服务器数据回传时间 proxy_send_timeout 600; #代理请求缓存区 proxy_buffer_size 8k; #同上,保存用几个buffer每个最大空间是多少 proxy_buffers 4 32k; #如果系统很忙时可以申请更大的proxy_buffers,官方推荐*2 proxy_busy_buffers_size 64k; #缓存临时文件的大小 proxy_temp_file_write_size 64k; location / { root html; index index.html index.htm; proxy_pass http://abc.tomcats.com; proxy_set_header Host $host; proxy_set_header X-Real-Ip $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /status{ stub_status on; access_log off; auth_basic "NginxStatus"; auth_basic_user_file htpasswd; } location ~ \.jsp$ { proxy_pass http://abc.tomcats.com; } location ~ \.(html|js|css|png|gif)$ { root html; proxy_pass http://abc.tomcats.com; } #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; } # proxy the PHP scripts to Apache listening on 127.0.0.1:80 # #location ~ \.php$ { # proxy_pass http://127.0.0.1; #} # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # #location ~ \.php$ { # root html; # fastcgi_pass 127.0.0.1:9000; # fastcgi_index index.php; # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; # include fastcgi_params; #} # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # #location ~ /\.ht { # deny all; #} } # another virtual host using mix of IP-, name-, and port-based configuration # #server { # listen 8000; # listen somename:8080; # server_name somename alias another.alias; # location / { # root html; # index index.html index.htm; # } #} # HTTPS server # #server { # listen 443; # server_name localhost; # ssl on; # ssl_certificate cert.pem; # ssl_certificate_key cert.key; # ssl_session_timeout 5m; # ssl_protocols SSLv2 SSLv3 TLSv1; # ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP; # ssl_prefer_server_ciphers on; # location / { # root html; # index index.html index.htm; # } #} }
然后使用“Nginx -s reload”命令重新加载Nginx的设置。
2.2.5.项目部署及启动
2.2.5.1. 部署web项目
将J2EE项目打包成war包分别放置到apache-tomcat-7.0.47-1和apache-tomcat-7.0.47-2的webapps目录下,然后分别启动Tomcat就行了。
注:webapps下放置的war版本要一致,这是两个相同的程序服务器部署。
2.2.5.2. 启动Tomcat和Nginx
2个Tomcat随便启动无先后顺序,并且Nginx与Tomcat启动也无先后顺序。如果修改了nginx.conf只需要执行“Nginx -s reload”命令重新加载Nginx的设置。而如果修改了Tomcat的配置则需要重新启动Tomcat和Nginx。
2.3. 启动测试负载均衡实施效果
2.3.1.导航到服务器默认界面
在浏览器输入输入localhost即可看到如下界面:
2.3.2.访问静态html文件
注:不一定用localhost,你也可以通过ip地址访问。
2.3.3.访问JSP动态页面
2.4. 配置Memcached 实现session共享
2.4.1.下载Memcached
你可以从这里下载对应系统版本的Memcached:http://pecl.php.net/package/memcache
Memcached与Nginx相似,安装这里就不再说了。
2.4.2.Windows Memcached常用命令
以下是 memcached 在 Windows 系统下的 x86/x64 版本的安装方法。命令提示符下运行如下,
-----------------------------------------安装--------------------:
memcached -d install
memcached -d start
net start "Memcached Server"
----------------------------------------卸载-------------------:
memcached -d stop
memcached -d remove
sc delete "Memcached Server"
-------------------------------memcached的基本设置:
-p 监听的端口
-l 连接的IP地址, 默认是本机
-d start 启动memcached服务
-d restart 重起memcached服务
-d stop|shutdown 关闭正在运行的memcached服务
-d install 安装memcached服务
-d uninstall 卸载memcached服务
-u 以的身份运行 (仅在以root运行的时候有效)
-m 最大内存使用,单位MB。默认64MB
-M 内存耗尽时返回错误,而不是删除项
-c 最大同时连接数,默认是1024
-f 块大小增长因子,默认是1.25
-n 最小分配空间,key+value+flags默认是48
-h 显示帮助
2.4.3.设置Tomcat的Memcached
下载如下jar包 (这些jar不能缺失,否则会出现问题)全部拷贝进TOMCAT/lib中全部的tomcat:然后修改 conf/context.xml添加如下代码:
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager" sticky="false" memcachedNodes="n1:localhost:11211" failoverNodes="" lockingMode="all" requestUriIgnorePattern=".*\.(png|gif|jpg|css|js|ico)$" sessionBackupAsync="false" sessionBackupTimeout="100" transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory" />
因为支持memcached分布式 如果有多台memcached在memcachedNodes="nx:IP:port" 即可。
注意:这里的端口号要和启动的设置的端口一致
打开cmd 进入nginx 的解压目录 输入 nginx -s -stop 输入 nginx start 重新启动nginx依次启动三台tomcat。在TOMCAT \webapps\ROOT 下新增一张页面demo.jsp:
<%@ page contentType="text/html; charset=UTF-8" %> <%@ page import="java.util.*" %> <html> <head><title>Cluster Test</title></head> <body> <% HttpSession sess = request.getSession(true); System.out.println(sess.getId()); out.println("<br> SESSION ID:" + sess.getId()+"<br>"); // 如果有新的请求,则添加session属性 String name = request.getParameter("name"); if (name != null && name.length() > 0) { String value = http://www.mamicode.com/request.getParameter("value"); >JVM 分别是 1 2 3 分别放进 t1 t2 t3 中 然后打开浏览器http://localhost/demo.jsp 多次刷新看到不同的jvm 相同的session 表示成功nginx + tomcat + memcached 环境就搭建好了。