基于HAProxy+Varnish实现动静分离、负载均衡的高可用集群
本帖最后由 4EWQE 于 2017-11-7 10:07 编辑拓扑结构介绍 在实际的生产使用过程中,一个基本的能够应对日均百万PV的网络,一般会具有以下几种结构。这其中每种结构担负了不同的角色。
[*]代理服务器,负责进行请求调度,实现了负载均衡。
[*]KeepAlived配置代理服务器实现了高可用。
[*]缓存服务器,实现了资源的缓存,提高了请求的命中率,加快了访问速度。
[*]动静分离,减轻后端服务器压力,提高资源访问速度。
[*]数据库主从复制,读写分离,降低了数据库的压力
[*]运维监控系统,实时监控系统运行状态。
[*]自动化运维控制系统,批量管理大量服务器。
[*]版本控制系统,在应用的迭代过程中有着至关重要的作用。
实验结构介绍 下面,我们来模拟实现一个简单的网络集群结构。下面是这个结构的网络拓扑图。实验环境介绍
序号担任角色主机名地址功能描述
A互联网客户端windows172.18.2.22充当互联网用户进行网络访问
B代理服务器haproxyVIP 172.18.3.77;DIP 192.168.22.77对网络请求进行调度,实现均衡负载
C缓存服务器varnish 1192.168.22.33针对网络请求进行缓存,同时对后端服务器进行动静分离,并提供均衡负载
D缓存服务器varnish 2192.168.22.44针对网络请求进行缓存,同时对后端服务器进行动静分离,并提供均衡负载
E静态web服务器staticweb1192.168.22.100提供静态的网络服务,例如html,js,css之类
F静态web服务器staticweb2192.168.22.101提供静态的网络服务,例如html,js,css之类
G动态web服务器dynamicweb1192.168.22.200提供动态的网络服务,例如PHP,jsp等
H动态web服务器dynamicweb2192.168.22.201提供动态的网络服务,例如PHP,jsp等
I数据库服务器database192.168.22.128提供数据库服务,供应用程序进行读写操作
实验过程中,首先关闭SELinux和防火墙策略一、配置HAproxy
在主机A上安装HAProxy,并对其进行配置。
global
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon # turn on stats unix socket
stats socket /var/lib/haproxy/stats
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
# 指定对外提供网络服务的端口
frontend web 172.18.3.77:80
bind 172.18.3.77:9099
stats enable
stats uri /hastats
stats hide-version
stats refresh 2s
use_backend varnish_srvs
# 指定后端的Varnish缓存服务器
# 使用的端口是varnish的默认端口,这一点需要在varnish服务器中进行配置
backend varnish_srvs
balance uri
hash-type consistent
servervarnish1 192.168.22.33:6081 weight 1 check
servervarnish2 192.168.22.44:6081 weight 1 check
将HAProxy配置好以后,重启一下服务。然后在浏览器中输入 http://172.18.3.77:9099/hastats,就可以查看到HAProxy的调度管理界面。
此时,如果Varnish服务器已经配置成功了的话,就会显示出如下界面。
二、配置Varnish缓存服务器
此时,在配置好HAProxy服务器之后,就可以对varnish缓存服务器进行配置了。主要修改的文件为下面两个。Varnish1 与Varnish2的配置文件一致,将IP修改为自己对应的IP就可以了。
/etc/varnish/default.vcl,varnish 的默认配置文件
/etc/varnish/varnish.params,varnish 的一些默认参数。
其中/etc/varnish/default.vcl的配置内容,如下。
# new 4.0 format.
vcl 4.0;
#引入负载均衡模块
import directors;
#静态检测
probe static_probe{
#指定检测URL
.url="/";
#探测超时时长
.timeout=2s;
#探测次数
.window=5;
#探测次数成功多少次才算健康
.threshold=2;
#Varnish启动探测后端主机2次健康后加入主机
.initial=2;
#探测间隔时长
.interval=2s;
#期望状态响应码
.expected_response=200;
}
#动态监测
probe dynamic_probe {
.url="/index.php";
.timeout=2s;
.window=5;
.threshold=2;
.initial=2;
.interval=2s;
.expected_response=200;
}
#指定后端服务器,并对后端服务器进行动态监测
backend staticweb1 {
.host = "192.168.22.100";
.port = "80";
.probe = static_probe;
}
backend staticweb2 {
.host = "192.168.22.101";
.port = "80";
.probe = static_probe;
}
backend dynamicweb1 {
.host = "192.168.22.200";
.port = "80";
.probe =dynamic_probe;
}
backend dynamicweb2 {
.host = "192.168.22.201";
.port = "80";
.probe =dynamic_probe;
}
# 定义负载均衡的调度算法
sub vcl_init {
new staticcluster=directors.round_robin();
staticcluster.add_backend(staticweb1);
staticcluster.add_backend(staticweb2);
new dynamiccluster=directors.round_robin();
dynamiccluster.add_backend(dynamicweb1);
dynamiccluster.add_backend(dynamicweb2);
}
#定义清理缓存的规则
acl purgers {
"127.0.0.0"/8;
"192.168.0.0"/16;
}
# 启用缓存清理
sub vcl_purge{
return(synth(200,"Purged"));
}
# 定义pipe函数
sub vcl_pipe{
return(pipe);
}
# 定义miss函数
sub vcl_miss{
return(fetch);
}
# 定义hash函数
sub vcl_hash{
hash_data(req.url);
if(req.http.host){
hash_data(req.http.host);
}else{
hash_data(server.ip);
}
if(req.http.Accept-Encoding~"gzip"){
hash_data("gzip");
}elseif(req.http.Accept-Encoding~"deflate"){
hash_data("deflate");
}
}
# 对接收到的请求进行配置处理
sub vcl_recv {
# 不符合请求的清理操作被拒绝掉
if (req.method == "PURGE") {
if (!client.ip ~ purgers) {
return(synth(405,"Purging not allowed for " + client.ip));
}
return(purge);
}
#让后端服务器能够看到真实的请求地址
if (req.restarts == 0) {
if (req.http.X-Fowarded-For) {
set req.http.X-Forwarded-For = req.http.X-Forwarded-For + "," + client.ip;
} else {
set req.http.X-Forwarded-For = client.ip;
}
}
# 设置动静分离
set req.http.X-Forward-For=client.ip;
if(req.url~"(?i)\.(php|asp|aspx|jsp|do|cshtml)($|\?)"){
setreq.backend_hint = dynamiccluster.backend();
}
# 只缓存下列方法中指定的方法
if (req.method != "GET" &&
req.method != "HEAD" &&
req.method != "PUT" &&
req.method != "POST" &&
req.method != "TRACE" &&
req.method != "OPTIONS" &&
req.method != "DELETE") {
return (pipe);
}
#如果请求不是GET或者HEAD,不缓存
if (req.method != "GET" && req.method != "HEAD") {
return (pass);
}
#如果请求包含Authorization授权或Cookie认证,不缓存
if (req.http.Authorization || req.http.Cookie) {
return (pass);
}
if(req.http.Accept-Encoding){
if(req.url~"\.(bmp|png|gif|jpg|jpeg|ico|gz|tgz|bz2|tbz|zip|rar|mp3|mp4|ogg|swf|flv)$"){
unset req.http.Accept-Encoding;
}elseif(req.http.Accept-Encoding~"gzip"){
setreq.http.Accept-Encoding="gzip";
}elseif(req.http.Accept-Encoding~"deflate"){
set req.http.Accept-Encoding="deflate";
}else{
unset req.http.Accept-Encoding;
}
}
return (hash);
}
# 对响应的请求进行处理
sub vcl_backend_response {
# 这里我们不做配置
}
# 记录缓存的命中状态
sub vcl_deliver {
if(obj.hits>0){
set resp.http.X-Cache="HITfrom"+req.http.host;
set resp.http.X-Cache-Hits=obj.hits;
}else{
set resp.http.X-Cache="MISSfrom"+req.http.host;
}
unset resp.http.X-Powered-By;
unset resp.http.Server;
unset resp.http.Via;
unset resp.http.X-Varnish;
unset resp.http.Age;
}
对varnish的参数文件进行修改。这样便于让代理服务器知道应该将请求调度给谁。
# 6081 是varnish的默认监听端口 ,在HAProxy中需要对这个端口进行监听。
VARNISH_LISTEN_ADDRESS=192.168.22.33
VARNISH_LISTEN_PORT=6081
在上面的配置完成之后,在varnishadm控制台界面调用backend.list命令就能够查看,后端服务器的健康状态了。
backend.list
200
Backend name Refs Admin Probe
staticweb1(192.168.22.100,,80) 1 probe Sick 0/5
staticweb2(192.168.22.101,,80) 1 probe Sick 0/5
dynamicweb1(192.168.22.200,,80) 1 probe Sick 0/5
dynamicweb2(192.168.22.201,,80) 1 probe Sick 0/5
因为我们的后端服务器还没有进行配置,所以四个服务器都是处于宕机状态。
三、在静态服务器上安装HTTPD,并添加一些静态资源
使用yum来安装Httpd软件包就可以。安装之后,启动服务,确保80端口已经打开。此时再在Varnish服务器上调用backend.list命令就可以查看到已经又两个服务器处于Healthy状态了。
backend.list
200
Backend name Refs Admin Probe
staticweb1(192.168.22.100,,80) 1 probe Healthy 5/5
staticweb2(192.168.22.101,,80) 1 probe Healthy 4/5
dynamicweb1(192.168.22.200,,80) 1 probe Sick 0/5
dynamicweb2(192.168.22.201,,80) 1 probe Sick 0/5
四、安装数据库
在数据库服务器上,安装数据库服务,同时建立给WordPress应用程序使用的数据库表和用户。
create database wpdb;
grant all on wpdb.* to 'wpuser'@'192.168.22.%' identified by "123456";
五、在动态服务器上安装HTTPD,php等相关内容
安装 httpd php php-mysql
# CentOS 6:
yum install httpdphp php-mysql
service httpd start
# CentOS 7:
yum install httpdphpphp-mysql
systemctl start httpd.service
安装wordpress,将wordpress 解压到http默认路径下,并修改WordPress的数据库配置文件。
修改目录权限
setfacl -R -m u:apache:rwx wordpress
创建varnish健康性检查页面
backend.list
200
Backend name Refs Admin Probe
staticweb1(192.168.22.100,,80) 1 probe Healthy 5/5
staticweb2(192.168.22.101,,80) 1 probe Healthy 5/5
dynamicweb1(192.168.22.200,,80) 1 probe Healthy 5/5
dynamicweb2(192.168.22.201,,80) 1 probe Healthy 5/5
在浏览器地址栏输入 http://172.18.3.77/wordpress/index.php,此时站点访问成功。
总结
1、架构优点
HAProxy为缓存服务器提供了负载均衡,使用了uri调度算法,保证了同样路径的请求能够被调度到同样的主机上,提高了缓存的命中率。
HAProxy提供了web管理界面,能够更直观的进行调度管理和管控
Varnish的缓存机制,以及动静分离等技术,提高了web服务器的负载能力,从而使系统能够应对高并发量的请求
数据库的主从复制,也是企业实际生产应用中使用较多的生产策略,这样能够实现网络请求的频繁读写,对降低了数据库服务器的压力。
2、尚且不足
用户上传的静态资源如何存储到静态服务器中,文件的分布式存储与数据同步是这个结构需要解决的一个重要问题
HAproxy做负载均衡,没有冗余能力,容易出现单点故障,最好配合KeepAlived实现高可用。
如果用户在访问过程中,建立了Session会话,会话行为应该如何保持
页:
[1]