天天看点

Varnish搭建缓存代理提高网站访问速度

简介:

Varnish是一款高性能、开源的反向代理服务器和缓存服务器,官方说是squid的四倍,实际应用测试中虽然达不到四倍的性能,那也能达到1-2倍的效果。

Varnish和Squid的对比:

Squid 也是一种开源的代理缓存软件,下面对比 Varnish 和 Squid 的不同点。

Varnish的稳定性很好。两者在完成相同负载的工作时,Squid服务器发生故障的几率要高于Varnish,因此Squid需要经常重启。Varnish访问速度更快。Varnish采用了 Visual Page Cache技术,所有缓存的数据都直接从内存读取,而Squid从硬盘读取缓存的数据,所以Varnish在访问速度方面会更快一些。Varnish可以支持更多的并发连接。因为Varnish的TCP连接与释放比Squid快,所以在高并发连接情况下可以支持更多的TCP连接。Varnish可以通过管理端口来管理缓存,使用正则表达式就可以批量清除部分缓存,而Squid做不到这一点。

Varnish缺点:

Varnish在高并发状态下,CPU、I/O和内存等资源的开销高于Squid。Varnish的进程一旦挂起、崩溃或者重启,缓存的数据都会从内存中释放出来。此时的所有请求都会被发送到后端应用服务器上,在高并发的情况下,就会给后端服务器造成很大压力。

一、安装varnish

1.下载:https://www.varnish-cache.org/releases/varnish-cache-3.0.3

1

2

3

4

5

<code>yum </code><code>install</code> <code>-y </code><code>make</code> <code>automake pkgconfig libtool pcre-devel </code><code>#安装依赖包</code>

<code>tar</code> <code>zxvf varnish-3.0.3.</code><code>tar</code><code>.gz</code>

<code>.</code><code>/autogen</code><code>.sh</code>

<code>.</code><code>/configure</code> <code>--prefix=</code><code>/usr/local/varnish</code> <code>--</code><code>enable</code><code>-debugging-symbols --</code><code>enable</code><code>-developer-warnings --</code><code>enable</code><code>-dependency-tracking</code>

<code>make</code> <code>&amp;&amp; </code><code>make</code> <code>install</code>

2.创建用户、组和日志文件

<code>groupadd varnish</code>

<code>useradd</code> <code>-g varnish -s </code><code>/sbin/nologin</code> <code>varnish</code>

<code>touch</code> <code>/usr/local/varnish/access</code><code>.log </code><code>#创建访问日志文件</code>

<code>chown</code> <code>-R varnish.varnish </code><code>/usr/local/varnish</code>

二、修改配置varnish

前端varnish缓存是以轮询的方式分担到后端web服务器,以下vcl不对php进行缓存。

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

<code>vi</code> <code>/usr/local/varnish/etc/varnish/default</code><code>.vcl</code>

<code> </code><code>backend web1 {</code>

<code> </code><code>.host = </code><code>"192.168.0.203"</code><code>; </code><code>#后端web1服务器ip</code>

<code> </code><code>.port = </code><code>"80"</code><code>; </code><code>#通过80端口来访问后端web</code>

<code> </code><code>.connect_timeout = 1s;  </code><code>#连接超时时间</code>

<code> </code><code>.probe = {</code>

<code>        </code><code>.url = </code><code>"/"</code><code>;</code>

<code>        </code><code>.interval = 5s;</code>

<code>        </code><code>.timeout = 1 s;  </code><code>#检测超时时间</code>

<code>        </code><code>.window = 5;</code>

<code>        </code><code>.threshold = 3;</code>

<code>    </code><code>}</code>

<code> </code><code>}</code>

<code> </code><code>backend web2 {</code>

<code> </code><code>.host = </code><code>"192.168.0.204"</code><code>;</code>

<code> </code><code>.port = </code><code>"80"</code><code>;</code>

<code>director default round-robin { </code><code>#定义后端服务器组,默认轮询方式</code>

<code> </code><code>{</code>

<code> </code><code>.backend = web1;</code>

<code> </code><code>.backend = web2;</code>

<code>}</code>

<code> </code><code>sub vcl_recv {</code>

<code> </code><code>if</code> <code>(req.restarts == 0) {</code>

<code> </code><code>if</code> <code>(req.http.x-forwarded-</code><code>for</code><code>) {</code>

<code> </code><code>set</code> <code>req.http.X-Forwarded-For =</code>

<code> </code><code>req.http.X-Forwarded-For + </code><code>", "</code> <code>+ client.ip;</code>

<code> </code><code>else</code> <code>{</code>

<code> </code><code>set</code> <code>req.http.X-Forwarded-For = client.ip;</code>

<code> </code><code>if</code> <code>(req.request != </code><code>"GET"</code> <code>&amp;&amp;</code>

<code> </code><code>req.request != </code><code>"HEAD"</code> <code>&amp;&amp;</code>

<code> </code><code>req.request != </code><code>"PUT"</code> <code>&amp;&amp;</code>

<code> </code><code>req.request != </code><code>"POST"</code> <code>&amp;&amp;</code>

<code> </code><code>req.request != </code><code>"TRACE"</code> <code>&amp;&amp;</code>

<code> </code><code>req.request != </code><code>"OPTIONS"</code> <code>&amp;&amp;</code>

<code> </code><code>req.request != </code><code>"DELETE"</code><code>) {</code>

<code> </code><code>return</code> <code>(pipe);</code>

<code> </code><code>if</code> <code>(req.request != </code><code>"GET"</code> <code>&amp;&amp; req.request != </code><code>"HEAD"</code><code>) {</code>

<code> </code><code>return</code> <code>(pass);</code>

<code> </code><code>if</code> <code>(req.http.Authorization || req.http.Cookie) {</code>

<code> </code><code>return</code> <code>(lookup);</code>

<code> </code><code>sub vcl_pipe {</code>

<code> </code><code>sub vcl_pass {</code>

<code> </code><code>sub vcl_hash {</code>

<code> </code><code>hash_data(req.url);</code>

<code> </code><code>if</code> <code>(req.http.host) {</code>

<code> </code><code>hash_data(req.http.host);</code>

<code> </code><code>hash_data(server.ip);</code>

<code> </code><code>return</code> <code>(</code><code>hash</code><code>);</code>

<code> </code><code>sub vcl_hit {</code>

<code> </code><code>return</code> <code>(deliver);</code>

<code> </code><code>sub vcl_miss {</code>

<code> </code><code>return</code> <code>(fetch);</code>

<code> </code><code>sub vcl_fetch {</code>

<code> </code><code>if</code> <code>(beresp.ttl &lt;= 0s ||</code>

<code> </code><code>beresp.http.Set-Cookie ||</code>

<code> </code><code>beresp.http.Vary == </code><code>"*"</code><code>) {</code>

<code> </code><code>set</code> <code>beresp.ttl = 120 s;</code>

<code> </code><code>return</code> <code>(hit_for_pass);</code>

<code> </code><code>sub vcl_deliver {</code>

<code> </code><code>sub vcl_error {</code>

<code> </code><code>set</code> <code>obj.http.Content-Type = </code><code>"text/html; charset=utf-8"</code><code>;</code>

<code> </code><code>set</code> <code>obj.http.Retry-After = </code><code>"5"</code><code>;</code>

<code> </code><code>synthetic {"</code>

<code> </code><code>&lt;?xml version=</code><code>"1.0"</code> <code>encoding=</code><code>"utf-8"</code><code>?&gt;</code>

<code> </code><code>&lt;!DOCTYPE html PUBLIC </code><code>"-//W3C//DTD XHTML 1.0 Strict//EN"</code>

<code> </code><code>"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"</code><code>&gt;</code>

<code> </code><code>&lt;html&gt;</code>

<code> </code><code>&lt;</code><code>head</code><code>&gt;</code>

<code> </code><code>&lt;title&gt;</code><code>"} + obj.status + "</code> <code>" + obj.response + {"</code><code>&lt;</code><code>/title</code><code>&gt;</code>

<code> </code><code>&lt;</code><code>/head</code><code>&gt;</code>

<code> </code><code>&lt;body&gt;</code>

<code> </code><code>&lt;h1&gt;Error </code><code>"} + obj.status + "</code> <code>" + obj.response + {"</code><code>&lt;</code><code>/h1</code><code>&gt;</code>

<code> </code><code>&lt;p&gt;</code><code>"} + obj.response + {"</code><code>&lt;</code><code>/p</code><code>&gt;</code>

<code> </code><code>&lt;h3&gt;Guru Meditation:&lt;</code><code>/h3</code><code>&gt;</code>

<code> </code><code>&lt;p&gt;XID: </code><code>"} + req.xid + {"</code><code>&lt;</code><code>/p</code><code>&gt;</code>

<code> </code><code>&lt;hr&gt;</code>

<code> </code><code>&lt;p&gt;Varnish cache server&lt;</code><code>/p</code><code>&gt;</code>

<code> </code><code>&lt;</code><code>/body</code><code>&gt;</code>

<code> </code><code>&lt;</code><code>/html</code><code>&gt;</code>

<code> </code><code>"};</code>

<code> </code><code>sub vcl_init {</code>

<code> </code><code>return</code> <code>(ok);</code>

<code> </code><code>sub vcl_fini {</code>

语句解析:

Varnish处理请求的主要处理方法

1. vcl_recv

首先接收请求,判断是否要进一步处理,还是直接转发给后端(pass)等。 此过程中可以使用和请求相关的变量,例如客户端请求的url,ip,user-agent,cookie等,此过程中可以把不需缓存的地址,通过判断(相等、不相等、正则匹配等方法)转给后端,例如gif/png/jpg/css/js等静态文件;

2. vcl_fetch

当从后端服务器获取内容后会进入此阶段,除了可以使用客户端的请求变量,还可以使用从后端获取的信息(bersp),如后端返回的头信息,设置此信息的缓存时间TTL等;

3. vcl_miss

缓存未命中时中要做的处理

4. vcl_hit

缓存命中后做的处理

5. vcl_deliver

发送给客户端前的处理

6. vcl_pass

交给后端服务器

7. vcl_hash

设置缓存的键值key

Varnish处理流程

首次请求时过程如下:

recv-&gt;hash-&gt;miss-&gt;fetch-&gt;deliver

缓存后再次请求:

recv-&gt;hash-&gt;hit-&gt;deliver(fetch的过程没了,这就是我们要做的,把要缓存的页面保存下来)

直接交给后端pass的情况:

recv-&gt;hash-&gt;pass-&gt;fetch-&gt;deliver(直接从后端获取数据后发送给客户端,此时Varnish相当于一个中转站,只负责转发)

三、测试

1、启动

<code>/usr/local/varnish/sbin/varnishd</code> <code>-f </code><code>/usr/local/varnish/etc/varnish/default</code><code>.vcl -s malloc,512M -g varnish -u varnish -T 127.0.0.1:2000 -a 0.0.0.0:80</code>

-f:选项用于指定Varnishd使用的配置文件的路径。

-s malloc,2G:–s选项用来确定Varnish使用的存储类型和存储容量,这里使用的是malloc类型(malloc是一个C函数,用于分配内存空间),2G 定义多少内存被malloced。

-T:127.0.0.1:2000是Varnish基于文本方式的一个管理接口,启动后可以在不停止Varnish的情况下来管理Varnish。管理端口2000可以指定。因为不是任何人都可以访问Varnish管理端口,所以这里推荐只监听本机端口。

-a:0.0.0.0:80中-a选项表示Varnish监听所有IP发给80端口的HTTP请求。

2、设置varnish访问日志

<code>/usr/local/</code><code>var</code><code>nish/bin/</code><code>var</code><code>nishncsa -n /usr/local/</code><code>var</code><code>nish/</code><code>var</code><code>/</code><code>var</code><code>nish/test.com -a -w /usr/local/</code><code>var</code><code>nish/access.log &amp; #将</code><code>var</code><code>nish访问日志写入到access.log里</code>

<code>/usr/local/</code><code>var</code><code>nish/</code><code>var</code><code>/</code><code>var</code><code>nish/test.com :默认缓存目录</code>

<code>netstat -tuplan |grep </code><code>var</code><code>nish #查看是否启动</code><code>2000</code><code>和</code><code>80</code><code>端口</code>

<code>tcp </code><code>0</code> <code>0</code> <code>0.0</code><code>.</code><code>0.0</code><code>:</code><code>80</code> <code>0.0</code><code>.</code><code>0.0</code><code>:* LISTEN </code><code>28551</code><code>/</code><code>var</code><code>nishd</code>

<code>tcp </code><code>0</code> <code>0</code> <code>127.0</code><code>.</code><code>0.1</code><code>:</code><code>2000</code> <code>0.0</code><code>.</code><code>0.0</code><code>:* LISTEN </code><code>28550</code><code>/</code><code>var</code><code>nishd</code>

<code>tcp </code><code>0</code> <code>0</code> <code>:::</code><code>80</code> <code>:::* LISTEN </code><code>28551</code><code>/</code><code>var</code><code>nishd</code>

<code>curl -I http:</code><code>//ip #使用curl命令查看是否被缓存</code>

<code>killall -</code><code>9</code> <code>var</code><code>nishd #关闭</code><code>var</code><code>nish</code>

现在输入varnish服务器ip就可以访问到后端web服务器!

3、设置开机启动:

<code>echo</code> <code>'/usr/local/varnish/sbin/varnishd -f /usr/local/varnish/etc/varnish/default.vcl -s malloc,512M -g varnish -u varnish -T 127.0.0.1:2000 -a 0.0.0.0:80'</code> <code>&gt;&gt; </code><code>/etc/rc</code><code>.</code><code>local</code>

4、添加多个后端服务器

如果添加多个后端网站服务器,在default.vcl里面添加不同网站的访问请求转发到对应的backend去。

本文转自 李振良OK 51CTO博客,原文链接:http://blog.51cto.com/lizhenliang/1300036,如需转载请自行联系原作者

继续阅读