第十六周微职位:Memcached,haproxy,varnish
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第十六周微职位:Memcached,haproxy,varnish相关的知识,希望对你有一定的参考价值。
1、为LNMP架构添加memcached支持,并完成对缓存效果的测试报告;
一、Memcached的简介:
Memcached是一个自由开源的,高性能,分布式内存对象缓存系统。它是一种基于内存的key-value存储,用来存储小块的任意数据(字符串、对象)。这些数据可以是数据库调用、API调用或者是页面渲染的结果。
Memcached简洁而强大。它的简洁设计便于快速开发,减轻开发难度,解决了大数据量缓存的很多问题。它的API兼容大部分流行的开发语言。本质上,它是一个简洁的key-value存储系统。
一般的使用目的是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web应用的速度、提高可扩展性。
特征:
1)协议简单;
2)基于libevent的事件处理;
3)内置内存存储方式;
4)memcached不互相通信的分布式。
Memcached常用选项:
-l <ip_addr>:监听的地址-m <num>:缓存空间大小,单位为MB, 默认为64
-c <num>:最大并发连接数,默认为1024
-M:缓存空间耗尽时,向请求者返回错误信息,而不是基于LRU算法进行缓存清理
-f <factor>:growth factor, 增长因子
-t <threads>:处理用于请求的线程数
二 基于LNMP架构添加Memcached支持并验证其结果
1、结构示意图:
2. 实验环境
IP 功用
192.168.237.129 nginx
192.168.237.131 php-fpm+mariadb+memcached
3. 实验步骤
Nginx, PHP-FPM和MariaDB安装在此忽略。
(1) Memcached安装
#安装Memcachedyum -y install memcached
#启动Memcached
memcached -d -m 1024 -u memcached
连接测试
telnet 192.168.237.131 11211
查看Memcached信息
(2) 安装PHP的Memcached的扩展
php连接memcached服务的模块有两个,php-pecl-memcache和php-pecl-memcached.若要安装php-pecl-memcached需要依赖libmemcached程序包,可以提供相应操作查看memcached的工具。在这里为方便演示就直接使用php-pecl-memcache扩展模块。
#安装PHP的Memcached扩展模块yum -y install php-pecl-memcache
测试PHP是否已支持Memcached, 浏览器中输入http://192.168.237.129/index.php
(3) 测试Memcached缓存
#在nginx根目录下写入php测试脚本vim /usr/share/nginx/html/test.php
<?php
$mem = new Memcache;
$mem->connect("192.168.237.131", 11211); #连接Memcached
$version = $mem->getVersion();
echo "Server‘s version: ".$version."<br/>\n"; #输出Memcached版本信息
$mem->set(‘testkey‘, ‘Hello World‘, 0, 600); #向Memcached存储数据‘Hello World‘,时间为600s
echo "Store data in the cache (data will expire in 600 seconds)<br/>\n";
$get_result = $mem->get(‘testkey‘); #获取testkey的值
echo "$get_result is from memcached server.";
?>
测试Memcached缓存结果,在浏览器中输入192.168.237.129/test.php
可以看出缓存已生效,再查看Memcached相应信息2、部署配置haproxy,能够实现将来自用户的80端口的http请求转发至后端8000上的server服务,写出其配置过程。
Haproxy的安装:(也可通过源码安装)
yum -y install haproxy
修改基本的配置文件如下:
配置文件所在地址: /etc/haproxy/haproxy.cfg
global maxconn 5120 chroot /usr/share/haproxy daemon quiet nbproc 2 pidfile /usr/share/haproxy/haproxy.pid defaults option httplog option dontlognull timeout connect 5s timeout client 50s timeout server 20s listen http bind :80 timeout client 1h tcp-request inspect-delay 2s tcp-request content accept if is_http server server-http :8080 backend servers server server1 127.0.0.1:8080 maxconn 32
3、阐述varnish的功能及其应用场景,并通过实际的应用案例来描述配置、测试、调试过程。
先安装varnish
#yum -y install varnish配置文件的简单介绍
NFILES=131072 MEMLOCK=82000 NPROCS="unlimited" # DAEMON_COREFILE_LIMIT="unlimited" #内核最大打开的文件数 RELOAD_VCL=1 #是否自动加载VCL VARNISH_VCL_CONF=/etc/varnish/default.vcl #默认加载的VCL文件 VARNISH_LISTEN_PORT=80 #监听端口,默认为6081 VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1 #管理的IP地址 VARNISH_ADMIN_LISTEN_PORT=6082 #管理端口 VARNISH_SECRET_FILE=/etc/varnish/secret #密钥文件 VARNISH_MIN_THREADS=50 #最小线程数量 VARNISH_MAX_THREADS=1000 #最大线程数量 VARNISH_THREAD_TIMEOUT=120 #线程超时时间 VARNISH_STORAGE_FILE=/var/lib/varnish/varnish_storage.bin #缓存文件位置 VARNISH_STORAGE_SIZE=1G #设置文件缓存大小变量 VARNISH_MEMORY_SIZE=64M #设置内存缓存大小变量 #VARNISH_STORAGE="file,${VARNISH_STORAGE_FILE},${VARNISH_STORAGE_SIZE}" #默认存储到文件中,这里可以修改存储位置 VARNISH_STORAGE="malloc,${VARNISH_MEMORY_SIZE}" #设置缓存位置为内存 VARNISH_TTL=120 DAEMON_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}" #所有启动加载选项
启动服务如下:
# service varnish start
Varnish命令介绍
# varnishd -h -a address:port #表示varnish对httpd的监听地址及其端口 -b address:port #表示后端服务器地址及其端口 -d #表示使用debug调试模式 -f file #指定varnish服务器的配置文件 -p param=value #指定服务器参数,用来优化varnish性能 -P file #Varnish进程PID文件存放路径 -n dir #指定varnish的工作目录 -s kind[,storageoptions] #指定varnish缓存内容的存放方式,常用的方式有:“-s file,<dir_or_file>,<size>”;其中“<dir_or_file>” 指定缓存文件的存放路径,“<size>”指定缓存文件的大小 -t #指定默认的TTL值 -T address:port #设定varnish的telnet管理地址及其端口 -V #显示varnish版本号和版权信息 -w int[,int[,int]] #设定varnish的工作线程数,常用的方式有: -w min,max -w min,max,timeout 如:-w3,25600,50 #这里最小启动的线程数不能设定过大,设置过大,会导致varnish运行异常缓慢环境如下:在lamp1、lamp2上分别都安装服务并启动
######在Lamp1服务器上安装Httpd、Php、mysql,启动服务 # yum -y install httpd php mysql-server php-mysql # service httpd start # service mysqld start ------------------------------------------------------------------------ ######在Lamp2服务器上安装Httpd、Php,启动服务 # yum -y install httpd php php-mysql # service httpd start
lamp上都测试php界面
安装论坛程序:
# mysql mysql> create database bbs; mysql> grant all on bbs.* to ‘bbsuser‘@‘172.16.%.%‘ identified by ‘bbspass‘; mysql> flush privileges; 注释:为论坛创建一个数据库并授权用户访问 ------------------------------------------------------------------------ ######安装论坛程序 # unzip Discuz_X3.0_SC_UTF8.zip # cp -rf upload/* /var/www/html/ # chmod -R +w /var/www/html/{config,data,uc_server,uc_client} #添加可写权限 # chown -R apache /var/www/html/* #修改属主权限
将论坛程序拷贝到lamp2服务器上一份并访问测试
# scp -rp /var/www/html/* 172.16.14.3:/var/www/html/
# service httpd restart #重启lamp2服务器的WEB服务
安装web服务器并测试页面:
# yum -y install httpd
# service httpd start
# echo "<h1>WEB</h1>" > /var/www/html/index.html #创建测试页
将Lamp1服务器上的论坛程序拷贝到WEB服务器一份,因为需要论坛中的一些静态文件如:(.jpg|.html)结尾的文件等
# scp -rp /var/www/html/* 172.16.14.3:/var/www/html/
Varnish安装及配置
在第一部分中我们已经修改过默认监听端口为"80",接下来为Varnish提供一个VCL配置文件,建议基于默认的配置文件基础上修改,修改前
备份一下文件。
[[email protected] ~]# cd /etc/varnish/
[[email protected] varnish]# cp default.vcl default.vcl.bak
[[email protected] varnish]# vim default.vcl
######定义ACL
acl purgers { #定义acl,实现IP地址过滤
"127.0.0.1";
"172.16.0.0"/16;
}
######定义健康状态检测
probe dynamic { #设置动态网站服务器健康状态检测
.url = "/index.html";
.interval = 5s;
.timeout = 1s;
.expected_response = 200;
} #这里设置了两个健康状态检测主要是为了区分动、静网站
probe static { #设置动态网站服务器健康状态检测
.url = "/index.html"; #定义检测的页面
.interval = 5s; #探测请求的发送周期,默认为5秒
.timeout = 1s; #每次探测请求的过期时间
.expected_response = 200;
}
######定义后端服务器
backend app1 { #定义一个后端服务器
.host = "172.16.14.2"; #服务器地址
.port = "80"; #服务器监听端口
.probe = dynamic; #健康状态检测
}
backend app2 {
.host = "172.16.14.3";
.port = "80";
.probe = dynamic;
}
backend web {
.host = "172.16.14.4";
.port = "80";
.probe = static;
}
######定义后端服务器组,实现负载均衡效果
director apps random { #定义一个后端服务器组,实现负载均衡效果
{
.backend = app1; #调用前面已定义过的后端主机
.weight = 2; #设置权重
}
{
.backend = app2;
.weight = 2;
}
}
######定义vcl_recv函数,实现请求到达并成功接收后调用此函数中定义的规则
sub vcl_recv {
######定义动、静分离,以".php"或".php?后面跟所有文件"结尾的请求都发送到动态服务器,其他请求都发送到静态服务器
if (req.url ~ "\.php(\?\.*|$)") {
set req.backend = apps;
} else {
set req.backend = web;
}
return(lookup);
######定义允许清除缓存的IP地址,调用的是前面定义的ACL
if (req.request == "PURGE") {
if (!client.ip ~ purgers) {
error 405 "Method not allowed";
}
return(lookup);
}
######重新定义http请求首部,让后端服务器可以记录请求客户端的真实IP地址
if (req.restarts == 0) {
if (req.http.x-forwarded-for) {
set req.http.X-Forwarded-For =
req.http.X-Forwarded-For + ", " + client.ip;
} else {
set req.http.X-Forwarded-For = client.ip;
}
}
######除了定义的请求方法外,其他请求都到后端服务器
if (req.request != "GET" &&
req.request != "HEAD" &&
req.request != "PUT" &&
req.request != "POST" &&
req.request != "TRACE" &&
req.request != "OPTIONS" &&
req.request != "DELETE") {
return (pipe);
}
if (req.request != "GET" && req.request != "HEAD") {
return (pass);
}
######定义不缓存认证与Cookie信息
if (req.http.Authorization || req.http.Cookie) {
return (pass);
}
######定义压缩功能
if (req.http.Accept-Enconding) {
if (req.url ~ "\.(jpg|jpeg|gif|bmp|png|flv|gz|tgz|tbz|mp3)$") {
remove req.http.Accept-Encoding;
remove req.http.Cookie;
} else if (req.http.Accept-Encoding ~ "gzip") {
set req.http.Accept-Encoding = "gzip";
} else if (req.http.Accept-Encoding ~ "deflate") {
set req.http.Accept-Encoding = "deflate";
} else { remove req.http.Accept-Encoding;
}
}
######定义指定格式结尾的文件去除Cookie信息
if (req.request == "GET" && req.url ~ "\.(jpeg|jpg|gif|png|bmp|swf)$") {
unset req.http.cookie;
}
######定义防盗链设置
if (req.http.referer ~ "http://.*") {
if (!(req.http.referer ~ "http://.*\.baidu\.com" || req.http.referer ~"http://.*\.google\.com.*")) {
set req.http.host = "www.allen.com";
set req.url = "http://172.16.14.4/error.html";
}
}
}
######定义vcl_hash函数
sub vcl_hash {
hash_data(req.url);
if (req.http.host) {
hash_data(req.http.host);
} else {
hash_data(server.ip);
}
return(hash);
}
######定义vcl_hit函数
sub vcl_hit {
if (req.request == "PURGE") { #语法方法为"PURGE"
purge; #清除缓存
error 200 "Purged."; #返回错误状态码为"200"
}
return(deliver);
}
######定义vcl_miss函数
sub vcl_miss {
if (req.request == "PURGE") {
purge;
error 404 "Not In Cache.";
}
return(fetch);
}
######定义vcl_psss函数
sub vcl_pass {
if (req.request == "PURGE") {
error 502 "Purged On A Passed Object.";
}
return(pass);
}
######定义vcl_fetch函数
sub vcl_fetch {
######定义缓存,如果匹配到已定义文件结尾的缓存1天,其他则缓存1小时
if (req.request == "GET" && req.url ~ "\.(html|jpg|png|bmp|jpeg|gif|js|ico|swf|css)$") {
set beresp.ttl = 1d;
set beresp.http.expires = beresp.ttl;
} else {
set beresp.ttl = 1h;
}
return(deliver);
}
######定义在http首部中,如果请求命中显示"HIT",未命中则显示"MISS"
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
}
----------------------------------------------------------------------
[[email protected] ~]# service varnish restart #重启服务生效,重启服务器后所有缓存将被清除,当然也可以不用重启服务使其生效,如下:
----------------------------------------------------------------------
[[email protected] ~]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082
varnish> help #获取帮助
varnish> vcl.load acl_1 default.vcl #加载acl文件,acl_1为配置名称
200
VCL compiled.
varnish> vcl.list #查看加载的acl文件列表
200
active 7 boot
available 0 acl_1
varnish> vcl.use acl_1 #应用acl文件
200
varnish> quit #退出
------------------------------------------------------------------------
注释: -S:指定varnish的密钥文件 -T:指定varnish服务器地址及管理端口,默认端口为"6082"
服务验证:
压力测试,如下:
######后端服务器不经过缓存测试
[[email protected] ~]# ab -c 100 -n 1000 http://172.16.14.2/index.php
Concurrency Level: 1000
Time taken for tests: 6.812 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Non-2xx responses: 10051
Total transferred: 2281577 bytes
HTML transferred: 0 bytes
Requests per second: 1468.04 [#/sec] (mean) #每秒请求并发
Time per request: 681.179 [ms] (mean)
Time per request: 0.681 [ms] (mean, across all concurrent requests)
Transfer rate: 327.10 [Kbytes/sec] received
----------------------------------------------------------------------
######经过缓存测试
[[email protected] ~]# ab -c 1000 -n 10000 http://172.16.14.1/index.php
Concurrency Level: 1000
Time taken for tests: 2.594 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Non-2xx responses: 10056
Total transferred: 3117360 bytes
HTML transferred: 0 bytes
Requests per second: 3855.05 [#/sec] (mean)
Time per request: 259.400 [ms] (mean)
Time per request: 0.259 [ms] (mean, across all concurrent requests)
Transfer rate: 1173.59 [Kbytes/sec] received
----------------------------------------------------------------------
注释:从上面数据中可以看出,经过缓存做压力测试并发量高
测试缓存是否能命中
[[email protected] ~]# curl -I http://172.16.14.1/index.php
HTTP/1.1 301 Moved Permanently
Server: Apache/2.2.15 (CentOS)
X-Powered-By: PHP/5.3.3
location: forum.php
Content-Type: text/html; charset=UTF-8
Content-Length: 0
Accept-Ranges: bytes
Date: Thu, 05 Oct 2017 09:48:01 GMT
X-Varnish: 2142028839
Age: 0
Via: 1.1 varnish
Connection: keep-alive
X-Cache: MISS #第一次请求,未命中显示"MISS"
------------------------------------------------------------------------
[[email protected] ~]# curl -I http://172.16.14.1/index.php
HTTP/1.1 301 Moved Permanently
Server: Apache/2.2.15 (CentOS)
X-Powered-By: PHP/5.3.3
location: forum.php
Content-Type: text/html; charset=UTF-8
Content-Length: 0
Accept-Ranges: bytes
Date: Thu, 05 Oct 2017 09:48:15 GMT
X-Varnish: 2142028841 2142028839
Age: 7
Via: 1.1 varnish
Connection: keep-alive
X-Cache: HIT #第二次请求,命中则显示"HIT"
从上图中可以看出,提供静态页面的服务停止后,所有图片都不能显示,当然把服务再启动起来就可以访问正常了,这里就不在测试了…
验证健康状态检测
查看缓存命中率状态;命中率的高低
本文出自 “11822904” 博客,请务必保留此出处http://11832904.blog.51cto.com/11822904/1970415
以上是关于第十六周微职位:Memcached,haproxy,varnish的主要内容,如果未能解决你的问题,请参考以下文章