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构建高速缓存相关推荐

  1. 利用varnish构建httpd缓存服务器

    varnish如何存储缓存对象: file: 单个文件:不支持持久机制: malloc: 缓存在内存中: persistent:基于文件的持久存储:(此方式不建议使用) vcl:配置缓存系统的缓存机制 ...

  2. 24张图7000字详解计算机中的高速缓存

    文章目录 1. 什么是缓存 2. 缓存的定义 3. 计算机中的高速缓存 3.1 高速缓存相关名词 3.2 计算机中的高速缓存存储器模型 3.3 计算机中有哪些缓存 3.4 硬件读取高速缓存的过程 4. ...

  3. varnish 加速

    Varnish是一个轻量级的Cache和反向代理软件,先进的设计理念和成熟的设计框架是Varnish的主要特点,现在的Varnish总共代码量不大,功能上虽然在不断改进,但是还需要继续丰富和加强.下面 ...

  4. “面试不败计划”: java语言基础面试题(二)

    点击上方"好好学java",选择"置顶公众号" 优秀学习资源.干货第一时间送达! 好好学java java知识分享/学习资源免费分享 关注 精彩内容 java实 ...

  5. java byte 判断相等_转发收藏 | 史上最全Java面试题+面试网站推荐!(含答案)

    今天要谈的主题是关于求职,求职是在每个技术人员的生涯中都要经历多次.对于我们大部分人而言,在进入自己心仪的公司之前少不了准备工作,有一份全面细致面试题将帮助我们减少许多麻烦. 相关概念 面向对象的三个 ...

  6. JAva面试题(微信分享)

    前几天,有朋友去面试之前问我关于后端架构相关的问题,但奈于我去年更多的工作是在移动SDK开发上,对此有所遗忘,实属无奈,后面准备总结下. 今天要谈的主题是关于求职.求职是在每个技术人员的生涯中都要经历 ...

  7. 请写出至少五个块级元素_Java 面试题(五)

    面向对象的三个特征 封装,继承,多态.这个应该是人人皆知. 多态的好处 允许不同类对象对同一消息做出响应,即同一消息可以根据发送对象的不同而采用多种不同的行为方式(发送消息就是函数调用).主要有以下优 ...

  8. 深入理解计算机系统第四版_《深入理解计算机系统》读书笔记 —— 第一章 计算机系统漫游...

    本书第一章沿着一个程序的生命周期,简要地介绍一些逐步出现的关键概念.专业术语和组成部分. 一.信息就是位+上下文 在计算机系统中所有的信息都由一串比特来表示. 一串相同的比特(或者几个相同的字节)可以 ...

  9. Android面试,给正在找工作的安卓攻城师们 ... ...

    从java基础技能到安卓进阶技能,有你想象不到的全面. ☆  JAVA技能 « 有良好的JAVA基础,熟练掌握面向对象思想: 理解面向对象: 面向对象是一种思想,是基于面向过程而言的,就是说面向对象是 ...

最新文章

  1. 发布一个持续集成的npm包并加上装逼小icon
  2. 痞子衡嵌入式:常用的数据差错控制技术(2)- 奇偶校验(Parity Check)
  3. linux 换行符_一个linux帮你做高效数据统计
  4. c语言链表递增,[C语言][PTA][2019Fall] 6-28 递增的整数序列链表的插入 (15 point(s))
  5. asio c++20 协程在windows下和linux下设定
  6. 狗狗手机壁纸|爱宠必备
  7. bootstraptable 怎么在特定行添加数据_同等权限下多任职之间数据权限的实例
  8. Spring-core-AnnotationAttributes
  9. [转]【人是怎么废掉的?】
  10. CMS软件系统架构设计思考
  11. nginx配置php虚拟主机
  12. 分享一个自己写的py扫描路径工具
  13. 列表ListBox、ListView、GridView 排序
  14. 当当图书分类html,基于httpclient与jsoup的抓取当当图书页面数据简单Demo
  15. 企业如何选择短信平台
  16. C++builder应用程序设计流程
  17. JavaWeb中的四大作用域对象
  18. 【2017-01-09】 资料链接摘录
  19. leetcode 组合总和IV(Java)
  20. itpt_TCPL 第四章:函数和程序结构

热门文章

  1. Java消息中间件--JMS规范
  2. golang 结构体判空
  3. python爬虫04--有道翻译
  4. session原理及实现共享
  5. Nginx进程间的通信机制
  6. ActiveMQ RabbitMQ KafKa对比
  7. kafka消息确认机制
  8. 利用WPF建立自己的3d gis软件(非axhost方式)(九)SDK自带部分面板的调用
  9. 社交系统ThinkSNS可以运营什么?可以应用于什么场景?
  10. 用CSS让文字居于div的底部