Nginx用作 内网CDN / edge cache 服务

news2024/11/28 23:54:58

文章目录

    • 什么是CDN?
    • 为什么需要 内网CDN/edge cache?
    • Nginx配置
      • Edge Cache服务配置
      • 简单静态文件缓存服务配置
      • 缓存控制
      • $upstream_cache_status
      • Gzip压缩
    • 参考

什么是CDN?

首先要明白什么是CDN?

CDN英文全称Content Delivery Network,中文翻译即为内容分发网络。它是建立并覆盖在承载网之上,由不同区域的服务器组成的分布式网络。将源站资源缓存到全国各地的边缘服务器,供用户就近获取,降低源站压力。

CDN应用广泛,支持多种行业、多种场景内容加速,例如:图片小文件、大文件下载、视音频点播、直播流媒体、全站加速、安全加速。

加速原理如下

以下内容来着阿里云

假设您的加速域名为www.aliyundoc.com,接入CDN开始加速服务后,当终端用户在北京发起HTTP请求时,处理流程如下图所示。原理

  1. 当终端用户向www.aliyundoc.com下的指定资源发起请求时,首先向Local DNS(本地DNS)发起请求域名www.aliyundoc.com对应的IP。
  2. Local DNS检查缓存中是否有www.aliyundoc.com的IP地址记录。如果有,则直接返回给终端用户;如果没有,则向网站授权DNS请求域名www.aliyundoc.com的解析记录。
  3. 当网站授权DNS解析www.aliyundoc.com后,返回域名的CNAME www.aliyundoc.com.example.com
  4. Local DNS向阿里云CDN的DNS调度系统请求域名www.aliyundoc.com.example.com的解析记录,阿里云CDN的DNS调度系统将为其分配最佳节点IP地址。
  5. Local DNS获取阿里云CDN的DNS调度系统返回的最佳节点IP地址。
  6. Local DNS将最佳节点IP地址返回给用户,用户获取到最佳节点IP地址。
  7. 用户向最佳节点IP地址发起对该资源的访问请求。
    • 如果该最佳节点已缓存该资源,则会将请求的资源直接返回给用户(步骤8),此时请求结束。
    • 如果该最佳节点未缓存该资源或者缓存的资源已经失效,则节点将会向源站发起对该资源的请求。获取源站资源后结合用户自定义配置的缓存策略,将资源缓存到CDN节点并返回给用户(步骤8),此时请求结束。

从这个例子可以了解到:

  1. CDN的加速资源是跟域名绑定的。
  2. 通过域名访问资源,首先是通过DNS查找离用户最近的CDN节点(边缘服务器)的IP
  3. 通过IP访问实际资源时,如果CDN上并没有缓存资源,则会到源站请求资源,并缓存到CDN节点上,这样,用户下一次访问时,该CDN节点就会有对应资源的缓存了。

简单讲,CDN就是通过将站点内容发布至遍布全球的海量加速节点,使其用户可就近获取所需内容。

CDN主要解决什么问题?

  • 物理距离远,多次网络转发,延时高不稳定;
  • 所在运营商不同,需运营商之间转发绕行;
  • 高并发访问时,网络带宽处理能力有限,海量请求时,响应速度与可用性降低。
  • 高并发下载或者下载突增场景下对源站性能要求非常高,且源站的带宽成本也较高。

为什么需要 内网CDN/edge cache?

我来说一种场景,当大型公司或者学校等大型单位在观看直播时,其总的出口带宽是有限的,当有很多人同时在看直播时会把总出口带宽拉满。

优化前

通过中间加个cache层优化后

Nginx配置

我们使用Nginx作为edge cache,配置NGINX的缓存策略就可以,不需要额外插件,NGINX本身就支持:

Edge Cache服务配置

启用基本缓存只需要两个指令:proxy_cache_pathproxy_cache

worker_processes auto; # 建议设置为cpu核心数 grep processor /proc/cpuinfo | wc -l
events{
    worker_connections 1024; # 配置可以同时处理的连接数,注意文件描述符的限制
}
http {
    keepalive_timeout 65; # 对于高流量的服务,最好设置一个较低的超时值,以便释放等待新请求的连接。
    # For Proxy Cache.
    # 用于缓存位置和缓存验证时间
    proxy_cache_path  /path/to/cache levels=1:2 keys_zone=nginx_cache:10m max_size=10g inactive=60m use_temp_path=off;
    #proxy_temp_path /tmp/nginx-cache/tmp; 

    server {
        listen       8085;
        #定义缓存数据的有效期
        proxy_cache_valid  404 10s;
        # 如果多个客户端请求缓存中不存在的文件,
        proxy_cache_lock on;
        proxy_cache_lock_age 300s;
        proxy_cache_lock_timeout 300s;
        # 定一个文件至少需要被用户访问多少次以后,才会被缓存,默认1
        proxy_cache_min_uses 1;
        
		proxy_cache_methods GET HEAD POST;
        
        location ~ /.+/.*\.(m3u8)$ {
            proxy_pass http://hls;
            # For Proxy Cache.
            proxy_cache nginx_cache;
            # 指定缓存的key的名称
            proxy_cache_key $scheme$proxy_host$uri$args;
            # 如果 NGINX从源服务器接收到error、timeout或任何指定的错误,并且它的缓存中有请求文件的陈旧版本,它会传送陈旧文件而不是将错误中继到客户端。
            #proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;
            proxy_cache_valid  200 302  10s;
        }
        location ~ /.+/.*\.(ts)$ {
            proxy_pass http://hls;
            # For Proxy Cache.
            proxy_cache nginx_cache;
            proxy_cache_bypass $http_cache_control;
            proxy_cache_key $scheme$proxy_host$uri;
            proxy_cache_valid  200 302  60m;
            proxy_read_timeout 120s;
            proxy_cache_lock on;
            proxy_cache_min_uses 3;
            proxy_cache_revalidate on;
            # 可以在响应header中查看是否名字缓存
            add_header X-Proxy-Cache $upsteam_cache_status;
        }
   
    }
    upstream hls {
        server www.laker.com; #原始的源网站地址
        server host2.example.com;
    }
}

proxy_cache_path指令的参数

  • /path/to/cache/:缓存的本地磁盘目录
  • levels:**在/path/to/cache/**下设置两级目录层次结构。在单个目录中拥有大量文件会减慢文件访问速度,因此我们建议对大多数部署使用两级目录层次结构。如果levels不包含该参数,NGINX 会将所有文件放在同一目录中。
    • Nginx会基于一个键值(在下面有定义)哈希生成一个缓存键(cache key),该键的最后一个字母作为一级目录名,倒数第二、三个字母作为二级目录名。
    • 1:2 1:表示一级目录可以由1个字符来构成,2:表示二级目录可以由2个字符来构成示缓存结果示例:/data/nginx/cache/c/29/c86156f7dcfecf44876ca30d1bac7feb
  • keys_zone:设置一个共享内存区域来存储缓存键和元数据。在内存中拥有key的副本使 NGINX 能够快速确定请求是 HIT 还是 MISS,而无需转到磁盘,从而大大加快了检查速度。 一个 1 MB 的区域可以存储大约 8,000 个键的数据,因此示例中配置的 10 MB 区域可以存储大约 80,000 个键的数据。
  • max_size:设置缓存大小的上限(本例中为 10 GB)。它是可选的;不指定值允许缓存增长以使用所有可用磁盘空间。当缓存大小达到限制时,一个称为缓存管理器的进程会删除最近最少使用的文件,以使缓存大小恢复到限制以下。
  • inactive:指定项目在不被访问的情况下可以保留在缓存中的时间。在此示例中,缓存管理器进程会自动从缓存中删除 60 分钟未请求的文件,而不管它是否已过期。默认值为 10 分钟 ( 10m)。无效内容不同于过期内容。NGINX 不会自动删除缓存控制标头定义的已过期内容(Cache-Control:max-age=120)。过期(陈旧)的内容只有在 指定的时间内未被访问时才会被删除inactive。当访问过期内容时,NGINX 会从源服务器刷新它并重置inactive计时器。
  • use_temp_path=off:NGINX 首先将要缓存的文件写入一个临时存储区,off指示NGINX 将它们写入将要缓存的相同目录。我们建议您将此参数设置为off以避免在文件系统之间进行不必要的数据复制。

proxy_cache_key "$scheme$request_method$host$request_uri$is_args$args":定义了一个键值,即上述用于区分目录用的键值。通过该键值,Nginx可以判断一个客户端请求需要的内容是否可以直接从缓存里找给它。对于这个键值,我们用scheme(http或https)、HTTP请求方式、host和URI的组合来创建。

proxy_cache_valid:条目可以多次设置,定义缓存数据的有效期,时间长短取决于状态码(status code)。我们在这里为success(200 成功)和redirect(302 转发)保存10分钟的缓存,404的缓存1分钟。

proxy_cache_valid 200 302 10m;

proxy_cache_valid 404 1m;

proxy_cache_bypass:在这里设置为$http_cache_control变量,该变量包含一个指示符,说明客户端请求是否明确要求返回一个非缓存的“新鲜”结果。如果是,则Nginx不会从缓存区找回复给客户端,而是按照客户端的要求,从后端取新回复。这里不需要做其他的设置。

X-Proxy-Cache:将其设置为$upstream_cache_status。简单来说,这个变量显示了一个请求是命中了缓存、没命中缓存、还是被指定不使用缓存。这对于debug而言比较有用,对于客户端也有一些价值。

简单静态文件缓存服务配置

对于站点中不经常修改的静态内容(如图片,JS,CSS),可以在服务器中设置expires过期时间,控制浏览器缓存,达到有效减小带宽流量,降低服务器压力的目的。

http {
    proxy_cache_path /home/cache/data levels=1:2 keys_zone=static:1000m inactive=600m max_size=50G;
    proxy_temp_path /home/cache/temp;
   server {
		location ~ ^/(img|css|js|scripts|stylesheets|uploads)/ {
        	expires 1d;
        	access_log off;
       	 	proxy_buffering on;
       	 	proxy_cache static;
       	 	proxy_cache_key "$host$request_uri$is_args$args";
        	proxy_ignore_headers "Cache-Control" "Expires";
        	proxy_cache_min_uses 1;
        	proxy_cache_valid 200 24h;
        	proxy_cache_use_stale http_502 http_503 http_504;
        	proxy_hide_header Set-Cookie;
        	add_header X-Cache "$upstream_cache_status";
            // ...
            root /data/static/webapp;
        }
        
        location ~* ^.+\.(ico|gif|jpg|jpeg|png)$ {
 			# 关闭日志
 			access_log off;
			#过期时间为30天,
			#图片文件不怎么更新,过期可以设大一点,
			#如果频繁更新,则可以设置得小一点。
 			expires 30d;
 		}
        
        location ~ .*\.(js|css)$ {
			expires 10d;
		}

缓存控制

不缓存配置

在常用的缓存设置里面有两种方式,都是使用add_header来设置:分别为Cache-Control和Pragma。

location ~ .*\.(css|js|swf|php|htm|html )$ {
	add_header Cache-Control no-store;
    add_header Pragma no-cache;
}

http缓存规则由响应首部字段进行控制,其中的关键字段有ExpiresCache-ControlLast-ModifiedEtag 四个字段,ExpiresCache-Control用来确定确定缓存的存储时间,Last-ModifiedEtag则用来确定缓存是否要被更新,我们简单来看一下区别。

  • expires: HTTP1.0中用来控制缓存时间的参数,响应头包含日期/时间, 即在此时间之后,响应过期。
  • cache-control: HTTP1.1中用来控制缓存时间的参数
    • public: 表明响应可以被任何对象(包括:发送请求的客户端,代理服务器,等等)缓存。
    • private: 表明响应只能被单个用户缓存,不能作为共享缓存(即代理服务器不能缓存它)。
    • max-age=: 设置缓存存储的最大周期,相对于请求的时间缓存seconds秒,在此时间内,访问资源直接读取本地缓存,不向服务器发出请求。(与expires同时出现时,max-age优先级更高)
    • s-maxage=: 规则等同max-age,覆盖max-age 或者 Expires 头,但是仅适用于共享缓存(比如各个代理),并且私有缓存中它被忽略。(与expires或max-age同时出现时,s-maxage优先级更高)
    • no-store: 不缓存服务器响应的任何内容,每次访问资源都需要服务器完整响应
    • no-cache: 缓存资源,但立即过期,每次请求都需要跟服务器对比验证资源是否被修改。(等同于max-age=0)
  • Last-modified: 源头服务器认定的资源做出修改的日期及时间。精确度比Etag低。包含有If-Modified-Since或 If-Unmodified-Since首部的条件请求会使用这个字段。
  • Etag: HTTP响应头是资源的特定版本的标识符。

判断资源是否更新,需要客户端与服务器共同协作,客户端在首次拿到资源缓存后会存储Etag(若有)和Last-Modified(若有),在下次缓存过期时会将Etag写在请求头部中的If-None-Match中,将Last-Modified值写在请求头部中的If-Modified-Since中,服务端优先对Etag进行对比,然后再对比Last-Modified,完全通过后即视为缓存没有修改,有一项不通过则认为资源已被修改,缓存失效。

不同刷新的请求执行过程

  • 浏览器输入 URL 后回车:浏览器如果发现缓存中已经有这个文件了,则不继续请求,直接取缓存,所以速度最快。
  • F5:使用协商缓存,使用 If-Modify-since 询问服务器资源是否过期。
  • Ctrl+F5:强制刷新,会先把缓存清理掉,再去请求资源。

$upstream_cache_status

  • MISS– 在缓存中未找到响应,因此是从源服务器获取的。然后响应可能已被缓存。
  • BYPASS– 响应是从原始服务器获取的,而不是从缓存中获取的,因为请求与指令匹配proxy_cache_bypass然后响应可能已被缓存。
  • EXPIRED– 缓存中的条目已过期。响应包含来自源服务器的新内容。
  • STALE– 内容陈旧,因为原始服务器未正确响应,并且proxy_cache_use_stale已配置。
  • UPDATING– 内容过时,因为条目当前正在更新以响应先前的请求,并且proxy_cache_use_stale updating已配置。
  • REVALIDATED– 该proxy_cache_revalidate指令已启用,NGINX 验证当前缓存的内容是否仍然有效(If-Modified-SinceIf-None-Match)。
  • HIT– 响应包含直接来自缓存的有效、新鲜的内容。

Gzip压缩

# 开启gzip
gzip  on;
# 启用gzip压缩的最小文件,小于设置值的文件将不会压缩
gzip_min_length 1k;
# gzip 压缩级别,1-10,数字越大压缩的越好,也越占用CPU时间。一般设置1和2
gzip_comp_level 2;
# 进行压缩的文件类型。javascript有多种形式。其中的值可以在 mime.types 文件中找到。
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
# 是否在http header中添加Vary: Accept-Encoding,建议开启
gzip_vary on;
# 禁用IE 6 gzip
gzip_disable "MSIE [1-6]\.";
# 设置缓存路径并且使用一块最大100M的共享内存,用于硬盘上的文件索引,包括文件名和请求次数,每个文件在1天内若不活跃(无请求)则从硬盘上淘汰,硬盘缓存最大10G,满了则根据LRU算法自动清除缓存。
proxy_cache_path /var/cache/nginx/cache levels=1:2 keys_zone=imgcache:100m inactive=1d max_size=10g;

参考

  • https://www.nginx.com/blog/nginx-caching-guide/
  • https://www.digitalocean.com/community/tutorials/how-to-optimize-nginx-configuration
  • https://docs.nginx.com/nginx/admin-guide/content-cache/content-caching/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/416889.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Springboot基础学习之(十七):通过Shiro实现用户得到登录认证和授权

前几篇文章讲解了关于信息安全的另一框架Spring security ,今天趁热打铁基础的了解以下shiro这一框架。 什么是shiro? Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应…

c++11 标准模板(STL)(std::stack)(二)

定义于头文件 <stack> template< class T, class Container std::deque<T> > class stack;std::stack 类是容器适配器&#xff0c;它给予程序员栈的功能——特别是 FILO &#xff08;先进后出&#xff09;数据结构。 该类模板表现为底层容器的包装…

线索二叉树(前序,中序,后序线索化以及遍历)

其实在这之前我想了很久&#xff0c;这个线索化二叉树我个人感觉是比实现二叉链表要难&#xff0c;很抽象的一个东西。好了&#xff0c;话先不多说&#xff0c;老规矩&#xff0c;先上代码&#xff1a; #pragma once #include<stdio.h> #include<stdlib.h> #inclu…

std::inner_product与std::accumulate初始值设置踩坑

std::inner_product函数可以用于计算两个序列的内积。在这个函数中&#xff0c;我们需要传递四个参数&#xff1a;两个源序列的起始迭代器、一个初始值和一个二元函数对象。 std::inner_product函数将对两个源序列中的每个元素进行乘法运算&#xff0c;并将结果累加到初始值中…

FPGA基于XDMA实现PCIE X4通信方案 提供工程源码和QT上位机程序和技术支持

目录1、前言2、我已有的PCIE方案3、PCIE理论4、总体设计思路和方案5、vivado工程详解6、驱动安装7、QT上位机软件8、上板调试验证9、福利&#xff1a;工程代码的获取1、前言 PCIE&#xff08;PCI Express&#xff09;采用了目前业内流行的点对点串行连接&#xff0c;比起 PCI …

桥接设计模式解读

目录 问题引进 手机操作问题 传统方案解决手机操作问题 传统方案解决手机操作问题分析 桥接模式(Bridge)概述 基本介绍 原理类图 主要角色 桥接模式解决手机操作问题 桥接模式的注意事项和细节 常见的应用场景 问题引进 手机操作问题 现在对不同手机类型的不同品牌…

Mybatis(七)Mybatis的日志体系

在介绍Mybatis日志实现前&#xff0c;我们先了解下java的日志体系以及日志框架的发展&#xff0c;目前比较常用的日志框架有下面几个&#xff1a; 而JCL和SLF4J属于日志接口&#xff08;没有日志具体实现&#xff09;&#xff0c;提供统一的日志操作规范&#xff0c;而日志的实…

Halo博客建站实战以及问题汇总

目录 简介 特性 快速开始 安装步骤 环境准备 Docker-compose方式部署 问题汇总 mac端无法访问页面 页面登录提示账号密码错误 重装注意点 资料 官方文档 简介 Halo 强大易用的开源建站工具 特性 代码开源 我们的所有代码开源在 GitHub 上且处于积极维护状态&…

stata数据处理

stata数据处理–潘登同学的stata笔记 文章目录stata数据处理--潘登同学的stata笔记数据导入、导出使表格第一行成为变量标注(label)数据合并横向与纵向合并一对多与多对一横向合并缺失值处理查看缺失值替换缺失值缺失值填充离群值处理取对数的方法截尾处理、缩尾处理分组统计列…

银行数字化转型导师坚鹏:银行数字化转型痛点、路径与对策

银行数字化转型痛点、路径与对策课程背景&#xff1a; 很多银行存在以下问题&#xff1a; 不知道银行数字化转型&#xff1f; 不清楚数字化转型对银行发展有什么影响&#xff1f; 不知道数字化转型对银行有什么机遇&#xff1f; 学员收获: 学习银行数字化转型的发展现状与成…

2021四川省icpc省赛H题 Nihongo wa Muzukashii Desu 日本語は難しいです!

日本語は難しいです&#xff01; それは難しくないと思うだけど 传送门 一些吐槽 这题好像恶心了不少学弟啊 其实只要读懂了题就很好做, 对于我这种日语高考生来说确实是有点犯规了不过当时我写的时候不能用翻译一看题面一大串英文就被我pass掉, 后面看到一大堆人过了我才去写…

迅为RK3568开发平台人工智能人脸识别全国产解决方案赋能NVR

人脸识别服务&#xff0c;能够在图像中快速检测人脸、分析人脸关键点信息、获取人脸属性、实现人脸的精确比对和检索。可应用于身份验证、电子考勤、客流分析等场景人脸检测、比对、搜索&#xff0c;人脸库管理等。 为什么使用它呢&#xff1f; 维持公众聚集场所的秩序 在餐厅…

Apache的配置与运用

1. web虚拟主机的构建 虚拟Web主机指的是在同一台服务器中运行多个Web站点&#xff0c;其中每一个站点实际上并不独立占用整个服务器&#xff0c;因此被称为“虚拟”Web 主机。通过虚拟 Web 主机服务可以充分利用服务器的硬件资源&#xff0c;从而大大降低网站构建及运行成本。…

2.3.2 单链表的插入结点操作

--单链表示意图 一、按位序插入&#xff08;带头结点&#xff09; ①表头插入 注意点 1.i1&#xff0c;while循环不执行 2.时间复杂度为O&#xff08;1&#xff09; 3.p&#xff01;NULL表示指针p有指向结点 4.头结点为第0个结点 5.pL表示指针p和L指向位置相同&#xff0…

ORB_SLAM3_优化方法 Pose优化

PoseOptimization PoseOptimization主要的作用是利用重投影优化单帧的位姿,主要用在Tracking的几种跟踪模式TrackWithMotionModel、TrackReferenceKeyFrame、 TrackLocalMap、Relocalization中 输入 优化变量观测帧的Pose帧的MapPoint帧的KeyPoint初始化 //创建优化器 g2o…

4.Java逻辑控制语句

Java逻辑控制语句 在实际生活中&#xff0c;我们的生活不是一成不变的&#xff0c;很多时候需要我们去选择&#xff0c;大到人生的十字路口&#xff0c;小到今天晚上吃什么&#xff0c;选择无处不在。小的选择决定了我们一件小事的走向&#xff0c;大的选择可能会改变我们人生…

大模型“云上经济”之权力游戏

文丨谭婧光阴者百代之过客。世人皆过客&#xff0c;软件亦如此。人工智能已有新旧之分。网友戏称&#xff0c;新人工智能是ChatGPT&#xff0c;旧人工智能是“之前那些”。历史在重演。云计算在美国问世的时候&#xff0c;否定论调居多。一个常见的否定论调是「做生意不用上云」…

vite+vue3使用UEditorPlus ,后端PHP

vitevue3使用UEditorPlus什么是UEditorPlus功能亮点前端安装安装vue-ueditor-wrap3.x下载 UEditorPlus在main.js注册组件v-model 绑定数据后端配置效果百度富文本编辑器是目前所有编辑器中功能最丰富的&#xff0c;但长时间不进行维护了。之前写了一篇使用UEditor的教程&#x…

回调函数含义查询云记debug调试

回调函数 同步回调函数 回调函数通常就是当父函数执行完后&#xff0c;再执行通过传参进来的函数&#xff0c;当然也可以不传参&#xff0c;直接在父函数内部调用回调函数 注&#xff1a;立即执行回调&#xff0c;执行完回调代码才会继续往下执行 function a(callback) {a…

力扣:两数之和(哈希表)

1、两数之和 1、问题描述 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那两个整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现。…