nginx+tomcat实现负载均衡以及双机热备

还记得那些年吗?

还记得更新代码之后,服务器起不来被领导训斥吗?还记得更新代码,需要停机过多的时间被渠道部们埋怨吗?还记得更新代码,代码出错时自己吓个半死吗?于是我们聪明勤快的程序员,看着电影待到夜深人静的时候;爬起来有条不紊的更新着代码,以保证明天大家一觉醒来打开网站,完美的呈现给用户。 看似非常的完美,但是代码更新频繁的时候,我们也吃不消;并且我们在停机更新的时候带来的影响。

你听过「灾备」、「异地多活」、「双机热备」这些词么?

大家都知道「不能把鸡蛋放在一个篮子里」,在我们开发中依然是如此,如果是稍微对系统数据及运行状态有要求的项目,千万可不能突然系统挂掉几分钟,这带来的后果是不可想象的。所以,在我们开发中就会有「灾备」这个词,我们要考虑到这些不可预防的事件发生,所以,往往我们会把系统部署到多台服务器上面,这就是「鸡蛋」的例子,也就是所谓的「双机热备」,以保证我们系统的高可用,当一个服务器挂掉,后边的这个完全有能力顶上去!就好像一个程序员你感觉他天天没什么事儿可干,非常气愤的去找你领导说:xxx 天天没事干,为什么他工资比我高?呵呵呵...

nginx+tomcat实现负载均衡以及双机热备

由于服务器资源有限,我们就做本地测试;

 

实现的原理:

  利用nginx的反向代理将我们配置好的应用池根据某种规则去访问。nginx分配tomcat请求的比例有四种,分别是轮询(默认),权重(红框所示)权重分配的越高,访问的承载量越大,第三种分配方式是根据ip分配;最后一种是第三方分配。我的配置文件用的是权重的分配方式。

nginx代码段

       准备如下nginx代码段将其添加到nginx的/etc/nginx/conf.d/default.conf中, 模拟方式很简单,通过down来表示流量为零(nginx中无法将weight设置为零),开始的时候100%的流量都发到蓝色版本。        

http {
upstream nginx_blug_green {
    server 127.0.0.1:8080 weight=100;
    server 127.0.0.1:8081 down;
}

    server {
        listen 8082;
     server_name localhost;

     location /callcenter-api {
     #root html;
       #index index.html index.htm;
       proxy_pass http://nginx_blug_green;

    }

}

  因为我这边服务器有限,装了两个Tomcat来模拟两个服务器的;安装完成之后开始配置我们的tomcat文件夹/conf/server.xml文件,如下所示

    

 

 

 

 

 

 

 

 

 

更改这三个端口号,防止出现运行多个tomcat会出现端口号被占用的问题。

tomcat和nginx的配置完成后把要运行项目的war包放到tomcat的webapps的文件夹下(在两个tomcat的项目里做一个标识,显示当前的端口号为多少),在tomcat的bin文件夹下运行startup.bat文件,启动tomcat,tomcat启动成功之后,使用dos命令启动我们的nginx,然后打开浏览器进行测试

运行nginx;

 1.cd /usr/local/nginx;

 2 ./nginx; 

  等待nginx启动完成;

假设我们要更新代码场景:    只需将8080端口设置为down,将所有流量走8081;此时并不会停机。

upstream nginx_blug_green {
    server 127.0.0.1:8080 down;
    server 127.0.0.1:8081 weight=100; 
}

nginx平滑重启

./nginx -s reload

访问 :http://localhost:8082/callcenter-api/sys/login 

温馨提示:如果在访问时出现:

 

 原因是在nginx配置文件中配置upstream时用了“_”字符,如上用的tomcat_server,直接报错了。改成tomcatserver,即不使用“_”字符就好了。主要还是版本原因,tomcat7就不会有这个问题

 

特别注意的是  nginx的过期时间和他的重试机制

当后端代理的服务器超时返回时;nginx会抛出错误给客户端;同时自己会多次发送请求给后端;后台会进行多次的请求操作。

proxy_next_upstream http_502 http_504 error timeout invalid_header;

上面的配置表示,如果后端服务器如下情况,将会把请求转发到下一台后端服务器上。

  • error - 在连接到一个服务器,发送一个请求,或者读取应答时发生错误。
  • timeout - 在连接到服务器,转发请求或者读取应答时发生超时。
  • invalid_header - 服务器返回空的或者错误的应答。
  • http_502 - 服务器返回502代码。
  • http_504 - 服务器返回504代码。

超时时间为15s,所以后端服务器响应慢,nginx没有在15s内收到返回的数据,所以将请求切换到下一台后端机器了,所以,同样的情况下, 请求第二台后端机器时,也没有在规定的时间内得到响应,所以又切换到第三台机器了,最终导致请求发送了三次。

几个参数说明:

proxy_send_timeout     后端服务器数据回传时间(代理发送超时时间)

proxy_read_timeout      连接成功后,后端服务器响应时间(代理接收超时时间)

proxy_connect_timeout    nginx连接后端的超时时间,一般不超过75s

如何解决呢?

     1、第一种办法:因为后端机器无法再进行优化减少响应时间,所以可以更改nginx的超时时间,将原本的15s更改为40s,这样可以保证结果正常返回。

      2、第二种办法 :关闭自动切换到下台机器的功能,即将proxy_next_upstream配置为off。但是这样虽然能解决问题,但是会导致nginx的容错能力下降。

     3、第三种办法:从业务角度出发,本质上我们是需要只发一次短信的。 所以可以采用分布式锁的方式解决。

以上现象还可能出现在以下的场景:

1、上传excel,然后服务端处理excel内容,插入到db里面的时候,可能存在多次转发导致数据重复。

2、post请求处理时间过长,可能出现重复提交的问题。

 

posted @ 2019-10-29 17:22  牧码人hhom  阅读(717)  评论(0编辑  收藏  举报