Nginx的前世今生(一)

一、引言

风云起时:单体江湖的末路与Web服务器的新纪元

        在互联网行业的初期发展阶段,单体应用因其部署简便、维护成本低的特点,成为众多初创企业的首选架构。然而,随着业务的快速扩张和用户流量的激增,单体架构的局限性逐渐显现,尤其是单一服务器承载能力的瓶颈,频繁引发服务宕机,严重时甚至导致整个系统崩溃,无法满足用户请求,这迫切要求一种更加高效、可扩展的解决方案。

        在此背景下,负载均衡技术与高性能Web服务器的角色愈发重要。提及Web服务器,Apache与Nginx无疑是两个绕不开的名字,它们各具特色,服务于不同的应用场景,对互联网基础设施的发展产生了深远影响。

英雄出世:Igor Sysoev与Rambler Media的创世传奇

        Apache Web服务器,作为业界元老,凭借其稳定性、开源特性和跨平台能力,长期占据市场主导地位。诞生于互联网尚未全面爆发的年代,Apache的设计更偏向于功能全面与稳定性,却也因此背负上了“重量级”的标签。面对现代互联网高并发挑战,Apache采用的进程或线程模型在处理大规模并发连接时显得力不从心,内存消耗巨大且CPU资源因频繁上下文切换而效率低下,这限制了其在高性能场景下的应用潜力。

        正是在这样的技术痛点下,Nginx横空出世,由俄罗斯工程师Igor Sysoev(伊戈尔·西索耶夫)在Rambler Media工作期间用C语言精心打造。Nginx以其事件驱动、非阻塞的架构设计,有效解决了高并发下的性能瓶颈问题。它能够以极低的资源消耗处理成千上万的并发连接,不仅提升了HTTP请求的响应速度,还极大地提高了系统的整体吞吐量,成为新一代高性能Web服务器的代表。

        更为重要的是,Igor Sysoev决定将Nginx源代码开源,并赋予其自由软件许可证,这一举措极大地促进了Nginx的社区发展与技术创新,使其迅速在全球范围内获得了广泛的应用与认可,尤其是在需要处理大量并发连接的场景下,如CDN、API网关、微服务架构的反向代理等。

nginx之父

 武林至尊:Nginx在互联网江湖的显赫地位

        根据最近的数据,Nginx目前是全球最受欢迎的Web服务器之一,特别是在世界排名前1万家网站中,Nginx的占有率高达34.3%。这一数据直接反映了Nginx在顶级网站和高流量平台中的广泛应用。Nginx在技术社区中享有极高的声誉,其开源特性、高性能、轻量级设计以及强大的可扩展性赢得了广泛的赞誉。开发者和技术博客中频繁讨论Nginx的配置优化、负载均衡、动静分离等高级特性,显示了其技术领域的活跃度和影响力。

        包括BAT(百度、阿里巴巴、腾讯)在内的许多国内外大型互联网企业均采用了Nginx作为其核心Web服务器或反向代理服务器,体现了其在高并发、高性能需求场景下的可靠性与高效性。Nginx不仅限于Web服务器的角色,其在反向代理、负载均衡、动静分离、SSL终止、缓存策略、防盗链保护、IP黑白名单管理、跨域配置等方面展现了全面的功能集合,几乎覆盖了Web服务的所有关键需求,为开发者提供了高度的灵活性和定制空间。

        Nginx不断推出新版本,引入新技术特性,如改进的HTTP/2支持、TLS 1.3的快速采用、以及对现代微服务架构的支持,这些都证明了其在技术演进中的领先地位。围绕Nginx形成了庞大的生态系统,包括丰富的插件、模块、工具以及大量的文档和教程,这降低了学习和使用门槛,促进了其在不同行业和应用场景中的普及。

        随着互联网业务的不断进化,Web服务器的选择与优化成为了提升系统性能、确保服务稳定的关键。Apache以其历史积淀和全面功能继续在特定领域发光发热,而Nginx则凭借其轻量级、高并发处理能力,成为支撑现代互联网高可用架构的重要基石。两者各展所长,共同推动着互联网技术的不断进步与革新

特性/服务器NginxApache (Prefork/Worker)Lighttpd
并发处理能力中/中高(取决于MPM)
内存效率中(Worker MPM较高)
静态内容处理非常好非常好
动态内容处理好(通过FastCGI等)非常好(尤其是mod_php)
事件驱动模型异步非阻塞阻塞/非阻塞(取决于MPM)异步非阻塞
资源消耗(CPU/内存)低/低中/中高低/低
社区支持与模块非常活跃,模块丰富非常活跃,历史悠久活跃,但相比Nginx和Apache较小
适用场景高并发、静态资源、反向代理通用服务器,尤其是动态内容处理轻量级服务、资源受限环境

二、初窥门径:剑庐练剑 

1.代理双绝:正向如龙,反向似凤

正向代理,匿形于市井,游走于江湖

        想象你住在一个小区里,小区管理规定居民不能直接外出购物,而是需要通过小区的“代购中心”来帮忙买东西。这个“代购中心”就像是正向代理。

                你,就像是互联网上的客户端,比如你的电脑或者手机。你想买一本新书,但是按照规定不能直接去书店。

        代购中心,就是正向代理,它位于你和书店之间。你告诉代购中心你需要的书名和作者,相当于你在浏览器中输入网址想要访问某个网站。

        接下来,代购中心根据你的需求,也就是你的请求,它自己去书店(目标服务器)帮你找这本书。书店并不直接和你交流,它只看到代购中心来购买,不知道是你想要这本书。

        最后,当书店找到了书,它会把书交给代购中心,代购中心再把书带回小区给你。这样,你就间接地通过代购中心得到了想要的书,而书店并不知道实际的买家是谁。

        简单来说,正向代理就是一个中间人,它代替你去访问网络上的其他地方,然后再把得到的信息或服务带回来给你,这样做的好处可能包括保护你的隐私、帮助你访问原本可能受限的内容,或者提高访问速度等。

        从技术角度来讲述,正向代理就是位于客户端和目标服务器之间的代理服务器,它主要用于代表客户端访问外部网络资源。在这一过程中,客户端明确知道正向代理的存在,并将所有的请求发送给代理,代理接收这些请求后,再向目标服务器发起请求,最后将从目标服务器获取的响应返回给客户端。这一机制常用于访问控制、身份验证、数据缓存以及突破网络限制等场景。

        在Nginx中配置正向代理,你通常需要在Nginx配置文件(通常是nginx.conf)中定义一个代理服务器块,指定代理的转发规则。以下是一个简单的Nginx正向代理配置示例:

http {
    proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=my_cache:10m inactive=60m;
    
    server {
        listen 8080;
        
        location / {
            proxy_pass http://$http_host$request_uri;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_cache my_cache;
            proxy_cache_bypass $http_pragma;
            proxy_no_cache $http_pragma;
        }
    }
}

        在这个例子中,Nginx监听8080端口,任何到达此端口的请求都会被当作正向代理请求处理,通过proxy_pass指令转发到目标服务器。同时,通过设置proxy_set_header指令,可以传递客户端的原始请求头信息,以便目标服务器能够识别客户端的部分信息。这种模式下,目标服务器看到的请求源头是代理服务器的IP地址,而不是实际客户端的地址,除非代理服务器特意转发了客户端的IP信息。

反向代理,藏锋于幕后,调度于无形

        想象一下你经营了一家非常受欢迎的餐厅,但由于厨房太小,你决定在城市的另一端开设一个更大的、专门的厨房来准备食物。然而,你不想让顾客知道食物不是现场制作的。于是,你设置了一个“前台接待处”,这个接待处就相当于Nginx的反向代理。

        顾客,就像是互联网上的用户,他们来到你的餐厅(访问你的网站)想要点餐(请求网页或者其他服务)。

        前台接待处,就是Nginx作为反向代理的角色,它接收顾客的订单(接收用户的请求),但并不直接准备食物(处理请求)。

        秘密厨房,则是你的后台服务器,比如Tomcat、Apache等,它们位于内部网络,负责处理实际的烹饪工作(数据处理和生成响应)。

过程如下:

  1. 顾客走进餐厅,向前台接待处点菜,顾客并不知道食物来自哪里。
  2. 前台接待处(Nginx反向代理)接收订单后,悄悄地将订单传给了秘密厨房
  3. 秘密厨房接收到订单后开始准备食物,完成后将做好的菜肴交还给前台接待处
  4. 前台接待处接过菜肴,就像自己做的一样,直接端给顾客,顾客享受美食,对整个过程浑然不觉。

        通过这样的设置,顾客只知道前台接待处,而不知道也不必关心食物是如何准备的,这就保护了你的厨房(服务器)信息,同时还能根据需要灵活地分配任务,比如高峰期时可以添加更多的厨房来处理订单,提高效率。

        从技术角度讲,反向代理(Reverse Proxy)是一种服务器部署架构,其中代理服务器位于客户端(用户)与目标服务器(如Web服务器、应用服务器)之间,但对外表现得像是目标服务器本身。客户端发起请求时,实际上连接的是反向代理服务器,该服务器接收请求后,根据配置规则,将请求转发给内部网络中的一个或多个目标服务器。目标服务器处理完请求后,将响应返回给反向代理,反向代理再将响应转发给客户端,使得客户端感觉就像直接与目标服务器交互一样。

nginx的反向代理的配置如下

upstream nginx_boot{  
   # 30s内检查心跳发送两次包,未回复就代表该机器宕机,请求分发权重比为1:2  
    # 这里的IP请配置成你WEB服务所在的机器IP 
   server 127.0.0.1:8080 weight=100 max_fails=2 fail_timeout=30s;   
   server 127.0.0.1:8090 weight=200 max_fails=2 fail_timeout=30s;  
    
}  
  
server {  
    location / {  
        root   html;  
        # 配置一下index的地址
        index  index.html index.htm;  
        proxy_set_header Host $host;  
        proxy_set_header X-Real-IP $remote_addr;  
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  
        # 请求交给名为nginx_boot的upstream上  
        proxy_pass http://nginx_boot;  
    }  
}

反向代理的主要作用和好处包括:

  1. 负载均衡(Load Balancing):反向代理可以将接收到的请求分配给后端的不同服务器,确保没有单一服务器过载,提高了系统的稳定性和扩展性。这有助于应对高流量场景,避免服务中断。

  2. 安全性和访问控制:作为外部访问内部服务器的第一道防线,反向代理可以实施安全策略,如SSL/TLS卸载(处理加密解密)、执行身份验证、过滤恶意请求等,有效防护DDoS攻击和其它安全威胁。

  3. 隐藏真实服务器地址:通过作为前端接收所有外部请求,反向代理可以隐藏后端服务器的真实IP地址和结构,增加了系统的安全性,防止直接针对服务器的攻击。

  4. 缓存静态内容:反向代理可以缓存经常请求的静态资源(如图片、CSS、JavaScript文件),减少对后端服务器的请求次数,提升网站响应速度和用户体验。

  5. 服务治理:便于管理和监控后端服务状态,例如进行健康检查、自动故障转移、服务降级等操作,增强服务的可靠性和稳定性。

  6. 内容路由和修改:反向代理可以根据请求的内容、来源等信息,动态地将请求路由到不同的后端服务,或者在转发前对请求或响应内容进行修改,以适应特定的业务需求。

  7. 加速内容分发:与CDN(内容分发网络)结合使用时,反向代理可以作为边缘节点,帮助加速内容的全球分发。

        通过以上机制,反向代理不仅提高了网站或服务的性能、可用性和安全性,还为系统架构提供了灵活性和可扩展性,是现代互联网基础设施中不可或缺的一部分。

2.负重前行:均衡之道,力扛千钧

负载均衡,分担压力,武林大会的秩序守护者

        随着互联网的发展,网站和应用的访问量急剧增长,单个服务器难以承受高并发访问的压力,容易导致服务崩溃、响应缓慢等问题。为了提高系统的可用性和扩展性,负载均衡技术应运而生。它通过将流量分散到多个服务器上,有效分摊请求压力,提升整体处理能力,同时提供故障切换机制,确保即使部分服务器出现故障,服务依然可以正常运行。

        想象凯叔是一名超级忙碌的程序员,每天都要处理大量工作任务,比如修复bug、开发新功能、回复同事邮件等。一开始,所有的任务都堆在他一个人身上,就像一个没有负载均衡的服务器,独自承受所有请求。凯叔很快就发现自己加班到深夜,效率也开始下降,甚至有时候因为过于疲惫,有些任务处理得不够及时,这就好比服务器过载导致响应慢或服务中断。

        后来,英明果敢,气宇不凡的领导们意识到这个问题,决定实施“负载均衡”。他们招入了几个新程序员小王、小李和小赵,组成了一个小团队。现在,每当有新的工作任务进来,领导(相当于负载均衡器)会根据每个人当前的工作量和擅长的领域,智能地分配任务。比如,小王擅长处理数据库问题,新来的数据库相关bug就优先给他;小李对前端开发熟练,前端的需求就交给他。这样一来,每个程序员都能在自己擅长且当前负担不重的领域高效工作。

        通过这样的“负载均衡”,凯叔和他的团队成员都不再过度劳累,任务完成得更快,团队的整体工作效率大幅提升,而且还能保证每个任务都能得到及时且高质量的处理。更重要的是,即便某位程序员临时请假(相当于服务器故障),因为有其他人可以接手工作,整个团队的运作不会受到影响,保证了工作的连续性和系统的稳定性。

        这就是负载均衡的基本概念,即通过合理分配任务(或网络请求)到多个处理单元(如服务器、工作人员),确保没有单一节点过载,从而提升整体系统的响应速度和可用性。

        Nginx实现负载均衡主要依赖于其内置的upstream模块。这个模块允许Nginx配置一组后端服务器,并定义请求分发的策略。当客户端请求到达Nginx时,Nginx会根据预先设定的策略,将请求转发给后端服务器池中的某一台服务器进行处理。这一过程涉及到以下几个关键技术点:

  1. 配置上游服务器池(upstream block):在Nginx配置文件中,通过upstream关键字定义一个或多个后端服务器集合,列出服务器的地址和端口,以及可选的权重值。

  2. 负载均衡策略:Nginx支持多种负载均衡算法,包括但不限于:

    • 轮询(Round Robin):这是默认策略,按照顺序轮流分配请求给后端服务器。
    • 最少连接(Least Connections):将请求分配给当前活动连接数最少的服务器。
    • IP哈希(IP Hash):根据客户端IP地址的哈希值分配请求,保证来自同一IP的请求总是被转发到同一后端服务器,适用于保持会话一致性。
    • 加权轮询、加权最少连接:在基本策略上增加权重因素,根据服务器的处理能力调整分配比例。
  3. 健康检查:Nginx可以配置健康检查,定期检查后端服务器的状态,自动移除不可达的服务器,确保请求不会被转发到故障服务器上。

以下是一个简单的Nginx负载均衡配置示例,使用轮询策略:

http {
    upstream backend {
        server backend1.example.com;
        server backend2.example.com;
        server backend3.example.com;
    }

    server {
        listen 80;

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

 通过负载均衡我们能得到很多好处:

  1. 提升性能和吞吐量:通过分发请求到多个服务器,有效利用服务器资源,提升整体处理能力和响应速度。
  2. 增强可靠性:当某台服务器故障时,流量可以自动转移到其他健康的服务器,减少服务中断的风险。
  3. 可扩展性:轻松添加或移除服务器,根据需求动态调整服务器资源,满足业务增长需求。
  4. 优化用户体验:通过降低延迟和避免服务器过载,确保用户能够快速、顺畅地访问服务。
  5. 简化管理:对外提供统一的入口,简化运维工作,方便进行维护和监控。
策略万千,轮转乾坤,轻重之间,尽显高手风范

        Nginx 支持多种负载均衡策略,这些策略旨在根据不同的需求和场景,高效且智能地分发客户端请求到后端服务器。

        1.均力旋风阵:轮询(Round Robin)

        这是最基本的负载均衡策略,也是Nginx的默认策略。请求按照顺序轮流分配给后端服务器,每个服务器依次处理请求。例如,如果有三个服务器A、B、C,第一次请求分配给A,第二次给B,第三次给C,然后再次轮到A,如此循环。

upstream force_even_circle {
    server server1.example.com;
    server server2.example.com;
    server server3.example.com;
}

        2.权衡天秤阵:加权轮询(Weighted Round Robin)

         在轮询的基础上,为每个后端服务器分配一个权重值。权重较高的服务器将被分配更多的请求。例如,服务器A权重为2,服务器B权重为1,那么每处理两次A的请求后,才会处理一次B的请求。

upstream weighted_scales {
    server server1.example.com weight=3;
    server server2.example.com weight=1;
    server server3.example.com;
}

        3.轻载飘逸步:最少连接(Least Connections)

        将请求分配给当前活动连接数最少的服务器,以达到更均衡的负载分布。这种策略适合处理请求处理时间不一致的情况,确保繁忙的服务器不会被进一步加重负担。

upstream lightfoot_strategy {
    least_conn;
    server server1.example.com;
    server server2.example.com;
    server server3.example.com;
}

        4.一脉同源锁:IP哈希(IP Hash)

        根据客户端的IP地址进行哈希运算,确保来自同一IP的请求始终被转发到同一个后端服务器。这种方法有助于维持用户会话的连贯性,适用于需要会话粘性的应用场景。

upstream consistent_bond {
    ip_hash;
    server server1.example.com;
    server server2.example.com;
    server server3.example.com;
}

        5.权重云游行:加权最少连接(Weighted Least Connections)

        结合了权重和最少连接两种策略,服务器不仅根据当前连接数选择,还会考虑其权重值,使得权重高的服务器在连接数较少时更有可能被选中。

upstream weighted_wanderers {
    least_conn;
    server server1.example.com weight=5;
    server server2.example.com weight=3;
    server server3.example.com;
}

        6.智判流云诀:fair(第三方模块)

        这是第三方模块提供的策略,它根据后端服务器的响应时间动态分配请求,响应时间短的服务器优先接收请求。此策略要求安装额外的模块,如ngx_http_upstream_fair模块,以实现更智能的负载分配。

upstream weighted_wanderers {
    least_conn;
    server server1.example.com weight=5;
    server server2.example.com weight=3;
    server server3.example.com;
}

 具体想要了解其中的机理和算法的,可以参考知乎上一篇文章:nginx负载均衡的5种策略及原理 - 知乎

三、登堂入室:内功心法

1.两界,剑影舞动

        Nginx动静分离技术是一种Web服务器优化策略,它将网站的静态资源(如HTML、CSS、JavaScript、图片、视频等)与动态内容(如通过脚本生成的页面、API接口返回的数据等)分离开来,分别由不同的服务器或服务器的不同部分处理。这一技术主要依赖于Nginx强大的反向代理和静态内容处理能力。

        想象一下凯叔是一名忙碌的帅气的苦逼程序猿,在一家伟大的公司创造价值,他的日常任务涵盖了编写代码(动态内容)和处理文档、图片等(静态内容)。

        动态内容:就像凯叔每天写的代码,这部分工作是高度个性化的,每次有新的需求或者bug修复,代码都会有所变化,需要跑在开发环境或服务器上才能看到效果,就像是网页上的用户登录、购物车结算等功能,每次访问可能结果都不一样,因为涉及到数据库查询、用户交互等动态过程。

        静态内容:则是凯叔准备的文档、设计图、教程视频等,这些内容一旦创建完成,除非有特别的理由,否则不会频繁改动。就像网站上的logo、页面布局的CSS样式、按钮的点击效果JavaScript代码等,用户每次访问这些内容都是相同的,不需要服务器再次计算生成。

        Nginx的动静分离就像是公司里有个超级高效的行政助理小N,小N非常擅长安排工作:

  • 当有访客(用户请求)来询问关于公司的介绍手册(静态内容)时,小N(Nginx)直接从文件柜(静态文件存储)取出手册给访客,迅速又高效,不用麻烦凯叔。

  • 如果访客想要提交订单或查看个性化推荐(动态内容),小N知道这些活儿得找凯叔,于是迅速把访客带到凯叔的办公桌(后端应用服务器),让凯叔亲自处理这些需要计算和处理的任务。

        通过这种方式,小N(Nginx)确保了凯叔(应用服务器)可以把更多精力放在处理复杂多变的编程任务上,而不被频繁的静态资源请求打扰,同时也大大提高了访客获取信息的速度和体验。这就是Nginx动静分离技术的通俗解释,通过区分并高效处理不同类型的请求,提升了整个网站的性能和响应速度。

静若处子,动如脱兔,Nginx的太极剑法

         在没有动静分离的情况下,用户的请求无论是对静态资源还是动态内容,都直接发送到应用服务器(如Apache、Tomcat等),由应用服务器统一处理。而在动静分离架构中,Nginx作为前端服务器,负责接收所有用户请求。Nginx根据请求的类型和预设的规则,将请求分流:

  • 静态请求:Nginx直接从静态资源存储位置(如本地文件系统、CDN等)返回静态文件,无需经过后端应用服务器。
  • 动态请求:Nginx将请求转发给后端的应用服务器(如通过FastCGI传递给PHP-FPM,或者直接代理到Java/Tomcat应用服务器),由应用服务器处理后返回动态内容。

        动静分离带来的好处:

  1. 性能提升:静态资源通常可以直接从Nginx缓存或快速的静态文件服务器返回,减少了应用服务器的负担,提高了响应速度和并发处理能力。

  2. 资源优化:静态资源可以被更有效地缓存,无论是浏览器缓存还是CDN缓存,这减少了网络传输和服务器处理的开销。

  3. 服务稳定性:即使后端应用服务器出现问题,静态资源仍然可以通过Nginx正常提供,保证了网站的基本可用性。

  4. 可扩展性和灵活性:动静分离使得架构更加模块化,静态资源和动态应用可以独立扩展,易于管理和维护。

  5. API接口服务化:动态请求的集中处理促使后端应用更加服务化,专注于提供API接口,有利于微服务架构的实施和跨平台服务的复用。

  6. 安全性增强:通过限制直接对应用服务器的访问,可以减少安全风险,提高系统的安全性。

分而治之,效率倍增,动静分离的真谛

        假设有一个电商网站,它包含大量商品图片、CSS样式、JavaScript脚本等静态资源,同时还有购物车、用户登录、商品详情页等动态内容。为了提高网站性能和稳定性,可以采用Nginx动静分离的架构:

  • 静态资源:如图片、CSS、JS等,存储在专门的静态文件服务器或者Nginx服务器的本地目录中。
  • 动态内容:如商品详情、用户会话管理等,由后端应用服务器(如Apache、Tomcat、Node.js等)处理。
server {
    listen 80;
    server_name example.com;

    # 静态资源处理
    location ~* \.(jpg|jpeg|png|gif|css|js|ico|xml)$ {
        root /var/www/static; # 静态资源存放目录
        expires 7d; # 设置静态资源浏览器缓存时间为7天
        access_log off; # 关闭静态资源的访问日志,减少磁盘IO
    }

    # 动态内容代理到后端应用服务器
    location / {
        proxy_pass http://127.0.0.1:8080; # 后端应用服务器地址,例如Tomcat
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
  • location 指令用于匹配URL路径,并基于匹配结果执行相应的操作。
  • 第一个 location 块使用正则表达式匹配常见的静态资源文件扩展名,当请求匹配这些扩展名时,Nginx直接从指定的静态文件目录 /var/www/static 提供服务,并设置了7天的浏览器缓存过期时间。
  • 第二个 location 块是一个通用块,用于匹配所有未在前面定义的请求,这些请求会被代理到后端应用服务器(例如运行在本机8080端口的Tomcat服务器)。这里还设置了几个代理相关的头部信息,以便正确传递客户端的请求信息给后端。

         Nginx能够高效地处理静态资源请求,并将动态内容请求转发给后端应用服务器,实现了动静分离,从而提高了网站的响应速度和整体性能。

2.缩骨易容,资源瘦身

        Nginx的GZIP压缩是指Nginx服务器利用内置的ngx_http_gzip_module模块,在向客户端发送响应数据前,自动对文本类数据(如HTML、CSS、JavaScript等)进行GZIP算法压缩的过程。

        想象一下苦逼程序猿凯叔在一家伟大的公司上班,他的工作涉及到上传大量的代码文件到公司网站上。这些文件包括HTML页面、CSS样式表、JavaScript脚本等。没有使用GZIP压缩时,这些文件就像是一箱箱未打包的书,体积大、占用空间多,运输起来既费时又费力。

         启用GZIP压缩后,凯叔的工作流程就像这样:

  • 凯叔编写好代码后,需要把这些“书籍”(文件)上传到公司的服务器(相当于仓库)。现在,服务器有了一个智能助手——Nginx,它装备了GZIP压缩技能。
  • 当有人(用户浏览器)想要获取这些书籍(文件)时,Nginx先检查这位访客是否携带了“我接受压缩包裹”的便签(即Accept-Encoding: gzip),确认后,Nginx不直接发送原书,而是用GZIP压缩机将书籍压缩成小体积的“压缩包”。
  • 这些压缩包体积小,更容易快递(网络传输),而且速度更快,减少了等待时间。
  • 用户的电脑收到这些压缩包后,就像拥有了解压工具的读者,能迅速打开阅读,也就是浏览器自动解压缩并展示网页内容。

        这样一来,凯叔的工作效率看似没变,但实际上,由于文件传输变得更快,用户反馈问题和请求新功能的周期缩短,凯叔可以更快地迭代产品,间接提升了工作效率,也让用户获得了更流畅的浏览体验。

Gzip神功,一掌压缩,信息流转无阻

        随着互联网资源传输过程中,尤其是对于文本类的文件(如HTML、CSS、JavaScript、XML等),其原始大小往往比压缩后的体积大得多。在网络带宽成本仍然显著的背景下,减少数据传输量可以显著降低运营成本。为了提高加速页面加载:用户感受到的网页加载速度与文件下载时间直接相关。通过压缩减小文件大小,可以缩短文件传输时间,从而加快页面的加载速度,提升用户体验。为了更好地网络条件适应性:在移动网络或带宽受限的环境下,数据压缩尤为重要。它可以确保用户即使在低速网络下也能较快地获取内容。

        现代浏览器几乎都支持接受压缩过的数据(主要通过gzip或brotli算法)。服务器可以根据客户端请求头中的Accept-Encoding字段判断是否支持压缩,并相应地发送压缩后的数据。

        Gzip整个压缩的过程包括:

  1. 客户端请求时声明支持:当用户的浏览器发送HTTP请求时,在Request Header中包含Accept-Encoding: gzip,表明该浏览器支持接收GZIP压缩过的数据。
  2. 服务器端判断与压缩:Nginx服务器接收到请求后,根据配置检查是否开启GZIP压缩以及请求内容是否符合压缩条件(比如文件大小超过最小压缩长度)。如果满足条件,服务器会对响应内容执行GZIP算法压缩。
  3. 数据传输:压缩后的数据会伴随着响应头中的Content-Encoding: gzip发送给浏览器。
  4. 客户端解压显示:浏览器接收到GZIP压缩的数据后,识别Content-Encoding: gzip,然后解压缩数据,最终渲染页面或处理数据。
轻装上阵,快人一步,优化之旅

        Nginx通过集成的ngx_http_gzip_module模块实现这一功能,管理员只需在Nginx配置文件中启用并适当配置gzip相关指令,即可实现对符合条件的响应内容进行压缩,从而达到上述的技术优势。压缩可以保证轻装上阵,快人一步。

  1. 减少网络传输时间:压缩减少了数据在网络中的传输时间,尤其是在高延迟的网络环境中,这种效果更为明显。

  2. 降低服务器负载:虽然压缩操作会占用CPU资源,但相比于未压缩情况下更多的网络传输和潜在的重传,整体上可以减轻服务器的负载,特别是对于高流量站点,压缩可以减少服务器需要处理的请求数量。

  3. 提升用户体验:快速加载的页面能够提升用户满意度,减少跳出率,对电子商务、新闻门户等依赖用户互动的网站尤其重要。

  4. 节能减排:减少数据传输量意味着在互联网基础设施中消耗的能源减少,有助于实现绿色IT目标。

  5. 增强系统扩展性:由于压缩可以减少数据传输量,这在一定程度上帮助网站更好地应对高流量冲击,更容易进行水平扩展。

http {
    # 开启gzip压缩
    gzip on;

    # 启用gzip压缩的最小文件大小,单位为字节,默认为256字节
    gzip_min_length 1024;

    # gzip压缩级别,1-9,数字越大压缩程度越高,CPU消耗也越大,默认为1
    gzip_comp_level 5;

    # 压缩类型,默认已经包含了很多类型,可以按需添加或删除
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    # 是否在http header中添加Vary: Accept-Encoding,建议开启,以便代理服务器正确缓存
    gzip_vary on;

    # 对于旧版本的IE浏览器禁用gzip,避免兼容性问题
    gzip_disable "MSIE [1-6]\.";

    # 设置用于gzip压缩的缓冲区大小,第一个数字表示缓冲区的数量,第二个数字表示每个缓冲区的大小
    gzip_buffers 4 16k;

    # 设置gzip压缩针对的HTTP协议版本
    gzip_http_version 1.1;
}

这个配置示例做了以下设置:

  • 开启了Gzip压缩。
  • 指定只有大于1KB的响应内容才会被压缩。
  • 设置了中等的压缩级别(5),以平衡压缩效率和CPU使用。
  • 指定了需要压缩的内容类型,涵盖了大部分文本和脚本文件。
  • 启用了Vary: Accept-Encoding,以便代理服务器和浏览器能够正确处理缓存。
  • 禁用了对旧版IE浏览器的Gzip压缩,避免潜在的兼容性问题。
  • 配置了Gzip使用的缓冲区大小。
  • 指定了使用HTTP/1.1版本的Gzip压缩。

完成配置后,需要重新加载或重启Nginx以使更改生效。你可以使用命令 nginx -s reload 来重新加载配置文件,而不需要中断服务。记得在进行任何配置更改之前备份原有的配置文件,以防万一。

  • 14
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值