热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

架构的高可用高性能keepalived和varnish

1、简述HA cluster原理
2、keepalived实现主从、主主架构
3、简述http协议缓存原理及常用首部讲解
4、简述回源原理和CDN常见多级缓存
5、varnish实现缓存对象及反代后端主机

1、简述HA cluster原理

高可用集群(High Availability Cluster)简单的理解就是多个节点作为一个整体向用户提供一组网络资源。如果某个节点失效,它的备用节点将在几秒钟的时间内接管它的职责。用户将完全感受不到这个过程,因此,对于用户而言,集群永远不会停机。高可用集群软件的主要作用就是实现故障检查和业务切换的自动化。只有两个节点的高可用集群又称为双机热备,即使用两台服务器互相备份。

2、keepalived实现主从、主主架构

首先需要同步时间,时间不同步的话就很可能会出错
然后下载keepalived安装包,默认在base的yum里面
安装完后我们编辑配置文件/etc/keepalived.conf

! Configuration File for keepalived

global_defs {
   notification_email {
        [email protected]  #接收信息的邮件地址
   }
   notification_email_from [email protected]   #邮件来自于谁,可以不存在
   smtp_server 127.0.0.1 #邮件服务器可以是自己;
   smtp_connect_timeout 30 #邮件服务器链接超时时长
   router_id rt1  #router标识一个组内不同的router
   vrrp_mcast_group4 224.0.0.1  #组播地址
}

vrrp_instance VI_1 {  #组名VI_1
    state MASTER 
    interface ens33   
    virtual_router_id 51   #整个虚拟组的id,同组配置须保持一致
    priority 100
    advert_int 1 #一秒检查一次
    authentication {
        auth_type PASS #simple认证
        auth_pass 12345678  #最大支持8位
    }
    virtual_ipaddress {
        #/ brd  dev  scope 
        192.168.31.240/24 dev ens33 label ens33:0
    }
}                    

然后将配置文件传给另一台主机
scp keepalived.conf [email protected]:/etc/keepalived/
在这一台主机里我们只需要简单的修改几项
router_id rt2
state BACKUP
ppriority 95 #低一点

配置到这里就结束了,很简单。接下来我们就可以开始测试了
先在backup机上开启keepalive进程


架构的高可用高性能keepalived和varnish

可以看到已经拿到地址了
现在我们在master上开启进程


架构的高可用高性能keepalived和varnish
image.png

发现被更高的优先级抢走了
然后我们可以抓包查看他们互相通告的信息
架构的高可用高性能keepalived和varnish
image.png

双主模式

但如果这样配置的话就只有一台在工作,另一台一直是备用的,我们可以在主机上分别配置两个虚拟路由器,假如A,B两台主机我们想要让他们同时工作起来,可以让A为第一个虚拟路由器的master,则B就是第二个虚拟路由器的master然后我们就有了两个VIP,但是有了两个VIP其他主机怎么与我们通信实现负载均衡呢,这个时候我们就需要一个新的调度器,但我们配置keepalive本来就是为了增强调度器的冗余安全性,如果引入了新的节点岂不是本末倒置。
这时我们可以使用DNS服务,DNS本来就是主从互备不存在单点性且只需要我们在一个域名里添加两条A记录就可以达到轮询负载均衡的目的。
编辑配置文件增加一个虚拟路由器配置:

#RT1上添加一段
vrrp_instance VI_2 {
    state BACKUP
    interface ens33 
    virtual_router_id 52
    priority 96
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 98765432
    }
    virtual_ipaddress {
        192.168.31.241/24 dev ens33 label ens33:1                                           
    }

#RT2上添加一段
vrrp_instance VI_1 {
    state MASTER 
    interface ens33 
    virtual_router_id 52
    priority 100 
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 98765432
    }
    virtual_ipaddress {
        192.168.31.241/24 dev ens33 label ens33:1                                           
    }
}

然后我们抓包看


架构的高可用高性能keepalived和varnish
image.png

每一台主机都分别获取到了一个IP地址如果我们down了其中一台主机,则ip地址会跑到另一台上,测试一下看看


架构的高可用高性能keepalived和varnish
image.png

则简单的实验就完成了
我们可以定义发生变化时执行指定的脚本
通知脚本的使用方式:
示例通知脚本:
#!/bin/bash
#
cOntact='[email protected]'

notify() {
        local mailsubject="$(hostname) to be $1, vip floating"
        local mailbody="$(date +'%F %T'): vrrp transition, $(hostname) changed to be $1"
        echo "$mailbody" | mail -s "$mailsubject" $contact
}
case $1 in
        master)
            notify master
            ;;
        backup)
            notify backup
            ;;
        fault)
            notify fault
            ;;
        *)
                        echo "Usage: $(basename $0) {master|backup|fault}"
            exit 1
            ;;
esac        
#脚本的调用方法,写在虚拟路由器中
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"  

3、简述http协议缓存原理及常用首部讲解

(1)强制缓存机制(过期时间机制)

基本原理:
客户端第一次请求服务端时,服务端把缓存规则信息添加到header中,客户端通过这些信息判断是否能缓存。若能强制缓存,则header中会有两个字段来标记缓存失效的时间(expires或cache-control)。在客户端第一次请求并添加缓存后,以后每次客户端的请求响应数据都是缓存服务器提供的,不会再是服务端。缓存服务器根据cache-control字段来判断是否使用、是否更新、何时更新缓存。

  • expires,缓存过期时间
  • cache-control有下面几个参数:
  • public,允许客户端和代理使用缓存,即客户端请求的资源可以被任何缓存区所缓存
  • private,允许客户端使用缓存,即对于某个用户的响应信息不能被共享缓存区所缓存
  • max-age,缓存最大失效时长(单位为秒)
  • no-cache,关闭强制缓存,需要使用对比缓存
  • no-store,所有内容都不缓存

(2)对比缓存机制(条件式缓存机制):

基本原理:

  • a)缓存命中的情况:客户端向缓存服务器请求获取缓存header标识,客户端获取标识后,向后端服务器发送header标识规则,若未失效便通知客户端使用缓存服务器缓存的数据(状态码304)。
  • b)缓存未命中的情况:客户端向缓存服务器请求获取缓存header标识,客户端获取标识后,向后端服务器发送header标识规则,若失效便通知客户端不使用缓存服务器缓存的数据(状态码200),并更新缓存。
    对比缓存标识:
    last-modified/if-modfied-since:资源最后的修改时间戳
    etag/if-none-match:资源校验码

4、简述回源原理和CDN常见多级缓存

回源是指浏览器在发送请求报文时,响应该请求报文的是源站点的服务器,而不是各节点上的缓存服务器,那么这个过程相对于通过各节点上的缓存服务器来响应的话就称作为回源。回源的请求或流量太多的话,有可能会让源站点的服务器承载着过大的访问压力,进而影响服务的正常访问。
CDN(Content Delivery Network)内容分发网络,其思路是尽可能避开网络上的瓶颈,通过在网络边缘部署边缘服务器,依靠CDN中心平台的负载均衡、内容分发及调度等功能,使用户就近获取所需的内容,降低网络拥堵,提高用户访问响应速度和命中率。所以基本上CDN就是广泛采用各种缓存服务器,使得用户的请求直接由这些缓存服务器响应,加快了响应速度;只有在用户请求的资源在缓存服务器上没有找到或者请求访问的资源在源站点服务器上已经修改过的情况下,缓存服务器才会去访问源站点服务器以获取最新的资源。简单的来说就是在多个地方设置缓存服务器,使当地的用户可直接访问当地的缓存服务器而不必频繁的去访问源站,减少根服务器的压力。


架构的高可用高性能keepalived和varnish
image.png

CDN节点的缓存机制也是遵循http协议,因此也会受到Cache-Control等字段的影响。如果缓存的时间太短就会频繁的向根源服务器发起请求,增加源站点的负担,如果缓存时间太长又有可能涉及到更新的问题,这就需要设计者根据实际情况去设计。

5、varnish实现缓存对象及反代后端主机

缓存原理

Varnish 与一般服务器软件类似,分为 master 进程和 child 进程。Master 进程读入存储配置文件,调用合适的存储类型,然后创建 / 读入相应大小的缓存文件,接着 master 初始化管理该存储空间的结构体,然后 fork 并监控 child 进程。Child 进程在主线程的初始化的过程中,将前面打开的存储文件整个 mmap 到内存中,此时创建并初始化空闲结构体,挂到存储管理结构体,以待分配。Child 进程分配若干线程进行工作,主要包括一些管理线程和很多 worker 线程。
接着,开始真正的工作,varnish 的某个负责接收新 HTTP 连接线程开始等待用户,如果有新的 HTTP 连接过来,它总负责接收,然后唤醒某个等待中的线程,并把具体的处理过程交给它。Worker 线程读入 HTTP 请求的 URI,查找已有的 object,如果命中则直接返回并回复用户。如果没有命中,则需要将所请求的内容,从后端服务器中取过来,存到缓存中,然后再回复。

分配缓存的过程是这样的:它根据所读到 object 的大小,创建相应大小的缓存文件。为了读写方便,程序会把每个 object 的大小变为最接近其大小的内存页面倍数。然后从现有的空闲存储结构体中查找,找到最合适的大小的空闲存储块,分配给它。如果空闲块没有用完,就把多余的内存另外组成一个空闲存储块,挂到管理结构体上。如果缓存已满,就根据 LRU 机制,把最旧的 object 释放掉。

释放缓存的过程是这样的:有一个超时线程,检测缓存中所有 object 的生存期,如果超初设定的 TTL(Time To Live)没有被访问,就删除之,并且释放相应的结构体及存储内存。注意释放时会检查该存储内存块前面或后面的空闲内存块,如果前面或后面的空闲内存和该释放内存是连续的,就将它们合并成更大一块内存。

整个文件缓存的管理,没有考虑文件与内存的关系,实际上是将所有的 object 都考虑是在内存中,如果系统内存不足,系统会自动将其换到 swap 空间,而不需要 varnish 程序去控制。

varnish的程序环境:
/etc/varnish/varnish.params: 配置varnish服务进程的工作特性,例如监听
的地址和端口,缓存机制;
/etc/varnish/default.vcl:配置各Child/Cache线程的缓存策略;
主程序:
    /usr/sbin/varnishd
CLI interface:
    /usr/bin/varnishadm
VCL配置文件重载程序:
    /usr/sbin/varnish_reload_vcl
varnish的缓存存储机制( Storage Types):
  -s [name=]type[,options]  
    · malloc[,size]
        内存存储,[,size]用于定义空间大小;重启后所有缓存项失效;
    · file[,path[,size[,granularity]]]
        磁盘文件存储,黑盒;重启后所有缓存项失效;
    · persistent,path,size
        文件存储,黑盒;重启后所有缓存项有效;实验;

通过yum安装完varnish后,首先我们来看看varnish.params配置文件

# Varnish environment configuration description. This was derived from
# the old style sysconfig/defaults settings

# Set this to 1 to make systemd reload try to switch VCL without restart.
RELOAD_VCL=1

# Main configuration file. You probably want to change it.
VARNISH_VCL_COnF=/etc/varnish/default.vcl  #指定默认的vcl文件

# Default address and port to bind to. Blank address means all IPv4
# and IPv6 interfaces, otherwise specify a host name, an IPv4 dotted
# quad, or an IPv6 address in brackets.
# VARNISH_LISTEN_ADDRESS=192.168.1.5
VARNISH_LISTEN_PORT=80 #指定监听的端口

# Admin interface listen address and port
VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1 #管理地址
VARNISH_ADMIN_LISTEN_PORT=6082

# Shared secret file for admin interface
VARNISH_SECRET_FILE=/etc/varnish/secret #口令文件

# Backend storage specification, see Storage Types in the varnishd(5)
# man page for details.
VARNISH_STORAGE="file,/var/varnish/cache,256M" #这个是我们主要改的,存储的位置,方法形式

# User and group for the varnishd worker processes
VARNISH_USER=varnish
VARNISH_GROUP=varnish

# Other options, see the man page varnishd(1)
#DAEMON_OPTS="-p thread_pool_min=5 -p thread_pool_max=500 -p thread_pool_timeout=300"    
varnish程序的选项:
            程序选项:/etc/varnish/varnish.params文件
                -a address[:port][,address[:port][...],默认为6081端口; 
                -T address[:port],默认为6082端口;
                -s [name=]type[,options],定义缓存存储机制;
                -u user
                -g group
                -f config:VCL配置文件;
                -F:运行于前台;

然后我们使用varnishadm来登陆接口
varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082
登陆进来使用help查看可用的命令

    
            配置文件相关:
                vcl.list 
                vcl.load:装载,加载并编译;
                vcl.use:**;
                vcl.discard:删除;
                vcl.show [-v] :查看指定的配置文件的详细信息;
                
            运行时参数:
                param.show -l:显示列表;
                param.show 
                param.set  
                
            缓存存储:
                storage.list
                
            后端服务器:
                backend.list 

下面我们来介绍下VCL配置文件,里面的功能是通过一种语言实现的。VCL有多个状态引擎,状态之间存在相关性,但状态引擎彼此间互相隔离;每个状态引擎可使用return(x)指明关联至哪个下一级引擎;每个状态引擎对应于vcl文件中的一个配置段,即为subroutine。


架构的高可用高性能keepalived和varnish
image.png
vcl_recv的默认配置:
            
                sub vcl_recv {
                    if (req.method == "PRI") {
                        /* We do not support SPDY or HTTP/2.0 */
                        return (synth(405));
                    }
                    if (req.method != "GET" &&
                    req.method != "HEAD" &&
                    req.method != "PUT" &&
                    req.method != "POST" &&
                    req.method != "TRACE" &&
                    req.method != "OPTIONS" &&
                    req.method != "DELETE") {
                        /* Non-RFC2616 or CONNECT which is weird. */
                        return (pipe);
                    }

                    if (req.method != "GET" && req.method != "HEAD") {
                        /* We only deal with GET and HEAD by default */
                        return (pass);
                    }
                    if (req.http.Authorization || req.http.COOKIE) {
                        /* Not cacheable by default */
                        return (pass);
                    }
                        return (hash);
                    }
                }

里面还有许许多多的变量

变量类型:
            内建变量:
                req.*:request,表示由客户端发来的请求报文相关;
                    req.http.*
                        req.http.User-Agent, req.http.Referer, ...
                bereq.*:由varnish发往BE主机的httpd请求相关;
                    bereq.http.*
                beresp.*:由BE主机响应给varnish的响应报文相关;
                    beresp.http.*
                resp.*:由varnish响应给client相关;
                obj.*:存储在缓存空间中的缓存对象的属性;只读;
                
                常用变量:
                    bereq.*, req.*:
                        bereq.http.HEADERS
                        bereq.request:请求方法;
                        bereq.url:请求的url;
                        bereq.proto:请求的协议版本;
                        bereq.backend:指明要调用的后端主机;
                        
                        req.http.COOKIE:客户端的请求报文中COOKIE首部的值; 
                        req.http.User-Agent ~ "chrome"
                        
                        
                    beresp.*, resp.*:
                        beresp.http.HEADERS
                        beresp.status:响应的状态码;
                        reresp.proto:协议版本;
                        beresp.backend.name:BE主机的主机名;
                        beresp.ttl:BE主机响应的内容的余下的可缓存时长;
                        
                    obj.*
                        obj.hits:此对象从缓存中命中的次数;
                        obj.ttl:对象的ttl值
                        
                    server.*
                        server.ip
                        server.hostname
                    client.*
                        client.ip                   
                
            用户自定义:
                set 
                unset 

默认的VCL文件

vcl 4.0;

# Default backend definition. Set this to point to your content server.
backend default {
    .host = "192.168.31.201";
    .port = "80";
}

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.
}

sub vcl_backend_response {
    # Happens after we have read the response headers from the backend.
    #
    # Here you clean the response headers, removing silly Set-COOKIE headers
    # and other mistakes your backend does.
}

sub vcl_deliver {
    # Happens when we have all the pieces we need, and are about to send the
    # response to the client.
    #
    # You can do acc

然后我们再在varnish主机上配置nginx来进行反代
测试实验结果

[[email protected] ~]# curl -I  http://192.168.31.201:/index.html
HTTP/1.1 200 OK
Server: nginx/1.12.2
Date: Tue, 12 Feb 2019 12:59:11 GMT
Content-Type: text/html
Content-Length: 22
Connection: keep-alive
Last-Modified: Thu, 03 Jan 2019 14:07:05 GMT
ETag: "5c2e1709-16"
X-Varnish: 32770 3
Age: 10
Via: 1.1 varnish-v4

配置手动清除缓存

backend default {
    .host = "192.168.31.203";
    .port = "80";
}

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.method == "PURGE") {
        return (purge);   //清除缓存
}

sub vcl_purge {
        return(synth(200,"success"));
}

vcl.load test1 /etc/varnish/default.vcl
200        
VCL compiled.
vcl.use test1
200        
VCL 'test1' now active

清除缓存的结果

[[email protected] ~]# curl -I -X PURGE http://192.168.31.201    
HTTP/1.1 200 success
Server: nginx/1.12.2
Date: Tue, 12 Feb 2019 13:49:13 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 240
Connection: keep-alive
X-Varnish: 56
Retry-After: 5

推荐阅读
  • ! Configuration File for keepalivedglobal_defs {   notification_email {     ... [详细]
  • 深入理解Kafka服务端请求队列中请求的处理
    本文深入分析了Kafka服务端请求队列中请求的处理过程,详细介绍了请求的封装和放入请求队列的过程,以及处理请求的线程池的创建和容量设置。通过场景分析、图示说明和源码分析,帮助读者更好地理解Kafka服务端的工作原理。 ... [详细]
  • 动态多点××× 单云双HUB
    动态多点是一个高扩展的IPSEC解决方案传统的ipsecS2S有如下劣势1.中心站点配置量大,无论是采用经典ipsec***还是采用greoveripsec多一个分支 ... [详细]
  • php网站设计实验报告,php网站开发实训报告
    本文目录一览:1、php动态网站设计的关键技术有哪些软件,及搭建步骤需要哪些页面,分别完成 ... [详细]
  • varnish2.04配置文章来源:http:blog.163.comkoumm126blogstatic9540383720091182424317修改varnishheader ... [详细]
  • 本文介绍了在rhel5.5操作系统下搭建网关+LAMP+postfix+dhcp的步骤和配置方法。通过配置dhcp自动分配ip、实现外网访问公司网站、内网收发邮件、内网上网以及SNAT转换等功能。详细介绍了安装dhcp和配置相关文件的步骤,并提供了相关的命令和配置示例。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • t-io 2.0.0发布-法网天眼第一版的回顾和更新说明
    本文回顾了t-io 1.x版本的工程结构和性能数据,并介绍了t-io在码云上的成绩和用户反馈。同时,还提到了@openSeLi同学发布的t-io 30W长连接并发压力测试报告。最后,详细介绍了t-io 2.0.0版本的更新内容,包括更简洁的使用方式和内置的httpsession功能。 ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
  • ZooKeeper 学习
    前言相信大家对ZooKeeper应该不算陌生。但是你真的了解ZooKeeper是个什么东西吗?如果别人面试官让你给他讲讲ZooKeeper是个什么东西, ... [详细]
  • 篇首语:本文由编程笔记#小编为大家整理,主要介绍了VoLTE端到端业务详解|VoLTE用户注册流程相关的知识,希望对你有一定的参考价值。书籍来源:艾怀丽 ... [详细]
  • 运维入门
    2019独角兽企业重金招聘Python工程师标准本文内容遵从CC版权协议转载请注明出自oschina.netedwinaclaublog#运维入门一个 ... [详细]
  • EvanWeaver是Twitter服务团队的总工程师,他的主要工作是优化与伸缩性。在QConLondon2009上,他谈到了Twitter的架构&#x ... [详细]
  • redis理论知识redis:非关系型数据库基于键值对的形式存储数据的查询效率非常的高没有表之间的约束查询起来比较方便redis特点:1.支持多种数据类型2.支持分布式存储3.功能 ... [详细]
  • 分布式系统关注点——360°全方位解读「缓存」
    如果这是第二次看到我的文章,欢迎文末扫码订阅我个人的公众号(跨界架构师)哟~  本文长度为3578字,建议阅读10分钟。坚持原创,每 ... [详细]
author-avatar
林佳煌8888
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有