用docker搭建一个高可用可扩展的服务支撑系统怎么做

用docker搭建一个高可用可扩展的服务支撑系统怎么做,第1张

一种方案为Haproxy+etcd+confd,采用松散式的组织结构,但各个组件之间的通讯是非常严密的,且扩展性更强,定制也更加灵活。

一、架构优势

约定由Haproxy+etcd+confd+Docker构建的基础服务平台简称“HECD” 架构,整合了多种开源组件,看似松散的结构,事实上已经是一个有机的整体,它们互相联系、互相作用,是Docker生态圈中最理想的组合之一,具有以下优势:

自动、实时发现及无感知服务刷新; 

支持任意多台Docker主宿机; 

支持多种APP接入且打散至不分主宿机; 

采用Etcd存储信息,集群支持可靠性高; 

采用Confd配置引擎,支持各类接入层,如Nginx; 

支持负载均衡、故障迁移; 

具备资源弹性,伸缩自如(通过生成、销毁容器实现); 

二、架构说明

在HECD架构中,首先管理员操作Docker Client,除了提交容器(Container)启动与停止指令外,还通过REST-API方式向Etcd(K/V)存储组件注册容器信息,包括容器名称、主宿机IP、映射端口等。Confd配置组件会定时查询Etcd组件获取最新的容器信息,根据定义好的配置模板生成Haproxy配置文件Haproxycfg,并且自动reload haproxy服务。用户在访问业务服务时,完全没有感知后端APP的上线、下线、切换及迁移,达到了自动发现、高可用的目的。详细架构图见图1-1。

图1-1 平台架构图

为了方便大家理解各组件间的关系,通过图1-2进行架构流程梳理,首先管理员通过Shell或API操作容器,下一步将容器信息注册到Etcd组件,Confd组件会定时查询Etcd,获取已经注册到Etcd中容器信息,最后通过Confd的模板引擎生成Haproxy配置,整个流程结束。

图1-2架构流程图

了解架构流程后,我们逐一对流程中各组件进行详细介绍。

1、Etcd介绍

Etcd是一个高可用的 Key/Value 存储系统,主要用于分享配置和服务发现。

简单:支持 curl 方式的用户 API (HTTP+JSON) 

安全:可选 SSL 客户端证书认证 

快速:单实例可达每秒 1000 次写操作 

可靠:使用 Raft 实现分布式

2、Confd介绍

Confd是一个轻量级的配置管理工具。通过查询Etcd,结合配置模板引擎,保持本地配置最新,同时具备定期探测机制,配置变更自动reload。

3、Haproxy介绍

HAProxy是提供高可用性、负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。(来源百科) 

三、架构部署

平台环境基于Centos65+Docker12构建,其中Etcd的版本为etcd version 050-alpha,Confd版本为confd 062,Haproxy版本为HA-Proxy version 1424。下面对平台的运行环境、安装部署、组件说明等进行详细说明,环境设备角色表如下:

1、组件安装

11 Docker安装

SSH终端登录192168122服务器,执行以下命令:

# yum -y install docker-io   

# service docker start   

# chkconfig docker on  

12 Haproxy、confd安装

SSH终端登录192168120服务器,执行以下命令:

1、haproxy   

# yum –y install haproxy   

2、confd   

# wget https://githubcom/kelseyhightower/confd/releases/download/v063/confd-063-linux-amd64  

# mv confd /usr/local/bin/confd   

# chmod +x /usr/local/bin/confd   

# /usr/local/bin/confd -version   

confd 062  

13 Etcd安装   

SSH终端登录192168121服务器,执行以下命令: 

# yum -y install golang   

# mkdir -p /home/install && cd /home/install   

# git clone https://githubcom/coreos/etcd  

# cd etcd   

# /build   

# cp bin/etcd /bin/etcd   

# /bin/etcd -version   

etcd version 050-alpha  2、组件配置   

21 Etcd配置

由于etcd是一个轻量级的K/V存储平台,启动时指定相关参数即可,无需配置。 

# /bin/etcd -peer-addr 192168121:7001 -addr 192168121:4001 -data-dir /data/etcd -peer-bind-addr 0000:7001 -bind-addr 0000:4001 &  

由于etcd具备多机支持,参数“-peer-addr”指定与其它节点通讯的地址;参数“-addr”指定服务监听地址;参数“-data-dir”为指定数据存储目录。    

由于etcd是通过REST-API方式进行交互,常见操作如下:   

1) 设置(set) key操作  

# curl -L http://192168121:4001/v2/keys/mykey-XPUT -d value="this is awesome"   

{"action":"set","node":{"key":"/mykey","value":"this is awesome","modifiedIndex":28,"createdIndex":28}} 2) 获取(get) key信息# curl -L http://192168121:4001/v2/keys/mykey  

{"action":"get","node":{"key":"/mykey","value":"this is awesome","modifiedIndex":28,"createdIndex":28}}  

3) 删除key信息 

# curl -L http://192168121:4001/v2/keys/mykey-XDELETE         {"action":"delete","node":{"key":"/mykey","modifiedIndex":29,"createdIndex":28},"prevNode":{"key":"/mykey","value":"this is awesome","modifiedIndex":28,"createdIndex":28}}   更多操作API见https://githubcom/coreos/etcd/blob/master/Documentation/apimd。 

22 Confd+Haproxy配置  

由于Haproxy的配置文件是由Confd组件生成,要求Confd务必要与haproxy安装在同一台主机上,Confd的配置有两种,一种为Confd资源配置文件,默认路径为“/etc/confd/confd”目录,另一种为配置模板文件,默认路径为“/etc/confd/templates”。具体配置如下:    

创建配置文件目录 

# mkdir -p /etc/confd/{confd,templates}

(1)配置资源文件   

详细见以下配置文件,其中“src”为指定模板文件名称(默认到路径/etc/confd/templates中查找);“dest”指定生成的Haproxy配置文件路径;“keys”指定关联Etcd中key的URI列表;“reload_cmd”指定服务重载的命令,本例中配置成haproxy的reload命令。    

/etc/confd/confd/ haproxytoml 

[template]  

src = "haproxycfgtmpl"  

dest = "/etc/haproxy/haproxycfg"  

keys = [  

 "/app/servers",  

]  

reload_cmd = "/etc/initd/haproxy reload"  

(2)配置模板文件  

Confd模板引擎采用了Go语言的文本模板,更多见http://golangorg/pkg/text/template/,具备简单的逻辑语法,包括循环体、处理函数等,本示例的模板文件如下,通过range循环输出Key及Value信息。   

/etc/confd/templates/haproxycfgtmpl 

global  

       log 127001 local3  

       maxconn 5000  

       uid 99  

       gid 99  

       daemon  

 

defaults  

       log 127001 local3  

       mode http  

       option dontlognull  

       retries 3  

       option redispatch  

       maxconn 2000  

       contimeout  5000  

       clitimeout  50000  

       srvtimeout  50000  

 

listen frontend 0000:80  

       mode http  

       balance roundrobin  

       maxconn 2000  

       option forwardfor  

       {{range gets "/app/servers/"}}  

       server {{base Key}} {{Value}} check inter 5000 fall 1 rise 2  

       {{end}}  

 

       stats enable  

       stats uri /admin-status  

       stats auth admin:123456  

       stats admin if TRUE  

(3)模板引擎说明  

本小节详细说明Confd模板引擎基础语法与示例,下面为示例用到的KEY信息。 

# curl -XPUT http://192168121:4001/v2/keys/app/servers/backstabbing_rosalind-d value="192168122:49156"   

# curl -XPUT http://192168121:4001/v2/keys/app/servers/cocky_morse-d value="192168122:49158"   

# curl -XPUT http://192168121:4001/v2/keys/app/servers/goofy_goldstine-d value="192168122:49160"   

# curl -XPUT http://192168121:4001/v2/keys/app/servers/prickly_blackwell-d value="192168122:49162"1、base   

作为pathBase函数的别名,获取路径最后一段。 

{{ with get "/app/servers/prickly_blackwell"}}

server {{base Key}} {{Value}} check 

{{end}}

prickly_blackwell 192168122:49162

2、get

返回一对匹配的KV,找不到则返回错误。   

{{with get "/app/servers/prickly_blackwell"}}

key: {{Key}}

value: {{Value}} 

{{end}}

/app/servers/prickly_blackwell 192168122:49162  

3、gets  

{{range gets "/app/servers/"}}

{{Key}} {{Value}}

{{end}} 

/app/servers/backstabbing_rosalind 192168122:49156  

/app/servers/cocky_morse 192168122:49158  

/app/servers/goofy_goldstine 192168122:49160  

app/servers/prickly_blackwell 192168122:49162

4、getv

返回一个匹配key的字符串型Value,找不到则返回错误。  

{{getv "/app/servers/cocky_morse"}}

192168122:49158  

5、getvs

返回所有匹配key的字符串型Value,找不到则返回错误。

{{range getvs "/app/servers/"}}

value: {{}}

{{end}} 

value: 192168122:49156  

value: 192168122:49158  

value: 192168122:49160  

value: 192168122:49162  

6、split

对输入的字符串做split处理,即将字符串按指定分隔符拆分成数组。

{{ $url := split (getv "/app/servers/cocky_morse") ":" }}

host: {{index $url 0}}

port: {{index $url 1}}

host: 192168122  

port: 49158  

7、ls

返回所有的字符串型子key,找不到则返回错误。 

{{range ls "/app/servers/"}}

subkey: {{}} 

{{end}}

subkey: backstabbing_rosalind  

subkey: cocky_morse  

subkey: goofy_goldstine  

subkey: prickly_blackwell  

8、lsdir

返回所有的字符串型子目录,找不到则返回一个空列表。 

{{range lsdir "/app/"}}

subdir: {{}} 

{{end}}

subdir: servers

(4)启动confd及haproxy服务

下面为启动Confd服务命令行,参数“interval”为指定探测etcd的频率,单位为秒,参数“-node”为指定etcd监听服务主地址,以便获取容器信息。 

# /usr/local/bin/confd -verbose -interval 10 -node '192168121:4001' -confdir /etc/confd > /var/log/confdlog &  

# /etc/initd/haproxy start  

1打开手机里的各大应用市场搜索“GO谷歌安装器”,下载并安装

2打开“GO谷歌安装器”,点击GO图标,根据提示点击安装

3安装谷歌服务框架

4安装Google账号管理程序

5安装Google  Play服务

6安装GooglePlay商店

7耐心等待以上软件安装完成

扩展资料

google服务框架的作用:

1、用来登录谷歌的账号,享受谷歌的服务

2、有些国外的应用和游戏需要谷歌服务框架,不然就闪退。

简单介绍一下制作主页的过程和方法:

一、准备材料

你首先做一个小计划,准备在主页上告诉人家什么?比如介绍三个方面:自我介绍,我的爱好,我的工作,那你就先起一个总目录(文件夹,比如d:\\\\html),来放你的所有文件,然后再在这个目录建立三个子目录:myself,interest,job。文件名你可以任意,但最好全部小写,因为有的主机要认大小写。然后将你的材料copy进相应的子目录。比如你要在你的主页里展示你的靓照,那就将你的照片扫描成jpg格式的文件,放在myself的目录下

要注意,网上只能使用jpg和gif两种图象格式,其他诸如bmp和tif等很通用的格式都不能用在网上,因为它们太大了,但你可以用图象软件进行转换,比如office

97的照片编辑器。把你准备在你主页上出现的图象放进相应的目录里后,你就可以开始制作了。

二、开始制作

你无须去记复杂的html语言,你可以用netscape40或者word70,我用的是frontpage打开netscape,在file菜单里选edit

page,便可以制作了文字的处理基本跟word没什么两样,关键是插入和产生链接我们先做关于你自我介绍的一页,你先写上“大家好,我是superboy,下面是我的照片:”这时要放了,只须点击insert菜单,选取image,在choosefile里选取你的图象文件即可,然后把这个文件保存为myselfhtml文件,放在myself的目录下。好,现在必须做封面了,你在封面写:“欢迎来到superboy的主页”以下是“自我介绍,我的爱好,我的工作”。你的自我介绍要链接到下一页去,你只须用鼠标选“自我介绍”后按鼠标右键

,再选create

link,然后再选你myself目录下的myselfhtml,就将“自我介绍”链接到下一页了,以后在浏览器中一按,就可以跳到镶有你靓照的页面啦。

在你的封面做好了所有链接和后,记住你必须将这一页保存为indexhtm(有的主机要求必须为indexhtml),因为网页默认的主页名称是index制作主页其实很简单,只要多实际制作,工多艺熟。还可以拿来主义,在网上看到什么好的主页,用另存为功能保存为html格式的文件,细细研究人家是如何做的。还可以借用网页模版来搞,我的就是~~~~~~

三、将你制作好的安放在网上

要在网上安你自己的家,你必须先申请一个主页空间,即向某一个主机申请一快硬盘空间。现在有较多的主机提供免费主页空间,具体见实用链接栏目。这些主机不仅提供免费个人主页空间,并且还提供留言簿、计数器等很有用的功能。只要到有关站点申请即可,具体方法,参考相关题目。申请完成以后用ftp将你所有的主页文件上传至主机指定的目录就可以了!

需要注意的是,一定要保持网页的相对位置,否则会看不到网页的。

服务发现就是服务提供者将自己提供的地址post或者update到服务中介,服务消费者从服务中介那里get自己想要的服务的地址。

但是有两个问题:

第一个问题:如果有一个服务提供者宕机,那么中介的key/value中会有一个不能访问的地址,该怎么办?

心跳机制: 服务提供者需要每隔5秒左右向服务中介汇报存活,服务中介将服务地址和汇报时间记录在zset数据结构的value和score中。服务中介需要每隔10秒左右检查zset数据结构,踢掉汇报时间严重落后的地址。这样就可以保证服务列表中地址的有效性。

第二个问题是服务地址变动时如何通知消费者。有两种解决方案。

第一种是轮询,消费者每隔几秒查询服务列表是否有改变。如果服务地址很多,查询会很慢。这时候可以引入服务版本号机制,给每个服务提供一个版本号,在服务变动时,递增这个版本号。消费者只需要轮询这个版本号的变动即可知道服务列表是否发生了变化。

第二种是采用pubsub。这种方式及时性要明显好于轮询。缺点是每个pubsub都会占用消费者一个线程和一个额外的连接。为了减少对线程和连接的浪费,我们使用单个pubsub广播全局版本号的变动。所谓全局版本号就是任意服务列表发生了变动,这个版本号都会递增。接收到版本变动的消费者再去检查各自的依赖服务列表的版本号是否发生了变动。这种全局版本号也可以用于第一种轮询方案。

CAP理论

CAP理论是分布式架构中重要理论

关于P的理解,我觉得是在整个系统中某个部分,挂掉了,或者宕机了,并不影响整个系统的运作或者说使用,而可用性是,某个系统的某个节点挂了,但是并不影响系统的接受或者发出请求,CAP 不可能都取,只能取其中2个。原因是

(1)如果C是第一需求的话,那么会影响A的性能,因为要数据同步,不然请求结果会有差异,但是数据同步会消耗时间,期间可用性就会降低。

(2)如果A是第一需求,那么只要有一个服务在,就能正常接受请求,但是对与返回结果变不能保证,原因是,在分布式部署的时候,数据一致的过程不可能想切线路那么快。

(3)再如果,同事满足一致性和可用性,那么分区容错就很难保证了,也就是单点,也是分布式的基本核心,好了,明白这些理论,就可以在相应的场景选取服务注册与发现了。

平时经常用到的服务发现的产品进行下特性的对比,首先看下结论:

补充:

(1)运维和开发如果是 Java 更熟,也更多 Java 的应用,那毫无疑问应该用 ZK;如果是搞 Go 的,那么还是 etcd 吧,毕竟有时候遇到问题还是要看源码的。

(2)在创建一百万个或更多键时,etcd可以比Zookeeper或Consul稳定地提供更好的吞吐量和延迟。此外,它实现了这一目标,只有一半的内存,显示出更高的效率。但是,还有一些改进的余地,Zookeeper设法通过etcd提供更好的最小延迟,代价是不可预测的平均延迟。

(3)

一致性协议: etcd 使用 Raft 协议,Zookeeper 使用 ZAB(类PAXOS协议),前者容易理解,方便工程实现;

运维方面:etcd 方便运维,Zookeeper 难以运维;

数据存储:etcd 多版本并发控制(MVCC)数据模型 , 支持查询先前版本的键值对

项目活跃度:etcd 社区与开发活跃,Zookeeper 感觉已经快死了;

API:etcd 提供 HTTP+JSON, gRPC 接口,跨平台跨语言,Zookeeper 需要使用其客户端;

访问安全方面:etcd 支持 HTTPS 访问,Zookeeper 在这方面缺失;

与 Eureka 有所不同,Apache Zookeeper 在设计时就紧遵CP原则,即任何时候对 Zookeeper 的访问请求能得到一致的数据结果,同时系统对网络分割具备容错性,但是 Zookeeper 不能保证每次服务请求都是可达的。

从 Zookeeper 的实际应用情况来看,在使用 Zookeeper 获取服务列表时,如果此时的 Zookeeper 集群中的 Leader 宕机了,该集群就要进行 Leader 的选举,又或者 Zookeeper 集群中半数以上服务器节点不可用(例如有三个节点,如果节点一检测到节点三挂了 ,节点二也检测到节点三挂了,那这个节点才算是真的挂了),那么将无法处理该请求。所以说,Zookeeper 不能保证服务可用性。

当然,在大多数分布式环境中,尤其是涉及到数据存储的场景,数据一致性应该是首先被保证的,这也是 Zookeeper 设计紧遵CP原则的另一个原因。

但是对于服务发现来说,情况就不太一样了,针对同一个服务,即使注册中心的不同节点保存的服务提供者信息不尽相同,也并不会造成灾难性的后果。

因为对于服务消费者来说,能消费才是最重要的,消费者虽然拿到可能不正确的服务实例信息后尝试消费一下,也要胜过因为无法获取实例信息而不去消费,导致系统异常要好(淘宝的双十一,京东的618就是紧遵AP的最好参照)。

当master节点因为网络故障与其他节点失去联系时,剩余节点会重新进行leader选举。问题在于,选举leader的时间太长,30~120s,而且选举期间整个zk集群都是不可用的,这就导致在选举期间注册服务瘫痪。

在云部署环境下, 因为网络问题使得zk集群失去master节点是大概率事件,虽然服务能最终恢复,但是漫长的选举事件导致注册长期不可用是不能容忍的。

Spring Cloud Netflix 在设计 Eureka 时就紧遵AP原则。Eureka是在Java语言上,基于Restful Api开发的服务注册与发现组件,由Netflix开源。遗憾的是,目前Eureka仅开源到1X版本,2X版本已经宣布闭源。

Eureka Server 也可以运行多个实例来构建集群,解决单点问题,但不同于 ZooKeeper 的选举 leader 的过程,Eureka Server 采用的是Peer to Peer 对等通信。这是一种去中心化的架构,无 master/slave 之分,每一个 Peer 都是对等的。在这种架构风格中,节点通过彼此互相注册来提高可用性,每个节点需要添加一个或多个有效的 serviceUrl 指向其他节点。每个节点都可被视为其他节点的副本。

在集群环境中如果某台 Eureka Server 宕机,Eureka Client 的请求会自动切换到新的 Eureka Server 节点上,当宕机的服务器重新恢复后,Eureka 会再次将其纳入到服务器集群管理之中。当节点开始接受客户端请求时,所有的操作都会在节点间进行复制(replicate To Peer)操作,将请求复制到该 Eureka Server 当前所知的其它所有节点中。

当一个新的 Eureka Server 节点启动后,会首先尝试从邻近节点获取所有注册列表信息,并完成初始化。Eureka Server 通过 getEurekaServiceUrls() 方法获取所有的节点,并且会通过心跳契约的方式定期更新。

默认情况下,如果 Eureka Server 在一定时间内没有接收到某个服务实例的心跳(默认周期为30秒),Eureka Server 将会注销该实例(默认为90秒, eurekainstancelease-expiration-duration-in-seconds 进行自定义配置)。

当 Eureka Server 节点在短时间内丢失过多的心跳时,那么这个节点就会进入自我保护模式。

Eureka的集群中,只要有一台Eureka还在,就能保证注册服务可用(保证可用性),只不过查到的信息可能不是最新的(不保证强一致性)。除此之外,Eureka还有一种自我保护机制,如果在15分钟内超过85%的节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,此时会出现以下几种情况:

Eureka不再从注册表中移除因为长时间没有收到心跳而过期的服务;

Eureka仍然能够接受新服务注册和查询请求,但是不会被同步到其它节点上(即保证当前节点依然可用);

当网络稳定时,当前实例新注册的信息会被同步到其它节点中;

因此,Eureka可以很好的应对因网络故障导致部分节点失去联系的情况,而不会像zookeeper那样使得整个注册服务瘫痪。

Consul 是 HashiCorp 公司推出的开源工具,用于实现分布式系统的服务发现与配置。Consul 使用 Go 语言编写,因此具有天然可移植性(支持Linux、windows和Mac OS X)。

Consul采用主从模式的设计,使得集群的数量可以大规模扩展,集群间通过RPC的方式调用(HTTP和DNS)。

Consul 内置了服务注册与发现框架、分布一致性协议实现、健康检查、Key/Value 存储、多数据中心方案,不再需要依赖其他工具(比如 ZooKeeper 等),使用起来也较为简单。

Consul 遵循CAP原理中的CP原则,保证了强一致性和分区容错性,且使用的是Raft算法,比zookeeper使用的Paxos算法更加简单。虽然保证了强一致性,但是可用性就相应下降了,例如服务注册的时间会稍长一些,因为 Consul 的 raft 协议要求必须过半数的节点都写入成功才认为注册成功 ;在leader挂掉了之后,重新选举出leader之前会导致Consul 服务不可用。

默认依赖于SDK

Consul本质上属于应用外的注册方式,但可以通过SDK简化注册流程。而服务发现恰好相反,默认依赖于SDK,但可以通过Consul Template(下文会提到)去除SDK依赖。

Consul Template

Consul,默认服务调用者需要依赖Consul SDK来发现服务,这就无法保证对应用的零侵入性。

所幸通过 Consul Template ,可以定时从Consul集群获取最新的服务提供者列表并刷新LB配置(比如nginx的upstream),这样对于服务调用者而言,只需要配置一个统一的服务调用地址即可。

Consul强一致性(C)带来的是:

Eureka保证高可用(A)和最终一致性:

其他方面,eureka就是个servlet程序,跑在servlet容器中; Consul则是go编写而成。

etcd是一个采用http协议的分布式键值对存储系统,因其易用,简单。很多系统都采用或支持etcd作为服务发现的一部分,比如kubernetes。但正事因为其只是一个存储系统,如果想要提供完整的服务发现功能,必须搭配一些第三方的工具。

比如配合etcd、Registrator、confd组合,就能搭建一个非常简单而强大的服务发现框架。但这种搭建操作就稍微麻烦了点,尤其是相对consul来说。所以etcd大部分场景都是被用来做kv存储,比如kubernetes。

etcd 比较多的应用场景是用于服务发现,服务发现 (Service Discovery) 要解决的是分布式系统中最常见的问题之一,即在同一个分布式集群中的进程或服务如何才能找到对方并建立连接。和 Zookeeper 类似,etcd 有很多使用场景,包括:

配置管理

服务注册发现

选主

应用调度

分布式队列

分布式锁

按照官网给出的数据, 在 2CPU,18G 内存,SSD 磁盘这样的配置下,单节点的写性能可以达到 16K QPS, 而先写后读也能达到12K QPS。这个性能还是相当可观。

etcd 提供了 etcdctl 命令行工具 和 HTTP API 两种交互方法。etcdctl命令行工具用 go 语言编写,也是对 HTTP API 的封装,日常使用起来也更容易。所以这里我们主要使用 etcdctl 命令行工具演示。

(1)注册中心ZooKeeper、Eureka、Consul 、Nacos对比

https://zhuanlanzhihucom/p/165217227utm_source=wechat_session

(2)常用的服务发现对比(Consul、zookeeper、etcd、eureka)

https://blogcsdnnet/gaohe7091/article/details/101197107

DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
网站模板库 » 用docker搭建一个高可用可扩展的服务支撑系统怎么做

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情