作者:孤独烟,我就是我,不一样的烟火,平安银行后端码农!

来自:孤独烟(ID:zrj_guduyan)

引言

近几年传统应用架构已经逐渐朝着微服务架构演进。那么随着业务的发展,微服务越来越庞大,此时服务配置的管理变得会复杂起来。为了方便服务配置文件统一管理,实时更新,配置中心应运而生。
其实,所谓配置中心,就是将配置的数据放在某种存储介质中,该介质可以是

  • File(例如Git、Svn)

  • Database(例如mysql、oracle)

  • nosql Database(例如Redis、Memacache、MongoDb)

  • 其他第三方中间件(例如Zookeeper)

那么配置中心可以简单理解为是封装了对这些介质进行操作的接口,供客户端拉取使用。

由于我们采用的是Spring-Boot的架构,因此当时自然而然会考虑到Spring-Cloud中提供的配置中心Spring-Cloud-Config,但是当时做完调研以后,觉得并不能直接用。
因此,本文想来分享一下,原生Spring-Cloud-Config的配置中心的缺点,以及我们对Spring-Cloud-Config做了哪些改动。

正文

OK,我们当时做配置中心的选型的时候。第一选择是Spring-Cloud- Config。
Spring-Cloud-Config在存储介质的选择这块,基本上网上所有的文章都在推荐使用Git,即将配置文件放在Git中,服务端从Git中读取。其实官网上讲的最详细的配置,也是采取用Git作为存储介质。
因此,我相信大部分读者在生产上也是用Git作为存储介质,搭配Spring-Cloud-Config使用。
但是呢,博主认为以Git作为存储介质存在一些硬伤。

Git的权限控制是个坑

Git的权限管理是说控制用户能不能Push或者Delete分支,或者能不能Push代码,而不是能不能访问某个目录的文件。
对目录和文件的可读是Git的最基本要求,不可能做到针对目录级别的不可读。
因此如果直接使用,会出现这样一种情形

不同团队之间可以互看对方配置!

于是,可能会有如下情形发生

A团队同事A:"小B,这个地方不懂怎么配?"
A团队同事B:"去看看B团队的配置,直接贴过来。"
然后B团队就会发现自己的中间件里总是会多出一些莫名奇妙的数据!

当然,你可以禁止研发直接登陆Git改配置。然后呢,基于Git研发一套配置管理系统,在上面做权限控制,但是又有几个公司这么做呢?因为,这可能带来第二个问题。

粒度问题

将配置信息放在Git中,有一个致命问题:粒度太粗了!
你每次对一条配置发生crud的操作,其带来的影响是整个文件发生变动。如果将来我们需要对某条配置做灰度发布,基于Git来做是比较麻烦的,注意了,我没说不能做,只是比较麻烦。

那么,当时我们最理想的存储介质就是数据库,将配置信息放在数据库里有两个好处

  • 基于数据库开发一套配置管理系统,显然比基于git来开发容易的多!

  • 将配置放在数据库里,每条配置对应数据库的表中的一条记录。这么做粒度够细,针对某些重要的配置,做灰度发布,实现起来就容易很多。

因此,我们采用数据库作为存储介质。庆幸的是,这一点在Spring-Cloud-Config中是支持的。在该组件下,只需要设置

spring.profiles.active=jdbc

就能够激活jdbc模式。
但是我们很快发现了一个更大的问题,也正是因为这个问题,我们不得以需要进行改写Spring-Cloud-Config。

Spring-Cloud-Config的刷新机制是个坑!

因为一个配置中心应该要能够做到,配置发生改动的时候,项目能够自动感知,自动更新配置才对。在Spring-Cloud-Config中,这套机制是借助一些代码仓库(SVN、Github等)提供的Webhook机制加上Spring-Cloud-Bus来实现的。
在Webhook中配置一个回调地址,刷新流程如下图所示

OK,那么问题又来了!
(1)配置数据放在数据库中,数据库里没有Webhook这种东西啊,怎么做到实时刷新?
(2)Spring-Cloud-Config的这套刷新机制依赖于消息总线,依赖于消息队列,存在延迟的情况!且依赖于消息队列的可用性,系统的复杂度大大增加。如果生产环境上消息队列出问题了,我们的刷新功能就会受到影响!

所以,笔者认为这套刷新机制并不是很尽如人意,需要进行修改。因此,我们很自然而然的想到了利用长轮询来改写Spring-Cloud-Config的刷新机制!

长轮询是什么

既然有长轮询,那必定有短轮询,我顺便讲讲短轮询是什么!
假设我们有一个需求

在页面上要实时显示后台的库存数量!比如库存减少了,用户不需要进行刷新,页面上的数字自己会变化。

那么,如果采取短轮询就是在客户端(js)中不断访问后台,后台接到请求马上返回最新的库存数,然后刷新到这个页面当中。
短轮询的缺点?
很明显资源浪费。假设有几百人打开了该页面,就有几百个请求在不停的请求服务端,明显听着就不合理。

因此,自然就有了长轮询的出现!
其实也很简单,客户端(js)依然是不断的去请求。但是呢,服务端不是马上返回。而是等待库存数量变化了再返回。大家知道,HTTP都有超时时间。如果在该时间内,依然没有变化,客户端将再次发起请求。

注意了,长短轮询对于客户端来说是没有区别的,就是不断的轮询。但是对于服务端,区别就比较大了。在短轮询情况下,服务端对于每次请求不管有没有变化都会立即返回结果。而长轮询情况下,如果有变化才会立即返回结果。而如果没有变化,服务端则不会再立即给客户端返回结果,直到超时为止。 

怎么实现

那么,我们在项目中采用Spring的DeferredResult来实现。在Servlet3.0以后引入了异步请求之后,Spring封装了一下提供了相应的支持,也就是DeferredResult,能够极大的提升吞吐量。
可能有人对Servlet的异步化不熟,我大概介绍一下。我们平时常用的是同步Servlet,其执行流程如下图所示

缺点很明显啦 ,业务逻辑线程和servlet容器线程是同一个,一般的业务逻辑总得发生点IO,比如查询数据库,比如产生RPC调用,这个时候就会发生阻塞,而我们的servlet容器线程肯定是有限的,当servlet容器线程都被阻塞的时候我们的服务这个时候就会发生拒绝访问,从而吞吐量上不去!
那么,你使用异步Servlet如下图所示

在异步Servlet中,业务线程有自己的线程池进行处理,并不会占用Tomcat中的线程,从而提升了吞吐量!

那么,怎么利用DeferredResult怎么实现长轮询呢?流程如下
(1)客户端和服务端建立TCP连接
(2)客户端发起HTTP请求
(3)服务端发起请求,监听60s内是否有配置发生变动(如何监听配置发生变动?)
(4)如果没发生变动,给客户端返回304标志位,客户端继续发起请求
(5)如果发生了变动,服务端会调用DeferredResult.setResult返回200状态码,客户端收到响应结果后,会发起请求获取变更后的配置信息。

最后一个问题:如何有效快速的监听出配置表的数据发生了变动?
因为我们用的是mysql。这里有一个Mysql的自定义函数叫mysql-udf-http。具有http_get()、http_post()、http_put()、http_delete()四个函数,可以在MySQL数据库中利用HTTP协议进行REST相关操作。
然后再和mysql的触发器结合起来用,可以实现在配置表发生变动的时候,主动通知我们的配置中心服务端。让服务端明白配置发生了变动!

一个疑问

采用长轮询技术来实现配置刷新,客户端和服务端需之间需要一直保持TCP连接进行通信。可能有些朋友会担心,到底服务端能撑多少的连接?可能觉得对性能有影响?
这里给出参考配置
使用了内存8G、4核的虚拟机约可以撑8000左右的连接!

总结

最后这套配置中心,我基于原有的Spring-Cloud-Config,改写其中的刷新机制,更加符合我们的业务场景!现已将改写思路说清,大家可以自行尝试!

架构师小秘圈

聚集20万架构师的小圈子

长按二维码 ▲

关注「架构师小秘圈」公众号

为什么不用原生Spring-Cloud-Config相关推荐

  1. 主流配置中心的比较 Spring Cloud Config、Apollo、Nacos

    为什么需要配置中心 配置实时生效: 传统的静态配置方式要想修改某个配置只能修改之后重新发布应用,要实现动态性,可以选择使用数据库,通过定时轮询访问数据库来感知配置的变化.轮询频率低感知配置变化的延时就 ...

  2. Spring Cloud Config 集中式配置

    2019独角兽企业重金招聘Python工程师标准>>> 本指南通过Spring cloud config服务器引导你建立和消费配置. 你要构建什么? 你需要设置一个config服务器 ...

  3. Spring Cloud Config采用数据库存储配置内容

    在之前的<Spring Cloud构建微服务架构:分布式配置中心>一文中,我们介绍的Spring Cloud Server配置中心采用了Git的方式进行配置信息存储.这一设计巧妙的利用Gi ...

  4. 聊聊 Spring Cloud Config

    一般服务器的应用都有以下几种类型, 其中当属业务部分最多也最繁杂. 当应用越来越庞大和复杂时,单机就肯定不能满足需求了,然后就要考虑分布式了,接下可能会应用不同的语言来开发应用. 比如 nginx 毫 ...

  5. spring cloud config笔记

    spring cloud config 官网的spring cloud config文档:Spring Cloud Config server端 server端主要读取远程源的配置信息到本地,然后给后 ...

  6. Spring Cloud Config采用数据库存储配置内容【Edgware+】

    在之前的<Spring Cloud构建微服务架构:分布式配置中心>一文中,我们介绍的Spring Cloud Server配置中心采用了Git的方式进行配置信息存储.这一设计巧妙的利用Gi ...

  7. spring 集成 spring cloud config 的相关知识

    这两篇 主要是在集成过程中 对相关知识的学习 1.了解springApplication 非spring boot 使用Spring cloud config (1) 了解springApplicat ...

  8. 【SpringCloud】四、Spring Cloud Config

    Spring Cloud Config 前言 一.什么是配置中心 1. 为什么需要分布式配置中心 2.常用分布式配置中心框架 二.什么是Spring Cloud Config? 1.Springclo ...

  9. (十九)Alian 的 Spring Cloud Config 集群配置

    目录 一.简介 1.1.第一步 二.maven依赖 三.配置 3.1.application.properties 3.2.主类 四.客户端修改(支付系统) 4.1 maven依赖 4.2 支付系统主 ...

  10. (六)Alian 的 Spring Cloud Config 配置中心(服务端)

    目录 一.简介 二.数据库 2.1.应用表 2.2.属性表 2.3.视图 2.4.初始化数据 三.配置 3.1.pom.xml 3.2.application.properties 3.3.主类 3. ...

最新文章

  1. 获取input数据_使用 PHP Masked Package 屏蔽敏感数据
  2. 在 Element-UI 的 Table 组件上添加列拖拽效果
  3. H.Minimum-cost Flow
  4. 【转】windows 7系统安装与配置Tomcat服务器环境
  5. 图论知识总结(简易)
  6. php fpm 日志级别,Php 错误日志级别
  7. Freeswitch配置:一台Freeswitch向另外一台Freeswitch转发视频会议命令
  8. shell while循环
  9. 模2除法(计算CRC校验码)
  10. 解决IE浏览器无法显示VUE项目的方法
  11. Mac 上“预览”中的键盘快捷键
  12. Thrift入门学习
  13. XGBoost股票预测
  14. 孙正义从阿里巴巴董事会辞职,原因是什么?
  15. 微信公众号网页授权记录
  16. 应用程序无法正常启动(0xc000007b) 问题解决
  17. 单细胞分析可视化工具盘点
  18. 深度学习图像分类:Kaggle植物幼苗分类(Plant Seedlings Classification)完整代码
  19. 钉钉企业内部开发报错notInDingTalk
  20. pta 7-7 哪两个点之间的距离最近

热门文章

  1. 博弈入门学习的博客[资源汇总]
  2. 论电子计算机在审计中的应用,计算机技术在审计中的应用领域分析.doc
  3. 解表化饮什么意思_为什么有人动不动就一身汗,有人再热也不出汗?中医告诉真实原因...
  4. pythoninterpolate用法_Pytorch上下采样函数--interpolate用法
  5. fifa17服务器维护,3月17日《EA SPORTS FIFA Online 2》服务器例行停机维护公告
  6. signature=0a26d8967069103efeee67346aac0529,Construction of Thinned Gated Single-Assignment Form
  7. angular 缓存 html5,Angular 如何及时更新客户端缓存?
  8. (三)WebGIS前端地图显示之根据地理范围换算出瓦片行列号的原理(核心)
  9. Node:非IO的异步API
  10. 关于浮点数的json解析