varnish是一款高性能且开源的反向代理服务器和Http加速器,开发者Poulhenning Kamp,其也是FreeBSD核心的开发人员之一,比较有名的应用安全当数,挪威最大的在线报纸Verdens Gang(vg.no)使用3台varnish代替了原有的12台squid,而且性能比以前更好,(思密达,google时都有此说明)可以运行于多种平台,如FreeBSD6.0,7.0 Solaris和Linux 2.6内核及以上版本的运行

一、原理概念介绍    

   1、varnish系统架构

   varnish主要运行两个进程:Management进程和Child进程(也叫Cache进程)。
   Management进程主要实现应用新的配置、编译VCL、监控varnish、初始化varnish以及提供一个命令行接口等。Management进程会每隔几秒钟探测一下Child进程以判断其是否正常运行,如果在指定的时长内未得到Child进程的回应,Management将会重启此Child进程。
   Child进程包含多种类型的线程,常见的如:
   Acceptor线程:接收新的连接请求并响应;
   Worker线程:child进程会为每个会话启动一个worker线程,因此,在高并发的场景中可能会出现数百个worker线程甚至更多;
   Expiry线程:从缓存中清理过期内容;
   Varnish依赖“工作区(workspace)”以降低线程在申请或修改内存时出现竞争的可能性。在varnish内部有多种不同的工作区,其中最关键的当属用于管理会话数据的session工作区。

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

varnish,squid二者的对比,如下

      说到varnish 就不得不提及同样是高性能的代理缓存功能的squid软件,

   相同点:
       都是反向代理软件
       都是开源软件
   不同点:
       在完成同样负荷的工作下,quid服务器故障的发生机率要高于varnish,原因是squid有时要经常重启
       varnish访问速度更快,其基于内存进行数据读取,而squid缓存代理的数据是存放在硬盘中的,要从硬盘读取数据到内存再响应用户的请求
       varnish对于TCP的连接释放要比squid快,因此在高并发连接情况下可以支持更多的TCP连接
       删除缓存方面,varnish可以通过管理端口,使用正则表达式批量删除部分缓存,而squid没有这项功能
当然varnish也有缺点:
       varnish在高并发状态下CPU,I/O和内存等相关资源开销都要高于squid
       varnish高并发状态下,进程一旦挂起,崩溃或重启,内存中的缓存数据则会完全释放,且此时大量的用户请求会发送到upstream server,这样会造成upstream server很大的压力,
   3、VCL
   Varnish Configuration Language (VCL)是varnish配置缓存策略的工具,它是一种基于“域”(domain specific)的简单编程语言,它支持有限的算术运算和逻辑运算操作、允许使用正则表达式进行字符串匹配、允许用户使用set自定义变量、支持if判断语句,也有内置的函数和变量等。使用VCL编写的缓存策略通常保存至.vcl文件中,其需要编译成二进制的格式后才能由varnish调用。事实上,整个缓存策略就是由几个特定的子例程如vcl_recv、vcl_fetch等组成,它们分别在不同的位置(或时间)执行,如果没有事先为某个位置自定义子例程,varnish将会执行默认的定义。
   VCL策略在启用前,会由management进程将其转换为C代码,而后再由gcc编译器将C代码编译成二进制程序。编译完成后,management负责将其连接至varnish实例,即child进程。正是由于编译工作在child进程之外完成,它避免了装载错误格式VCL的风险。因此,varnish修改配置的开销非常小,其可以同时保有几份尚在引用的旧版本配置,也能够让新的配置即刻生效。编译后的旧版本配置通常在varnish重启时才会被丢弃,如果需要手动清理,则可以使用varnishadm的vcl.discard命令完成。
   VCL用于让管理员定义缓存策略,而定义好的策略将由varnish的management进程分析、转换成C代码、编译成二进制程序并连接至child进程。varnish内部有几个所谓的状态(state),在这些状态上可以附加通过VCL定义的策略以完成相应的缓存处理机制,因此VCL也经常被称作“域专用”语言或状态引擎,“域专用”指的是有些数据仅出现于特定的状态中。
   VCL状态引擎
   在VCL状态引擎中,状态之间具有相关性,但彼此间互相隔离,每个引擎使用return(x)来退出当前状态并指示varnish进入下一个状态。
   varnish开始处理一个请求时,首先需要分析HTTP请求本身,比如从首部获取请求方法、验正其是否为一个合法的HTT请求等。当这些基本分析结束后就需要做出第一个决策,即varnish是否从缓存中查找请求的资源。这个决定的实现则需要由VCL来完成,简单来说,要由vcl_recv方法来完成。如果管理员没有自定义vcl_recv函数,varnish将会执行默认的vcl_recv函数。然而,即便管理员自定义了vcl_recv,但如果没有为自定义的vcl_recv函数指定其终止操作(terminating),其仍将执行默认的vcl_recv函数。事实上,varnish官方强烈建议让varnish执行默认的vcl_recv以便处理自定义vcl_recv函数中的可能出现的漏洞。
   VCL语法
   VCL的设计参考了C和Perl语言,因此,对有着C或Perl编程经验者来说,其非常易于理解。其基本语法说明如下:
       (1)//、#或/* comment */用于注释
       (2)sub $name 定义函数
       (3)不支持循环,有内置变量
       (4)使用终止语句,没有返回值
       (5)域专用
       (6)操作符:=(赋值)、==(等值比较)、~(模式匹配)、!(取反)、&&(逻辑与)、||(逻辑或)
   VCL的函数不接受参数并且没有返回值,因此,其并非真正意义上的函数,这也限定了VCL内部的数据传递只能隐藏在HTTP首部内部进行。VCL的return语句用于将控制权从VCL状态引擎返回给Varnish,而非默认函数,这就是为什么VCL只有终止语句而没有返回值的原因。同时,对于每个“域”来说,可以定义一个或多个终止语句,以告诉Varnish下一步采取何种操作,如查询缓存或不查询缓存等。
二、具体应用与设置

   1,一张图介绍varnish作为代理时,用户请求时的数据处理策略

   2,此次实验的具体架构

上图简单描述:

   对于用户不同的请求,varnish代理至不同的服务器,请求图片,静态页面时转到web1,请求动态页面时转到web2

以下为各配置文件具体配置

varnish的安装与配置:

##实验环境安装的包,centos6.5 64bitsrpm -ivh varnish-3.0.4-1.el6.x86_64.rpm  varnish-docs-3.0.4-1.el6.x86_64.rpm  varnish-libs-3.0.4-1.el6.x86_64.rpm

   安装后的文件及相关说明

具体配置文件/etc/sysconfig/varnish (只解释操作中用到的相关参数配置)

NFILES=131072MEMLOCK=82000NPROCS="unlimited"RELOAD_VCL=1VARNISH_VCL_CONF=/etc/varnish/my.vclVARNISH_LISTEN_PORT=80VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1VARNISH_ADMIN_LISTEN_PORT=6082VARNISH_SECRET_FILE=/etc/varnish/secretVARNISH_MIN_THREADS=50VARNISH_MAX_THREADS=1000VARNISH_THREAD_TIMEOUT=120VARNISH_STORAGE_FILE=/var/lib/varnish/varnish_storage.binVARNISH_STORAGE_SIZE=1GVARNISH_STORAGE="malloc,100m"VARNISH_TTL=120DAEMON_OPTS="-a ${VARNISH_LISTEN_ADDRESS}:${VARNISH_LISTEN_PORT} \             -f ${VARNISH_VCL_CONF} \             -T ${VARNISH_ADMIN_LISTEN_ADDRESS}:${VARNISH_ADMIN_LISTEN_PORT} \             -t ${VARNISH_TTL} \             -w ${VARNISH_MIN_THREADS},${VARNISH_MAX_THREADS},${VARNISH_THREAD_TIMEOUT} \             -u varnish -g varnish \             -S ${VARNISH_SECRET_FILE} \             -s ${VARNISH_STORAGE}"

配置文件/etc/varnish/my.vcl (自定义的文件只解释操作中用到的相关参数配置)

##/etc/varnish/my.vcl###################################backend web1 {  .host = "172.15.251.23";  .port = "80";}backend web2 {  .host = "172.15.251.24";  .port = "80";}director webservs random {{ .backend=web1; .weight = 10;  }{ .backend=web2;  .weight = 2;  }}acl purgers {   "127.0.0.1";   "172.15.0.0"/16;}sub vcl_recv {  if(req.url ~ "\.(html|js|css|png)$") {   set req.backend = web1;} else {    set req.backend = web2; }set req.request = webservs;  if (req.request == "PURGE") {     if (!client.ip ~ purgers) {    error 405 "Method not allowed.";}}   return(lookup);}sub vcl_deliver {  if (obj.hits > 0) {    set resp.http.X-Cache = "HIT from" + server.hostname; } else {    set resp.http.X-Cache = "MISS";}}

到此varnish相关配置完成

配置静态文件服务器(p_w_picpaths,html等静态文件 172.16.251.23)

   yum install -y httpd

   复制1.png文件,新建index.html到目录/var/www/html,如下图:

网页index.html内容如下

[root@node3 html]# pwd/var/www/html[root@node3 html]# ls1.png  index.html[root@node3 html]# cat index.html

Hi,this is real server 23

[root@node3 html]#

配置动态web服务器(以tomcat jsp测试环境为例 172.16.251.24)

   安装Tomcat并配置文件路径,如下图:

[root@node4 software]# tar -xf apache-tomcat-7.0.42.tar.gz -C /usr/local/[root@node4 software]# cd /usr/local/[root@node4 local]# ln -sv apache-tomcat-7.0.42 tomcat[root@node4 local]# cat /etc/profile.d/tomcat.shexport CATALINA_HOME=/usr/local/tomcatexport PATH=$CATALINA_HOME/bin:$PATH[root@node4 local]# source /etc/profile.d/tomcat.sh[root@node4 local]#

   注:由于tomcat启动默认监听8080端口,要修改为80,具体如下:

       找文件/usr/local/tomcat/conf/server.xml 中port="8080" 修改为port="80",重新启动tomcat即可  

   为tomcat增加启动服务

   增加tomcat 服务启动脚本,如下:

#!/bin/sh# Tomcat init script for Linux.## chkconfig: 2345 96 14# description: The Apache Tomcat servlet/JSP container.# JAVA_OPTS='-Xms64m -Xmx128m'JAVA_HOME=/usr/java/lastestCATALINA_HOME=/usr/local/tomcatexport JAVA_HOME CATALINA_HOMEcase $1 instart)  exec $CATALINA_HOME/bin/catalina.sh start ;;stop)  exec $CATALINA_HOME/bin/catalina.sh stop;;restart)  $CATALINA_HOME/bin/catalina.sh stop  sleep 2  exec $CATALINA_HOME/bin/catalina.sh start ;;*)  echo "Usage: `basename $0` {start|stop|restart}"  exit 1  ;;esac

   安装JDK,如下图:

[root@node4 software]# rpm -ivh jdk-7u9-linux-x64.rpm[root@node4 software]# cat /etc/profile.d/java.shexport JAVA_HOME=/usr/java/latestexport PATH=$JAVA_HOME/bin:$PATH[root@node4 software]# source /etc/profile.d/java.sh[root@node4 software]#

Tomcat环境测试安装成功,如下图:

   万事倶备,只差进行varnish动静分离测试(思密达)。。。。。。。。。。。

三 varnish 测试

   启动varnish

       service varnish start

   查看监听的商品:80 web反向代理服务端口,6082管理端口

   登陆管理控制台(交互式命令行)并查看帮助

启用策略文件/etc/varnish/my.vcl

动静资源回顾:

   172.16.251.23服务器上的为p_w_picpaths,html等

   172.16.251.24服务器上的为JSP、do动态网页文件等

通过访问 、 varnish直接代理至后端realserver 172.15.251.23

通过访问  varnish直接代理至后端realserver 172.15.251.24

后记:随堂学习感觉是喝凉水,但自己动手还是感觉在吃硬馒头,长篇大论了好几页,感觉重点的还是没有提到,后续工作还有很多,如静态文件的存储方案,高可用可扩展的地方,先这么多