第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > Nginx用作 内网CDN / edge cache 服务

Nginx用作 内网CDN / edge cache 服务

时间:2019-08-21 15:12:08

相关推荐

Nginx用作 内网CDN / edge cache 服务

文章目录

什么是CDN?为什么需要 内网CDN/edge cache?Nginx配置Edge Cache服务配置配置AWS cloudfront反向代理简单静态文件缓存服务配置缓存控制$upstream_cache_statusGzip压缩 参考

什么是CDN?

首先要明白什么是CDN?

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

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

加速原理如下

以下内容来着阿里云

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

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

从这个例子可以了解到:

CDN的加速资源是跟域名绑定的。通过域名访问资源,首先是通过DNS查找离用户最近的CDN节点(边缘服务器)的IP通过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 -levents{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;# 定一个文件至少需要被用户访问多少次以后,才会被缓存,默认1proxy_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 $upstream_cache_status;}}upstream hls {server ; #原始的源网站地址server ;}}

proxy_cache_path指令的参数

/path/to/cache/:缓存的本地磁盘目录levels:**在/path/to/cache/**下设置两级目录层次结构。在单个目录中拥有大量文件会减慢文件访问速度,因此我们建议对大多数部署使用两级目录层次结构。如果levels不包含该参数,NGINX 会将所有文件放在同一目录中。 Nginx会基于一个键值(在下面有定义)哈希生成一个缓存键(cache key),该键的最后一个字母作为一级目录名,倒数第二、三个字母作为二级目录名。1:21:表示一级目录可以由1个字符来构成,2:表示二级目录可以由2个字符来构成示缓存结果示例:/data/nginx/cache/c/29/c86156f7dcfecf44876ca30d1bac7febkeys_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而言比较有用,对于客户端也有一些价值。

配置AWS cloudfront反向代理

proxy_cache_path /spare levels=1:2 keys_zone=nginx_cache:10m max_size=1g inactive=10m use_temp_path=off;server {listen 80;server_name localhost;proxy_cache_valid any 5m;location / {proxy_pass ;proxy_set_header Host ;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header REMOTE-HOST $remote_addr;# 重点配置这里 否则反向代理失败proxy_ssl_name ;proxy_ssl_server_name on;# 开启缓存proxy_cache nginx_cache;proxy_cache_key $uri;proxy_read_timeout 10s;proxy_cache_lock on;# 可以在响应header中查看是否名字缓存add_header X-Proxy-Laker-Cache $upstream_cache_status;}

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

对于站点中不经常修改的静态内容(如图片,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压缩

# 开启gzipgzip on;# 启用gzip压缩的最小文件,小于设置值的文件将不会压缩gzip_min_length 1k;# gzip 压缩级别,1-10,数字越大压缩的越好,也越占用CPU时间。一般设置1和2gzip_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 gzipgzip_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;

参考

/blog/nginx-caching-guide//community/tutorials/how-to-optimize-nginx-configuration/nginx/admin-guide/content-cache/content-caching/

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。