Tomcat和Nginx之间的PK

如果Tomcat服务发布怎么办

Tomcat在服务发布期间是不可用的,在发布期间Http请求打到发布的服务器,就会失败。由于DNS 最多配置3台服务器,也就是发布期间是 1/3 的失败率。我会被老板枪毙,用加特林

DNS不能自动摘掉故障的IP地址吗?

不能,DNS只是负责解析域名对应的IP地址,他并不知道对应的服务器状态,更不会知道服务器上Tomcat的状态如何。DNS只是解析IP,并没有转发Http请求,所以压根不知道哪台服务器故障率高。更无法自动摘掉IP地址。

我能手动下掉故障的IP地址吗?

这个我能,但是还是会有大量请求失败。以阿里云为例,配置域名映射时,我可以下掉对应的IP地址,但需要指定域名映射的缓存时间,默认10分钟。换句话说,就算你在上线前,摘掉了对应的IP,依然要等10分钟,所有的客户端才会拿到最新的DNS解析地址。

那么把TTL缓存时间改小,可以吗?可以的,但是改小了,就意味更多的请求被迫从DNS服务器拿最新的映射,整体请求耗时增加,用户体验下降!被老板发现,会骂我。

节点突然挂掉怎么办?

虽然可以在DNS管理后台手动下掉IP地址,但是节点突然宕机、Tomcat Crash等因素导致的突然故障,我是来不及下掉对应IP地址的,我只能打电话告诉老板,“线上服务崩了,你等我10分钟改点东西”。

如果这时候有个软件能 对Tomcat集群健康检查和故障重试,那就太好了。

恰好,这是 Nginx 的长处!

Nginx可以健康检查和故障重试

而Tomcat没有。

例如有两台Tomcat节点,在Nginx配置故障重试策略

upstream test {
    server 127.0.0.1:8001 fail_timeout=60s max_fails=2; ## Server A
    server 127.0.0.1:8002 fail_timeout=60s max_fails=2; ## Server B
}

当A节点出现 connect refused时(端口关闭或服务器挂了),说明服务不可用,可能是服务发布,也可能是服务器挂了。此时nginx会把失败的请求自动转发到B节点。假设第二个请求 请求到A还是失败,正好累计2个失败了,那么Nginx会自动把A节点剔除存活列表 60 秒,然后继续把请求2 转发到B节点进行处理。60秒后,再次尝试转发请求到A节点…… 循环往复,直至A节点活过来……

而这一过程客户端是感知不到失败的。因为两次请求都二次转发到B节点成功处理了。客户端并不会感知到A节点的处理失败,这就是Nginx 反向代理的好处。即客户端不用直连服务端,加了个中间商,服务端的个别节点宕机或发布,对客户端都毫无影响。

而Tomcat只是Java Web容器,并不能做这些事情。

10个服务,10个Tomcat集群,就要10个域名,30个公网IP吗?

以阿里云为例,域名管理后台是可以配置二级域名映射,所以一个公网域名拆分为10个二级域名就可以了。

所以只用Tomcat,不用Nginx。需要1个公网域名,10个二级域名,30台服务器、30个公网IP。

当我和老板提出这些的时候,他跟我说:“你XX疯了,要不滚蛋、要不想想别的办法。老子没钱,你看我脑袋值几个钱,拿去换公网IP吧”。

DNS映射到Tomcat的IP地址,必须要公网,成本实在hold不住。心里苦啊,要是能有一个软件,能帮我把一个域名分别映射到30个内网IP就好了。

恰好 Nginx可以!

Nginx 虚拟主机和反向代理

例如把多个二级域名映射到不同的文件目录,例如

  1. bbs.abc.com,映射到 html/bbs

  2. blog.abc.com 映射到 html/blog

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       80;
        server_name  www.abc.com;
        location / {
            root   html/www;
            index  index.html index.htm;
        }
    }
   
    server {
        listen       80;
        server_name  bbs.abc.com;
        location / { 
            root   html/bbs;
            index  index.html index.htm;
        }   
    }   

    server {
        listen       80;
        server_name  blog.abc.com;
        location / { 
            root   html/blog;
            index  index.html index.htm;
        }   
    }   
}

例如把不同的二级域名或者URL路径 映射到不同的 Tomcat集群

  1. 分别定义 serverGroup1、serverGroup2 两个Tomcat集群

  2. 分别把路径group1、group1 反向代理到serverGroup1、serverGroup2

upstream serverGroup1 {                    ## 定义负载均衡设备的ip和状态
        server 192.168.225.100:8080 ;           ## 默认权重值为一
        server 192.168.225.101:8082 weight=2;   ## 值越高,负载的权重越高
        server 192.168.225.102:8083 ;       
        server 192.168.225.103:8084 backup;     ## 当其他非backup状态的server 不能正常工作时,才请求该server,简称热备
    }

upstream serverGroup2 {                    ## 定义负载均衡设备的ip和状态
        server 192.168.225.110:8080 ;           ## 默认权重值为一
        server 192.168.225.111:8080 weight=2;   ## 值越高,负载的权重越高
        server 192.168.225.112:8080 ;
        server 192.168.225.113:8080 backup;     ## 当其他非backup状态的server 不能正常工作时,才请求该server,简称热备
    }

    server {                                    ## 设定虚拟主机配置
        listen  80;                             ## 监听的端口
        server_name  picture.itdragon.com;      ## 监听的地址,多个域名用空格隔开
        location /group1 {                      ## 默认请求 ,后面 "/group1" 表示开启反向代理,也可以是正则表达式
           root     html;                       ## 监听地址的默认网站根目录位置
           proxy_pass   http://serverGroup1;   ## 代理转发
           index  index.html index.htm;         ## 欢迎页面
           deny 127.0.0.1;                      ## 拒绝的ip
           allow 192.168.225.133;               ## 允许的ip
        }
    location /group2 {                      ## 默认请求 ,后面 "/group2" 表示开启反向代理,也可以是正则表达式
           root     html;                       ## 监听地址的默认网站根目录位置
           proxy_pass   http://serverGroup2;   ## 代理转发
           index  index.html index.htm;         ## 欢迎页面
           deny 127.0.0.1;                      ## 拒绝的ip
           allow 192.168.225.133;               ## 允许的ip
        }

        error_page   500 502 503 504  /50x.html;## 定义错误提示页面     
        location = /50x.html {                  ## 配置错误提示页面
            root   html;
        }
    }

总结

经过以上的教训,我再也不会犯这么愚蠢的错误了,我需要Tomcat,也需要Nginx。

当然如果钱足够多、资源无限丰富,公网IP、公网服务器、域名无限…… 服务发布,网站崩溃,无动于衷,可以不用Nginx。

  • 21
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

数字化信息化智能化解决方案

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值