测试开发必知:有Tomcat,为什么还要Nginx?

2024-01-21

只用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集群

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

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

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。

总结:

感谢每一个认真阅读我文章的人!!!

作为一位过来人也是希望大家少走一些弯路,如果你不想再体验一次学习时找不到资料,没人解答问题,坚持几天便放弃的感受的话,在这里我给大家分享一些自动化测试的学习资源,希望能给你前进的路上带来帮助

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

测试开发必知:有Tomcat,为什么还要Nginx? 的相关文章

  • 如何更改tomcat jmx密码的文件权限

    我正在尝试保护 Windows 平台上托管的本地 tomcat 实例上的 JMX 访问 我已经创建了访问权限和密码文件 并使用以下 VM 参数插入这些文件 Dcom sun management jmxremote password fil
  • Kibana 5.5.1 位于 nginx 1.13 代理之后(dockerized)

    Goal 我想在 docker 容器中运行 elk 堆栈 能够通过 nginx 代理访问 ELK Stack 以绕过服务的各个端口 Kibana 服务 默认端口 5601 http
  • Capistrano 部署后 EC2 服务器中缺少 puma.sock

    通过 capistrano 将 ruby on Rails 项目的生产部署到 ec2 上的实例后 我在 nginx 错误日志中收到以下错误 亚马逊公共主机显示 502 Bad Gateway nginx 1 10 0 Ubuntu 我按照教
  • 从 git repo 拉取后出现白屏死机(React JS、Nginx)

    每当我从 master 分支执行 git pull 到服务器上时 我所有的 React 文件似乎都消失了 屏幕变成白色 我发现的临时解决方法是 删除浏览器 cookie 缓存和站点历史记录 然后关闭浏览器并重试 删除node modules
  • java.sql.SQLException:已经关闭

    我们有一个在 Tomcat 上运行的 Web 应用程序 带有 MySQL 后端 有一段时间一切都很好 然后突然我们开始遇到这个异常java sql SQLException Already closed 整个堆栈跟踪是 DEBUG org
  • 在龙卷风 v4+ 下,WebSocket 连接被拒绝并显示 403

    我有一个旧的龙卷风服务器 可以处理普通的 WebSocket 连接 我通过 Nginx 将这些连接从 wss info mydomain com 代理到 wss mydomain com 8080 以便绕过阻止非标准端口的客户代理 最近升级
  • 使用会话空闲超时进行轮询

    我对 Tomcat 中的所有应用程序使用单点登录 我的要求是 我必须轮询应从后端获取的事务状态 但它也不应该影响会话的空闲超时 有人可以建议是否可以做点什么吗 Thanx 我不知道是否有标准方法可以做到这一点 如果没有 你可以写一个过滤器
  • Nginx Node.js 快速下载大文件止于 1.08GB

    我有这个由 Nginx 代理的 Node js 应用程序 在生产环境中 路线是这样的 exports download function req res var id req params id if id id latest res do
  • nginx proxy_pass 省略路径

    我已经配置了 nginx 反向代理 location root var www html index index html location login proxy pass http 127 0 0 1 9080 proxy set he
  • Tiff 的 getImageWritersByFormatName 中存在问题。获取图像作家

    我正在尝试将 PDF 转换为 tiff 图像 我使用以下代码按格式获取图像编写器 Iterator
  • 部署解耦的前端+后端应用程序

    我使用两个完全解耦的组件编写了一个网络应用程序 一个基于 Place Framework 并服务以下请求的 API 类型 api 任何客户 基于解耦的前端AngularJS建造使用grunt build 现在 前端与API但我希望这两个单元
  • Tomcat 如何保持会话完整性?

    HttpServletRequest s 获取会话 布尔值 http download oracle com javaee 6 api javax servlet http HttpServletRequest html getSessio
  • 使用 NGINX auth_request 和 oauth2_proxy 设置标头

    我想使用授权请求 http nginx org en docs http ngx http auth request module html and oauth2 proxy https github com bitly oauth2 pr
  • 使用 nginx 将 PATCH 请求代理为 POST

    我尝试使用 nginx 将 HTTP PATCH 请求重定向到 HTTP POST 请求 我还尝试了以下配置 但它不起作用 我收到 400 错误请求 http map request method my method default req
  • nginx 代理重定向,带有来自 uri 的端口

    我正在尝试使用 nginx 进行重定向 这个想法是将某些端口的 uri id 1234 重定向到 localhost 1234 固定端口的重定向 location id 1234 rewrite id 1234 1 break proxy
  • GitLab 发布临时 IP 禁令 - 403 禁止

    我的 GitLab 实例设置有时会对我们自己的 IP 地址实施 IP 禁令 导致办公室中的所有用户在任何网页或 git 请求上都会收到 403 Forbidden 该禁令的实施是由于身份验证重复出现错误 这完全是一个单独的问题 但我想防止我
  • favicon.ico 在 Tomcat 7.0 的 spring mvc 3.2.2 中不显示?

    我是 spring mvc 新手 我的 favicon ico 没有显示在使用 spring 3 2 2 使用 tomcat 7 0 的浏览器选项卡中 我尝试查看相关的谷歌搜索 但仍然无法让它显示在浏览器选项卡中 FF Chrome IE
  • Tomcat 唯一 SessionId

    有没有办法配置 xml tomcat 6 x 来生成唯一的SessionId 无需扩展 ManagerBase StandardManager 我正在数据库表中捕获用户登录详细信息 会话 ID 在具有唯一约束的列中 并且收到唯一约束异常 您
  • 当 ssl 和 http2 打开时,Nginx 似乎忽略 server_name

    我有这个 nginx 配置 server listen 80 default server listen 80 default server server name www example com return 301 https www
  • 使用 nginx 在云上部署 django 和 React

    我有一个 digitalocean 服务器 并且已经使用 Gunicorn 和 nginx 部署了 Django 后端服务器 如何在同一台服务器上部署 React 应用程序 您可以构建 React 应用程序并使用 Nginx 提供其静态文件

随机推荐