互联网早已惠及全人类, 我们可以通过网络与家人、朋友进行实时通信, 也能通过网络随时随地在各大电商站点上购物, 我们访问 web 站点的速度也越来越快, 这背后都是有很多精巧的架构以及各种先进的技术来支撑的, 我们就今天主要聊聊 Web 的缓存技术, 对于当今的互联网来说, Cahe Is King , 缓存真的有那么神奇么? 就由我来带领朋友们先领略一番当今最流行的开源缓存解决方案 Varnish 的风采
为什么需要缓存?
当今的 Web 站点, 特别是电商站点; 时常承受着高并发访问, 我们之前了解了一些负载均衡的解决方案可以将用户的请求调度到后端不同的服务器, 从而解决单台服务器不能承载高并发访问的情况; 但是我们如果将用户请求的 URL 所返回的页以特定存储方式存到特定的前端服务器中, 当用户再次请求相同资源时, 直接通过前端服务器响应给用户, 能够有效地减少后端服务器的的需要响应的次数
我们来举个例子:
不考虑负载均衡的情况下, 我们有一台工作在 prefork 模型下 LAMP 服务器, 2000个并发连接中有1600个都是静态页面, 只有400个是动态页面, 服务器需要1分钟响应完所有的请求, 大家都知道 prefork 模型一般情况下不能同时响应1024以上的连接数, 那么部分用户的请求就需要排队等待; 我们如果不修改 Apache 的工作模型, 该如何有效地解决这种问题呢?
这种时候我们就需要缓存了, 我们可以通过 Apache 带的缓存模块对用户请求的 URI 和响应的页面以特定的形式存储在特定介质上(内存、文件), 当有其他用户再次请求此 URI 可以直接通过文件中的内容响应给用户, 一般这种情况只适用于静态页面; 我们还可以通过 memcached 来提供 MySQL 查询结果的缓存, 这样的情况下, 我们对于动态页面的响应速度也上了一个台阶. 经过测试我们只需要10秒左右就能响应所有的请求
从上面的示例中我们可以看出缓存对 web 服务器整体性能的提升很大, 但是正常情况下, 我们都会通过特定的缓存服务器来提供缓存, 如 varnish , squid 等开源的程序
varnish简介
varnish 是一款非常流行的 http加速器 , 性能有可能比 squid 要好; 官方站点: varnish-cache.org
varnish
在请求的接收到响应中间的各个位置都有类似于 netfilter钩子函数 的东西, 我们称它们为 ate engine
具体相关知识查看官方文档, 和下面的图片
Varnish Architecture
图片源地址:http://book.varnish-software.com/3.0/Tuning.html
Varnish(v4) Work Flow
图片源地址:http://book.varnish-software.com/3.0/VCL_Basics.html
varnish的基本使用
varnish 的配置比较其他的服务有所不同, varnish 通过 VCL(varnish configuration language) 的语法来编写其配置文件, 并且编写完配置文件后还要对其进行编译(基于C编译器), 才能够使用
varnish简单的配置示例
多说无益, 我们先给大家做一个实验, 能够明白基本用法了
实验环境:
主机 | IP | 功用 |
---|---|---|
varnish | 172.16.1.12 | varnish node |
web1 | 1272.16.1.2 | httpd server |
配置过程和测试
注意: 本次实验, varnish主机的系统为CentOS7, varnish版本为4.0.3
以下操作在web服务器上执行
[root@web ~]# yum install httpd -y
[root@web ~]# vim /etc/httpd/conf/httpd.conf #编辑配置文件
Listen 8080 #修改监听端口为8080
[root@web ~]# echo "This is Web1" > /var/www/html/index.html #创建主页文件
[root@web ~]# service httpd start #启动httpd
以下操作在varnish
服务器上执行
[root@varnish ~]# yum install varnish -y #安装varnish
[root@varnish ~]# systemctl start varnish #启动varnish
[root@varnish ~]# vim /etc/varnish/varnish.params #编辑varnish的参数配置文件
VARNISH_LISTEN_PORT=80 # 修改PORT为80
VARNISH_STORAGE="malloc,256M" #修改缓存的存储方式为内存, 可以不修改
[root@varnish ~]# vim /etc/varnish/default.vcl #编辑varnish的主配置文件, 将default{}按照下面进行修改
backend default {
.host = "172.16.1.2"; #修改为后端的主机
.port = "8080"; #要和后端的http主机监听端口相同
}
[root@varnish ~]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082 #连接到varnish的管理工具
varnish> vcl.load test1 default.vcl #编译配置文件为test1
200
VCL compiled.
varnish> vcl.use test1 #使用test1
200
VCL \'test1\' now active
测试
测试访问和缓存效果
[root@node2 html]# curl 172.16.1.12 #通过node2访问varnish IP地址能够获取到web的网页资源
This is Web1
这时候我们查看一下web服务的日志, 可以看到是varnish主机GET index.html
172.16.1.12 - - [18/Apr/2016:22:37:04 0800] "GET / HTTP/1.1" 200 22 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.19.1 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
我们再次访问web, web的日志并没有更新
[root@node2 html]# curl 172.16.1.12
This is Web1
我们查看varnish的部分log如下
- VCL_call HASH
- VCL_return lookup
- Hit 2147483654
- VCL_call HIT #已经通过缓存响应给客户端
-
实现动静分离
通过上面的实验相信大家也看出来了, varnish 其实也是一个反向代理服务器, 下面我们使用 varnish 实现动静分离的效果
实验环境:
主机 | IP | 功用 |
---|---|---|
varnish | 172.16.1.12 | varnish主机 |
dynamic | 172.16.1.2 | 动态页面去主机 |
static | 172.16.1.3 | 静态页面主机(图片) |
本实验所有主机关闭iptables
和SElinux
配置过程和测试
web服务器配置过程
以下操作在dynamic下进行:
[root@dynamic ~]# yum install httpd php -y #安装httpd和php
[root@dynamic ~]# vim /etc/httpd/conf/httpd.conf #修改监听端口为8080
Listen 8080
[root@dynamic html]# vim /var/www/html/index.php #创建动态网页文件
<html>
<body>
![](1.gif)
<h1>This is Index on node1 dynamic</h1>
<?php
echo "<This is PHP Page";
?>
</body>
</html>
[root@dynamic html]# service httpd start #启动httpd
以下操作在static下进行
[root@static ~]# yum install httpd -y
[root@sttaic ~]# vim /etc/httpd/conf/httpd.conf #修改监听端口为8080
Listen 8080
[root@static ~]# vim /var/www/html/index.html #创建静态网页文件
<h1>This is Index on Node2 static </h1>
[root@static html]# ls #我们从本地上传了一张gif图
1.gif index.html
[root@static html]# service httpd start #启动httpd
varnish配置
以下操作在varnish主机上执行
[root@varnish ~]# vim /etc/varnish/default.vcl #编辑配置文件添加以下字段
backend dynamic {
.host = "172.16.1.2";
.port = "8080";
}
backend static {
.host = "172.16.1.3";
.port = "8080";
}
下面的字段在sub vcl_recv中添加
if (req.url ~ "(php|php5)$") {
set req.backend_hint = dynamic;
} else {
set req.backend_hint = static;
}
if (req.url ~ "(php|php5)$") {
return(pass); #如果请求动态页面不查缓存
}
}
[root@varnish varnish]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082
varnish> vcl.load test1 default.vcl
varnish> vcl.use test1
测试效果
我们访问index.html
我们访问index.php
网友评论