Nginx底层架构(非常清晰)

打印 上一主题 下一主题

主题 1634|帖子 1634|积分 4902

目录
媒介:
场景带入:
HTTP服务器是什么?
反向署理是什么?
模块化网关能力:
1.配置能力:
2.单线程:
3.多worker进程
4.共享内存:
5.proxy cache
6.master进程
最后:


媒介:

在互联网流量呈指数级增长的今天,如何用有限的资源支撑百万级并发请求,是每个后端开辟者必须面对的挑战。作为全球最受欢迎的高性能Web服务器之一,Nginx以不足2MB的内存占用轻松处理万级连接,其设计哲学堪称分布式体系的范例。
本文将深入Nginx的多进程架构事故驱动模型,揭开其“用最少的资源做最多的事变”的奥秘。从惊群效应的优雅规避,到SO_REUSEPORT的今世负载平衡策略,我们将通过源码级视角,解析Nginx如安在操纵体系内核与用户态代码之间编织出一张高效网络。无论你是想优化现有服务,还是探索服务器编程的艺术,这趟旅程都将为你打开一扇新天下的大门。
场景带入:

      你是一个程序员,你在本地写了一个html文件,将他拖入到浏览器,就可以通过浏览器渲染出相应的数据。

    但这只是本地的,本身写的数据,我们在浏览器上访问到的数据和页面,都是通过,远端服务器传送到我们的客户端的。那二者之间是如何进行数据传输的呢?没有什么是加一层中间层不能解决的。如果有,那就再加一层,这次我们要加的中间层是nginx。


HTTP服务器是什么?

我们想要在远端服务器上拿到数据,就让远端服务器创建一个进程,而且让他对外提供HTTP服务,也就是提供一个URL。当用户在客户端输入这个URL时,比如(www.baidu.com),那客户端会对远端服务器发送一个HTTP请求,当远端服务器收到这个请求时,就会响应相应的数据。浏览器进行解析与展示,这就完成了一次平凡的网页访问。


反向署理是什么?

一个完整的产品,它不止有前端页面,他另有后端服务。

前端需要时刻对后端请求最新数据。


此时,流量小的时候,压力并不大,后端服务还能轻松完成使命,不过流量一旦大起来,前端页面对后端的请求就会变多,那此时我们只能增多后端服务的数目,来完成对这些请求的处理,但是问题来了,后端服务多了,每个后端服务都有对应的IP与端口,前端就不知道该访问哪个服务了。还是那句话,没有什么是加一层中间层不能解决的。中间加一个进程,对外提供一个域名,当这些前端请求打过来的时候,这个进程就负责把这些请求匀称的转发给每个服务,让每个服务都能处理请求,这就是负载平衡。像这种屏蔽掉背后详细有哪些服务器的署理方式,我们就叫他反向署理
有了它,我们就可以对外只提供一个URL的域名。我们就可以根据需要,随时扩缩后端服务的数目

那我们这个反向署理就可以加在我们之条件到的远端服务器的谁人进程上,这样不但可以为前端提供HTTP服务,还可以将请求分给后端服务器。



模块化网关能力:

既然它是一个中间层,且会有大量的流量穿过它,那他高低也算个网关了。

那么我们就可以在他上面加入一些通用网关的功能,比如: 
   1.日记:我们就可以记载每次调用的结果,方便后续排查问题;
  2.压缩:我们就可以对输入输出内容进行压缩,减少网络带宽消耗;
  3.限流与封禁:主要是对某个模块进行限流和封禁;
  4.修改内容:修改输入输出的内容;
  5.自定义:本身根据需要开辟新的功能;
  还可以添加新的协议如:HTTP,HTTP2,TCP,UDP,Websocket。 

1.配置能力:

前面提到那么多种能力,用户肯定不会全部用上,所以需要有个地方来让人选择用那些能力,于我们可以加个配置文件,也就是Nginx.conf,然后,用户在配置文件上选择本身想要的功能。

2.单线程:

这个网关需要有这个多的前端请求打过来,如果每个请求都要开一个单独的进程,那么开销会很大,那么只需要将这些请求的线程都塞到一个单线程里头去,就能避免并发问题和线程开销。

3.多worker进程

但单个网关进程要单线程处理这么多的网络流量,纵然处理的再快,当有海量数据时,依然压力会很大。那么我们此时就将一个网关进程变成多个网管进程,我们叫他Worker进程,每个进程之间互不干扰。让多个进程监听一个端口,一有流量进来,我们就分给每个进程,将进程数目设置成和操纵体系CPU核数一致,那每个进程都能够得到一个核,那这里就能让效率最大化。


问题来了:这么多的work进程监听同一个端口,不会造成端口辩论吗?
   在传统的多进程服务器模型中(如Nginx的早期版本),通常由主进程(Master Process)创建并绑定监听套接字(Socket),随后通过fork()派生出多个Worker子进程。此时:
  

  • 共享文件描述符:全部Worker进程继承同一个监听套接字,而非各自独立创建新套接字。因此,它们现实上共享同一个内核套接字对象,不存在多个套接字绑定同一端口的问题。
  • 内核负载平衡:当新连接到达时,操纵体系内核会选择一个处于accept()状态的Worker进程来处理连接。这种方式称为“惊群效应”优化后的负载平衡(今世内核如Linux通过EPOLLEXCLUSIVE等机制避免多个进程被同时叫醒)。
  

4.共享内存:

前端页面发来的请求都会打到worker进程上,那如果说要限流这样的要计数的功能,每个worker上的计数都不一样,这个时候我们就要创建一个共享内存了,每一个worker进程都共有一个内存,这样就能包管多个进程之间做逻辑,这样就能包管体系数据的一致性。



5.proxy cache

前端发送请求给后端,后端响应结果返回给前端,此时,每次的请求都要重复这一过程,那能不能像redis一样设置中间层,将查询的结果暂存,下次在查询时就能直接拿了。我们只需要准备一些磁盘文件,将查询的数据放在那边就可以了。注意:不能放在共享内存里,内存太贵了

6.master进程

每个worker会分走一部门流量,如果功能更新,全部的worker同时重启,上面的网络连接就会全部断掉。那么我们此时创建一个新的进程,让他读取前面的Nginx.conf文件,让他同一管理各个worker进程,解决谁先连谁后连的问题。


最后:

在数字天下的汪洋中,每一次TCP握手都是浪花,每一个HTTP请求皆是潮汐。Nginx像一位冷静的船长,用事故驱动的罗盘指引着数据洪流的航向。当我们赞叹于它举重若轻的并发处理能力时,或许更应该思索:在摩尔定律逐渐失效的今天,软件架构的智慧是否比硬件堆砌更具生命力?
下次当你看到Nginx的羽毛Logo时,愿你能闻声多进程协同工作的交响,看见操纵体系内核与今世软件设计的共舞。在技术的星辰大海中,Nginx永远是最可靠的灯塔之一——由于它告诉我们,真正的力气,往往藏匿于简便之中。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

卖不甜枣

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表