Varnish 是一款高性能且开源的反向代理服务器和 HTTP 加速器,其采用全新的软件体系机构,和现在的硬件体系紧密配合,与传统的 squid 相比,varnish 具有性能更高、速度更快、管理更加方便等诸多优点。

什么是反向代理?

反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。

在网络上常见的代理服务器有三种:

1、标准的代理缓冲服务器

一个标准的代理缓冲服务被用于缓存静态的网页(例如:html文件和图片文件等)到本地网络上的一台主机上---即代理服务器(传统代理)优点:当被缓存的页面被第二次访问的时候,浏览器将直接从本地代理服务器那里请求数据而不再向原web站点请求数据。这样就节省了宝贵的网络带宽,而且提高了访问速度。缺点:要想实现这种方式,必须在每一个内部主机的浏览器上明确指明代理服务器的IP地址和端口号。

2、透明代理缓冲服务器

透明代理缓冲服务和标准代理服务器的功能完全相同。但是,代理操作对客户端的浏览器是透明的(即不需指明代理服务器的IP和端口)。透明代理服务器阻断网络通信,并且过滤出访问外部的HTTP(80端口)流量。如果客户端的请求在本地有缓冲则将缓冲的数据直接发给用户,如果在本地没有缓冲则向远程web服务器发出请求,其余操作和标准的代理服务器完全相同。对于Linux操作系统来说,透明代理使用Iptables缓存及加速-03单-高性能缓存服务器Varnish.txt[2016/8/19 15:28:24]或者Ipchains实现。因为不需要对浏览器作任何设置,所以,透明代理对于ISP(Internet服务器提供商)特别有用。

3、反向代理缓冲服务器

反向代理是和前两种代理完全不同的一种代理服务。使用它可以降低原始WEB服务器的负载。反向代理服务器承担了对原始WEB服务器的静态页面的请求,防止原始服务器过载。它位于本地WEB服务器和Internet之间,处理所有对WEB服务器的请求,阻止了WEB服务器和Internet的直接通信。如果互联网用户请求的页面在代理服务器上有缓冲的话,代理服务器直接将缓冲内容发送给用户。如果没有缓冲则先向WEB服务器发出请求,取回数据,本地缓存后再发送给用户。这种方式通过降低了向WEB服务器的请求数从而降低了WEB服务器的负载。

Varnish 文件缓存的工作流程

Varnish 与一般服务器软件类似,分为 master 进程和 child 进程。Master 进程读入存储配置文件,调用合适的存储类型,然后创建 / 读入相应大小的缓存文件,接着 master 初始化管理该存储空间的结构体,然后 fork 并监控 child 进程。Child 进程在主线程的初始化的过程中,将前面打开的存储文件整个 mmap 到内存中,此时创建并初始化空闲结构体,挂到存储管理结构体,以待分配。Child 进程分配若干线程进行工作,主要包括一些管理线程和很多 worker 线程。接着,开始真正的工作,varnish 的某个负责接收新 HTTP 连接线程开始等待用户,如果有新的 HTTP 连接过来,它总负责接收,然后唤醒某个等待中的线程,并把具体的处理过程交给它。Worker 线程读入 HTTP 请求的 URI,查找已有的 object,如果命中则直接返回并回复用户。如果没有命中,则需要将所请求的内容,从后端服务器中取过来,存到缓存中,然后再回复。分配缓存的过程是这样的:它根据所读到 object 的大小,创建相应大小的缓存文件。为了读写方便,程序会把每个 object 的大小变为最接近其大小的内存页面倍数。然后从现有的空闲存储结构体中查找,找到最合适的大小的空闲存储块,分配给它。如果空闲块没有用完,就把多余的内存另外组成一个空闲存储块,挂到管理结构体上。如果缓存已满,就根据 LRU 机制,把最旧的 object 释放掉。释放缓存的过程是这样的:有一个超时线程,检测缓存中所有 object 的生存期,如果超初设定的 TTL(Time To Live)没有被访问,就删除之,并且释放相应的结构体及存储内存。注意释放时会检查该存储内存块前面或后面的空闲内存块,如果前面或后面的空闲内存和该释放内存是连续的,就将它们合并成更大一块内存。整个文件缓存的管理,没有考虑文件与内存的关系,实际上是将所有的 object 都考虑是在内存中,如果系统内存不足,系统会自动将其换到 swap 空间,而不需要 varnish 程序去控制。

varnish的安装可以根据具体的平台进行,既可以下载现有的rpm包进行安装也可以下载源码包进行编译安装。

Varnish 配置解读

示例配置在后面

VCL 简介

VCL(varnish configuration language)是 varnish 配置语言,其用来定义 varnish 的存取策略。VCL 语法比较简单,跟 C 和 Perl 比较相似。主要有以下几点:

块是由花括号分隔,语句以分号结束,使用‘ # ’符号可以添加注释。VCL 使用指定运算符“=”、比较运算符“==”、逻辑运算符“!,&&,!!”等形式,还支持正则表达式和用“~”进行 ACL 匹配运算。VCL 没有用户自己定义的变量,你可以在 backend、request 或 object 上设置变量值,采用 set 关键字进行设置。例如 set req.backend = director_employeeui;两个字符串的连接,他们之间没有任何运算符。代码如清单 5 所示:

清单 5. 字符串连接代码

 set req.http.X-hit = " hit" "it"; \”字符在 VCL 里没有特别的含义,这点与其他语言略有不同。VCL 可以使用 set 关键字设置任何 HTTP 头,可以使用 remove 或是 unset 关键字移除 HTTP 头。VCL 有 if/else 的判断语句,但是没有循环语句。

VCL backend

声明并初始化一个后端对像,backend 声明代码示例

 backend www { .host = "www.example.com"; .port = "9082"; }

后端对象的使用,backend 的使用代码示例

 if (req.http.host ~ "^(www.)?example.com$") { set req.backend = www; }

VCL 后端的集合 director

VCL 可以把多个 backends 聚合成一个组,这些组被叫做 director,这样可以增强性能和弹力,当组里一个 backend 挂掉后,可以选择另一个健康的 backend。VCL 有多种 director,不同的 director 采用不同的算法选择 backend,主要有以下几种:

The random director

Random director 会根据所设置的权值(weight)来选择 backend,.retries 参数表示尝试找到一个 backend 的最大次数,.weight 参数表示权值

The round-robin director

Round-robin director 在选择 backend 时,会采用循环的方式依次选择。

The client director

Client director 根据 client.identity 来选择 backend,您可以设置 client.identity 的值为 session cookie 来标识 backend。

backend probes

VCL 可以设置 probe 来检测一个 backend 是否健康,定义一个 backend probes 的示例:

 backend www { .host = "www.example.com"; .port = "9082"; .probe = { .url = "/test.jpg";// 哪个 url 需要 varnish 请求.timeout = 1 s;// 等待多长时间超时.interval = 5s// 检查的时间间隔.window = 5;// 维持 5 个 sliding window 的结果.threshold = 3;// 至少有三次 window 是成功的,就宣告 backend 健康} }

ACL

ACL 可创建一个客户端的访问控制列表,你可以使用 ACL 控制哪些客户端可以访问,哪些客户端禁止访问。定义 ACL 代码:

 Acl local{ "localhost"; "192.0.2.0"/24; !"192.0.2.23";// 除去该 IP }

VCL 内置函数

vcl_recv 函数

用于接收和处理请求。当请求到达并成功接收后被调用,通过判断请求的数据来决定如何处理请求。例如如何响应、怎么响应、使用哪个后端服务器等。

此函数一般以如下几个关键字结束。

pass:表示进入 pass 模式,把请求控制权交给 vcl_pass 函数。

pipe:表示进入 pipe 模式,把请求控制权交给 vcl_pipe 函数。

lookup:表示进入 lookup 模式,把请求控制权交给 lookup 指令处理,在缓存中查找被请求的对象,并且根据查找的结果把控制权交给函数 vcl_hit 或函数 vcl_miss。

error code [reason]:表示返回“code”给客户端,并放弃处理该请求。“code”是错误标识,例如 200 和 405 等。“reason”是错误提示信息。

vcl_pipe 函数

此函数在进入 pipe 模式时被调用,用于将请求直接传递至后端主机,在请求和返回的内容没有改变的情况下,将不变的内容返回给客户端,直到这个连接被关闭。

此函数一般以如下几个关键字结束。

error code [reason]。

pipe。

vcl_pass 函数

此函数在进入 pass 模式时被调用,用于将请求直接传递至后端主机。后端主机在应答数据后将应答数据发送给客户端,但不进行任何缓存,在当前连接下每次都返回最新的内容。

此函数一般以如下几个关键字结束。

error code [reason]。

pass。

restart 重新启动流程,增加启动次数,如果重新启动次数高于 max_restarts 发出一个错误警告

vcl_hash

当您想把一个数据添加到 hash 上时,调用此函数。

此函数一般以如下几个关键字结束。

Hash。

vcl_hit 函数

在执行 lookup 指令后,在缓存中找到请求的内容后将自动调用该函数。

此函数一般以如下几个关键字结束。

deliver:表示将找到的内容发送给客户端,并把控制权交给函数 vcl_deliver。

error code [reason] 。

pass。

restart 重新启动流程,增加启动次数,如果重新启动次数高于 max_restarts 发出一个错误警告

vcl_miss 函数

在执行 lookup 指令后,在缓存中没有找到请求的内容时自动调用该方法。此函数可用于判断是否需要从后端服务器获取内容。

此函数一般以如下几个关键字结束。

fetch:表示从后端获取请求的内容,并把控制权交给 vcl_fetch 函数。

error code [reason] 。

pass。

vcl_fetch 函数

在后端主机更新缓存并且获取内容后调用该方法,接着,通过判断获取的内容来决定是将内容放入缓存,还是直接返回给客户端。

此函数一般以如下几个关键字结束。

error code [reason]。

pass。

deliver。

esi。

restart 重新启动流程,增加启动次数,如果重新启动次数高于 max_restarts 发出一个错误警告

vcl_deliver 函数

将在缓存中找到请求的内容发送给客户端前调用此方法。

此函数一般以如下几个关键字结束。

error code [reason]。

deliver。

restart 重新启动流程,增加启动次数,如果重新启动次数高于 max_restarts 发出一个错误警告

vcl_error

出现错误时调用此函数。

此函数一般以如下几个关键字结束。

deliver。

restart。

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_fetch)状态。在 fetch 状态下,对请求进行后端获取,发送请求,获得数据,并根据设置进行本地存储。Deliver(vcl_deliver)状态。将获取到的数据发给客户端,然后完成本次请求。

以上为一些基本的概念,接下来我们来配置一下(平台为rhel6.5.x86_64):

1. 配置一个后端服务器(本机ip为172.25.5.100)

vim /etc/varnish/default.vcl

backend web1 {
.host = "172.25.5.10";
.port = "80";
}

配置 varnish 服务端口

VARNISH_LISTEN_PORT=80

为了测试显示更加清晰在vcl中添加如下代码

sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT from  web1  cache";
}
else {
set resp.http.X-Cache = "MISS from  web1 cache";
}
return (deliver);
}

/etc/init.d/varnish restart

本机多次测试缓存命中

首次测试的结果
[root@vm10 ~]# curl   172.25.5.100
HTTP/1.1 200 OK
Server: Nginx (Red Hat)
Last-Modified: Mon, 10 Aug 2017 15:22:19 GMT
ETag: "1c13aa-16-4c7b4135e08a6"Content-Type: text/html; charset=UTF-8
Content-Length: 22
Accept-Ranges: bytes
Date: Fri, 24 Aug 2012 14:30:40 GMT
X-Varnish: 766434032
Age: 0
Via: 1.1 varnish
Connection: keep-alive
X-Cache: MISS from web1 cache #未命中

再次测试的结果:

[root@vm10 ~]# curl   172.25.5.100
HTTP/1.1 200 OK
Server: Nginx (Red Hat)
Last-Modified: Mon, 10 Aug 2017 15:23:10GMT
ETag: "1c13aa-16-4c7b4135e08a6"
Content-Type: text/html; charset=UTF-8
Content-Length: 22
Accept-Ranges: bytes
Date: Fri, 24 Aug 2017 15:23:10 GMT
X-Varnish: 766467033 766467032
Age: 14
Via: 1.1 varnish
Connection: keep-alive
X-Cache: HIT from westos cache #命中

通过 varnishadm 手动清除缓存

# varnishadm ban.url .*$
#清除所有
# varnishadm ban.url /index.html
#清除 index.html 页面缓存
# varnishadm ban.url /admin/$
#清除 admin 目录缓存

定义多个不同域名站点的后端服务器

backend web1 {
.host = "172.25.5.10";
.port = "80";
}
backend web2 {
.host = "172.25.5.20";
.port = "80";
}

当访问 www.lockey.com 域名时从 web1 上取数据,访问 bbs.lockey.com 域名时到 web2 取数据,访问其他页面报错。

sub vcl_recv {
if (req.http.host ~ "^(www.)?lockey.com") {
set req.http.host = "www.lockey.com";
set req.backend = web1;
return (pass);       #为了测试方便,不进行缓存。
} elsif (req.http.host ~ "^bbs.lockey.com") {
set req.backend = web2;
} else {error 404 "lockeycache";
}
}

定义负载均衡
director lb round-robin {
{ .backend = web1;}
{.backend = web2;}
}
上面采用rr算法,还有其他算法如hash,fallback,random等

varnish cdn 推送平台

首先系统要有 php 支持

unzip bansys.zip -d /var/www/html
vim /var/www/html/bansys/config.php #只保留如下设置,其余注释掉

<?php
$var_group1 = array(
'host' => array('172.25.5.100'),
'port' => '6082',
);

#varnish 群组定义
#对主机列表进行绑定

$VAR_CLUSTER = array(
'www.lockey.com' => $var_group1,
);

#varnish 版本2.x 和 3.x 推送命令不一样

$VAR_VERSION = "3";
?>

bansys 有两种工作模式,分别是:telnet 和 http 模式。

telnet 模式需要关闭 varnish 服务管理端口的验证,注释掉/etc/sysconfig/varnish 文件中的“-S $
{VARNISH_SECRET_FILE}”这行,重启 varnish 服务即可。
如果是http模式需要做如下设置:

vim    /etc/varnish/default.vcl
acl lockey{
#设置访问控制
"127.0.0.1";
"172.25.5.0"/24;
}
sub vcl_recv {
if (req.request == "BAN") {
if (!client.ip ~ lockey) {
error 405 "Not allowed.";
}
ban("req.url ~ " + req.url);
error 200 "ban added";
}
}

Varnish反向代理服务器和 HTTP 加速器相关推荐

  1. Varnish Cache:高性能反向代理服务器和HTTP加速器

    1 Varnish简介 Varnish是高性能且开源的反向代理服务器和HTTP加速器(cache server).其开发者Poul-Henning Kamp是FreeBSD核心的开发人员之一.Varn ...

  2. 什么是反向代理服务器

    我们常会看到'反向代理服务器'这个名词,例如常看到文章上说 nginx 是一个反向代理服务器.varnish 是一个反向代理服务器 -- 下面就了解下这个概念 含义 '反向代理服务器' 有两个概念,一 ...

  3. 反向代理服务器的工作原理

    最近接触了nginx,nginx可以作为一个反向代理服务器完成负载均衡,下面记录一下从网上学习到的一些知识. 一  概述 反向代理(Reverse Proxy)方式是指以代理服务器来接受Interne ...

  4. 反向代理服务器(Reverse Proxy)

    反向代理服务器(Reverse Proxy) 普通代理服务器是帮助内部网络的计算机访问外部网络.通常,代理服务器同时连接内网和外网.首先内网的计算机需要设置代理服务器地址和端口,然后将HTTP请求发送 ...

  5. 【大型网站技术实践】初级篇:借助Nginx搭建反向代理服务器

    一.反向代理:Web服务器的"经纪人" 1.1 反向代理初印象 反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网 ...

  6. squid之反向代理服务器

    代理服务器是使用非常普遍的一种将局域网主机联入互联网的一种方式,使用代理上网可以节约紧缺的IP地址资源,而且可以阻断外部主机对内部主机的访问,使内部网主机免受外部网主机的***.但是,如果想让互联网上 ...

  7. Fikker反向代理服务器的网站缓存加速/网站加速基础教程

    2019独角兽企业重金招聘Python工程师标准>>> Fikker反向代理服务器的网站缓存加速/网站加速基础教程 - 简介篇 前言: 本教程是针对第一次接触和使用 Fikker 的 ...

  8. Nginx server之Nginx作为反向代理服务器

    2019独角兽企业重金招聘Python工程师标准>>> 一:Nginx介绍 1.Nginx简介:nginx [engine x]是一个俄罗斯人编写的HTTP和反向代理服务器,另外它也 ...

  9. IIS作为ASP.NET Core2.1 反向代理服务器未说的秘密

    --以下内容针对 ASP.NET Core2.1,2.2出现IIS进程内寄宿 暂不展开讨论--- 相比ASP.NET,出现了3个新的组件:ASP.NET Core Module.Kestrel.dot ...

最新文章

  1. 解决Windows7下vs2008 Active control test container 不能运行的问题
  2. 这就是编程的终极难题? | 每日趣闻
  3. 转: 理解AngularJS中的依赖注入
  4. 【小安中文翻唱】听海——毁中文歌啦~
  5. 突然发现我还有博客园的博客呢哈哈哈哈
  6. 案例:图书管理——补充知识(数组相关API)||补充知识(数组响应式变化)
  7. 用python读取stata文件及写入and注意事项
  8. Web 趋势榜:上周最有意思、又实用的 10 大 Web 项目 - 210730
  9. Addin and Automation Development In VB.NET 2003 (3)
  10. MFC 操作配置文件INI的方法
  11. 解决input输入框在iOS中有阴影问题
  12. BEC translation exercise 4
  13. linux下无权限安装opencv3.4.6
  14. Git上手:四种常见的Git协同工作方式
  15. 跨境电商独立站门槛高,为什么还有无数人挤破头想入坑!
  16. 如何批量生成UPC-E条码
  17. 什么是准静态平坦瑞利衰落信道?
  18. C/C++ Npcap包实现数据嗅探
  19. 开启samba服务的设置步骤
  20. ADO数据库访问技术

热门文章

  1. 选择关键词:SEM助力活动推广
  2. SCSI/iSCSI及SAS、NAS、SAN的基本介绍
  3. 笔趣阁小说站的爬虫小程序
  4. 关于attach和detach的疑问
  5. GBase 8a 数据抽取工具orato8a用法介绍
  6. 孩子用台灯对眼睛好吗?眼科医生推荐好用不伤眼睛的台灯牌子
  7. xception in thread “main“ org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualif
  8. java反射各种属性获取
  9. 在vue项目中使用Antv-f2的小案例
  10. Android定时任务及闹钟的实现