varnish3----进阶配置
varnish3----进阶配置
varnish进阶配置
用户 -req.*(用户发过来的请求方法)
-> varnish代理 -bereq.*(发往后端主机的 http 请求首部的值)
-> 后端服务
后端服务 -beresp.*
-> varnish代理 -resp.*
-> 用户
实例1,对公开的图片取消cookie,并设定缓存时间
修改varnish配置文件
vim /etc/varnish/default.vcl
sub vcl_backend_response {
if (beresp.http.cache-control !~ "s-maxage") {
if (bereq.url ~ "(?i)\.(jpg|jpeg|png|gif|css|js)$") {
unset beresp.http.Set-Cookie;
set beresp.ttl = 3600s;
}
}
}
重载varnish
vcl.load testvcl3 default.vcl
vcl.use testvcl3
客户端访问
[root@localhost web1]# curl 192.168.10.2:6081/1.jpg -I
HTTP/1.1 403 Forbidden
Server: nginx/1.14.2
Date: Thu, 12 Aug 2021 05:58:32 GMT
Content-Type: text/html
Content-Length: 169
X-Varnish: 65596 32827
Age: 324
Via: 1.1 varnish-v4
X-Cache: Hit via 192.168.10.2
Connection: keep-alive
实例2,缓存对象的修剪:purge, ban,删除某缓存项
简单版,仅实现功能
修改varnish配置文件
vim /etc/varnish/default.vcl
sub vcl_purge {
return (synth(200,"Purged"));
}
sub vcl_recv {
if (req.method == "PURGE") {
return(purge);
}
}
重载varnish
vcl.load testvcl4 default.vcl
vcl.use testvcl4
测试访问curl使用自定义方法PURGE
当前是被命中的
[root@localhost web1]# curl 192.168.10.2:6081/1.jpg -I
HTTP/1.1 403 Forbidden
Server: nginx/1.14.2
Date: Thu, 12 Aug 2021 05:58:32 GMT
Content-Type: text/html
Content-Length: 169
X-Varnish: 18 32827
Age: 2020
Via: 1.1 varnish-v4
X-Cache: Hit via 192.168.10.2
Connection: keep-alive
使用PURGE方法删除缓存项
[root@localhost web1]# curl 192.168.10.2:6081/1.jpg -X PURGE
<!DOCTYPE html>
<html>
<head>
<title>200 Purged</title> #返回值
</head>
<body>
<h1>Error 200 Purged</h1>
<p>Purged</p>
<h3>Guru Meditation:</h3>
<p>XID: 98317</p>
<hr>
<p>Varnish cache server</p>
</body>
</html>
当前未被命中
[root@localhost web1]# curl 192.168.10.2:6081/1.jpg -I
HTTP/1.1 200 OK
Server: nginx/1.14.2
Date: Thu, 12 Aug 2021 06:32:26 GMT
Content-Type: image/jpeg
Content-Length: 961243
Last-Modified: Thu, 12 Aug 2021 05:58:01 GMT
ETag: "6114b869-eaadb"
X-Varnish: 20
Age: 0
Via: 1.1 varnish-v4
X-Cache: Miss from 192.168.10.2
Connection: keep-alive
加强版----注意:这样任何人都可以删除缓存,建议做访问控制
varnish配置文件添加访问控制并做if判断
acl purgers {
"127.0.0.0"/8;
#"10.1.0.0"/16;
}
sub vcl_recv {
if (req.method == "PURGE") {
if (!client.ip ~ purgers) { # 这里正则匹配的时 acl 列表,不需要引号
return (synth (405,"Purging not allowed for" + client.ip)); #来自不属于 acl 定义的 purgers 组的 purge 请求则返回错误代码
}
return(purge);
}
}
重载varnish
vcl.load testvcl5 default.vcl
vcl.use testvcl5
客户端测试访问
允许
[root@localhost ~]# curl 127.1:6081/1.jpg -X PURGE
<!DOCTYPE html>
<html>
<head>
<title>200 Purged</title>
</head>
<body>
<h1>Error 200 Purged</h1>
<p>Purged</p>
<h3>Guru Meditation:</h3>
<p>XID: 32842</p>
<hr>
<p>Varnish cache server</p>
</body>
</html>
拒绝
[root@localhost ~]# curl 192.168.10.2:6081/1.jpg -X PURGE
<!DOCTYPE html>
<html>
<head>
<title>405 Purging not allowed for192.168.10.2</title>
</head>
<body>
<h1>Error 405 Purging not allowed for192.168.10.2</h1>
<p>Purging not allowed for192.168.10.2</p>
<h3>Guru Meditation:</h3>
<p>XID: 65628</p>
<hr>
<p>Varnish cache server</p>
</body>
</html>
注意:修剪和访问不是同一项,会有不同的结果,可以查看下varnish默认配置规则
vcl.show -v boot
sub vcl_hash {
hash_data(req.url);
if (req.http.host) {
hash_data(req.http.host);
} else {
hash_data(server.ip);
}
return (lookup);
}
修改varnish配置文件,若多个虚拟主机应用IP/域名是同一台
sub vcl_hash {
hash_data(req.url);
return(lookup);
}
重载varnish
vcl.load testvcl6 default.vcl
vcl.use testvcl6
测试访问
使用127地址修剪
[root@localhost ~]# curl 127.1:6081/1.jpg -X PURGE
<!DOCTYPE html>
<html>
<head>
<title>200 Purged</title>
</head>
<body>
<h1>Error 200 Purged</h1>
<p>Purged</p>
<h3>Guru Meditation:</h3>
<p>XID: 32847</p>
<hr>
<p>Varnish cache server</p>
</body>
</html>
使用外部地址访问
[root@localhost web1]# curl 192.168.10.2:6081/1.jpg -I
HTTP/1.1 200 OK
Server: nginx/1.14.2
Date: Thu, 12 Aug 2021 07:54:22 GMT
Content-Type: image/jpeg
Content-Length: 961243
Last-Modified: Thu, 12 Aug 2021 05:58:01 GMT
ETag: "6114b869-eaadb"
X-Varnish: 65632
Age: 0
Via: 1.1 varnish-v4
X-Cache: Miss from 192.168.10.2
Connection: keep-alive
如果要修剪多个项,可以使用ban
交互式终端
ban req.url ~ (?i).jpg$
测试访问
[root@localhost web1]# curl 192.168.10.2:6081/1.jpg -I
HTTP/1.1 200 OK
Server: nginx/1.14.2
Date: Thu, 12 Aug 2021 08:40:31 GMT
Content-Type: image/jpeg
Content-Length: 961243
Last-Modified: Thu, 12 Aug 2021 05:58:01 GMT
ETag: "6114b869-eaadb"
X-Varnish: 65637 32852
Age: 1
Via: 1.1 varnish-v4
X-Cache: Hit via 192.168.10.2
Connection: keep-alive
动静分离
用户请求 --> 后端服务 --> 由后端服务调度 --> 静态转发给B,动态给A
在启动一个容器做为静态服务
docker run --name web1 -d --net bridge -v /data/web1:/usr/share/nginx/html/ nginx:1.14-alpine
修改varnish配置文件
/etc/varnish/default.vcl
backend default {
.host = "172.17.0.2";
.port = "80";
}
backend imgsrv {
.host = "172.17.0.3";
.port = "80";
}
sub vcl_recv {
if (req.url ~ "(?i)\.(jpg|png|gif)$") {
set req.backend_hint = imgsrv;
return (pass); #为了查看效果,可以PASS,下面有策略缓存策略的
} else {
set req.backend_hint = default;
}
}
重新装载varnish
vcl.load testvcl7 default.vcl
vcl.use testvcl7
测试验证
[root@localhost ~]# curl -I 192.168.10.2:6081/2.jpg
HTTP/1.1 200 OK
Server: nginx/1.14.2
Date: Fri, 13 Aug 2021 02:37:17 GMT
Content-Type: image/jpeg
Content-Length: 980265
Last-Modified: Fri, 13 Aug 2021 02:29:52 GMT
ETag: "6115d920-ef529"
Accept-Ranges: bytes
X-Varnish: 32869
Age: 0
Via: 1.1 varnish-v4
X-Cache: Miss from 192.168.10.2
Connection: keep-alive
查看docker日志
docker logs -f web2
172.17.0.1 - - [13/Aug/2021:02:37:15 +0000] "HEAD /2.jpg HTTP/1.1" 200 0 "-" "curl/7.29.0" "192.168.10.2"
实例,使用不同的调度算法
将无状态和有状态调度分开,采用不同的调度算法
修改配置文件
import directors; #建议写在backend项上面
sub vcl_init { #建议写在backend项下面, vcl_init 状态引擎中配置初始化一个组,然后把这两台主机加到对应的组中;
new webservs = directors.round_robin(); #表示用 directors 模块中的 round_robin () 方法初始化一个组对象,取名叫 webservs;此组有两个成员default、imgsrv,此成员之前实例已经定义好了
webservs.add_backend(default);
webservs.add_backend(imgsrv);
}
为了更于验证效果,更新此项
sub vcl_recv {
set req.backend_hint = webservs.backend();
return (pass); 这里为了更好的验证,若实际应用可取消此项
}
补充
补充:directors.round_robin () 用这个方法初始化组对象表示往后端调度的算法是轮询,即没有权重;要想有权重,需要用 directors.random () 方法;如果需要做会话保持,需要用到 directors.hash () 方法;
基于随机调度方法,支持服务器权重
sub vcl_init {
new webservs = directors.random(); #命令random方法
webservs.add_backend(default,2); #后面2表示权重
webservs.add_backend(imgsrv,3);
}
基于cookie的session sticky
sub vcl_init {
new webservs = directors.hash(); #使用hash方法
webservs.add_backend(default,2); #server名称后面表示权重
webservs.add_backend(imgsrv,3);
}
重载varnish
vcl.load testvcl8 default.vcl
vcl.use testvcl8
客户端验证
[root@localhost ~]# for i in {1..10};do curl 192.168.10.2:6081/test.html ; sleep 1;done
this is nginx web1 test
this is nginx web2 test
this is nginx web1 test
this is nginx web2 test
this is nginx web1 test
this is nginx web2 test
this is nginx web1 test
this is nginx web2 test
this is nginx web1 test
this is nginx web2 test
实例,健康检测
健康检查比如10次有8次成功,这样更靠谱
修改配置文件
probe healthchk { #定义一组健康检查名称
.url = "/test.html"; #请求主机上的 /test.html 资源,此处是字符串,注意加双引号
.timeout = 1s; #表示超长时长
.interval = 2s; #表示检查的频度,每隔多久检查一次,根据实际情况设置
.window = 6; # 表示基于最近的多少次检查来判读其健康状态
.threshold = 4; #表示最近.window 中定义的检查次数至少有多少次是成功的,简单来说大于或等于
}
backend default {
.host = "172.17.0.2";
.port = "80";
.probe = healthchk; #应用healthchk项
}
backend imgsrv {
.host = "172.17.0.3";
.port = "80";
.probe = healthchk;
}
重载varnish
vcl.load testvcl9 default.vcl
vcl.use testvcl9
验证
varnish> backend.list
200
Backend name Refs Admin Probe
default(127.0.0.1,,80) 1 probe Healthy (no probe)
default(172.17.0.2,,80) 12 probe Healthy 6/6
imgsrv(172.17.0.3,,80) 3 probe Healthy 6/6
[root@localhost ~]# while true;do curl 192.168.10.2:6081/test.html ; sleep 1;done
this is nginx web1 test
this is nginx web2 test
关闭后端服务在验证
docker stop web1
varnish> backend.list
200
Backend name Refs Admin Probe
default(127.0.0.1,,80) 1 probe Healthy (no probe)
default(172.17.0.2,,80) 13 probe Sick 3/6 #此处3<6,所有是Sick标志
imgsrv(172.17.0.3,,80) 3 probe Healthy 6/6
测试访问的页面
[root@localhost ~]# while true;do curl 192.168.10.2:6081/test.html ; sleep 1;done
this is nginx web2 test
this is nginx web2 test
在启动web1
docker start web1
varnish> backend.list
200
Backend name Refs Admin Probe
default(127.0.0.1,,80) 1 probe Healthy (no probe)
default(172.17.0.2,,80) 12 probe Healthy 4/6 #Healthy 已经激活
imgsrv(172.17.0.3,,80) 3 probe Healthy 6/6
sick使用
将某台主什么打上标志下线,迭代版本完成之后,更新标志重新上线
varnish> help backend.set_health
200
backend.set_health <backend_expression> <state>
Set health status on the backends.
varnish> backend.list
200
Backend name Refs Admin Probe
default(127.0.0.1,,80) 1 probe Healthy (no probe)
default(172.17.0.2,,80) 12 probe Healthy 6/6
imgsrv(172.17.0.3,,80) 3 probe Healthy 6/6
varnish> backend.set_health imgsrv sick
200
varnish> backend.list
200
Backend name Refs Admin Probe
default(127.0.0.1,,80) 1 probe Healthy (no probe)
default(172.17.0.2,,80) 12 probe Healthy 6/6
imgsrv(172.17.0.3,,80) 3 sick Healthy 6/6
以自动探测结果为准
varnish> backend.set_health imgsrv auto
200
varnish> backend.list
200
Backend name Refs Admin Probe
default(127.0.0.1,,80) 1 probe Healthy (no probe)
default(172.17.0.2,,80) 12 probe Healthy 6/6
imgsrv(172.17.0.3,,80) 3 probe Healthy 6/6
varnish简单优化
varnish是单进程模型的,内部靠线程来维持与客户端连接,而最大连接并发数多少个是靠线程池的数量和每一个线程池的所能承载连接的数量来定义,varnish内部这些参数称运行时参数,可动态修改立即生效
varnish> param.show -l
thread_pool_min
每个池中的最小工作线程数。增加此值可能有助于在低负载情况下或线程过期时加快速度。最少 10 个线程,最大 5000
最大空间线程数,简单来说就是服务启动启动多少个线程,便于承载更多的连接请求
thread_pools
工作线程池的数量。建议根据物理或逻辑核心数据来决定,还要考虑其他进程是否占用某个核心,可对应用进行CPU绑定,减少线程在CPU核心来回切换,减少时延
增加工作池的数量会减少锁争用。太多的池会浪费 CPU 和 RAM 资源,每个 CPU 超过一个池可能对性能不利 可以在 fTy 上增加。但减少需要重新启动才能生效
使用varnishadm设置
param.set thread_pools 4
param.show thread_pools
可以将参数写入配置文件,注意格式 -p 参数=值
vim /etc/varnish/varnish.params
DAEMON_OPTS="-p thread_pools=4 -p thread_pool_min=5 -p thread_pool_max=500 -p thread_pool_timeout=300"
varnish日志
varnish日志存放在内存中,大概90M的空间
varnish日志有两种记录方式,varnishlog和varnishncsa,日志分别存放在/var/log/varnish/{varnish.log,varnishncsa.log}
可以执行varnishlog或varnisncsa命令,日志信息在终端上显示,注意此模式只有被访问,才能显示日志相关信息
varnishncsa和nginx访问日志类似
systemctl start varnishncsa varnishlog
varnishncsa
varnishlog
varnish统计相关数据工具
varnishtop 工具读取共享内存的日志,然后连续不断的显示和更新大部分普通日志
varnishstat 有很多计数器,我们计数丢失率,命中率,存储信息,创建线程,删除对象等,几乎所有的操作
varnishhist 取 varnishd 的共享内存段日志,生成一个连续更新的柱状图,显示最后 N 个请求的处理情况。这个 N 的值是终端的纵坐标的高度,横坐标代表的是对数,如果缓存命中就标记 “|”,如果缓存没有命中就标记上 “#” 符号
小结
前端状态机 vcl_recv,vcl_hash,vcl_pass,vcl_pipe,cvl_deliver,vck_synth
后端状态机 vcl_backend_fetch,val_backend_error,vcl_backend_reponse
vcl_init,vcl_fini,在任何连接处理之前
varnish:http代理,page cache缓存
reids: 存储系统
squid httpd一般是正向代理 varnish一般是反向代理
缓存分两种,代理层,旁路模式下(客户端自身知道如何驱动缓存)
php解释器 --> php功能驱动模块,其实就是mysql客户端 --> mysql
对象式编程
程序=算法+数据结构
程序=指令+数据
以数据为中心,事先打算完成功能抽象独立的实体或类别,真正的代码运行将这类别实例化具体可操作的数据结构,让数据结构与数据结构之间通过对方结构所支持的方式完成调用
过程式编程
数据结构服务于算法,数据服务指令,关注事物演变过程
设计算法,设定指令流程
目前互联网分布式通信当中,大部分交互式语言都是http,数据存取最后一层可能用的是特殊存储设备的协议,但除此之外,正常应用组件之前的交互都是http语言
http已经发展到传输协议,而不是应用协议
静态内容分开存放,大致分三类
1、图片、CSS、JS
2、HTML5代码
3、业务代码
后端存储内容,比如mysql
PC、移动端、APP
达到一定的架构模式,无论向上,还是向外,都会达到瓶颈,后期扩容性能不会像之前那么明显
比如,一开始一台2000并发数,10台就是2W,机器多了会有损耗,性能下降0.1,继续扩容会递减
应用程序内部分层,分层也依然解决不了问题
软件架构模式
分层架构:表现层、业务层、持久层、数据层
事件驱动架构:分布式异步、调度解耦
微内核架构:即插件式架构
微服务架构:API REST-based,application REST-based,中心化消息
基于空间的架构:云架构
系统达到一定的程度后,基本都需要做服务化,每一个独立功能组件都会做一个个服务化通过API向外暴露,让别人调用请求,而这种调用请求其实就是系统组件内部通讯