最新消息:网站迁移至香港,数据恢复中。

Varnish基础知识

Linux ipcpu 631浏览

零、概述

Varnish Cache是一个Web 应用加速器,也是一个知名的反向代理程序。你可以把它安装在任何http服务器的前端,同时对它进行配置来缓存内容。

一、安装

varnish目前有3、4、5一共三个版本,目前3系列版本已经停止更新和维护。

本文以4.1.3 为例进行讲解。

安装的RPM文件可以从官网下载 https://repo.varnish-cache.org/redhat/

二、Varnish缓存原理

Varnish是一个高速HTTP反向代理程序。它从客户端接收请求并且尝试从缓存中直接返回。如果Varnish缓存找不到相关数据,那么它将会请求服务器,获取到服务器响应之后,将结果缓存下来并返回给客户端。
当Varnish已有缓存来响应请求,一般响应速度都是毫秒级别的,并且比请求后台服务器要快两个数量级,因此你可以通过varnish来响应更多的请求。
Varnish会自己决定是通过缓存直接返回,还是请求后台服务器来获取结果。后台服务器可以让varnish缓存内容,并携带http响应头Cache-Control。也有一些条件下varnish是不会缓存,最常见的情况是使用了Cookie。因为Cookie是一个特殊的客户端网络对象,Varnish默认不会缓存它。

三、基本配置

3.1 更改监听端口 /etc/sysconfig/varnish

  1. VARNISH_LISTEN_PORT=6081

3.2 更改后端服务器地址/etc/varnish/default.vcl

  1. backend default {
  2. .host = "www.ipcpu.com";
  3. .port = "80";
  4. }

3.3 启动varnish

  1. /etc/init.d/varnish start

3.4 简单测试

  1. [root@QYER-1-17 soft]#curl -I http://www.ipcpu.com -x 127.0.0.1:6081
  2. HTTP/1.1 200 OK
  3. Server: Tengine
  4. Date: Mon, 28 Nov 2016 06:55:05 GMT
  5. Content-Type: text/html; charset=UTF-8
  6. Last-Modified: Mon, 28 Nov 2016 06:55:02 GMT
  7. Vary: Accept-Encoding
  8. X-Varnish: 65538 3
  9. Age: 8
  10. Via: 1.1 varnish-v4
  11. Accept-Ranges: bytes
  12. Connection: keep-alive

可以看到明显的varnish的参数X-Varnish和缓存存活时间Age

四、varnish后端存储

varnish可以使用多种存储后端,常见有以下两种,默认是内存方式。

内存 Malloc
Malloc是基于内存的存储方式。每个对象都会从内存中来分配资源来进行存储。

文件 file
文件存储使用 mmap 通过非软链的磁盘文件来存储内存中的对象。

后端存储的修改是在/etc/sysconfig/varnish文件中,

  1. # Backend storage specification
  2. VARNISH_STORAGE="malloc,${VARNISH_STORAGE_SIZE}"

注意,缓存存储的实际存储空间可能会超出你设置,所以即使你使用-s malloc,16G参数设置了存储空间,varnish可能实际使用了32G都是有可能的。所以,如果您在缓存中有大量比较小的存储对象,那么这种问题可能更为显著。

五、Varnish进程的工作模式

varnish启动或有2个进程 master(management)进程和child(worker)进程。master读入存储配置命令,进行初始化,然后fork,监控child。child则分配线程进行cache工作,child还会做管理线程和生成很多worker线程。
child进程主线程初始化过程中,将存储大文件整个加载到内存中,如果该文件超出系统的虚拟内存,则会减少原来配置mmap大小,然后继续加载,这时候创建并初始化空闲存储结构体,放在存储管理的struct中,等待分配。
接着varnish某个负责接口新http连接的线程开始等待用户,如果有新的http连接,但是这个线程只负责接收,然后唤醒等待线程池中的work线程,进行请求处理。
worker线程读入uri后,将会查找已有的object,命中直接返回,没有命中,则会从后端服务器中取出来,放到缓存中。如果缓存已满,会根据LRU算法,释放旧的object。对于释放缓存,有一个超时线程会检测缓存中所有object的生命周期,如果缓存过期(ttl),则删除,释放相应的存储内存。

六、varnish状态

varnishstat 用于查看varnish的缓存状态

默认不加任何参数打开varnishstat时显示的内容如上图所示,默认会1秒刷新一次数据。

Hitrate ratio由三个数字组成,第一个数字范围0-10,第二个数字范围0-100,第三个数字范围0-1000。分别表示过去N秒内的Hitrate avg。如果打开的时间足够长,以上三个数字就会逐渐变成10,100,1000。
Hitrate avg里的内容是命中率,需要乘以100转换成百分比 。

还有一些需要注意的参数解释如下

Client connections accepted: (每秒处理连接数)。
Client requests received:经验表明connection:request=1:10左右时比较理想,比这个数大很多或者小很多都是不好的。代表到目前为止,浏览器向反向代理服务器发送的HTTP请求累积次数,由于可能使用长连接,所以它可能会大于上边的Client connections accepted。
Backend connections failures:这个数应该尽可能小,没有就最好,多的话就要看看backend指向的服务是否有问题了。
N struct object:当前被cache的条目。
N worker threads:当前工作线程数。
N worker threads created:创建了多少线程(should be close to the number you are running now) 。
N worker threads not created :最好是0,表示varnish尝试创建线程但失败。
N worker threads limited :由于线程上限限制或者线程池反应延迟导致不能成功创建的线程数,越小越好。
N overflowed work requests :进入等待队列的请求数,越小越好。
N dropped work requests:队列被塞满后扔掉的请求,这个最好不要有。
N LRU nuked objects:由于cache空间满而不得不扔掉的cache条目,如果这个数字是0,就没必要增加cache的大小了。
n_expired :由于cache时间超时而被扔掉的cache条目,具体要看你的ttl设多大了。
Cache hits: 代表在这些请求中,反向代理服务器在缓存区中查找并且命中缓存的次数。
Cache misses: 代表在这些请求中,反向代理服务器在缓存区中查找但是没有命中缓存的次数。
N expired objects: 代表过期的缓存内容个数
N LRU nuked objects: 由于cache空间满而不得不扔掉的cache条目,如果这个数字是0,就没必要增加ache的大小了。
N LRU moved objects: 代表被淘汰的缓存内容个数
Total header bytes: 代表缓存区中所有缓存内容的HTTP头信息长度
Total body bytes: 代表缓存区中所有缓存内容的正文长度

七、varnish日志

varnish提供了varnishlog和varnishncsa两个工具用于日志处理。
varnishlog 用于显示实时日志,varnishncsa是一个daemon进程,负责将日志安装特定格式写入文件。

  1. #@输出当前日志到屏幕
  2. varnishlog
  3. #@打印日志到一个文件
  4. varnishlog -w /var/log/varnish.log

varnishncsa服务默认是关闭的,可以使用/etc/init.d/varnishncsa start打开,日志文件的格式可以在配置文件/etc/sysconfig/varnishncsa中定义。

  1. #默认的日志格式 “%h %l %u %t \”%r\” %s %b \”%{Referer}i\” \”%{User-agent}i\””
  2. LOG_FORMAT='%h %l %u %t %{Varnish:hitmiss}x "%r" %s %b "%{Referer}i" "%{User-Agent}i" "%{Cookie}i" "%{X-Forwarded-For}i"'
  3. DAEMON_OPTS="$DAEMON_OPTS $PREFER_X_FORWARDED_FOR -F '$LOG_FORMAT'"

八、常见错误

1.Cannot open socket: :6081: Address family not supported by protocol

  1. Starting Varnish Cache: Error: Cannot open socket: :6081: Address family not supported by protocol

此原因是系统关闭了IPv6,varnish默认监听IPv4和IPv6,找不到IPv6就会报错。
解决方法:
在配置文件增加配置/etc/sysconfig/varnish,强制指定使用IPv4

  1. VARNISH_LISTEN_ADDRESS=0.0.0.0

2.Backend host resolves to too many addresses.

  1. Backend host "www.baidu.com": resolves to too many addresses.
  2. Only one IPv4 and one IPv6 are allowed.
  3. Please specify which exact address you want to use, we found all of these:
  4. 119.75.218.70:80
  5. 119.75.217.109:80

域名解析对应了多个IP地址,必须使用指向一个IP的域名。

九、参考文章

https://onebitbug.me/2012/12/04/varnish-tune/
https://jefferywang.gitbooks.io/varnish_4_1_doc_zh/content/chapter2.html
https://varnish-cache.org/

转载请注明:IPCPU--网络之路 » Varnish基础知识