天天看点

consul-服务发现、服务隔离、服务配置

服务发现组件记录了(大规模)分布式系统中所有服务的信息,其它服务可以据此找到这些服务。dns 就是一个简单的例子。当然,复杂系统的服务发现组件要提供更多的功能,例如,服务元数据存储、健康监控、多种查询和实时更新等。

服务发现是支撑大规模 soa 的核心服务。

为什么需要服务发现呢?

假设我们写的代码会调用webservice、rest api、 thrift api 的服务。在调用过程中,为了完成一次请求,代码需要知道服务实例的网络位置(ip 地址和端口)。

整个过程,对于基于云端的、现代化的微服务应用而言,这却是一大难题。

1.1 单体应用

假设你是项目经理或者公司的架构师,正准备组织团队开发一款产品,类似滴滴与uber的出租车调度软件。其中系统的核心业务有:客户端、司机端、定位、通知、支付。

传统的架构图为:六边形架构(即模块化的单体是应用),也称单体式应用,如下图

consul-服务发现、服务隔离、服务配置

单体应用的不足 

这种简单方法却有很大的局限性。

一个简单的应用会随着时间推移逐渐变大。在每次的迭代中,开发团队都会面对新“故事”(需求),然后开发许多新代码。几年后,这个小而简单的应用会变成了一个巨大的怪物。如果有经验的管理者都知道,一旦你的应用变成一个又大又复杂的怪物,那开发团队肯定很痛苦。

敏捷开发和部署举步维艰,其中最主要问题就是这个应用太复杂,以至于任何单个开发者都不可能搞懂它。

降低开发速度

不利于持续性开发

模块相互冲突

可靠性低

重构困难

1.2微服务

随着时间的发展和项目的发展,业务团队越来越庞大,业务越来越复杂,单体应用架构已经无法满足项目需求,所以微服务就腾空出世了。许多公司,比如amazon、ebay,通过采用微处理结构模式解决了单体应用出现的问题。

其思路不是开发一个巨大的单体式的应用,而是将应用分解为小的、互相连接的微服务。

consul-服务发现、服务隔离、服务配置

微服务架构的好处

单个服务很容易开发、理解和维护。

这种架构使得每个服务都可以有专门开发团队来开发。

微服务架构模式是每个微服务独立的部署。

微服务架构模式使得每个服务独立扩展。

微服务架构的不足

微服务应用是分布式系统,由此会带来固有的复杂性。

服务地址目录,服务健康度,部署困难,服务依赖问题,数据库分区问题。

如何解决微服务出现的这些问题呢?服务发现框架在这时就闪亮登场了。

常用服务发现框架consul、zookeeper及etcd比较:

consul-服务发现、服务隔离、服务配置

zookeeper是这种类型的项目中历史最悠久的之一,它起源于hadoop。它非常成熟、可靠,被许多大公司(youtube、ebay、雅虎等)使用。

etcd是一个采用http协议的健/值对存储系统,它是一个分布式和功能层次配置系统,可用于构建服务发现系统。其很容易部署、安装和使用,提供了可靠的数据持久化特性。它是安全的并且文档也十分齐全。

consul是hashicorp公司推出的开源工具,用于实现分布式系统的服务发现与配置。与其他分布式服务注册与发现的方案相比,consul的方案更“一站式”,内置了服务注册与发现框架、分布一致性协议实现、健康检查、key/value存储、多数据中心方案,不再需要依赖其他工具(比如zookeeper等),使用起来也较为简单。

consul用golang实现,因此具有天然可移植性,安装包仅包含一个可执行文件,方便部署,与docker等轻量级容器可无缝配合。

要想利用consul提供的服务实现服务的注册与发现,我们需要建立consul cluster。在consul方案中,每个提供服务的节点上都要部署和运行consul的client agent,所有运行consul agent节点的集合构成consul cluster。consul agent有两种运行模式:server和client。这里的server和client只是consul集群层面的区分,与搭建在cluster之上的应用服务无关。以server模式运行的consul agent节点用于维护consul集群的状态,官方建议每个consul cluster至少有3个或以上的运行在server mode的agent,client节点不限。

每个被注册到consul中的node上,都部署一个consul agent,这个agent负责对本地的服务进行监控检查,以及将查询请求转发给consul server。consul server负责存放、备份数据(使用raft协议保证一致性),通常要有多台形成集群,选举出一个leader。查询服务地址的时候,可以直接向consul server发起查询,也可以通过consul agent查询,后者将转发给consul server。如果是多数据中心,每个数据中心部署一组consul server。跨数据中心查询通过本数据中心的consul server进行。注意:多数据中心的时候,不同数据中心的consul server之间不会同步key-value数据。

consul-服务发现、服务隔离、服务配置

@client

client表示consul的client模式,就是客户端模式。是consul节点的一种模式,这种模式下,所有注册到当前节点的服务会被转发到server,本身是不持久化这些信息。

@server

server表示consul的server模式,表明这个consul是个server,这种模式下,功能和client都一样,唯一不同的是,它会把所有的信息持久化的本地,这样遇到故障,信息是可以被保留的。

@server-leader

中间那个server下面有leader的字眼,表明这个server是它们的老大,它和其它server不一样的一点是,它需要负责同步注册的信息给其它的server,同时也要负责各个节点的健康监测。

@raft

server节点之间的数据一致性保证,一致性协议使用的是raft,而zookeeper用的paxos,etcd采用的也是raft。

@服务发现协议

consul采用http和dns协议,etcd只支持http

@服务注册

consul支持两种方式实现服务注册,一种是通过consul的服务注册http api,由服务自己调用api实现注册,另一种方式是通过json个是的配置文件实现注册,将需要注册的服务以json格式的配置文件给出。consul官方建议使用第二种方式。

@服务发现

consul支持两种方式实现服务发现,一种是通过http api来查询有哪些服务,另外一种是通过consul agent 自带的dns(8600端口),域名是以name.service.consul的形式给出,name即在定义的服务配置文件中,服务的名称。dns方式可以通过check的方式检查服务。

@服务间的通信协议

consul使用gossip协议管理成员关系、广播消息到整个集群,他有两个gossip  pool(lan pool和wan pool),lan pool是同一个数据中心内部通信的,wan pool是多个数据中心通信的,lan pool有多个,wan pool只有一个。

consul的三个主要应用场景:服务发现、服务隔离、服务配置。

服务发现场景中,consul作为注册中心,服务地址被注册到consul中以后,可以使用consul提供的dns、http接口查询,consul支持health check。

服务隔离场景中,consul支持以服务为单位设置访问策略,能同时支持经典的平台和新兴的平台,支持tls证书分发,service-to-service加密。

服务配置场景中,consul提供key-value数据存储功能,并且能将变动迅速地通知出去,通过工具consul-template可以更方便地实时渲染配置文件。

consul是一个二进制文件,可独立运行,直接从官网下载解压后保存到/usr/local/bin下即可:​​https://www.consul.io/downloads.html​​。

consul必须启动agent才能使用,有两种启动模式server和client,还有官方自带的ui。

参数解释:

常用命令如下:

1)information

可以在raft:stat看到此节点的状态是fllower或者leader

2)列出集群成员

3)新加入一个节点有几种方式;

这种方式,重启后不会自动加入集群

在启动的时候使用-join指定一个集群

使用-startjoin或-rejoin

4)consul默认绑定的端口

8300:server rpc address

8301:lan gossip,the serf lan port

8302:wan gossip,the serf wan port

8500:http api端口

8501:httpsapi端口,默认disabled

8502:grpcapi端口,默认disabled

8600:dns服务端口

21000:sidecar proxy min: inclusive min port number to use for automatically assigned sidecar service registrations.

21255:sidecar proxy max: inclusive max port number to use for automatically assigned sidecar service registrations.

5)健康检查

check使用来做服务的健康检查的,可以拥有多个,也可以不使用支持多种方式检查。check必须是script或者ttl类型的,如果是script类型则script和interval变量必须被提供,如果是ttl类型则ttl变量必须被提供。script是consul主动去检查服务的健康状况,ttl是服务主动向consul报告自己的状况。

script check:

http check:

tcp  check:

ttl  check:

6)服务注册

注册服务有三种方式。

通过配置文件的方式静态注册

保存json配置文件到consul配置目录,重启consul,并将配置文件的路径给consul。

通过http api接口来动态注册

直接调用/v1/agent/service/register接口注册即可,需要注意的是:http method为put提交方式,如:

注意:这种方式,和上面的注册方式有一点不一样,body的参数,是上面service的值。

使用程序实现服务的注册和发现(java)

7)查询服务

或者通过httpapi查询:

查询agent上所有服务:

8)删除服务

在一台主机上通过docker容器方式分别运行1个server和3个client,docker容器基于ubuntu:16.04,在此基础上安装ifconfig(net-tools),ping工具包用于基础应用和consul,并提交为新镜像:

然后server容器执行下列命令:

三个client容器创建命令:

三个client运行consul agent:

注:4个容器模拟4台主机,共享文件名不可相同(否则创建错误),只有server配置webui并暴露端口。

可通过此访问consul:http://192.168.134.144:8500。

在一个client上运行web服务(如cn12),web.json内容(启动consul时check错误,可先去掉check):

web服务采用go,即web.go:

在cn1上运行web并重启consul,可在其他主机上(如cn13)运行如下命令探测到相关服务,或通过ui查看到web service。

golang可直接通过consul库注册、发现服务。