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

在微服务实践当中,服务注册发现与配置中心是必要的两个基础服务。JAVA因为有Netflix公司开源的一套微服务生态加上与Spring架构的无缝衔接,可以很方便的使用这两个组件,在Python当中还没有一套完整的生态可以利用。
所以我们选择基于开源项目自己来开发一些对Python友好的组件,今天介绍下为Consul开发的Python客户端。
Consul是一个开源的分布式K/V系统,可以用来实现服务注册发现与配置中心。下面是consul的架构图,和etcd,zookeeper等一样,consul运行几个server节点来维护系统一致性,并且对外提供服务,我们使用了restful api。另外在每台服务器上可以运行一个agent节点来转发请求到server集群,这样服务可以不用知道consul集群的具体位置了。


20170308-01.png

刚才提到了我们使用了consul的restful api,这些api可以将我们的服务接入到conusl集群。但是在实践的过程中我们发现只有api接入是不够的,为此我们自己开发了一个客户端实现如下的功能:

实时推送数据到微服务内存

出于性能的考虑,微服务不应该直接请求consul集群来获取最新的数据,因为传统的配置文件可以加载数据到内存中,服务直接读取内存中的数据是最快的选择,但是传统配置文件修改后需要重新启动服务,而consul的优势在于不需要重新启动服务就可以获取最新的配置,那有没有什么办法可以让我们将数据存放到consul集群的同时也能达到从内存中读取最新配置的速度呢?为此我们在每个微服务启动之前启动一个进程来专门维护这个服务对应的配置数据到内存中,并将这块内存共享给本机的微服务使用。这个进程称为watch进程,watch进程会向consul集群发送请求最新数据并记下这份数据的index,在下一次发送获取最新数据请求时会带上这个index,consul集群收到请求后会阻塞请求30秒,在这30秒内如果数据有变化就立即返回,如果在30秒后没有变化就返回timeout断开连接,watch进程如果收到返回就更新内存中的数据,如果收到timeout就发起下一次请求。这样通过watch进程就可以实时的将最新数据保存到内存当中了,本机的微服务进程就可以从内存中读取最新的数据,并且对于微服务而言这一切都是无感知而且高效的。

定时同步与本地备份

上面说了watch进程,虽然watch运行良好,但我们认为不应该只依靠这一个机制,我们需要保证在watch进程挂掉后微服务还能从内存中获取新的数据。为此我们在服务启动之前会再启动一个心跳进程,心跳进程会每隔15分钟获取一次全量数据,并将数据更新到内存中,这样我们的服务就有了双保险,watch与心跳机制任何一个失效都不会影响到微服务。
但是还有一种情况会影响到服务的运行,那就是当consul集群不可用时,虽然这发生的概率很低,但我们依然要将这种情况考虑进去,为此心跳进程在更新内存之后会将数据更新到本地的文件中,当整个consul集群都不可用时,如果微服务不重启依然可以从内存中获取最后一份数据,即使微服务重启也可以从本地文件中读取备份数据到内存中。第三重机制保障了微服务不会受到consul集群可用性的影响。

客户端的部署

具有这三重机制的客户端如何部署呢,是不是要在每台服务器上都部署一份呢?我们并没有这样选择,原因有两点,1.这会增加运维成本,这是我们不愿意看到的 2. 客户端是为本机的服务提供代理服务的所以没有必要设计成常驻的进程
所以我们将客户端的启动嵌入到微服务的启动中,一旦微服务代码中使用了consul服务,客户端就会在微服务之前启动,并读取一份最新的配置到内存中,紧接着我们的微服务就可以启动了,同样的在微服务关闭之后客户端进程也会跟着关闭,这样做的原因是我们的服务器并非固定发布一种服务,所以我们自然不希望在服务发布后有其他微服务的consul客户端还在继续运行。通过这种方式我们的客户端在不增加任何运维成本的前提下提供了consul集群的代理服务。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容