• 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)、轮询(默认) 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。 
        #2)、weight 指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。 
        #2)、ip_hash 每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。  
        #3)、fair(第三方)按后端服务器的响应时间来分配请求,响应时间短的优先分配。  
        #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_body_buffer_size     128k;	#缓冲区代理缓冲用户端请求的最大字节数,  
                proxy_connect_timeout       90;	#nginx跟后端服务器连接超时时间(代理连接超时)  
                proxy_send_timeout          90;	#后端服务器数据回传时间(代理发送超时)  
                proxy_read_timeout          90;	#连接成功后,后端服务器响应时间(代理接收超时)  
                proxy_buffer_size           4k;	#设置代理服务器(nginx)保存用户头信息的缓冲区大小
                proxy_buffers               4 32k;	#proxy_buffers缓冲区,网页平均在32k以下的话,这样设置  
                proxy_busy_buffers_size     64k;	#高负荷下缓冲大小(proxy_buffers*2)  
                proxy_temp_file_write_size  64k;	#设定缓存文件夹大小,大于这个值,将从upstream服务器传  
            }
    
            #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)


    这样子根据客户端IP做负载均衡的同步策略已基本可满足需求,但是考虑到客户端多网卡或者客户端访问不同的服务器时产生session不同步的问题,需要使用memcached做session同步策略,后续我会跟上配置文档。

    附:以下是来自于互联网的三中方法:
    1、不用session,通过cookie等方式绕过session 。
          貌似这种方式还是会存在问题,假如客户端禁用cookie怎么办。
    2、应用服务器自行实现共享
        如单点登录,采用中央认证服务器;或者memcache来存放后端服务器需要使用的公共数据。我曾经就有程序采用本地ehcache+memcache来缓存数据,其中ehcache缓存一些与他机无关的数据,memcache缓存一些公共数据,但这样往往也容易出现问题。
    3、ip_hash方式解决session共享  
            nginx中的ip_hash技术能够将某个ip的请求定向到同一台后端,这样一来这个ip下的某个客户端和某个后端就能建立起稳固的session,ip_hash是在upstream配置中定义的, 配置方式样例:
    upstream backend {  
      server 127.0.0.1:8080 ;  
      server 127.0.0.1:9090 ;  
       ip_hash;  
    }  
     ip_hash是容易理解的,但是因为仅仅能用ip这个因子来分配后端,因此ip_hash是有缺陷的,不能在一些情况下使用:
         (1)/ nginx不是最前端的服务器。ip_hash要求nginx一定是最前端的服务器,否则nginx得不到正确ip,就不能根据ip作hash。譬如使用 的是squid为最前端,那么nginx取ip时只能得到squid的服务器ip地址,用这个地址来作分流是肯定错乱的。
          (2)/ nginx的后端还有其它方式的负载均衡。假如nginx后端又有其它负载均衡,将请求又通过另外的方式分流了,那么某个客户端的请求肯定不能定位到同一 台session应用服务器上。这么算起来,nginx后端只能直接指向应用服务器,或者再搭一个squid,然后指向应用服务器。最好的办法是用 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 服务器:相比 Apache,Nginx 使用更少的资源,支持更多的并发连接,体现更高的效率,这点 使 Nginx 尤其受到虚拟主机提供商的欢迎。在高连接并发的情况下,Nginx是Apache服务器不错的替代品: Nginx在美国是做虚拟主机生 意的老板们经常选择的软件平台之一. 能够支持高达 50,000 个并发连接数的响应, 感谢Nginx为我们选择了 epoll and kqueue 作为开发模型. Nginx 作为负载均衡服务器: Nginx 既可以在内部直接支持 Rails 和 PHP 程序对外进行服务, 也可以支持作为 HTTP代理 服务器对外进行服务. Nginx采用C进行编写, 不论是系统资源开销还是CPU使用效率都比 Perlbal 要好很多. 
    作为邮件代理服务器: Nginx 同时也是一个非常优秀的邮件代理服务器(最早开发这个产品的目的之一也是作为邮件代理服务器), Last.fm 描述了成功并且美妙的使用经验. Nginx 是 一个安装非常的简单 , 配置文件非常简洁(还能够支持perl语法), Bugs 非常少的服务器: Nginx 启动特别容易, 并且几乎可以做到 7*24不间断运行,即使运行数个月也不需要重新启动. 你还能够不间断服务的情况下进行软件版本的升级 . 

    3、Nginx 配置简洁, Apache 复杂 
    Nginx 静态处理性能比 Apache 高 3倍以上 
    Apache 对 PHP 支持比较简单,Nginx 需要配合其他后端用 
    Apache 的组件比 Nginx 多 
    现在 Nginx 才是 Web 服务器的首选 

    4、最核心的区别在于apache是同步多进程模型,一个连接对应一个进程;nginx是异步的,多个连接(万级别)可以对应一个进程 

    5、nginx处理静态文件好,耗费内存少.但无疑apache仍然是目前的主流,有很多丰富的特性.所以还需要搭配着来.当然如果能确定nginx就适合需求,那么使用nginx会是更经济的方式. 
    apache有先天不支持多核心處理負載雞肋的缺點,建議使用nginx做前端,後端用apache。大型網站建議用nginx自代的集群功能

    6、 从个人过往的使用情况来看,nginx的负载能力比apache高很多。最新的服务器也改用nginx了。而且nginx改完配置能-t测试一下配置有没有问题,apache重启的时候发现配置出错了,会很崩溃,改的时候都会非常小心翼翼现在看有好多集群站,前端nginx抗并发,后端apache集群, 配合的也不错。

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

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

    9、 Nginx优于apache的主要两点:
    (1).Nginx本身就是一个反向代理服务器 
    (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处理慢或者前端压力很大的情况下,很容易出现Apache进程数飙升,从而拒绝服务的现象。 

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

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

    13、Apache在处理动态有优势,Nginx并发性比较好,CPU内存占用低,如果rewrite频繁,那还是Apache吧
  • 相关阅读:
    2014年工作中遇到的20个问题:141-160
    雷观(八):等我有钱了再付费,是一种很扯淡很没有远见的想法
    Mybatis中sql语句中的in查询,一定要判断null的情况
    Mybatis中sql语句中的in查询,一定要判断null的情况
    Java中的equals比较,小坑一个
    Java中的equals比较,小坑一个
    魔戒三曲,黑暗散去;人皇加冕,光明归来
    魔戒三曲,黑暗散去;人皇加冕,光明归来
    我才是真的“研究生”,虽然我只是本科毕业
    我才是真的“研究生”,虽然我只是本科毕业
  • 原文地址:https://www.cnblogs.com/wuyida/p/6300935.html
Copyright © 2020-2023  润新知