Python微服务实践-集成Consul配置中心
A litmus test for whether an app has all config correctly factored out of the code is whether the codebase could be made open source at any moment, without compromising any credentials.
配置是软件开发中一个古老而有用的概念,我们需要通过配置来控制代码运行的方式,比如缓存时间,数据库地址等等。
长久以来我们使用配置文件来保存配置项,软件在启动时读取配置文件并将配置项加载到内存中, 在软件运行过程中就可以从内存中读取配置项。如果需要修改,只需修改配置文件并且重新发布服务就可,这个方式被沿用了几十年直到分布式系统伴随着互联网时代的到来。
对于一个分布式应用来说重新发布服务意味着重新启动分布在几十台甚至几千台服务器上的服务,但是重新发布整个系统是一个耗时耗力过程而且可能会引起整个系统的波动,这显然不优雅。为此需要一种可以动态调整配置而不需要重启应用的方式。

动态配置
动态配置主要包含两个概念:
配置与代码区分对待,配置不再是代码的一部分,同样的代码在不同的配置下可以表现出不同的功能;
配置更新与代码更新严格区分,配置不再与DI/DC流程耦合,配置可以独立进行更新。
配置中心实现了这两个概念,通过一个独立的基础服务为微服务提供集中式的配置管理。
配置中心与Python
对于JAVA应用来说,配置中心与开发框架的集成已经很成熟,比如Spring或者Spring Boot集成了Netflix开源的Archaius与Spring cloud,另外比如携程开源的Apollo配置中心也可以集成进Spring框架。
但是对于Python服务开发者而言,配置中心与开发框架的集成还没有一个成熟的开源方案,为了优雅的使用配置中心实现动态配置,我们为Python开发框架集成了Consul客户端。
Consul配置中心
先简单介绍下Consul本身。Consul是一个开源的分布式K/V系统,可以用来实现服务注册发现与配置中心。下面是Consul的架构图。

和etcd、zookeeper等一样,Consul运行几个server节点来维护系统一致性,配置项即存储在server节点的内存中并且对外提供读写服务,另外在每台服务器上可以运行一个agent节点来转发请求到server集群,这样服务可以不用知道Consul集群的具体位置。我们就是使用了agent节点提供的restful api来读取最新的配置数据。这些api可以将我们的服务接入到Consul集群。
实践的过程中只有api接入是远远不够的,为此我们从性能、可靠性、运维三个方面出发,还设计实现了实时推送、定时同步与本地备份、部署客户端三大功能。
实时推送
传统的配置文件可以加载配置项到内存中,服务直接读取内存中的配置项最简单最快速,但是传统配置文件修改后需要重新启动服务,配置中心克服了这个缺点但不能以性能损失为代价,我们仍然希望读取配置的过程简单快速。出于性能的考虑,服务不应该直接请求Consul集群来获取最新的数据,那有没有什么办法可以让我们将数据存放到Consul集群的同时也能达到从内存中读取最新配置的速度呢?
我们在每个服务启动之前启动一个进程来专门维护这个服务对应的配置数据到内存中,并将这块内存通过IPC的方式共享给本机的服务使用。这个进程称为watch进程。

watch进程会向Consul集群发送请求读取最新的配置项并记下这份数据的index,在下一次发送请求时会带上这个index,Consul集群收到请求后会阻塞请求30秒,在这30秒内如果数据有变化就立即返回,如果在30秒后没有变化就返回timeout断开连接,watch进程如果收到返回就更新内存中的数据,如果收到timeout就发起下一次请求。这样通过watch进程就可以实时的将最新数据维护在内存当中了,因为服务进程是通过IPC的方式从本机内存中读取配置项,所以读取速度可以与从进程内存中读取相当。并且我们将这个过程封装起来,对外暴露一个代理对象,将这个对象注入到服务进程中,所以对于服务的开发者而言,读取最新的配置项就是读取这个代理对象的属性,非常简单透明。
watch进程本身实际上就是一个事件循环,所以我们采用tornado提供的IoLoop来实现watch进程,并通过tornado的coroutine实现了异步的request,我们保证watch进程足够简单进而足够可靠。
定时同步与本地备份
如何保证在watch进程挂掉后服务还能从内存中获取新的数据?
我们在服务启动之前会再启动一个心跳进程,心跳进程会每隔15分钟获取一次全量数据,并将数据更新到内存中,这样我们的服务就有了双保险,watch与心跳机制任何一个失效都不会影响到微服务。
但是还有一种情况会影响到服务的运行,那就是当Consul集群不可用时,虽然这发生的概率很低。为此心跳进程在更新完内存之后会将数据再更新到本地的文件中,当整个Consul集群都不可用时,如果服务不重启依然可以从内存中获取最后一份数据,即使服务重启也可以从本地文件中读取备份数据到内存中。第三重机制保障了服务的可用性不会受到Consul集群可用性的影响。

客户端的部署
如何部署这个客户端呢?最直接的方式是在每台服务器上都部署一份客户端Agent。但我们并没有这样选择,原因有两点:首先这会增加运维成本,这是我们不愿意看到的,其次客户端是为本机的服务提供代理服务的所以没有必要设计成常驻的进程。
所以我们将客户端的启动嵌入到服务的启动中,一旦服务代码中声明使用了Consul配置中心,客户端就会在服务启动之前启动,并读取一份最新的配置到内存中,紧接着我们的服务就可以启动了,同样的在服务关闭之后客户端进程也会跟着关闭,这样做的原因是我们的服务器并非固定发布一种服务,所以我们自然不希望在服务发布后有其他服务的Consul客户端还在继续运行。通过这种方式我们的客户端在不增加任何运维成本的前提下提供了Consul集群的代理服务。
Python微服务实践-集成Consul配置中心的更多相关文章
- Spring Boot实战系列(7)集成Consul配置中心
本篇主要介绍了 Spring Boot 如何与 Consul 进行集成,Consul 只是服务注册的一种实现,还有其它的例如 Zookeeper.Etcd 等,服务注册发现在微服务架构中扮演这一个重要 ...
- Spring Cloud 微服务一:Consul注册中心
Consul介绍 Consul is a service mesh solution providing a full featured control plane with service disc ...
- 微服务系列之 Consul 注册中心
原文链接:https://mrhelloworld.com/posts/spring/spring-cloud/consul-service-registry/ Netflix Eureka 2.X ...
- SpringCloud与微服务Ⅹ --- SpringCloud Config分布式配置中心
一.SpringCloud Config是什么 分布式系统面临的问题 --- 配置问题 微服务意味着要将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中会出现大量的服务.由于每个 ...
- 使用 Consul 作为 Python 微服务的配置中心
使用 Consul 作为 Python 微服务的配置中心 Consul 作为数据中心,提供了 k/v 存储的功能,我们可以利用这个功能为 Python 微服务提供配置中心. Consul 提供了 HT ...
- .Net微服务实践(五)[服务发现]:Consul介绍和环境搭建
目录 介绍 服务发现 健康检查.键值存储和数据中心 架构 Consul模式 环境安装 HTTP API 和Command CLI 示例API介绍 最后 在上篇.Net微服务实践(四)[网关]:Ocel ...
- 服务注册发现、配置中心集一体的 Spring Cloud Consul
前面讲了 Eureka 和 Spring Cloud Config,今天介绍一个全能选手 「Consul」.它是 HashiCorp 公司推出,用于提供服务发现和服务配置的工具.用 go 语言开发,具 ...
- .Net微服务实践(三):Ocelot配置路由和请求聚合
目录 配置 路由 基本配置 占位符 万能模板 优先级 查询参数 请求聚合 默认聚合 自定义聚合 最后 在上篇.Net微服务实践(二):Ocelot介绍和快速开始中我们介绍了Ocelot,创建了一个Oc ...
- QCon技术干货:个推基于Docker和Kubernetes的微服务实践
2016年伊始,Docker无比兴盛,如今Kubernetes万人瞩目.在这个无比需要创新与速度的时代,由容器.微服务.DevOps构成的云原生席卷整个IT界.在近期举办的QCon全球软件开发大会上, ...
随机推荐
- Echo团队Alpha冲刺随笔 - 第十天
项目冲刺情况 进展 对Web端和小程序端进行各项功能的测试 问题 bug无穷无尽 心得 debug使人秃头,希望明天能挑好 今日会议内容 黄少勇 今日进展 测试小程序,对发现的bug进行处理 存在问题 ...
- 微信小程序转百度小程序代码
听说百度小程序开始出现手机端搜索流量,作为SEO一员,必须搞他.但是又奈何之前做的都是微信小程序,所以用php写了一个微信小程序转百度小程序代码. 修改文件后缀名 .wxml转换为.swan .wxs ...
- 如何使用project制定项目计划?(附详细步骤截图)
使用project制定项目计划可以分为六个步骤,如下图(1): 图(1)-project制定项目计划步骤 下面我们就以project2010为例,按上图所示步骤对如何制定项目计划进行详细说明: 一.创 ...
- 用wpjam插件的朋友记得勾选移除工具栏
今天ytkah在调试页面的时候发现网页一直出现32px高度的空白,非常奇怪,样式如下,全盘查找了关键词也没找到对应的样式文件,后面想到wpjam插件好像有个屏蔽选项,到那边设置一下说不定可以 < ...
- vs下载代码
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u012605477/article/details/62222919Visual Studio 20 ...
- 简易配置中心Confd入手
改成动态更新配置文件,如下每五秒重新生成配置文件 confd与etcd的使用 Add keys This guide assumes you have a working etcd, or consu ...
- ipcs
用于报告Linux中进程间通信设施的状态,显示的信息包括消息列表.共享内存和信号量的信息
- 数据结构实验之排序四:寻找大富翁(SDUT 3401)
#include <stdio.h> #include <stdlib.h> #include <string.h> void Swap(int a[], int ...
- mapreduce中reduce没有执行
hadoop执行mapreduce过程reduce不执行原因 1.如果你的map过程中没有context.write()是不执行reduce过程的:2.如果你的map过程中context.write( ...
- nginx重启 平滑重启
进入 ngiinx sbin目录下./nginx -c /usr/local/nginx/conf/nginx.conf -c参数指定了要加载的nginx配置文件路径 停止操作停止操作是通过向ngin ...