nginx+tomcat负载均衡策略

測试环境均为本地,測试软件为:

nginx-1.6.0,apache-tomcat-7.0.42-1。apache-tomcat-7.0.42-2。apache-tomcat-7.0.42-3

利用nginx做负载均衡,三台tomcat做WEB详细业务处理。

nginx配置nginx.conf:

#Nginx所用用户和组。window下不指定  
#user  niumd niumd;  
#user  nobody;

#工作的子进程数量(通常等于CPU数量或者2倍于CPU)
worker_processes  2;

#错误日志存放路径
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#指定pid存放文件
#pid        logs/nginx.pid;


events {
    #使用网络IO模型linux建议epoll,FreeBSD建议採用kqueue,window下不指定。  
    #use epoll;  
      
    #同意最大连接数
    worker_connections  1024;
}


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;
    access_log  logs/access.log;  
  
    client_header_timeout  3m;  
    client_body_timeout    3m;  
    send_timeout           3m;  
   
    client_header_buffer_size    1k;  
    large_client_header_buffers  4 4k;  
 
 

    sendfile        on;
    tcp_nopush     on;
    tcp_nodelay     on;  

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;
    include    gzip.conf;  

    upstream localhost {  
      #依据ip计算将请求分配各那个后端tomcat。很多人误觉得能够解决session问题。事实上并不能。
#同一机器在多网情况下,路由切换。ip可能不同 server localhost:18081; server localhost:18082; server localhost:18083; #依据IP做分配策略 ip_hash; } #down 表示单前的server临时不參与负载 #weight 默觉得1.weight越大,负载的权重就越大。
#max_fails :同意请求失败的次数默觉得1.当超过最大次数时,返回proxy_next_upstream 模块定义的错误 #fail_timeout:max_fails 次失败后,暂停的时间。 #backup: 其他全部的非backup机器down或者忙的时候,请求backup机器。所以这台机器压力会最轻。 #nginx 的 upstream眼下支持 4 种方式的分配 #1)、轮询(默认) 每一个请求按时间顺序逐一分配到不同的后端server。假设后端serverdown掉,能自己主动剔除。
#2)、weight 指定轮询几率,weight和訪问比率成正比。用于后端server性能不均的情况。
#2)、ip_hash 每一个请求按訪问ip的hash结果分配,这样每一个訪客固定訪问一个后端server,能够解决session的问题。 #3)、fair(第三方)按后端server的响应时间来分配请求。响应时间短的优先分配。
#4)、url_hash(第三方) server { listen 80; server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; location / { proxy_pass http://localhost; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; client_max_body_size 10m; #同意client请求的最大单文件字节数 client_body_buffer_size 128k; #缓冲区代理缓冲用户端请求的最大字节数。 proxy_connect_timeout 90; #nginx跟后端server连接超时时间(代理连接超时) proxy_send_timeout 90; #后端server数据回传时间(代理发送超时) proxy_read_timeout 90; #连接成功后,后端server响应时间(代理接收超时) proxy_buffer_size 4k; #设置代理server(nginx)保存用户头信息的缓冲区大小 proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置 proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2) proxy_temp_file_write_size 64k; #设定缓存目录大小。大于这个值。将从upstreamserver传 } #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 ssl; # server_name localhost; # ssl_certificate cert.pem; # ssl_certificate_key cert.key; # ssl_session_cache shared:SSL:1m; # ssl_session_timeout 5m; # ssl_ciphers HIGH:!aNULL:!MD5; # ssl_prefer_server_ciphers on; # location / { # root html; # index index.html index.htm; # } #} }

Tomcat1配置server.xml:

<?
xml version='1.0' encoding='utf-8'?
> <Server port="18001" shutdown="SHUTDOWN"> <Connector port="18081" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="18441" /> <Connector port="18021" protocol="AJP/1.3" redirectPort="18441" /> <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1"> </Service> </Server>
Tomcat1配置server.xml:
<?
xml version='1.0' encoding='utf-8'?
> <Server port="18002" shutdown="SHUTDOWN"> <Connector port="18082" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="18442" /> <Connector port="18022" protocol="AJP/1.3" redirectPort="18442" /> <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1"> </Service> </Server>
Tomcat3配置server.xml:
<?xml version='1.0' encoding='utf-8'?>

<Server port="18003" shutdown="SHUTDOWN">
 <Connector port="18083" protocol="HTTP/1.1"  connectionTimeout="20000"  redirectPort="18443" />
    <Connector port="18023" protocol="AJP/1.3" redirectPort="18443" />
    <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">
  </Service>
</Server>

分别启动三台tomcat,訪问到地址依次是:http://localhost:18081。http://localhost:18082;http://localhost:18083

然后启动nginx,訪问地址是:http://localhost

(cmd以下执行nginx.exe,关闭cmd以下执行nginx -s stop)

这样子依据clientIP做负载均衡的同步策略已基本可满足需求,可是考虑到client多网卡或者client訪问不同的server时产生session不同步的问题,须要使用memcached做session同步策略。兴许我会跟上配置文档。

附:以下是来自于互联网的三中方法:

1、不用session,通过cookie等方式绕过session 。

貌似这样的方式还是会存在问题,假如client禁用cookie怎么办。

2、应用server自行实现共享

如单点登录,採用中央认证server。或者memcache来存放后端server须要使用的公共数据。我以前就有程序採用本地ehcache+memcache来缓存数据。当中ehcache缓存一些与他机无关的数据,memcache缓存一些公共数据,但这样往往也easy出现故障。

3、ip_hash方式解决session共享

nginx中的ip_hash技术能够将某个ip的请求定向到同一台后端,这样一来这个ip下的某个client和某个后端就能建立起稳固的session。ip_hash是在upstream配置中定义的, 配置方式例子:

upstream backend {

server 127.0.0.1:8080 ;

server 127.0.0.1:9090 ;

ip_hash;

}

ip_hash是easy理解的,可是由于仅仅能用ip这个因子来分配后端。因此ip_hash是有缺陷的,不能在一些情况下使用:

(1)/ nginx不是最前端的server。ip_hash要求nginx一定是最前端的server,否则nginx得不到正确ip。就不能依据ip作hash。譬如使用 的是squid为最前端。那么nginx取ip时仅仅能得到squid的serverip地址,用这个地址来作分流是肯定错乱的。

(2)/ nginx的后端还有其他方式的负载均衡。

假如nginx后端又有其他负载均衡。将请求又通过另外的方式分流了。那么某个client的请求肯定不能定位到同一 台session应用server上。

这么算起来,nginx后端仅仅能直接指向应用server,或者再搭一个squid。然后指向应用server。最好的办法是用 location作一次分流,将须要session的部分请求通过ip_hash分流,剩下的走其他后端去。

(3) upstream_hash(这样的方式没有尝试过)

以下是从网络上整理的关于nginx与apache的对照:

1、nginx与apache优缺点对照

nginx相对于apache的长处:

(1)轻量级,相同起web 服务。比apache占用更少的内存及资源

(2)抗并发。nginx 处理请求是异步非堵塞的,而apache 则是堵塞型的,在高并发下nginx 能保持低资源低消耗高性能

(3)高度模块化的设计,编写模块相对简单

(4)社区活跃。各种高性能模块出品迅速啊

apache 相对于nginx 的长处:

(1)rewrite:比nginx 的rewrite 强大

(2)动态页面:模块超多。基本想到的都能够找到

(3)少bug ,nginx 的bug 相对较多

(4)超稳定

存在就是理由,一般来说。须要性能的web 服务,用nginx 。假设不须要性能仅仅求稳定,那就apache 吧。 后者的各种功能模块实现得比前者,比如ssl 的模块就比前者好。可配置项多。

这里要注意一点。epoll(freebsd 上是 kqueue )网络 IO 模型是nginx 处理性能高的根本理由,但并非全部的情况下都是epoll 大获全胜的,假设本身提供静态服务的就仅仅有寥寥几个文 件,apache 的select 模型也许比epoll 更高性能。

当然。这仅仅是依据网络IO 模型的原理作的一个假设,真正的应用还是须要实測了再说 的。

2、作为 Web server:相比 Apache,Nginx 使用更少的资源。支持很多其他的并发连接。体现更高的效率,这点 使 Nginx 尤其受到虚拟主机提供商的欢迎。

在高连接并发的情况下,Nginx是Apacheserver不错的替代品: Nginx在美国是做虚拟主机生 意的老板们常常选择的软件平台之中的一个. 能够支持高达 50,000 个并发连接数的响应, 感谢Nginx为我们选择了 epoll and kqueue 作为开发模型. Nginx 作为负载均衡server: Nginx 既能够在内部直接支持 Rails 和 PHP 程序对外进行服务, 也能够支持作为 HTTP代理 server对外进行服务. Nginx採用C进行编写, 不论是系统资源开销还是CPU使用效率都比 Perlbal 要好非常多.

作为邮件代理server: Nginx 同一时候也是一个非常优秀的邮件代理server(最早开发这个产品的目的之中的一个也是作为邮件代理server), Last.fm 描写叙述了成功而且美妙的使用经验. Nginx 是 一个安装非常的简单 , 配置文件非常简洁(还能够支持perl语法), Bugs 非常少的server: Nginx 启动特别easy, 而且差点儿能够做到 7*24不间断执行,即使执行数个月也不须要又一次启动. 你还能够不间断服务的情况下进行软件版本号的升级 .

3、Nginx 配置简洁, Apache 复杂

Nginx 静态处理性能比 Apache 高 3倍以上

Apache 对 PHP 支持比較简单,Nginx 须要配合其他后端用

Apache 的组件比 Nginx 多

如今 Nginx 才是 Web server的首选

4、最核心的差别在于apache是同步多进程模型。一个连接相应一个进程。nginx是异步的。多个连接(万级别)能够相应一个进程

5、nginx处理静态文件好,耗费内存少.但无疑apache仍然是眼下的主流,有非常多丰富的特性.所以还须要搭配着来.当然假设能确定nginx就适合需求,那么使用nginx会是更经济的方式.

apache有先天不支持多核心處理負載雞肋的缺點,建議使用nginx做前端。後端用apache。大型網站建議用nginx自代的集群功能

6、 从个人过往的使用情况来看,nginx的负载能力比apache高非常多。

最新的server也改用nginx了。而且nginx改完配置能-t測试一下配置有没有问题,apache重新启动的时候发现配置出错了,会非常崩溃,改的时候都会非常小心翼翼如今看有好多集群站,前端nginx抗并发。后端apache集群, 配合的也不错。

7、nginx处理动态请求是鸡肋。一般动态请求要apache去做,nginx仅仅适合静态和反向。

8、從我個人的經驗來看,nginx是非常不錯的前端服務器,負載性能非常好,在老奔上開nginx,用webbench模擬10000個靜態文件請求毫不吃力。apache對php等語言的支持非常好。此外apache有強大的支持網路。發展時間相對nginx更久.

9、 Nginx优于apache的主要两点:

(1).Nginx本身就是一个反向代理server

(2).Nginx支持7层负载均衡。其他的当然,Nginx可能会比 apache支持更高的并发。可是依据NetCraft的统计,2011年4月的统计数据,Apache依旧占有62.71%,而Nginx是 7.35%。因此总得来说。Aapche依旧是大部分公司的首先,由于其成熟的技术和开发社区已经也是非常不错的性能。

10、你对web server的需求决定你的选择。

大 部分情况下nginx都优于APACHE,比方说静态文件处理、PHP-CGI的支持、反向代理功能、前端Cache、维持连接等等。在 Apache+PHP(prefork)模式下。假设PHP处理慢或者前端压力非常大的情况下,非常easy出现Apache进程数飙升,从而拒绝服务的现象。

11、能够看一下nginx lua模块:https://github.com/chaoslaw...apache比nginx多的模块,可直接用lua实现apache是最流行的,why?大多数人懒得更新到nginx或者学新事物

12、对于nginx。我喜欢它配置文件写的非常简洁。正则配置让非常多事情变得简单执行效率高,占用资源少。代理功能强大,非常适合做前端响应server

13、Apache在处理动态有优势,Nginx并发性比較好。CPU内存占用低。假设rewrite频繁,那还是Apache吧