本文主要研究一下spring cloud的ConsulCatalogWatch
spring-cloud-consul-discovery-212RELEASE-sourcesjar!/org/springframework/cloud/consul/discovery/ConsulCatalogWatchjava
spring-cloud-consul-discovery-212RELEASE-sourcesjar!/org/springframework/cloud/consul/discovery/ConsulDiscoveryClientConfigurationjava
ConsulCatalogWatch构造器接收ConsulDiscoveryProperties、ConsulClient、TaskScheduler;其start方法会使用taskSchedulerscheduleWithFixedDelay注册catalogServicesWatch的定时任务;stop方法则是cancel掉这个定时任务;catalogServicesWatch方法使用consulgetCatalogServices方法获取consulIndex然后更新本地的catalogServicesIndex,发布HeartbeatEvent
微服务加上如今的服务发现,在基础设施即代码(指使用脚本配置计算基础设施,而不是手动配置计算机的方法)的过程中,我们正在不断的尝试各种实践方案。如何在云基础设施下结合业务场景,通过负载均衡、服务发现、容器化来实现业务链自动化,这就是本文给大家带来的分享。
困扰和烦恼
首先来看下我们其中一个平台之前的大体架构:
随着业务的递增,我们遇到了以下的问题:
什么是服务发现?
在分布式微服务架构中,一个应用可能由一组职责单一化的服务组成。这时候就需要一个注册服务的机制,注册某个服务或者某个节点是可用的,还需要一个发现服务的机制来找到哪些服务或者哪些节点还在提供服务。
在实际应用中,通常还都需要一个配置文件告诉我们一些配置信息,比如数据连接的地址,Redis 的地址等等。但很多时候,我们想要动态地在不修改代码的情况下得到这些信息,并且能很好地管理它们。
然而,服务发现组件记录了(大规模)分布式系统中所有服务的信息,其它服务可以据此找到这些服务。DNS 就是一个简单的例子。当然,复杂系统的服务发现组件要提供更多的功能,例如,服务元数据存储、 健康 监控、多种查询和实时更新等。服务发现是支撑大规模 SOA 的核心服务。
Consul 介绍
Consul 是一个支持多数据中心分布式高可用,用于服务发现和配置共享的开源工具。它具有开箱即用、可跨系统平台部署(在任何基础架构上连接任何应用)等特点。Consul 的三个主要应用场景:服务发现、服务隔离、服务配置。Consul 关键特性:
Consul 之服务发现
Consul 之服务配置
首先 Consul 集群内的所有数据都是可共享的,任何一个节点都是可以同时获取到集群内最新的数据信息。然后通过一些例如 Key/Value、Server、Node 等等数据进行文本内容渲染,从而达到一个变更的全程实时自动化。例如根据 Key/Value 信息渲染:
例如根据服务信息渲染:
在传统运维方式上可以有哪些改变
传统方式如何向微服务化转变
入口的动态自动化
容器和服务发现始终只是在对内部的通信实现,如何将这些服务快速方便的对外实现通信,并且能够高度自动化呢?我们通过将 HA 作为各类后端服务的对外统一入口;配置 backend 服务时,配置的是 Consul 中的服务域名。从而作为内部和外部通信的一个通信转发枢纽。
HA 的域名动态解析
首先看看容器化下的服务地址是怎样通过 Consul 完成变更的。
然后为什么是 HA 的 DNS 动态解析?这个不是 DNS 的锅么?
在常见的代码更新、服务配置变更、迁移、扩容等需要容器重建时,会导致 N 个容器同时发生 Consul 域名解析变更(当然也是预期内的变更),这个时候需要使用了 Consul 域名的服务在访问失败时能够去重新解析一次域名获取新的 IP,完成解析的自动变更。
需要注意的是这里有个坑,原来使用 HAProxy 15 版本,后端服务配置使用域名时,启动服务后只解析一次(和 Nginx 类似)域名,这时如果已解析的服务挂掉或进行了切换等,即使异常节点已屏蔽,访问 HA 时依然会出现例如 503 等异常(即使 DNS 已经发生了改变,但 HA 服务本身缓存了旧 IP 等于地址未更新)。后续查询官网得知 HAProxy 16+ 才支持了动态DNS。
如何利用 HA 的域名解析配置实现后端路由动态化
首先,HA配置增加一段 resolvers 定义,用来实现 HA 的域名动态解析。
其次,对不同业务环境隔离的路由分发,同样需要增加 HA 的 frontend 配置进行流量隔离。
最后,在 HA 的 backend 处引用前面定义的 resolvers 和 frontend,实现到后端RS的动态转发。
WEB 配置内容自动托管
文件内容更新:使用 Consul 的 K/V watch 功能,一旦有新服务上线/下线时,配置自动化接入和自动化下线流程,更新 Web 服务配置并 reload(触发脚本完成),完成整个流程的自动化。
后端服务自动加入集群
云主机节点自动初始化自身后进行服务注册,自动导入流量。
总的来说,我们根据业务特性,使用 HA、Consul、Docker 这样的一个组合来实现高度可扩展性、稳定性,及流程的基本全自动化过程。
业务链高度自动化,从上线到下线,整个流程包括服务上线、配置变更、产品发布、功能迭代、下线回收等全自动衔接完成。
整个过程至少实现了:
现在(图 A)和原有(图 B)对比如下:
作者:丁易锋,网易 游戏 资深运维工程师,主要工作方向为网易 游戏 项目运维支持。专注于运维技术的突破,以及为产品提供更加高质量和便捷的服务支撑。
本文转载自公众号:网易 游戏 运维平台,原文。
从本周开始对consul的源码做一个简单的阅读和了解,希望能持续下去吧。
consul是使用go编写的,在阅读过程中可能会涉及到对go语法的相关笔记,这个会分开两个系列文章去更新。
1agent的定义(agentgo)
agent是一个常驻进程部署在所有机器上,可以分client和server两种模式运行(client模式只负责转发请求,轻量级)。
config为agent的配置,包括nodeID等核心的配置都在里
delegate为Server或者client的对象,取决于进程启动选择的方式
2程序入口(agentgo)
这里主要是构建一个Server或者client的对象,我们接下来看一个server对象是如何构建的
我们看下server对象的重要属性,跟raft协议相关的对象封装在这里。
这里做的事情很简单,启动服务器并输出日志。
最后我们看起构建一个raft对象具体做了哪些事情。
安装路径:
/home/cube/consul
配置文件 (/home/cube/consul/config/configjson) :
启动脚本:
注:server关闭一个节点,然后马上加入一个节点,至少保证有两个节点以上才行,当server低于两个的时候,整个注册服务会丢失数据,并且服务处于不可用状态。
关闭脚本最好不要kill进程,执行 consul leave 优雅关服务。
consul权限配置有个专门的acl模块,有一套比较强大的权限控制规则。
1 在 /home/cube/consul/config/ 新建 acl_configjson 文件,server三个服务器都需要新建,文件内容为:
然后重新加载配置 /consul reload
2 生成token,这里生成的token需要依赖上面的acl_master_token子密钥。随机选一台服务器执行:
结果返回一个token
3 配置生成的token ,后面的验证都是基于这个token来验证的,只是第一次生成token稍微麻烦点,以后的token管理可以在consul manager上管理。
在所有的server端的acl_configjson加上刚刚生成的token,新的acl_configjson为:
4 上面只是生成server端的token, 现在需要配置client端的token, 将上面的>
如何用Consul打造d性可扩展的PaaS平台
杜威,程序员,混迹互联网研发和运维近十年。《Linux系统案例精解》合著者之一。目前就职亮风台,专注DevOps、云计算、大数据等相关领域。
应用背景
HiAR 是亮风台打造的新一代增强现实(AR)开发平台,提供简单易用、功能强大、跨平台的 AR 服务。让广大开发者可以轻松使用最前沿的计算机视觉技术、计算机图形学技术,快速搭建个性化的 AR 应用。
云服务是HiAR平台中重要的基础设施。无论从高可用,还是到可扩展,服务发现都发挥着不可或缺的作用。在没有使用服务发现之前,我们遇到的几个痛点:
◆ 系统添加一个服务节点,我们需要手工修改Nginx/LVS的配置文件、修改DNS记录。
◆ 应用服务发布新版本,我们还是需要手工修改Nginx的配置文件把节点下线、等待发布成功后,再次修改Nginx的配置文件把服务上线。
◆ 尽管后来我们对上面两种场景的运维做了改进,编写脚本把过程改良为半自动半手动的方式,但还不是很方便,而结合服务注册就可以做到全自动。
◆ 内网DNS出了故障,我们需要对DNS服务进行维护。
◆ 没有服务注册,限制了Docker的发挥,只能当轻量级虚拟机来用。
现在,有了服务发现,一切都变得简单有趣。增减服务节点可以自动更新Nginx/LVS的配置文件;DNS丢一边吧!用IP就好;接入Mesos+Docker玩d性扩展。
为什么选择 Consul
已经有很多文章对Zookeeper、etcd、Consul进行比较,这里就不重复类比了。没有什么比合适更重要!Consul 的运维成本低,部署简单、使用方便、五脏俱全,这对于中小型团队应该是性价比很高的。
在进入实战前,先看看 Consul 都有哪些特性。
◆ 服务注册。通过>
废话不多说先上yaml
由于采用的是多server的注册方式,存在一个问题,当我们向consul集群的一个agent注册服务的时候,会出现相同的instanceid会在不同的节点上重复注册。这就是一个大坑了,这意味着有多少个节点就有可能出现多少个重复的服务实例。当然实际上需要用到的只有一个,那意味着多余的实例需要删除,但真实 *** 作起来就没有想象中那么简单了。
consul的官方文档上有这么一段描述:
The agent is responsible for managing the status of its local services, and for sending updates about its local services to the servers to keep the global catalog in sync
大致的意思是每个agent都维护着其自己节点上注册的服务,并将其发送到其他的服务上使其在全局的catlog上同步。
这意味着其实每个agent维护的都是自己节点注册的服务,当同一个servername和instanceid在不同节点上进行注册的时候会被认为是不同的服务,而不是想当然的认为每个instanceid都是唯一的,当重复注册的时候会进行覆盖,实际上consul集群不是这么处理的。只有当在同一个节点注册的时候才会出现覆盖 *** 作。这描述真的是很隐晦,就不能直白一点嘛,关键网上找不到什么相关的资料,全靠意会,真的是非常坑爹!
所以consul其实提供了两个注册的接口,/agent/service/register和/catlog/register,其需要的参数都是不一样的,具体的可以去看下consul的文档。
这个想法没问题,但实际 *** 作起来是一堆的坑。
首先来看下consul提供的删除服务的API接口
1、/agent/service/deregister/:service_id
2、/catalog/deregister
第一个看着没啥问题,但是实际上是有问题的,由于考虑到高可用,在k8s里面我们会用一个service代理所有的所有的consul,所以是负载均衡的,这个接口实际上只会删除当前consul server节点上的该服务,其他节点的是不会删除的,所以这个接口不能直接使用
第二个接口看着就正常了,是通过catlog的方式进行删除,调用之后确实把对应节点的服务删掉了,正当你暗自窃喜的时候,这个被删除的服务过了一会儿就又冒出来了,其实他只是删除了缓存在catlog里面的数据,真实节点上的服务并没有删除,过了一会儿节点有把这个服务的信息同步上来了
我这时候已经想骂娘了,这不是个坑爹玩意儿嘛!!!!!直接删的想法只能先放弃了,看看有没有其他的方式来解决。
主要思路还是两种:
1、多了就删
在看了一遍consul提供的接口之后我的第一反应其实就是需要自己造轮子来解决了,其实通过consul提供的API接口确实也是可以解决的,具体的流程如下,如果你真的最后只能通过这种方式来解决的话也可以借鉴一下,逻辑其实也是比较简单的
2、注册之前先检查
由于我使用的是springcloud,直接重写注册接口就完事儿
此方法有一个局限性,由于是直接调用对应agent的接口进行服务的注销,那就意味着该服务必须能直接访问到agent,否则就无法实现。
如上文所说其实consul提供了两个注册的接口,默认使用的是/agent/service/register这个接口而没有使用/catlog/register这个接口,由于时间问题我就没有进行尝试,后续有时间的话会测试一下通过catlog的接口是否就不会存在这个问题。
以上就是关于聊聊spring cloud的ConsulCatalogWatch全部的内容,包括:聊聊spring cloud的ConsulCatalogWatch、网易消息推送系统微服务化实践、consul源码笔记等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)