• 使用Nginx实现Tomcat集群负载均衡


    1. 概述
    2. 要解决的问题
    3. 环境准备以及问题解决思路
    4. 配置
    5. 测试
    6. 小结

    一、概述

      使用Nginx主要是来解决高并发情况下的负载均衡问题。

    二、要解决的问题

      1、最主要是负载均衡请求分发。

      2、文件上传功能,只能上传到一个Tomcat上,下载文件或者图片的时候就有可能发生404错误。

      3、多个Tomcat之间Session共享问题,否则会出现不断要求登录的情况。

    三、环境准备以及问题解决思路

      1、第一个问题肯定就是使用Nginx来做负载均衡。安装Nginx,请参考:Linux Centos 6.5_x86安装Nginx

      2、第二个问题思路有两个:

        a)在Linux上搭建NFS服务器来实现文件共享,参考:Tomcat 集群 文件上传下载的共享问题 NFS配置

        b)利用Nginx的负载均衡,请求转发功能,将关于图片的上传和下载请求全部转到一台Tomcat上。具体配置参考下边配置一节。本文使用的是这种方式。

      3、上述提到的第三个问题即Session共享问题选择是Tomcat-Redis-Session_manager来解决的,具体请参考:使用Tomcat-redis-session-manager来实现Tomcat集群部署中的Session共享

      3、一台Linux安装多个Tomcat请参考:linux系统下安装两个或多个tomcat

      本文使用的是三台Tomcat,两台处理除文件以外的请求,一台专门处理文件上传和下载的请求。

      分别为:Tomcat1:192.168.1.96:7070

          Tomcat2:192.168.1.96:8081

          Tomcat3:192.168.1.96:9090

    四、配置

      

    复制代码
    # 使用的用户和组
    user root root
    ;
    # 指定工作衍生进程数(一般等于CPU的总核数或总核数的两倍,例如两个四核CPU,则综合数为8.通过命令ps -ef|grep nginx可以看出来设置的是几个)
    worker_processes
    8;
    #指定错误日志存放的路径,错误日志记录级别可选项为:[debug|info|notice|warn|error|crit],默认是crit,记录的日志数量从crit到debug,由少到多。
    error_log /usr/local/nginx/logs/nginx_error.log crit
    ;

    #指定pid存放的路径
    pid /usr/local/nginx/nginx.pid
    ;

    # 指定文件描述符数量??
    worker_rlimit_nofile
    51200;

    #events settings
    events {
    # 使用的网络I/O模型,Linux系统推荐采用epoll模型,FreeeBSD系统推荐采用kqueue模型
    use epoll
    ;
    # 允许的连接数
    worker_connections
    51200;
    }

    遵循http协议的服务器全局设置

    http {

    include mime.types;

    default_type application/octet-stream;

    #设置使用的字符集,如果一个网站有多种字符集,请不要随便设置,应让程序员在HTML代码中通过Meta标签设置

    #charset utf-
    8;



    server_names_hash_bucket_size
    128;

    client_header_buffer_size 32k;

    large_client_header_buffers 4 32k;



    # 设置客户端能够上传的文件大小,注意要与应用程序中的文件大小限制兼容。

    client_max_body_size 300m
    ;



    sendfile on
    ;

    tcp_nopush on;
    keepalive_timeout 60;

    tcp_nodelay on;

    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;



    #log_format 自定义日志记录格式设置,main为名字,在access_log命令中引用
    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 访问日志文件设置

    #关闭日志记录

    #access_log off
    ;

    #指定日志存放路径,如果想使用默认的combined格式记录日志,可以使用access_log logs/access.log combined; 以下是使用log_format自定义的格式记录日志的。

    access_log logs/access.log main;



    # 开启gzip压缩设置(只能在http模块中设置)

    gzip on
    ;

    gzip_min_length 1k;

    gzip_buffers 4 16k;

    gzip_http_version 1.1;

    gzip_comp_level 2;

    gzip_types application/x-javascript text/css application/xml;

    gzip_vary on;



    # 用于设置如果出现指定的HTTP错误状态码,则返回指定的url页面

    error_page
    404 /404.html;

    error_page 500 502 503 504 /50x.html;



    #upstream设置,设置代理服务器(负载均衡池),默认的负载均衡方式是轮询,另外一种是ip_hash

    upstream tomcat_server {

    #ip_hash;

    server 192.168.1.96:7070 weight=1;

    server 192.168.1.96:8081 weight=1;

    }

    #处理上传和下载的图片文件服务器,设置代理服务器(负载均衡池),默认的负载均衡方式是轮训,另外一种是ip_hash</br>
    upstream image_server{</br>
        server 192.168.1.96:9090 weight=1;</br>
    

    }

    #server虚拟主机设置,可以设置多个:基于IP的虚拟主机,基于域名的虚拟主机</br>
    # 第一个虚拟主机(基于域名的虚拟主机),反向代理tomcat_server和image_server这两组服务器</br>
    server {</br>
        # 监听的端口</br>
        listen       </span>8000<span style="color: #008000">;</br>
    

    # 主机名称

    server_name localhost
    ;

    # 设置Nginx的默认首页文件

    index index.html index.htm index.jsp index.do
    ;

    #root /home/oracle/dev_tools/server/apache-tomcat-6.0.44/webapps/examples;



    # 配置该虚拟机的字符设置,如果不配置继承自http中的charset设置

    #charset koi8-r
    ;



    #access_log 访问日志文件设置,如果server虚拟机中不设置,则继承http模块中的access_log的设置

    #access_log logs/access.log main
    ;



    #rewrite settings

    if (-d $request_filename)

    {

    rewrite ^/(.*)(
    [^/])$ http://$host/$1$2/ permanent;

    }

        # location模块说明</br>
        # 使用环境:server模块</br></br>
    
       <strong><span style="color: #3366ff"> # iamge 服务器location</br>
        location ~*/NginxTest/image/ {</br>
            proxy_pass http://image_server</span></strong></span><strong><span style="color: #3366ff">;</br>
        }</br></br>
    
        location ~*/NginxTest/ {</br>
            # root /home/oracle/dev_tools/server/apache-tomcat-6.0.44/webapps/;</br></br>
            
            # HTTP代理模块 proxy,主要是用来转发请求到其他服务器</br>
            # 如果后端服务器返回502,504,执行超时等错误,自动将请求转发到upstream负载均衡池中的另一台服务器,实现failover。</br>
            proxy_next_upstream http_502 http_504 error timeout invalid_header;</br>
            # 变量$host等于客户端请求头中的Host值。</br>
            proxy_set_header Host $host;</br>
            #后端的web服务器可以通过X-Forwarded-For获取真实的IP地址,$remote_addr客户端的ip地址</br>
            proxy_set_header X-Forwarded-For $remote_addr;</br>
            proxy_pass http://tomcat_server;</br>
    

    }



    #image expires settings

    # expires 属于http Header模块,主要用来Nginx返回给用户网页添加附件的header信息,可以在http
    ,server,location中使用

    location ~ .*.(gif|jpg|jpeg|png|bmp|swf)$


    {
    expires 30d
    ;

    }

        #css&amp;js expires settings</br>
        # expires 属于http Header模块,主要用来Nginx返回给用户网页添加附件的header信息,可以在http</span>,server,<span style="color: #000000">location中使用</br>
        location ~ .*.(js|css|html)?$</br></br>
        {
            expires 2h</span><span style="color: #008000">;</br>
    

    }

        # 如果http模块设置了,则继承。此处设置了则覆盖。</br>
        #error_page  </span>404              /404.html<span style="color: #008000">;</br>
    

    #error_page 500 502 503 504 /50x.html;



    }

    }

    复制代码

       以下代码配置了两组负载均衡服务器。

    复制代码
      #upstream设置,设置代理服务器(负载均衡池),默认的负载均衡方式是轮询,另外一种是ip_hash
    upstream tomcat_server {
    #ip_hash
    ;
    server 192.168.1.96:7070 weight=1;
    server 192.168.1.96:8081 weight=1;
    }

    #处理上传和下载的图片文件服务器,设置代理服务器(负载均衡池),默认的负载均衡方式是轮询,另外一种是ip_hash</br>
    upstream image_server{</br>
        server </span>192.168.1.96:9090 weight=1<span style="color: #008000">;</br>
    

    }

    复制代码

      第一组就tomcat_server是用来处理普通请求的。第二组image_server主要是用来处理图片文件的上传和下载的,可以理解为一个文件服务器,所有文件相关的上传和下载都通过这组服务器。那怎么配置才能让Nginx实现这种目的呢?看以下配置:

    复制代码
        # iamge 服务器location
    location ~*/NginxTest/image/ {
    proxy_pass http://image_server
    ;
    }

        location ~*/NginxTest/ {</br>
            # root /home/oracle/dev_tools/server/apache-tomcat-</span>6.0.44/webapps/<span style="color: #008000">;</br>
    



    # HTTP代理模块 proxy,主要是用来转发请求到其他服务器

    # 如果后端服务器返回502,
    504,执行超时等错误,自动将请求转发到upstream负载均衡池中的另一台服务器,实现failover。

    proxy_next_upstream http_502 http_504 error timeout invalid_header
    ;

    # 变量$host等于客户端请求头中的Host值。

    proxy_set_header Host $host
    ;

    #后端的web服务器可以通过X-Forwarded-For获取真实的IP地址,$remote_addr客户端的ip地址

    proxy_set_header X-Forwarded-For $remote_addr
    ;

    proxy_pass http://tomcat_server;

    }

    复制代码

      其中location ~*/NginxTest/image/ 符合这种url路径(这种路径是根据自己的应用需求约定的)的请求转发到 proxy_pass属性指定的 image_server服务器,其他请求转发到tomcat_server这组服务器。具体的路径规则请按照自己项目需求约定。Nginx配置参数请参考书籍:《实战Nginx:取代Apache的高性能Web服务器》。

    五、测试

      将三个应用分别部署到不同的Tomcat中,应用代码下载:NginxTest.rar

      说明:

      解压后有三个文件:NginxTest.war,NginxTest2.war,NginxImageTest.war,

      其中NginxTestImage必须放到Tomcat3中,三个应用程序名字在放入Tomcat之后必须都改为NginxTest。

      只用NginxTestImage应用有图片文件,NginxTest和NginxTest2中无图片文件。

      访问:http://ip:port/NginxTest/whichTomcat,如下图:

      

       不断刷新该页面,SessionId如果是不变化的说明,Session是从Redis中取到的,解决了Session共享问题。

       不断刷新页面,这是“Tomcat服务器1“文字应该和“Tomcat服务器2”不断变化,说明请求访问的不是相同的Tomcat。因为只有Tomcat3中的应用有图片文件,所以图片的获取是从Tomat3中获取的,也就解决了第二个问题。

    六、小结

      1、此时Nginx只有一台,如果这台Nginx访问不了了,整个集群就无法提供服务,所以为了实现Nginx的高可用,需要实现Nginx的failover,实现方式参考:Nginx+Keepalived实现站点高可用

      2、Redis的问题同上,参考:keepalived+redis 高可用redis主从解决方案

      

  • 相关阅读:
    一份详尽的 Java 问题排查工具清单,值得收藏!
    专业解决 MySQL 查询速度慢与性能差!
    马士兵对话京东T6阿里P7(薪水):月薪5万,他为何要离职?
    Java中的注解到底是如何工作的?
    一道简单的面试题,难倒各大 Java 高手!
    疯狂618,当当买书打 3 折!
    SQL才是世界上最牛逼的语言!
    程序员必须掌握的职场黑话,你知道几个?
    面试问我 Java 逃逸分析,瞬间被秒杀了。。
    redis 介绍与操作
  • 原文地址:https://www.cnblogs.com/jpfss/p/9181406.html
Copyright © 2020-2023  润新知