草庐IT

【nginx原理】企业中使用nginx必须知道的那些事

我是沐风晓月 2023-04-22 原文

前言

本文是nginx原理篇,包含了nginx能用来做负载均衡,缓存,动静分离的原理:

nginx 的安装可以参考:

  1. 【Linux】CentOS7操作系统安装nginx实战(多种方法,超详细)

  2. 【编译安装】使用CentOS7安装编译安装nginx-1.22版本实战

nginx的使用:

  1. 【nginx实战】nginx实现虚拟主机及访问认证实战

  2. 利用nginx实现动静分离的负载均衡集群实战

  3. 手把手演示Ngnix+Tomcat实现动静分离

  4. 【shell脚本】nginx服务管理及存活检测脚本实战

文章目录

一. nginx原理:

1.1 进程模型

nginx默认采用的是多进程 master-worker模式, 以及IO多路复用模型

nginx启动后,会有一个master和多个互相独立的worker进程,master进程主要用来管理worker进程,主要包含:

  • 接收外界信号
  • 向各个worker进程发送信号
  • 监控woker进程的进程状态
  • 当worker进程退出后(异常情况下),会自动重新启动新的worker进程

基本的网络事件,都是放在worker进程中进行处理,多个worker进行之间是相互独立的,它们同等的竞争来自客户端的请求。

worker进程的功能:

  • 多个worker一起竞争来自客户端的请求
  • 一个请求只能在一个worker中进行处理
  • woker的进程的个数是可以设置的,一般我们会设置的与机器的cpu核心数一致。

在上图中可以看到: 我们的master接收外界信号,然后根据信号做不同的事情,如果想要控制nginx,只需要控制master即可。

master进程在接收到HUP信号后是怎么做的呢?

HUP 信号值得是重新加载配置,服务不会中断,类似于 nginx -s reload;

整个过程是这样的:

  • master进程在接到信号后,会先重新加载配置文件
  • 启动新的worker进程,并向所有老的worker进程发送信号,终止老的work进程
  • 在新的worker在启动后,就可以以新的配置文件来接收新的请求了。
  • 而老的worker在收到来自master的信号后,就不再接收新的请求,并且在当前进程中的所有未处理完的请求处理完成后,退出。

如下图:

1.2 惊群现象

master在分发信号的时候,所有的worker进程都是有机会抢夺到信号的。 一个用户发起服务器连接请求,内核在收到TCP的SYN包时,就会激活所有休眠的worker进程。 但最终只有最先开始执行accept的worker进程抢到了资源,其他的worker节点accept失败,在这里我们会发现,这些抢不到资源的worker进程就没有激活的必要。

一旦激活就会占用系统资源,增加系统的开销。

那如何解决惊群现象呢?

答: Nginx中规定同一时刻只能有唯一一个的worker进程监听Web端口,这样就不会发生惊群了,此时新连接事件只能唤醒唯一正在监听端口的worker进程

1.3 事件模型

常见的五种I/O模式:

  • 阻塞I/O模型
  • 非阻塞的I/O模型
  • I/O复用模型(select ,poll ,epoll)
  • 信号驱动I/O模型
  • 异步I/O模型

nginx默认采用的是IO多路复用的原理,通过异步非阻塞的时间处理机制,epoll模型,实现轻量级和高并发。

淘宝团队测试说: 24G内存的机器上,采用异步非阻塞的事件处理机制,处理并发请求可以达到200万。

apache和nginx工作流程的区别?

  1. apache的工作流程

我们平时去餐厅吃饭。餐厅的工作模式是一个服务员全程服务客户,流程是这样,服务员在门口等候客人(listen),客人到了就接待安排的餐桌上(accept),等着客户点菜(request uri),去厨房叫师傅下单做菜(磁盘I/O),等待厨房做好(read),然后给客人上菜(send),整个下来服务员(进程)很多地方是阻塞的。

这样客人一多(HTTP请求一多),餐厅只能通过叫更多的服务员来服务(fork进程),但是由于餐厅资源是有限的(CPU),一旦服务员太多管理成本很高(CPU上下文切换),这样就进入一个瓶颈。

  1. nginx的工作流程:

餐厅门口挂个门铃(注册epoll模型的listen),一旦有客人(HTTP请求)到达,派一个服务员去接待(accept),之后服务员就去忙其他事情了(比如再去接待客人)。

等这位客人点好餐就叫服务员(数据到了read()),服务员过来拿走菜单到厨房(磁盘I/O),服务员又做其他事情去了,等厨房做好了菜也喊服务员(磁盘I/O结束),服务员再给客人上菜(send()),厨房做好一个菜就给客人上一个,中间服务员可以去干其他事情。

整个过程被切分成很多个阶段,每个阶段都有相应的服务模块。这样一旦客人多了,餐厅也能招待更多的人。

拿到apache这边:

同样的4个进程,如果采用一个进程负责一个request的方式,那么,同时进来4个request之后,每个进程就负责其中一个,直至会话关闭。期间,如果有第5个request进来了。就无法及时反应了,因为4个进程都没干完活呢,因此,一般有个调度进程,每当新进来了一个request,就新开个进程来处理。

而nginx最大的优势就是不会干等着,这就类似于那个泡茶的小故事:

沐风晓月想给客人烧水沏茶,需要完成以下几件事:洗水壶,2分钟;烧开水,12分钟;买茶叶,5分钟;洗茶杯,1分钟;冲茶,1分钟。要让客人尽早喝上茶,最合理的安排是什么?

当然是等待一个事情完成的时间去做下一件事。比如烧开水,就没必要等12分钟,再去干其他的。

1.4 nginx的 特点

  • 1)占用资源少,3万个并发,开启10个nginx实例的情况下,才占用了150M内存
  • 2)c 语言编写,可移植性强,在一些主流的 linux,unix,windows 都可以很好的执行
  • 3)支持高并发,使用了10模型为epolI模型,5万个并发,生产环境2-3万没问题
  • 4)反向代理的服务器
  • 5)轻量级的web服务器
  • 6)负载均衡、容错服务器,可以通过软件的形式来实现很好的负载均衡
  • 7)电子邮件的代理服务器
  • 8)一个主进程多个工作进程,即常说的Master-worker模式,工作进程都是单线程

二. 正向代理和反向代理

2.1 正向代理

正向代理:正向代理服务器位于客户端和服务器之间,为了从服务器上获取数据,客户端向代理服务器发起请求,然后服务器返回数据到客户端,这个代理是代理的客户端的请求.

正向代理即是客户端代理, 代理客户端, 服务端不知道实际发起请求的客户端

如下图:

用户知道自己的资料在s3上,但s3并没有外网,只能通过访问S1来获取s3上的数据, 对于S3来说,它并不知道用户请求的存在,只能接收S1发送的请求。

所以在这里S1就充当了中间代理的角色。 S1获取数据后反馈给用户

2.2 反向代理

反向代理即是服务端代理, 代理服务端, 客户端不知道实际提供服务的服务端
用户 C,服务器 S1、S2 和 S3,在S2和S3上有数据资源。 这时候用户C不知道数据资源在S2和S3上, 用户只知道访问S1获取可以自己想要的资源。

反向代理,对用户C来说,他不知道具体的资源在哪台服务器上。

反向代理的作用:

(1)保证内网的安全,阻止web攻击,大型网站,通常将反向代理作为公网访问地址,Web服务器是内网

(2)负载均衡,通过反向代理服务器来优化网站的负载

三. 企业必备的实用技能

3.1 平滑升级理论

所谓的平滑升级,指的是在不停止公司业务的前提下,对nginx版本服务进行升级

平滑升级的操作流程:

  • 在不停掉低版本nginx进程的情况下,启动高版本nginx进程。
  • 让老进程负责处理仍然没有处理完的用户请求,但不再接受新的用户请求。
  • 新启动的高版本nginx进程来接收新的用户请求去处理。
  • 低版本nginx进程处理完之前所有的旧请求之后,关闭所有连接并退出
  • 这样我们这台服务器上就只有一个高版本的Nginx服务

什么时候会用到平滑升级:

  1. 本身低版本nginx存在高危漏洞,必须要升级Nginx的版本来修复这个漏洞
  2. 需要用到Nginx新增加的功能模块

3.2 公司中的打压测试

先看看运维的工作流程:

  1. 根据服务器的数量和性能、公司产品的依赖服务,来设计运维架构图
  2. 在硬件服务器上安装Linux操作系统
  3. 按运维架构图去各个服务器部署产品及依赖服务如: MySQL、Nginx
  4. 部署服务器的监控系统、日志收集系统
  5. 打压测试,或者叫压力测试
  6. 产品上线

为什么要做打压测试?

  • 做压力测试可以判断出目前所搭建的运维架构可以承载多少的用户量
  • 做压力测试可以使服务器处于高压情况下,在这种情形下,很大程度能暴露运维架构的短板或者缺陷

比如我们模拟12000的并发访问我们公司的服务器,要求在3秒钟内处理完。

第一秒: 处理2000个用户请求
第二秒: 处理4000个用户请求
第三秒: 处理6000个用户请求

这里就涉及到一些概念:

  • 吞吐率: 12000/3=4000 平均每秒钟处理400个用户请求, 4000reqs/s

  • 最大吞吐率: 服务器并发处理能力的上限,也就是在某个时刻,服务器能够处理的最大请求数

  • 并发连接数: 服务器在某个时间点,同时处理多少条请求的数量。

  • 并发用户数: 在同一时刻与服务器进行了交互的在线用户数量。

  • 用户平均请求等待时间 (每个请求的时间)
    计算公式:处理完成所有请求数所花费的时间/(总请求数/并发用户数),即每个请求的时间=测试所花费的时间/(完整请求/并发级别)

  • 服务器平均请求等待时间(每个请求的时间:跨所有并发请求)计算公式:处理完成所有请求数所花费的时间/总请求数

常用的压力测试工具: ab命令

3.3 衡量网站大小和处理能力的指标

  1. IP
    每天(00:24)之间内的单个IP数量,重复的不算。缺点:对于使用同一个IP作为出口
    的情况下,可能统计不准确。

  2. PV
    Page view即页面的浏览数量,即这一个网页被浏览多少次。例如统计某个网站的 Pv
    数量=IP*每个人平均的点击次数。从这个角度来说,PV能够衡量一个网站的粘性,即
    如果两个网站的IP一样,那么PV多的网站,说明比较吸引人。

  3. UV
    Userview 即真实的用户数量,通常情况,Uv 一般大于IP。统计精确的 Uv是非常困难
    的,可以提供过COOKIE,浏览器的类型。UV 就是客户端的数量。

  4. QPS
    每秒钟查询的次数。一个 PV 下来,可能会贡献多个 QPS.

  5. TPS

    吞吐量,单位时间(1 秒)内处理的请求数量,反应的是某个网站平均的处理能力。

  6. 并发
    同一时间内请求的数量,处理并发可以有相应的策略

  7. 最大并发
    某一个峰值的情况下,请求的数量。最大并发可以衡量一个网站峰值的处理能力。

  8. 并发和吞吐量的关系

    吞吐量=并发/平均的相应时间。例如:1000 个并发,每个并发需要 0.01 处理,那么吞
    吐量=1000/0.01=100000 个。

3.4 动静分离理论

网站的资源可以分为两类,一类是静态的,一类是动态的:


nginx本身是可以处理静态资源的,nginx本身可以处理的文件,我们称为静态文件, 需要经过后端处理的,我们称为动态文件:


在这里,nginx处理动态请求是需要转发给php,才能进行处理,其实是php进行处理然后返回查询结果的。

动静分离和负载均衡的结合架构图:

3.5 nginx作为缓存的原理

缓存技术的基本思想其实是对用户已经访问过的内容在Nginx建立副本,如果在一段时间内(缓存尚未过期)再次访问该数据,则不需要重新发起请求获取数据,可以直接从缓存中读取到该数据。

这样可以大大减少nginx与后端服务器的交互,提升用户的访问速度。

Nginx基于Proxy Store实现,使用Nginx的http_proxy模块可以实现类似于squid的缓存功能。当启用缓存时,Nginx会将相应数据保存在磁盘缓存中,只要缓存数据尚未过期,就会使用缓存数据来响应客户端的请求。

3.6 四层负载和七层负载

负载均衡主要分为四层和七层负载均衡,对应osi七层模型的四层和七层:

四层负载均衡工作在OSI模型的传输层,由于在传输层,只有TCP/UDP协议,这两种协议中除了包含源IP、目标IP以外,还包含源端口号及目的端口号。

四层负载均衡服务器在接受到客户端请求后,以后通过修改数据包的地址信息(IP+端口号)将流量转发到应用服务器。

七层负载均衡工作在OSI模型的应用层,应用层协议较多,常用http、radius、dns等。七层负载就可以基于这些协议来负载。

公有云中的负载均衡:

SLB 阿里云负载均衡
QLB 青云负载均衡
CLB 腾讯云负载均衡
ULB ucloud负载均衡

常用的负载软件:

Nginx
Haproxy
LVS

总结

nginx在公司中有很多用途,本文主要讲解了nginx的原理,以及用来做缓存,动静分离,负载均衡的原理。

更多内容请关注:《linux基本功-系统服务实战》 专栏

💕 好啦,这就是今天要分享给大家的全部内容了,我们下期再见!
💕 博客主页:mufeng.blog.csdn.net
💕 本文由沐风晓月原创,首发于CSDN博客
💕 全力以赴,持续学习,不负如来不负卿,喜欢的话记得点赞收藏哦

有关【nginx原理】企业中使用nginx必须知道的那些事的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  3. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  4. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  5. ruby - 在 Ruby 中使用匿名模块 - 2

    假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于

  6. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  7. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  8. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  9. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  10. ruby - 在 64 位 Snow Leopard 上使用 rvm、postgres 9.0、ruby 1.9.2-p136 安装 pg gem 时出现问题 - 2

    我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po

随机推荐