Flag Counter
© 2017 Tao Peng. All rights reserved.

(反向代理 + cache) varnish 使用 (实例)


2016年11月08日

###1. 简介

Varnish是什么? 额, 一周前我也不知道, Orz… 不过现在知道了233333. 不清楚的点这里.
简单来说, varnish是一款高性能且开源的反向代理服务器和Http加速器, 类似于squid. 关于varnish的具体的流程&原理, 本文不做讲述, 之后看源码的时候再说. 这里”摘抄”一些varnish的特点以及和squid的对比(摘抄连接文末给出):

varnish一些特点:

1.基于内存进行缓存,速度快但服务重启数据将消失的缺点
2.由于基于内存进行缓存,其I/O性能相当的好
3.支持设置0到60秒的精确缓存时间
4.VCL(varnish configure language)配置管理灵活易懂

varnish,squid二者的对比,如下:

<font color=#0099ff>相同点:</font>
1.都是反向代理软件
2.都是开源软件
<font color=#0099ff>不同点:</font>
1.在完成同样负荷的工作下,quid服务器故障的发生机率要高于varnish,原因是squid有时要经常重启
2.varnish访问速度更快,其基于内存进行数据读取,而squid缓存代理的数据是存放在硬盘中的,要从硬盘读取数据到内存再响应用户的请求
3.varnish对于TCP的连接释放要比squid快,因此在高并发连接情况下可以支持更多的TCP连接
4.删除缓存方面,varnish可以通过管理端口,使用正则表达式批量删除部分缓存,而squid没有这项功能

相对于squid来说, varnish的缺点:

1.varnish在高并发状态下CPU,I/O和内存等相关资源开销都要高于squid
2.varnish高并发状态下,进程一旦挂起,崩溃或重启,内存中的缓存数据则会完全释放,且此时大量的用户请求会发送到server,这样会造成server很大的压力

Varnish的强大还在于, 有一个叫VCL的配置文件可以供我们使用, 请见: varnish 配置语言 VCL.

关于Varnish的介绍到此结束.

###2. 实验

环境:
本机: Mac OS X 10.11.3
虚拟机: virtual box, 安装3个ubuntu虚拟机
虚拟机: 分别安装tomcat, Apache 2, varnish

本实验基本架构图如下:


13


####1). 安装虚拟机

mac 安装virtual box很简单, 点击 virtualbox 下载.

新建虚拟机如下图所示: 我装的是Linux 64bits系统, ubuntu 12.04 (当然你可以安装任何喜欢的Linux系统)下载镜像地址: ubuntu-releases.


1

安装好虚拟机后, 需要注意的是, 配置网络问题, virtual box的网络连接模式必须配置为 “桥接模式”, 如下图:


2

“桥接模式” 使得虚拟机和本机一样能够分片到同一个局域网的IP.
<font color=#0099ff>注意: </font>有些限制网络没法使用”桥接模式”, 例如公司的一些网络, 如果这样, 额… 回家再玩吧, Orz…

OK, 现在检测三个虚拟机之间能够ping通, 那么虚拟机安装就OK了.

最终三台机器的IP如下:

test1: 192.168.0.106/24
test2: 192.168.0.107/24
test3: 192.168.0.108/24


####2). test1 虚拟机安装Tomcat

在第一个机器上安装Tomcat, 用于请求动态资源.

  1. test1 安装的Tomcat8, 下载地址: tomcat.
  1. 解压文件: tar -zxvf apache-tomcat-8.5.6.tar.gz, 并将解压后的文件copy到/opt/tomcat下. 不copy也行, 下面设置TOMCAT_HOME设置成自己的路径就OK.
  1. cd /opt/tomcat/apache-tomcat-8.5.6/, 注意, 如果文件没有权限, 那么需要chmod一下!
  1. 下载jdk, 如果有了就不需要了. 我下载的是1.8版本. 我的JAVA SDK放在home目录的java_home下.
  1. 设置JDK的环境变量.
    export JAVA_HOME='/home/test1/java_home/jdk1.8.0_111',
    export JRE_HOME='/home/test1/java_home/jdk1.8.0_111/jre',
    export TOMCAT_HOME='/opt/tomcat/apache-tomcat-8.5.6/'
    如果想要开机就使得上面的环境变量有效, 那么需要在 “/etc/profile”中写入上面的语句, 这个文件在开机的时候会被读取.
  1. 下面进入tomcat目录下, cd /opt/tomcat/apache-tomcat-8.5.6/, 然后在 “./bin/startup.sh” 文件中增加下面两句:
    PATH=$JAVA_HOME/bin:$JRE_HOME:$PATH
    CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar


3

保存退出后需要启动Tomcat, sudo ./bin/startup.sh, 启动后 ps -ef | grep tomcat看一下进程是否真的起起来了, 如果没有 应该是前面的路径配置有问题. 然后我们进入: “http://127.0.0.1:8080” 看一下能不能看到页面, 如果能那就OK.


4

此时, 如果之前的test1, test2, test3三台机器之间能够ping通, 那么在test2和test3上访问: http://192.168.0.106:8080, 也是 能够看到上面的页面的!

注意: tomcat 默认端口是: 8080.


####3). test2 虚拟机安装Apache 2

在test2机器上, 安装静态资源服务器:

sudo apt-get install apache2

安装完成后, 在/var目录下会发现www文件目录, 这个里面放置的就是静态资源文件, 安装好后, 里面应该就有 “index.html” 文件了, 现在 sudo apache2 start 启动Apache server, 然后访问: http://127.0.0.1, 理论上网页应该就能打开了.


5

现在我们加一个图片 “1.jepg”(如下图) 到目录下, 访问http://127.0.0.1/1.jepg就能获取相应的图片资源.


6

注意: Apache 默认端口是: 80.


####4). test3 虚拟机安装 Varnish

ubuntu安装varnish很简单:

sudo apt-get install varnish

首先我们看一下varnish的配置文件, 在test3上的有一个”/etc/default/varnish”文件, 如果你的机器上不是, 那么请sudo find / -name "varnish" 找一下这个文件的位置.


7

表明默认端口号是6081, VCL文件是default.vcl(这个VCL文件在”/etc/varnish/”下面), 还有默认分配的缓存空间大小是256M(生产环境中需要加大!) 等等信息.

现在我们写一个自己的VCL文件, 功能是根据访问的资源不同, 转向不同的server请求:

# server1用于请求动态文件, tomcat, 默认port: 8080
backend server1 {
    .host="192.168.0.106";
    .port="8080";
}

# server2用于请求静态文件,apache, 默认port: 80
backend server2 {
    .host="192.168.0.107";
    .port="80";
}

# 设置两个server不同的权重
# 此处用的是随机director, 在VCL篇有详细讲述
director servers random {
    {.backend=server1;
     .weight=2;}
    {.backend=server2;
     .weight=10;}
}

# 控制列表,设置允许清除varnish缓存的机器
acl purgers {
    "127.0.0.1";
    "192.168.0.0"/24;
}

# 定义不同资源访问server策略
sub vcl_recv {
    # 如果是下面结尾的文件访问, 那么request的backend server转向server2
    # 否则是server1
    if (req.url ~ "\.(html|js|css|png|jepg)$") {
        set req.backend=server2;
    } else {
       set req.backend=server1;
    }

    # 判断删除缓存主机是否是我们定义的主机
    set req.request=servers;
    if (req.request=="PURGE") {
        if (!client.ip ~ purgers) {
            error 405 "Method not allowed!";
        }
    }

    return(lookup);
}

# 对于缓存命中的请求,响应时在头部显示是哪台机器
sub vcl_deliver {
    # 如果返回的object中说明缓存命中了, 那么我们记下一条log
    if (obj.hits > 0) {
        set resp.http.X-Cache="Hit from: " + server.hostname;
    } else {
        set resp.http.X-Cache="Miss hit";
    }
}

OK, 现在进入 cd /etc/varnish目录下, 创建”mytest.vcl”文件, 然后将之前的”/etc/default/varnish”文件改成:


8

我们将http端口改成了80, 使用之前的也是OK的, 不过url后面需要加上:6081; 然后将自己写的 “mytest.vcl” 文件配置进去, 现在启动 varnish:

sudo service varnish start

然后 ps -ef | grep varnish看一下是不是成功:


9

看起来好像没问题, OK, 那么现在在test3上再次访问:

#
# 需要注意, 我现在访问的是192.168.0.108地址, 是test3地址, 即varnish地址
# 我们之前直接访问test1和test2的地址当然是可以访问资源的, 现在访问资源相当于
# 是varnish帮助client进行代理访问了!!!这就是varnish反向代理功能.
#
# 下面还会演示cache功能.
#

http://192.168.0.108/index.jsp  --> test1
http://192.168.0.108/index.html --> test2
http://192.168.0.108/1.jepg     --> test2

OK, 如果没什么问题上面肯定是可以访问的!

那么我们怎么知道varnish是不是cache了呢?

那么我们看之前的一段子程序:

sub vcl_deliver {
    # 如果返回的object中说明缓存命中了, 那么我们记下一条log
    if (obj.hits > 0) {
        set resp.http.X-Cache="Hit from: " + server.hostname;
    } else {
        set resp.http.X-Cache="Miss hit";
    }
}

这个子程序修改了response的http的header中的X-cache字段, 那么我下面这样测试:

在test3机器上, 使用:

curl -I http://192.168.0.108/index.html

第一次访问我们发现:


10

第二次访问我们发现:


11

哈哈~ 赞~

对于:

curl -I http://192.168.0.108/index.jsp
curl -I http://192.168.0.108/1.jepg

也是一样的, 不信自己试一下~~~

OK, 看起来这篇博客应该可以结束了哈~ 关于代码级别的以后再写吧~ 睡觉~

###3. 参考
Varnish 入门
varnish详解与实际应用案例
查看Varnish缓存效果与状态