当前位置: 欣欣网 > 码农

既然有了Tomcat,为什么还要Nginx?

2024-06-27码农

扫码关注 后端架构师 」,选择 星标 公众号

重磅干货,第一时间送达!

责编:架构君 | 来源:五阳

链接: juejin.cn/post/7280088532377534505

上一篇好文:

正文

大家好,我是后端架构师。

只用Tomcat,不用Nginx搭建Web服务,行不行?我曾经提出的愚蠢问题,今天详细给自己解释下,为什么必须用Nginx!

不用Nginx,只用Tomcat的Http请求流程

浏览器处理一个Http请求时,会首先通过DNS服务器找到域名关联的IP地址,然后请求到对应的IP地址。以阿里云域名管理服务为例,一个域名可以最多绑定三个IP地址,这三个IP地址需要是公网IP地址,所以首先需要在三个公网Ip服务器上部署Tomcat实例。

此时我将面临的麻烦如下

  • 由于DNS域名管理绑定的IP地址有限,最多三个,你如果想要扩容4台Tomcat,是不支持的。无法满足扩容的诉求

  • 如果你有10个服务,对应10套Tomcat集群,就需要10 * 3台公网Ip服务器。成本还是蛮高的。

  • 10个服务需要对应10个域名,分别映射到对应的Tomcat集群

  • 10个域名我花不起这个钱啊!(其实可以用二级域名配置DNS映射)

  • 公网服务器作为接入层需要有防火墙等安全管控措施,30台公网服务器,网络安全运维,我搞不定。

  • 公网IP地址需要额外从移动联通运营商或云厂商购买,30个公网IP价格并不便宜。

  • 前后端分离的情况,Tomcat无法作为静态文件服务器,只能用Nginx或Apache

  • 以上几个问题属于成本、安全、服务扩容等方面。

    如果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 虚拟主机和反向代理

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

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

  • 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集群

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

  • 分别把路径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。

    你还有什么想要补充的吗?

    最后给大家推荐一个ChatGPT 4.0国内网站,是我们团队一直在使用的,我们对接是OpenAI官网的账号,给大家打造了一个一模一样ChatGPT,很多粉丝朋友现在也都通过我拿这种号,价格不贵,关键还有售后。

    一句话说明:用官方一半价格的钱,一句话说明:用跟官方 ChatGPT4.0 一模一样功能,无需魔法,无视封号,不必担心次数不够。

    最大优势:可实现会话隔离!突破限制:官方限制每个账号三小时可使用40次4.0本网站可实现次数上限之后,手动切换下一个未使用的账号【相当于一个4.0帐号,同享受一百个账号轮换使用权限】

    最后,再次推荐下我们的AI星

    为了跟上AI时代我干了一件事儿,我创建了一个知识星球社群:ChartGPT与副业。想带着大家一起探索 ChatGPT和新的AI时代

    有很多小伙伴搞不定ChatGPT账号,于是我们决定,凡是这三天之内加入ChatPGT的小伙伴,我们直接送一个正常可用的永久ChatGPT独立账户。

    不光是增长速度最快,我们的星球品质也绝对经得起考验,短短一个月时间,我们的课程团队发布了 8个专栏、18个副业项目

    简单说下这个星球能给大家提供什么:

    1、不断分享如何使用ChatGPT来完成各种任务,让你更高效地使用ChatGPT,以及副业思考、变现思路、创业案例、落地案例分享。

    2、分享ChatGPT的使用方法、最新资讯、商业价值。

    3、探讨未来关于ChatGPT的机遇,共同成长。

    4、帮助大家解决ChatGPT遇到的问题。

    5、 提供一整年的售后服务,一起搞副业

    星球福利:

    1、加入星球4天后,就送ChatGPT独立账号。

    2、邀请你加入ChatGPT会员交流群。

    3、赠送一份完整的ChatGPT手册和66个ChatGPT副业赚钱手册。

    其它福利还在筹划中... 不过,我给你大家保证,加入星球后,收获的价值会远远大于今天加入的门票费用 !

    本星球第一期原价 399 ,目前属于试运营,早鸟价 149 ,每超过50人涨价10元,星球马上要来一波大的涨价,如果你还在犹豫,可能最后就要以 更高价格加入了 。。

    早就是优势。 建议大家尽早以便宜的价格加入!

    欢迎有需要的同学试试,如果本文对您有帮助,也请帮忙点个 赞 + 在看 啦!❤️

    在 还有更多优质项目系统学习资源,欢迎分享给其他同学吧!

    PS:如果觉得我的分享不错,欢迎大家随手点赞、转发、在看。

    最后给读者整理了一份BAT大厂面试真题,需要的可扫码加微信备注:「面试」获取。

    版权申明:内容来源网络,版权归原创者所有。除非无法确认,我们都会标明作者及出处,如有侵权烦请告知,我们会立即删除并表示歉意。谢谢!

    END

    最近面试BAT,整理一份面试资料【Java面试BAT通关手册】,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。在这里,我为大家准备了一份2021年最新最全BAT等大厂Java面试经验总结。

    别找了,想获取史上最全的Java大厂面试题学习资料

    扫下方二维码回复面试就好了

    历史好文:

    扫码关注后端架构师」,选择星标公众号

    重磅干货,第一时间送达