基于Centos7 部署Varnish缓存代理服务器

论坛 期权论坛 脚本     
niminba   2021-5-23 04:22   1391   0

一.Varnish概述

1.Varnish 简介

Varnish是一款高性能且开源的反向代理服务器和HTTP加速器,其采用全新的软件体系机构,和现在的硬件体系紧密配合。与传统的squid相比,Varnish具有高性能、速度快、管理更加方便等优点,目前很多大型的网站都开始尝试使用Varnish来代替squid,这便是Varnish迅速发展的最根本的原因。

Varnish的主要特征:

(1)缓存代理位置:可以使用内存也可以使用磁盘;
(2)日志存储:日志存储在内存中;
(3)支持虚拟内存的使用;
(4)有精确的时间管理机制,即缓存的时间属性控制;
(5)状态引擎架构:在不同的引擎上完成对不同的缓存和代理数据进行处理;
(6)缓存管理:以二叉堆管理缓存数据,做到数据的及时清理;

2.Varnish 与 Squid 的对比相同点

  • 都是开源软件;
  • 都是一个反向代理服务器;

Varnish 的优势

(1)稳定性:Varnish和Squid在完成相同负载的工作时,Squid服务器发生故障的几率要高于Varnish,因为使用Squid需要经常重启;
(2)访问速度更快:Varnish所有缓存的数据都是直接从内存中读取,而Squid是从硬盘中读取;
(3)支持更多的并发连接:因为Varnish的TCP连接和释放的速度比Squid快很多

Varnish 的劣势

(1)Varnish进程一旦重启,缓存数据都会从内存中完全释放,此时所有请求都会发送到后端服务器,在高并发情况下,会给后端服务器造成很大压力;
(2)在Varnish使用中如果使用单个URL的请求通过负载均衡时,则每次请求都会落在不同的Varnish服务器中,造成请求都会到后端服务器;而且同样的秦桂在多台服务器上缓存,也会造成Varnish的缓存资源的浪费,造成性能下降;

Varnish 劣势的解决方案

针对劣势一:在访问量很大的情况下推荐使用 varnish 的内存缓存方式启动,而且后面需要 跟多台 squid/nginx 服务器。主要为了防止前面的 varnish 服 务、服务器被重启的情况下, 大量请求穿透 varnish,这样 squid/nginx 可以就担当第二层 CACHE,而且也弥补了 varnish 缓 存在内存中重启都会释放的问题;
针对劣势二:可以在负载均衡上做 url 哈希,让单个 url 请求固定请求到一台 varnish 服务器 上;

3.Varnish的工作原理

当Varnish服务器收到客户端的请求时,首选检查缓存中是否有数据,如果有,则直接响应客户端;如果没有则向后端服务器请求相应的资源,缓存到Varnish服务器本地,再响应客户端;

根据规则和请求页面的类型选择数据是否需要进行缓存,可以根据请求头中Cache-Contorl判断是否缓存,以及cookis是否有标记,这些功能都可以通过编写配置文件的方式来实现。

4.Varnish简单架构

Varnish分为management进程和child进程

  • management进程:对child进程进行管理,同事对VCL配置进行编译,并应用到不同的状态引擎中;
  • child进程:生成线程池,负责对用户请求进行处理,并通过hash查找返回用户结果;

child进程生成的常见线程有

  • accept线程:接收新的连接请求并响应;
  • worker线程:会话,处理请求资源;
  • expiry线程:清除缓存中过期的内容;

5.varnish 主要配置部分

  • 后端配置:给Varnish添加反向代理服务器节点,最少配置一个;
  • ACL配置:给Varnish添加访问控制列表,可以指定这些列表访问或禁止访问;
  • probes配置:给Varnish添加探测后端服务器是否正常的规则,方便切换或禁止对应后端服务器;
  • directors配置:给Varnish添加负载均衡模式管理多个后端服务器;
  • 核心子程序配置:给Varnish添加后端服务器切换,请求缓存、访问控制、错误处理等规则;

6.VCL 中内置预设变量:变量(也叫 object):

如图

(1)req:客户端请求Varnish服务器时可用的变量;
(2)bereq:Varnish服务器请求后端服务器可用的变量;
(3)beresp:后端服务器响应Varnish服务器请求,并返回结果时,使用的变量;
(4)resp:Varnish服务器响应客户端请求是使用的变量;
(5)obj:高速缓存对象,缓存后端响应请求内容;
(6)now:作用就是返回当前的时间戳;

客户端

Clienet.ip:返回客户端的IP地址
Client.port:获"; } else { unset req.http.Accept-Encoding; #其他未定义的页面也取消客户但接收的压缩类型. } } if (req.url ~ "\.(css|js|html|htm|bmp|png|gif|jpg|jpeg|ico|gz|tgz|bz2|tbz|zip|rar|mp3|mp4|ogg|swf|flv)($|\?)") { unset req.http.cookie; #取消客户端的cookie值. return (hash); #将请求转发给hash子程序,也就是查看本地缓存. } if (req.restarts == 0) { #判断客户端是不是第一次请求 if (req.http.X-Forwarded-For) { #如果是第一次请求,设置获取客户端的IP地址. set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip; } else { set req.http.X-Forwarded-For = client.ip; } } return (hash); } sub vcl_hash { hash_data(req.url); #查看客户端请求的页面,并且进行hash if (req.http.host) { hash_data(req.http.host); #设置客户端的主机 } else { hash_data(server.ip); #设置服务器的IP } return (lookup); } sub vcl_hit { if (req.method == "PURGE") { #如果是HIT并且当客户端请求的类型是PURGE返回的200的状态码,并返回相应页面. return (synth(200, "Purged.")); } return (deliver); } sub vcl_miss { if (req.method == "PURGE") { return (synth(404, "Purged.")); #如果是miss返回404 } return (fetch); } sub vcl_deliver { if (obj.hits > 0) { set resp.http.CXK = "HIT-from-varnish"; #设置http头部X-Cache =hit set resp.http.X-Cache-Hits = obj.hits; #返回命令的次数 } else { set resp.http.X-Cache = "MISS"; } unset resp.http.X-Powered-By; #取消显示web版本 unset resp.http.Server; #取消显示varnish服务 unset resp.http.X-Drupal-Cache; #取消显示缓存的框架 unset resp.http.Via; #取消显示文件内容来源 unset resp.http.Link; #取消显示HTML的超链接地址 unset resp.http.X-Varnish; #取消显示varnish的id set resp.http.xx_restarts_count = req.restarts; #设置客户端请求的次数 set resp.http.xx_Age = resp.http.Age; #显示缓存文件的时长 #set resp.http.hit_count = obj.hits; #显示缓存命中的次数 #unset resp.http.Age; return (deliver); } sub vcl_pass { return (fetch); #将后端服务器返回的数据缓存到本地 } sub vcl_backend_response { set beresp.grace = 5m; #缓存额外宽限时间 if (beresp.status == 499 || beresp.status == 404 || beresp.status == 502) { set beresp.uncacheable = true; #当后端服务器相应状态码是449等,不缓存 } if (bereq.url ~ "\.(php|jsp)(\?|$)") { set beresp.uncacheable = true; #当是PHP的页面不缓存 } else { if (bereq.url ~ "\.(css|js|html|htm|bmp|png|gif|jpg|jpeg|ico)($|\?)") { set beresp.ttl = 15m; #当是上面结尾的,缓存15分钟 unset beresp.http.Set-Cookie; } elseif (bereq.url ~ "\.(gz|tgz|bz2|tbz|zip|rar|mp3|mp4|ogg|swf|flv)($|\?)") { set beresp.ttl = 30m; #缓存30分钟 unset beresp.http.Set-Cookie; } else { set beresp.ttl = 10m; #生存时间10分钟 unset beresp.http.Set-Cookie; } } return (deliver); } sub vcl_purge { return (synth(200,"success")); } sub vcl_backend_error { if (beresp.status == 500 || beresp.status == 501 || beresp.status == 502 || beresp.status == 503 || beresp.status == 504) { return (retry); #如果状态码是上述其中之一,则重新请求 } } sub vcl_fini { return (ok); }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持社区。

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:1060120
帖子:212021
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP