我们都知道,nginx作为一个轻量级的web服务器,其在高并发下处理静态页面的优越性能是tomcat这样的web容器所无法媲美的,tomcat更倾向于处理动态文件,所以一个web应用可以通过nginx反向代理来实现动静分离,静态文件由nginx处理,动态文件由tomcat处理。
环境:
hadoop0.updb.com 192.168.0.100 nginx server
hadoop2.updb.com 192.168.0.102 tomcat server
hadoop3.updb.com 192.168.0.103 tomcat server
hadoop4.updb.com 192.168.0.104 tomcat server
hadoop5.updb.com 192.168.0.105 tomcat server
操作系统:
centos
Nginx版本:
nginx-1.7.6.tar.gz,采用源码编译安装
Tomcat版本:
apache-tomcat-7.0.56.tar.gz
JDK版本:
jdk-7u60-linux-x64.rpm
最终架构:
在弄明白架构之后,我们开始着手一步步来实现:
1、安装jdk + tomcat
hadoop2、hadoop3、hadoop4、hadoop5上安装jdk
rpm -ivh jdk-7u60-linux-x64.rpm
配置环境变量
[[email protected] ~]# cat .bash_profile # .bash_profile # Get the aliases and functions if [ -f ~/.bashrc ]; then . ~/.bashrc fi # User specific environment and startup programs PATH=$PATH:$HOME/bin export JAVA_HOME=/usr/java/jdk1.7.0_60 export JRE_HOME=/usr/java/jdk1.7.0_60/jre export CLASSPATH=./:/usr/java/jdk1.7.0_60/lib:/usr/java/jdk1.7.0_60/jre/lib export PATH
使环境变量生效,并验证java环境是否安装成功
[[email protected] ~]# . .bash_profile [[email protected] ~]# java -version java version "1.7.0_60" Java(TM) SE Runtime Environment (build 1.7.0_60-b19) Java HotSpot(TM) 64-Bit Server VM (build 24.60-b09, mixed mode)
hadoop2、
hadoop3、hadoop4、hadoop5上安装tomcat,在webapps下创建测试目录shop和测试文件test.html和
test.jsp,测试文件中的内容为每个tomcat节点的主机名和IP地址,方便后边测试负载均衡
[[email protected] ~]# tar xf apache-tomcat-7.0.56.tar.gz -C /opt/ [[email protected] ~]# cd /opt/apache-tomcat-7.0.56/webapps/ [[email protected] webapps]# mkdir shop [[email protected] webapps]# vi shop/test.html this is hadoop2 root`s html! [[email protected] webapps]# vi shop/test.jsp this is hadoop2 root`s jsp!
将tomcat的bin目录配置到环境变量,并使更改生效,并启动tomcat
## 设置环境变量 [[email protected] ~]# cat .bash_profile # .bash_profile # Get the aliases and functions if [ -f ~/.bashrc ]; then . ~/.bashrc fi # User specific environment and startup programs PATH=$PATH:$HOME/bin:/opt/apache-tomcat-7.0.56/bin export JAVA_HOME=/usr/java/jdk1.7.0_60 export JRE_HOME=/usr/java/jdk1.7.0_60/jre export CLASSPATH=./:/usr/java/jdk1.7.0_60/lib:/usr/java/jdk1.7.0_60/jre/lib export PATH ## 使设置生效 [[email protected] ~]# . .bash_profile ## 启动tomcat [[email protected] ~]# startup.sh Using CATALINA_BASE: /opt/apache-tomcat-7.0.56 Using CATALINA_HOME: /opt/apache-tomcat-7.0.56 Using CATALINA_TMPDIR: /opt/apache-tomcat-7.0.56/temp Using JRE_HOME: /usr/java/jdk1.7.0_60/jre Using CLASSPATH: /opt/apache-tomcat-7.0.56/bin/bootstrap.jar:/opt/apache-tomcat-7.0.56/bin/tomcat-juli.jar Tomcat started.
测试tomcat是否正常工作,浏览器中访问,能够正常显示测试页面,表明工作正常。
2、安装nginx
[[email protected] ~]# tar xf nginx-1.7.6.tar.gz -C /opt/ [[email protected] ~]# cd /opt/nginx-1.7.6/ [[email protected] ~]# ./configure --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module [[email protected] ~]# make && make install
关于源码安装nginx,比较简单,如果过程中遇到问题可以到网上看看,都能找到答案,也可以在下面留言,一起讨论。
为了方便管理,为nginx编写服务脚本
[[email protected] ~]# vi /etc/init.d/nginx #!/bin/bash # #chkconfig: - 85 15 #description: this script use to manage nginx process. # #set -x . /etc/rc.d/init.d/functions procnum=`ps -ef |grep "/usr/local/nginx/sbin/nginx"|grep -v "grep"|wc -l` start () { if [ "$procnum" -eq 1 -a -f /usr/local/nginx/logs/nginx.pid ]; then echo -n "Starting nginx:" success echo else /usr/local/nginx/sbin/nginx if [ "$?" -eq 0 ]; then echo -n "Starting nginx:" success echo else echo -n "Starting nginx:" failure echo exit 4 fi fi } stop () { if [ "$procnum" -eq 1 -a -f /usr/local/nginx/logs/nginx.pid ]; then /usr/local/nginx/sbin/nginx -s stop if [ "$?" -eq 0 ]; then echo -n "Stopping nginx:" success echo else echo -n "Stopping nginx:" failure echo exit 3 fi else echo -n "Stopping nginx:" success echo fi } case $1 in start) start ;; stop) stop ;; restart) stop sleep 1 start ;; reload) if [ "$procnum" -eq 1 -a -f /usr/local/nginx/logs/nginx.pid ]; then /usr/local/nginx/sbin/nginx -s reload else echo "nginx is not running!please start nginx first..." exit 2 fi ;; status) if [ "$procnum" -eq 1 -a -f /usr/local/nginx/logs/nginx.pid ]; then echo "nginx is running..." else echo "nginx is not running..." fi ;; *) echo "Usage : nginx [ start|stop|reload|restart|status ]" exit 1 ;; esac
然后授予脚本可执行权限,并加入chkconfig开机自启动,并测试
[[email protected] ~]# chmod +x /etc/init.d/nginx [[email protected] ~]# chkconfig nginx on [[email protected] ~]# /etc/init.d/nginx start Starting nginx: [ OK ] [[email protected] ~]# /etc/init.d/nginx status nginx is running... [[email protected] ~]# /etc/init.d/nginx stop Stopping nginx: [ OK ]
3、配置nginx,实现反向代理和动静分离
[[email protected] ~]# cat /usr/local/nginx/conf/nginx.conf user www www; worker_processes 8; error_log /usr/local/nginx/logs/error.log crit; pid /usr/local/nginx/logs/nginx.pid; events { use epoll; worker_connections 65535; } http { include mime.types; default_type application/octet-stream; access_log /usr/local/nginx/logs/access.log; charset utf-8; sendfile on; tcp_nopush on; keepalive_timeout 60; client_body_buffer_size 512k; proxy_connect_timeout 5; proxy_read_timeout 60; proxy_send_timeout 5; proxy_buffer_size 16k; proxy_buffers 4 64k; proxy_busy_buffers_size 128k; proxy_temp_file_write_size 128k; gzip on; gzip_min_length 1k; gzip_buffers 4 16k; gzip_http_version 1.1; gzip_comp_level 2; gzip_types text/plain application/x-javascript text/css application/xml; gzip_vary on; ## 配置反向代理的后端tomcat集群 upstream web_server { server 192.168.0.102:8080 weight=1 max_fails=2 fail_timeout=30s; server 192.168.0.103:8080 weight=1 max_fails=2 fail_timeout=30s; server 192.168.0.104:8080 weight=1 max_fails=2 fail_timeout=30s; server 192.168.0.105:8080 weight=1 max_fails=2 fail_timeout=30s; } server { listen 80; server_name 192.168.0.100; root html; index index.html index.htm; ## 网页、视频、图片文件从本地读取,且定义在浏览器中缓存30天 location ~ .*\.(htm|html|gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)$ { expires 30d; } ## js、css文件从本地读取,且定义在浏览器中缓存1小时 location ~ .*\.(js|css)?$ { expires 1h; } ## 动态文件转发到后端的tomcat集群 location ~ .*\.(php|jsp|cgi|jhtml)?$ { proxy_pass http://web_server; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; } ## 关闭访问日志 access_log off; } }
4、测试反向代理的负载均衡和动静分离
在nginx的html目录下创建测试目录shop、测试文件test.html和test.jsp
[[email protected] ~]# cd /usr/local/nginx/html/ [[email protected] html]# mkdir shop [[email protected] html]# vi shop/test.jsp this is nginx root`s jsp! [[email protected] html]# vi shop/test.html this is nginx root`s html!
在浏览器中访问http://192.168.0.100/shop/test.html ,无论怎样刷新,页面都显示如下:
在浏览器中访问http://192.168.0.100/shop/test.jsp ,刷新几次,页面显示结果依次如下:
从结果来看,访问html静态文件时,返回的是nginx中的文件,而访问jsp动态页面时则是轮询后端的tomcat集群。至此,反向代理+动静分离已经实现。
5、接着我们来比较动静分离与单纯的反向代理的性能差异
首先安装模拟并发访问的压力测试工具
yum install httpd-tools -y
首先测试访问nginx代理
[[email protected] ~]# ab -n 20000 -c 3000 Server Software: nginx/1.7.6 Server Hostname: 192.168.0.100 Server Port: 80 Document Path: /shop/test.html Document Length: 192 bytes Concurrency Level: 3000 Time taken for tests: 4.090 seconds Complete requests: 20000 Failed requests: 10907 (Connect: 0, Receive: 0, Length: 10907, Exceptions: 0) Write errors: 0 Non-2xx responses: 9994 Total transferred: 7563616 bytes HTML transferred: 2223840 bytes Requests per second: 4890.27 [#/sec] (mean) Time per request: 613.464 [ms] (mean) Time per request: 0.204 [ms] (mean, across all concurrent requests) Transfer rate: 1806.06 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 64 303 338.8 172 3145 Processing: 98 241 131.0 211 1214 Waiting: 24 183 131.0 146 1203 Total: 201 544 381.9 403 3297
一共请求20000次,每次3000的并发访问,总共用的时间为4.090秒,吞吐量为1.806M/s,再看直接访问tomcat的结果:
[[email protected] ~]# ab -n 20000 -c 3000 http://192.168.0.105:8080/shop/test.html Server Software: Apache-Coyote/1.1 Server Hostname: 192.168.0.105 Server Port: 8080 Document Path: /shop/test.html Document Length: 29 bytes Concurrency Level: 3000 Time taken for tests: 8.591 seconds Complete requests: 20000 Failed requests: 0 Write errors: 0 Total transferred: 5900000 bytes HTML transferred: 580000 bytes Requests per second: 2328.12 [#/sec] (mean) Time per request: 1288.594 [ms] (mean) Time per request: 0.430 [ms] (mean, across all concurrent requests) Transfer rate: 670.70 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 256 824.9 0 7007 Processing: 1 70 148.9 38 3117 Waiting: 1 69 148.4 38 3117 Total: 4 327 866.9 40 8468
相同压力下,访问tomcat需要8.591秒,且吞吐量只有0.67M/s,可见nginx在处理静态页面上远优于tomcat。
结束语:我在实现了动静分离之后,想通过nginx自带的proxy_cache模块来实现nginx缓存自身代理的静态页面,发现无法成功缓存到,认为porxy_cache无法缓存作为静态服务器的nginx中的文件,但无法求证,如果您知道,拜托指点一二。拜谢!