nginx的作用

一直听说nginx是个负载均衡的反向代理工具

却不曾了解他到底有什么用处。

 

为什么要使用反向代理?

那么到了这一步我们又面临一个新的问题, 那就是为啥要整这个反向代理呢? 类似于碰到正向代理时的诘问那样, 直接访问不香吗? 为啥还要走这个反向代理? 关于正向代理前面已经解释了一些原因, 而反向代理的出现, 正像这个世界上没有无缘无故的爱与恨一样, 自然也有它存在的原因.

一个很直接的原因就是利用反向代理可以作为内部 负载均衡(load balance) 的手段.

举个例子来说, 假如我现在开发了一个 java web 的应用作为我的网站后台, 我直接部署它到 tomcat 服务器上, 让 tomcat 监听 80 端口, 直接对外服务. 一开始访问量也不大, 所以这样也是没有问题的, 如下图所示:

注: 因为 http 协议的缺省端口就是 80, 所以用户输入地址时可以省略这个端口号, 也即只需这样: xiaogd.net, 而不是繁琐的像这样: xiaogd.net:80, 关于缺省端口的话题, 还是可以参考前面所提的 深入理解端口.

但过一段时间之后, 访问量可能上来了, 一个 tomcat 进程处理不过来, 那怎么办呢? 于是我打算再起一个新的 tomcat 进程, 但这样就面临一个问题, 只有一个 80 端口, 它已经被第一个 tomcat 进程占用, 如果还要再起另外一个, 则只能选用其它的端口, 比如 8080.

当使用另外一个端口时, 确实可以启动两个 tomcat 的进程, 但用户想访问到第二个 tomcat 进程的服务, 却要这样去访问: xiaogd.net:8080. 显然, 这样的方案是有问题的, 用户根本不知道 8080 端口上服务的存在, 就算你有办法告诉用户, 用户也可能不太理解, 用户同时也很怕麻烦的, 为啥要我输入一个冒号加 8080 呢?

此外, 就算有些用户愿意如你所说转向访问 8080 端口, 你还是不能很好的控制把访问量平均地分配在两个 tomcat 上, 毕竟这是用户随机决定的, 也许很多用户又突然涌过来了 8080 端口的应用上, 造成了这边的拥挤.

又或者只有很少的用户愿意听从你的劝告转到新的 8080 端口上, 访问还是集中在旧的 80 端口上的, 这样旧的应用上响应还是很缓慢, 而新的应用却因为没几个用户访问而显得空闲, 没有得到充分的使用.

那么, 在这种情况下, 反向代理的好处就体现出来了, 具体的操作是这样的, 让 Nginx 作为一个前置的反向代理, 监听在 80 端口上; 而第一个 tomcat 则躲到幕后, 同时它也不再监听 80 端口(需要让给 Nginx), 而改为监听一个其它没有被使用的端口, 比如 8081, 然后让 Nginx 转发请求给它处理.

当然了, 如果只有一个 tomcat, 配置大概是这样的:

location / {
    proxy_pass   http://127.0.0.1:8080;
}

请求处理的流程是这样的:

请求: browser -- [http] --> Nginx -- [http] --> tomcat
响应: browser <-- [http] -- Nginx <-- [http] -- tomcat

自然, 这种情形下反向代理似乎不太必要, 还加多了一个环节, 响应速度反而慢了.

但如果有两个 tomcat, 情况就不一样了, 此时就可以在 Nginx 这个反向代理的层面, 启用负载均衡的策略, 大概的配置如下:

http {
    upstream myapp1 {
        server 127.0.0.1:8080;
        server 127.0.0.1:8081;
    }

    server {
        listen 80;

        location / {
            proxy_pass http://myapp1;
        }
    }
}

此时, 如果同时涌入了很多请求, Nginx 会把一半的请求交给 8080 端口上的 tomcat, 另一半的请求交给 8081 端口上的 tomcat, 如下图所示:

对外来看, 所有请求还是 Nginx 来处理, 用户不需要去做选择, 也不需要知道什么 8080, 8081 端口上应用的存在, 他们还是继续访问原来的网址 xiaogd.net 即可, 无需做任何改变.

如果你在云上有好几台主机, 甚至还可以将其组成一个内网, 然后将 tomcat 部署在不同的主机上. 比如有三台主机的话, 一台运行 Nginx 监听 80 端口, 其余两台运行 tomcat, 分别监听 8080 和 8081 端口, 同时接受并处理 Nginx 反向代理过来的请求, 如下图所示:

如果两台 tomcat 主机的配置不同, 比如一台的性能更强劲些, 还可以调整负载的比例(即权重, weight), 让性能更强的一台承担更多的请求:

http {
    upstream myapp1 {
        server 192.168.0.20:8080 weight=3;
        server 192.168.0.21:8080 weight=2;
    }

    server {
        listen 80;

        location / {
            proxy_pass http://myapp1;
        }
    }
}

如上配置 3:2 的权重比, 让其中一台承担 60% 的请求, 而另一台性能较差的则承担 40%, 也即每 5 个请求, 3 个会被转到 ip 为 20 的主机上, 2 个会转到 ip 为 21 的主机上.

自然, 有人可能还会有疑问, 所有请求都还是要经过 Nginx, 它能处理得过来吗? 答案是可以的, 因为它的功能仅仅是转发, 这就有点像美团外卖, 虽然它每天接受成千上万的人的点餐, 但它自己不需要去买菜, 洗菜, 切菜, 炒菜等, 它仅仅需要把订单交给饭店餐馆, 然后把它们做好的饭菜配送出去, 也即那些耗时的做饭过程都交给了饭店餐馆处理.

在这种反向代理的模式中, 同样的, 生成网页这个重任交到了隐藏在背后的 tomcat, 生成一个复杂的动态网页可能需要经过一些复杂的计算, 要查询数据库, 要拼凑各个页面组件, 可能会比较耗时, 但这些请求被两个 tomcat 应用并发地处理了, 因此响应的速度还是得到了保证, 而这些就是反向代理能给我们带来的好处.

总结

至此, 关于直接访问, (正向)代理以及反向代理就介绍完了, 最后总结下三种情形及与购物例子的比喻.

在直接访问的情形中, 浏览器直接访问了最终生成响应的服务器, 类似我们以厂家直销的方式从厂商购物, 如下图所示:

在(正向)代理的情形中, 浏览器主动访问代理服务器, 通过它间接获取最终响应, 类似我们从商店购物, 而商店的物品又是从厂家购来的, 如下图所示:

在反向代理的情形中, 从浏览器的角度看还是类似于直接访问, 但它的请求在服务端被透明的代理了. 类似于我们在网上从一个声称是厂家直销的"伪厂家"那里购物, 这个伪厂家实际还是把我们的订单转给了真正的厂家, 并从中拿了货给我们, 只是我们无从知道这一切幕后的交易, 如下图所示:

在一个复杂的网络中, 浏览器的请求还可能先被正向代理了, 然后又被反向代理了, 如下图所示::

关于 http 正向代理和反向代理就讲到这里.

posted @ 2023-07-19 21:12  好咯莫讲咯  阅读(16)  评论(0)    收藏  举报