企业级服务架构组成-varnish
varnish
Varnish是一款高性能的开源HTTP加速器
varnish也可以用做反向代理,但是其最擅长的是web缓存加速。因此我们只使用它作缓存加速服务,而不是用作反向代理
squid与varnish
squid和varnish的关系类似于httpd与nginx的关系
早期的缓存服务器的常见方案是Squid
在中小规模的应用场景中,Varnish比Squid轻量级,但是单个Varnish所能承载的并发访问量在5000个左右
在较大规模的应用场景中,仍然可能看到Squid
客户对于某个页面的访问请求:
varnish第一次被访问时,相当于反向代理服务器
varnish第二次被访问及以后,相当于缓存服务器
初步使用varnish
部署服务时,要让软件性能和硬件参数相结合起来,使得性能最优
因此我们需要在使用varnish之前,先更改内核控制进程参数;其实,即便不更改参数,也可以使用varnish
安装varnish:
1.开启3个终端窗口,并分别远程连接server1,2,3三台虚拟机(其中,server1作为varnish缓存服务器;而server2,3则是作为http资源服务器使用;真实主机作为客户端去访问资源)
ssh root@172.25.60.1
2.安装3个包(varnish的安装包,以及其依赖)
yum install varnish-4.0.5-1.el7.x86_64.rpm jemalloc-3.6.0-1.el7.x86_64.rpm varnish-libs-4.0.5-1.el7.x86_64.rpm -y
配置系统参数,使得varnish在服务器上可以达到最优运行性能:
1.查看varnish最优性能运行下,对于系统内核参数的要求(内核参数不足varnish的最优运行需求也是可以运行varnish的,只是不能充分发挥varnish的性能)
vim /usr/lib/systemd/system/varnish.service # 并不更改参数,只是查看varnish最大性能对于内核参数的要求,并在接下来修改内核的参数
下面的是该文件中varnish对于内核参数的要求(最大打开文件数,最大占用内存大小)
# Maximum number of open files (for ulimit -n)
LimitNOFILE=131072
# Locked shared memory (for ulimit -l)
# Default log size is 82MB + header
LimitMEMLOCK=82000
2.查看目前的内核参数配置
ulimit -a
open files
max locked memory
查看所显示的上面两项参数是否符合varnish要求,不符合的话,去修改内核参数
3.更改内核参数的配置文件
vim /etc/security/limits.conf
# 在配置文件的底部添加以下内容
varnish - nofile 131072
varnish - memlock 82000
id varnish # 查看varnish安装后是否成功创建了varnish用户
ulimit -n 131072
ulimit -l 82
ulimit -a # 查看内核参数是否更改成功
ulimit -n 更改的是所有普通用户能使用的内核硬件资源限制
而 vim /etc/security/limits.conf 则是更改的是针对于varnish服务所能使用的内核资源限制
使用varnish:
1.切换到server2的终端窗口,下载apache
yum install httpd -y
2.在apache发布目录下,创建用于测试的index.html文件
cd /var/www/html
ls
vim index.html
systemctl start httpd
3.切换回到server1终端窗口,设置后端的实际的资源服务器的参数
vim /etc/varnish/default.vcl
# Default backend definition. Set this to point to your content server.
backend default { # 以下参数均是填写你所配置的varnish缓存服务器的后端(backend)资源服务器的参数
.host = "172.25.60.2";
.port = "80";
}
4.配置varnish的监听端口为80端口
(为了使得用户访问varnish缓存服务器时,体验更加接近于去访问真实的apache服务器;毕竟用户并不知道它所访问的只是缓存代理服务器,而不是真实的服务器)
vim /etc/varnish/varnish.params
# 更改下面的这个参数,使得它与后端资源服务器的监听端口一致
VARNISH_LISTEN_PORT=80
# 注意的是,不要改错了地方!!! 该参数下面还有一个参数VARNISH_ADMIN_LISTEN_PORT=6082,这两个参数看起来比较像,但这个参数并不需要更改,博主就改错了一次...
5.启动varnish服务,并查看端口是否开启
systemctl start varnish # 这里由于博主第一次更改配置文件时改错了参数,开启服务后,访问结果不对;因此,又重新更改了配置参数,在已经开启了varnish服务的情况下,只能restart重启服务才能使得配置的更改生效
netstat -antlp
6.切换到真实的物理主机的终端窗口,访问varnish服务器
curl 172.25.60.1 # 访问缓存服务器的数据,apache服务默认显示index.html文件的内容
curl -I 172.25.30.1 # 查看到详细信息
curl 172.25.60.1:/index.html # 访问缓存服务器的数据,varnish去后端apache服务器上找发布目录下的指定文件index.html
(curl 172.25.60.1/index.html也是可以访问到的)
curl 172.25.60.1:/index # 用户请求访问缓存服务器上的指定的文件index,在后端资源服务器上也找不到,于是服务返回一个我们常见到的404页面的html文件内容显示。
缓存命中测试:
上面我写到了,对于同一个页面资源的访问,varnish从第二次访问以后才是作为缓存服务器被使用。
那么,应当如何判断varnish服务器对于这次用户访问请求是作为反向代理服务器,还是作为高速缓存服务器呢?
这就需要配置/etc/varnish/default.vcl这个文件,这个文件是使用vcl语言写的,因此,是有着其特定的语法的,我们只需要按照前人所写的格式来写即可。
vim /etc/varnish/default.vcl (在配置文件底部vcl_deliver大括号内部增加)
if (obj.hits > 0) {
set resp.http.X-Cache = "Hit from westos cache";
}
else {
set resp.http.X-Cache = "MISS from westos cache";
}
return (deliver);
varnish清空服务器中的缓存数据:
varnishadm ban req.url "~" / # 清空varnish服务器中从根目录~(varnish发布目录)开始的全部数据
设置varnish访问后端资源服务器的策略
根据客户端访问的域名不同,varnish服务器去寻找不同的资源服务器:
即,定义不同的域名站点的相应的后端资源服务器
对于不同的访问域名www.westos.com 和 bbs.westos.com 返回的web地址不同
varnish反向代理更改http的request请求报文中的内容(工作于应用层)
而有的反向代理则是基于ip转发,工作在网络层
7层osi网络模型
应用层 这一层转发更加精准,但是需要占用tcp/ip握手连接,因此在网络层转发更好更快,不需要占用tcp连接
表示层
会话层
传输层
网络层 ip地址形式 从这向上都是以报文的形式
数据链路层 mac地址形式
物理层 0101二进制形式
1.更改varnish的配置文件
vim /etc/varnish/default.vcl
# Default backend definition. Set this to point to your content server.
backend default {
.host = "172.25.60.2";
.port = "80";
}
# 上面的这个是原来的访问策略——就只是访问默认的唯一的后端服务器
#将backend后端服务器配置参数复制一份,并将二者的名称更改为web1与web2,如下:
# Default backend definition. Set this to point to your content server.
backend web1 {
.host = "172.25.60.2";
.port = "80";
}
backend web2 {
.host = "172.25.60.3";
.port = "80";
}
# 还要更改下面的vcl_recv内部的参数设置,如下:
sub vcl_recv {
# Happens before we check if we have this in cache already.
#
# Typically you clean up the request here, removing cookies you don't need,
# rewriting the request, etc.
if (req.http.host ~ "^(www.)?westos.org") { # www.westos.org(或westos.org)的后端服务器为web1
set req.http.host = "www.westos.org";
set req.backend_hint = web1;
} elseif (req.http.host ~ "^bbs.westos.org") { # bbs.westos.org(或westos.org)的后端服务器为web1
set req.backend_hint = web2;
} else {
return (synth(405));
}
}
2.重启varnish服务
systemctl restart varnish
3.切换到server3的终端窗口,搭建apache服务并创建文件index.html用于测试
yum install httpd -y
cd /var/www/html
ls
vim index.html
systemctl start httpd
4.在真实主机中写对于要访问的域名的解析记录并分别访问3个网址
vim /etc/hosts
172.25.60.1 www.westos.org bbs.westos.org westos.org
curl www.westos.org
访问后端服务器的策略—负载均衡
lb(Load Balance)负载均衡
return (pass) 使varnish只做反向代理,不做缓存(缓存生效的时候,负载均衡不起效果) (先去找缓存,有了缓存就不去轮询了,一直是在访问web1服务器资源)
4.0 以后的varnish必须要导入模块,在# Default backend 上面写
现在,在上面功能的基础上,要使varnish服务器在接收访问(www.)westos.org域名请求时,根据负载均衡的轮询调度去平均地访问web1与web2两台后端服务器.而在访问bbs.westos.org这个域名时,则只会去访问web2这台后端服务器。
具体操作如下:
1.更改配置文件中对于后端资源服务器的访问策略
vim /etc/varnish/default.vcl
# 在上面所配置的文件基础上,在backend web2与sub vcl_recv两个大括号之间插入下面内容:
sub vcl_init {
new lb=directors.round_robin();
lb.add_backend(web1);
lb.add_backend(web2);
}
# 在sub vcl_recv大括号内部添加内容,使其变为如下:
sub vcl_recv {
# Happens before we check if we have this in cache already.
#
# Typically you clean up the request here, removing cookies you don't need,
# rewriting the request, etc.
if (req.http.host ~ "^(www.)?westos.org") {
set req.http.host = "www.westos.org";
set req.backend_hint = lb.backend();
return (pass);
} elseif (req.http.host ~ "^bbs.westos.org") {
set req.backend_hint = web2;
} else {
return (synth(405));
}
}
# 按ctrl+z,暂停该进程,因为要在该配置文件的前面导入一个模块来支持轮询调度
import directors from "/usr/lib64/varnish/vmods/libvmod_directors.so";
2.重启varnish服务
systemctl restart varnish
3.开启一个真实物理主机的终端,分别访问不同的域名,根据访问结果来测试配置是否成功
PHP网页前端服务推送页面
网页前端,自动清理缓存 当有活动更新,需要更新页面时,就是用这个一起推送,清空缓存
使用apache将这个前端页面显示的工具使用浏览器打开,为了避免与varnish的80端口冲突,导致服务起不来,将apache的80端口,更改为8080端口
vim cnfig.php 删除不需要的东西(因为我们目前没有数据库)
在前端页面中
选中http选项
.* 向所有的能访问到www.westos.org的varnish服务器推送
每次刷新推送页面,需要重新选择到http,否则默认的telnet会推送失败
在这里插入代码片