varnish构建高速缓存
os:
[root@aliyun_test html]# cat /etc/system-release
CentOS release 6.5 (Final)
首先安装varnish:
配置好varnish源
[root@aliyun_test yum.repos.d]# cat >> varnish.repo << EOF
> [varnish]
> name=varnish for enterprise linux 6
> baseurl=https://repo.varnish-cache.org/redhat/varnish-4.0/el6/
> enabled=1
> gpgcheck=0
> cost=500
> EOF
安装varnish
yum -y install varnish
[root@aliyun_test html]# varnishd -V
varnishd (varnish-4.0.3 revision b8c4a34)
Copyright (c) 2006 Verdens Gang AS
Copyright (c) 2006-2014 Varnish Software AS
Built in subroutines
Varnish 处理 HTTP 请求的过程如下
Receive 状态(vcl_recv):也就是请求处理的入口状态,根据 VCL 规则判断该请求应该 pass(vcl_pass)或是 pipe(vcl_pipe),还是进入 lookup(本地查询);
Lookup 状态:进入该状态后,会在 hash 表中查找数据,若找到,则进入 hit(vcl_hit)状态,否则进入 miss(vcl_miss)状态;
Pass(vcl_pass)状态:在此状态下,会直接进入后端请求,即进入 fetch(vcl_fetch)状态;
Fetch(vcl_backend_fetch)状态:在 fetch 状态下,对请求进行后端获取,发送请求,获得数据,并根据设置进行本地存储;
Deliver(vcl_deliver)状态:将获取到的数据发给客户端,然后完成本次请求;
注:Varnish4中在vcl_fetch部分略有出入,已独立为vcl_backend_fetch和vcl_backend_response 2个函数;
内置函数(也叫子例程)
vcl_recv:用于接收和处理请求;当请求到达并成功接收后被调用,通过判断请求的数据来决定如何处理请求;
vcl_pipe:此函数在进入pipe模式时被调用,用于将请求直接传递至后端主机,并将后端响应原样返回客户端;
vcl_pass:此函数在进入pass模式时被调用,用于将请求直接传递至后端主机,但后端主机的响应并不缓存直接返回客户端;
vcl_hit:在执行 lookup 指令后,在缓存中找到请求的内容后将自动调用该函数;
vcl_miss:在执行 lookup 指令后,在缓存中没有找到请求的内容时自动调用该方法,此函数可用于判断是否需要从后端服务器获取内容;
vcl_hash:在vcl_recv调用后为请求创建一个hash值时,调用此函数;此hash值将作为varnish中搜索缓存对象的key;
vcl_purge:pruge操作执行后调用此函数,可用于构建一个响应;
vcl_deliver:将在缓存中找到请求的内容发送给客户端前调用此方法;
vcl_backend_fetch:向后端主机发送请求前,调用此函数,可修改发往后端的请求;
vcl_backend_response:获得后端主机的响应后,可调用此函数;
vcl_backend_error:当从后端主机获取源文件失败时,调用此函数;
vcl_init:VCL加载时调用此函数,经常用于初始化varnish模块(VMODs)
vcl_fini:当所有请求都离开当前VCL,且当前VCL被弃用时,调用此函数,经常用于清理varnish模块;
vcl_pass:请求后端,但不进入到cache中
client---------->varnish-------------->backend severs
client------>varnish:req请求报文
varnish----->backend:bereq向后端请求
backend----->varnish:beresp后端响应给缓存服务器
varnish----->client:resp缓存响应给client
缓存处理的具体步骤:
接受客户端请求
解析请求(具有代理的功能)
查询缓存(检测本地缓存中是否存在对方请求的内容的副本)
副本的新鲜度检测(检查本地的缓存副本是否为最新版本)
构建响应(代理的功能)
发送响应
记录日志
首部:
通用首部
Connection:close|keep-alive
Date:日期时间
host:请求的主机
Pragma:no-cache
Via:请求或响应在客户端和服务器之间传递时所经过的代理
Transfer-Encoding:消息主体的传输编码方式,chunked表示采用块编码的方式
请求首部
if-modified-since
if-none-match
Referer:跳转
User-Agent:用户的浏览器类型
Host:请求的主机
Accept-Encoding:接受的编码方式
Accept-Language:接受的自然语言
Authorization:服务器发送www-authenticate时,客户端通过此首部提供认证信息
Accept-Charset:接受的字符集
响应首部
ETag:内容的扩展标签
Location:重定向后的新位置
Server:服务器软件信息
www-authenticate:要求对客户端进行认证
实体首部
Content-Encoding:内容编码
Content-Language:内容语言
Content-Length:内容长度
Content-Type:内容的MIME格式
Expires:内容的过期时间
Last-Modified:最后一次修改的时间
配置文件:
vi /etc/sysconfig/varnish
NFILES=131072:打开的最大文件数
NFILES=131072:默认日志内存大小
NPROCS="unlimited":最大线程数(ulimit -u)
RELOAD_VCL=1:直接加载,不用重启
VARNISH_LISTEN_PORT=6081:varnish服务监听的端口,一般改为与后端web服务一样的端口
VARNISH_ADMIN_LISTEN_PORT=6082:远程管理接口监听的端口
VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1:远程管理端监听的ip(本机varnish服务)
VARNISH_SECRET_FILE=/etc/varnish/secret:对管理接口秘钥文件
VARNISH_MIN_THREADS=50:varnish服务开启的最小线程
VARNISH_MAX_THREADS=1000:varnish服务开启的最大线程
VARNISH_STORAGE_SIZE=256M:varnish服务存储的内存大小
VARNISH_STORAGE="malloc,${VARNISH_STORAGE_SIZE}":varnish缓存存储的方式,malloc内存
VARNISH_TTL=120
vi /etc/varnish/default.vcl
backend default {:后端web服务器以及名称
.host = "127.0.0.1";:后端web服务器主机
.port = "8080";:后端web服务器监听的端口
}
varnish存储缓存内容的方法:
1、file:自管理的文件系统,黑盒,只对当前进程有效,不支持持久机制;
2、malloc:使用内存分配函数malloc()库调用varnish启动时向内存申请指定大小的空间;
3、persisent:与file功能相同;仍处于测试期,基于文件的持久存储。
开始配置varnish并启动:
后端服务器:120.26.68.152端口为8080,为nginx
varnish服务器:120.26.68.152端口为7480
echo "<h1> test </h1>" > /usr/share/nginx/html/index.html
配置:vim /etc/varnish/test.vcl
设置响应是否命中
sub vcl_deliver { ##定义子例程
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT via" + " " + server.ip;
} else {
set resp.http.X-Cache = "MISS via" + " " + server.ip;
} ##判断如果命中就在http响应首部设置X-Cache为HIT,否则
就在http响应首部设置X-Cache为MISS。
}
如下结果:
Age:表示缓存的时长(这里设置一个小时),当超过这个时长之后,请求报文会再次miss,之后的1个小时才是hit
sub vcl_backend_response {
set beresp.ttl = 1h;
}
vcl_backend_response:子程序为后端响应给varnish
一些动态解析的程序文件都不能够缓存:
backend default { ----》先定义后端服务器
.host = "192.168.1.112";
.port = "80";
}
sub vcl_recv {
set req.backend_hint = default; ---》设置使用的backend为default
unset req.http.Cookie; -----》不设置客户端请求的cookie信息
if (req.url ~ "\.(php|asp|aspx|jsp|do|ashx|shtml)$") { ----》匹配的是默认后端主机
return(pass); ----》请求的是默认后端主机,如果不先设置主机将会网页访问不存在
}
}
设置默认后端效果图:
如果不先设置默认主机,效果如下:
不正常的请求不缓存 -----》在vcl_rcv子程序中
if (req.method != "GET" &&
req.method != "HEAD" &&
req.method != "PUT" &&
req.method != "POST" &&
req.method != "TRACE" &&
req.method != "OPTIONS" &&
req.method != "PATCH" &&
req.method != "DELETE") {
return (pipe);
}
如果请求不是GET或者HEAD,不缓存
if (req.method != "GET" && req.method !="HEAD") {
return (pass);
}
如果请求包含Authorization授权或Cookie认证,不缓存
if (req.http.Authorization || req.http.Cookie) {
return (pass);
}
启用压缩,但排除一些流文件压缩
if (req.http.Accept-Encoding) {
unset req.http.Accept-Encoding;
} elseif (req.http.Accept-Encoding ~ "gzip") {
set req.http.Accept-Encoding = "gzip";
} elseif (req.http.Accept-Encoding ~ "deflate") {
set req.http.Accept-Encoding = "deflate";
} else {
unset req.http.Accept-Encoding;
}
}
return (hash);
}
定义vcl_pipe函数段
sub vcl_pipe {
return (pipe);
}
sub vcl_miss {
return (fetch);
}
定义vcl_hash函数段
sub vcl_hash {
hash_data(req.url);
if (req.http.host) { -----》如果请求host首部,利用has算法返回host首部信息
hash_data(req.http.host);
}else {
hash_data(server.ip);
}
if (req.http.Accept-Encoding ~ "gzip") {
hash_data ("gzip");
}elseif (req.http.Accept-Encoding ~ "deflate") {
hash_data ("deflate");
}
}
sub vcl_recv {
if (req.restarts ==0) {:刚接收到请求,或者再一次请求时,记录客户端首部及ip
if (req.http.x-forwad-for) {
set req.http.X-Forward-For = set req.http.X-Forward-For + " " client.ip;
} else {
set req.http.X-Forward-For = client.ip;
}
}
}
这里我已经改用虚拟机测试了
varnish:192.168.1.155
nginx:192.168.1.11
隐藏后端Server系统及版本
if (resp.http.Server) {
unset resp.http.Server;
}属于sub vcl_deliver子程序
可以看见响应报文没有Server段了
定义两个后端:
backend default {
.host = "192.168.1.11";
.port = "80";
}
backend java {
.host = "192.168.1.12";
.port = "80";
}
当匹配java时,选择java后端,其他默认选择默认端
sub vcl_recv {
if (req.url ~ "^/java/") {
set req.backend_hint = java;-----》hint暗示、示意
} else {
set req.backend_hint = default;
}
}
根据请求报文的主机来判断:
sub vcl_recv {
if (req.http.host ~ "foo.com") {
set req.backend_hint = foo;
} elsif (req.http.host ~ "bar.com") {
set req.backend_hint = bar;
}
}
sub vcl_recv {
if (req.http.host == "foo.com" || req.http.host == "www.foo.com") {
set req.backend_hint = foo;
}
}
定义后端组,并且采用round robin算法和后端服务器监控检测机制
import directors; # load the directors
backend web1 {
.host = "192.168.1.11";
.port = "80";
.probe = {
.url = "/";
.interval = 5s;
.window = 5;
.timeout = 1s;
.threshold = 3;
}
}
backend web2 {
.host = "192.168.1.12";
.port = "80";
.probe = {
.url = "/";
.interval = 5s;
.timeout = 1s;
.window = 5;
.threshold = 3;
}
}
sub vcl_init {
new nginx = directors.round_robin(); -----》nginx就是后端组的组名称,进行轮训
nginx.add_backend(web1);
nginx.add_backend(web2);
}
sub vcl_recv {
# send all traffic to the bar director:
set req.backend_hint = nginx.backend();
}
ACL控制列表
# Who is allowed to purge....
acl local {
"localhost";
"192.168.1.0"/24; /* and everyone on the local network */
! "192.168.1.13"; /* except for the dialin router */
}
sub vcl_recv {
if (req.method == "PURGE") {
if (client.ip ~ local) {
return(purge);
} else {
return(synth(403, "Access denied."));
}
}
}
不设置请求报文的cookie信息
sub vcl_recv {
unset req.http.Cookie;
}
不设置响应报文的cookie信息
sub vcl_backend_response {
if (bereq.url ~ "\.(png|gif|jpg)$") {
unset beresp.http.set-cookie;
set beresp.ttl = 1h;
}
}
更多信息参考:https://www.varnish-cache.org/docs/4.0
http://my.oschina.net/monkeyzhu/blog/482051
转载于:https://blog.51cto.com/huangsir007/1840713
varnish构建高速缓存相关推荐
- 利用varnish构建httpd缓存服务器
varnish如何存储缓存对象: file: 单个文件:不支持持久机制: malloc: 缓存在内存中: persistent:基于文件的持久存储:(此方式不建议使用) vcl:配置缓存系统的缓存机制 ...
- 24张图7000字详解计算机中的高速缓存
文章目录 1. 什么是缓存 2. 缓存的定义 3. 计算机中的高速缓存 3.1 高速缓存相关名词 3.2 计算机中的高速缓存存储器模型 3.3 计算机中有哪些缓存 3.4 硬件读取高速缓存的过程 4. ...
- varnish 加速
Varnish是一个轻量级的Cache和反向代理软件,先进的设计理念和成熟的设计框架是Varnish的主要特点,现在的Varnish总共代码量不大,功能上虽然在不断改进,但是还需要继续丰富和加强.下面 ...
- “面试不败计划”: java语言基础面试题(二)
点击上方"好好学java",选择"置顶公众号" 优秀学习资源.干货第一时间送达! 好好学java java知识分享/学习资源免费分享 关注 精彩内容 java实 ...
- java byte 判断相等_转发收藏 | 史上最全Java面试题+面试网站推荐!(含答案)
今天要谈的主题是关于求职,求职是在每个技术人员的生涯中都要经历多次.对于我们大部分人而言,在进入自己心仪的公司之前少不了准备工作,有一份全面细致面试题将帮助我们减少许多麻烦. 相关概念 面向对象的三个 ...
- JAva面试题(微信分享)
前几天,有朋友去面试之前问我关于后端架构相关的问题,但奈于我去年更多的工作是在移动SDK开发上,对此有所遗忘,实属无奈,后面准备总结下. 今天要谈的主题是关于求职.求职是在每个技术人员的生涯中都要经历 ...
- 请写出至少五个块级元素_Java 面试题(五)
面向对象的三个特征 封装,继承,多态.这个应该是人人皆知. 多态的好处 允许不同类对象对同一消息做出响应,即同一消息可以根据发送对象的不同而采用多种不同的行为方式(发送消息就是函数调用).主要有以下优 ...
- 深入理解计算机系统第四版_《深入理解计算机系统》读书笔记 —— 第一章 计算机系统漫游...
本书第一章沿着一个程序的生命周期,简要地介绍一些逐步出现的关键概念.专业术语和组成部分. 一.信息就是位+上下文 在计算机系统中所有的信息都由一串比特来表示. 一串相同的比特(或者几个相同的字节)可以 ...
- Android面试,给正在找工作的安卓攻城师们 ... ...
从java基础技能到安卓进阶技能,有你想象不到的全面. ☆ JAVA技能 « 有良好的JAVA基础,熟练掌握面向对象思想: 理解面向对象: 面向对象是一种思想,是基于面向过程而言的,就是说面向对象是 ...
最新文章
- 发布一个持续集成的npm包并加上装逼小icon
- 痞子衡嵌入式:常用的数据差错控制技术(2)- 奇偶校验(Parity Check)
- linux 换行符_一个linux帮你做高效数据统计
- c语言链表递增,[C语言][PTA][2019Fall] 6-28 递增的整数序列链表的插入 (15 point(s))
- asio c++20 协程在windows下和linux下设定
- 狗狗手机壁纸|爱宠必备
- bootstraptable 怎么在特定行添加数据_同等权限下多任职之间数据权限的实例
- Spring-core-AnnotationAttributes
- [转]【人是怎么废掉的?】
- CMS软件系统架构设计思考
- nginx配置php虚拟主机
- 分享一个自己写的py扫描路径工具
- 列表ListBox、ListView、GridView 排序
- 当当图书分类html,基于httpclient与jsoup的抓取当当图书页面数据简单Demo
- 企业如何选择短信平台
- C++builder应用程序设计流程
- JavaWeb中的四大作用域对象
- 【2017-01-09】 资料链接摘录
- leetcode 组合总和IV(Java)
- itpt_TCPL 第四章:函数和程序结构