目标

开发一个开源的,开箱即用的,用户友好,扩展性好的,状态实时的的注册中心Frontend。

注册中心的对象图如下图,Frontend的职责是把下述的数据结构,对象以及他们的相互关系通过各种View清晰的展示出来:

scf-uml 1个应用包含多个Service,Service之间有provide和comsume的关系,Service的主键为ID:Version, 每个Serivce包含多个Instance,也包含多个API的Contract, 每个Contacts包含多个TestCase,TestCase包含针对该API的输入和期望的输出,以及上次调用(如果有)时的输出。

系统中各组件交互的流程图:

以前端显示Service列表的前端组件为例: scf-uml 因为很多Service的变化是一个不定时发生的异步事件,所以对这类情况采用,前端订阅,后端发现变化后推送最新版本的数据的方式来交互。当前端发起首次订阅时,后端总会推送一次数据当前版本的数据给前端。

架构图

scf-arch 有上图可以看出,主要的职责集中在SCF-Backend中,即ServiceCenter UI的后端部分。它的职责包括:

  • 把部分API请求转发给SerivceCenter以获取数据。
  • 把SeriviceCenter已有的非异步的又不好改造的API,可以通过轮询的方式,转化为异步API提供给前端。
  • 提供一些非原始SerivceCenter数据对象的API操作接口,比如TestCase,对的增删改查接口。
  • 提供非原始SerivceCenter数据对象的持久化保存功能,通过etcd.
  • 对一些异步的变化的数据,可以考虑将其存入时序数据库中,供后续查询,比如instances out of service的事件。前期该类型事件不多的情况下,为了不引入新的数据库,可以同样用etcd 持久话保存或用内存数据结构做非持久化存储。

Frontend Views

目前ServiceCenter Frontend包括如下这些视图:

  • API doc: 显示当前某服务的所有的API接口列表,按Service分组。
  • API detail: 显示某API接口的Swagger UI, 显示历史的TestCase列表,可以执行某一个TestCase,显示执行结果,可以对上个执行的TestCase进行保存。
  • ….

API doc View的详细设计

  1. 接口 GET /apis 参数: Service Id, Service Version, Channel ID, 返回该Service的所有的接口的概要列表。

API Detail View的详细设计

  1. 接口 Get /api_detail/:id 参数: API id, 返回该该API详情的json。包括:contract yaml, test case 列表。
  2. 接口 Post /testcases, 参数, 一个测试用例的输入,和期望输出。 创建新的测试用例。
  3. 接口 Delete /testcases/:id 参数, 测试用例ID。
  4. 接口 PUT /api_detail/:id/try_out 参数,测试用例的输入和输出。

模型

  • 某一类商品的所有特性,可以用一个多元组来表示:(a0, a1, a2 … aN),比如对一辆车,包括成本,空间,加速能力,油耗等等 (20万,5000L, 10秒,6L/百公里, …)
  • 不同的商品有不同的多元组,多元组的每个元素之间是有相互制约关系的,比如,成本会制约空间,加速能力,所谓产品研发,主要就是在多元组的各元素之间做调整和平衡。
  • 一个商品对用户的”综合效用”,或者说综合应价比,是该商品的多元组的一个函数,该函数反应了商品每个特性对用户效用的权重和变化关系,每个特性对用户的效用可正可负。 比如:成本对用户的效用为负,用户学习使用该商品的事件成本效用为负。把某个商品对某一个用户的效用函数简成为效用函数f(a0,a1,a2 … aN),对同一个商品,对不同人的效用函数 不一样。对同一个人,不同类的商品的效用函数不一样。一个简单的效用函数可以为线性函数,即f = a0w0 + a1w1 + a2w2 … aNwN。 其中w0,w1,wN为不同特性的权重,可正可负。不同人的w0..wN是不一样的,有无穷多种组合。
  • 市场上的商品种类是有限的。对某一个类别的商品,市面上只有有限个商品,记为p0, p1 … pN。为了可以把所有人的效用函数计算和所有商品的特性多元组进行计算。把所有 认为p0的效用得分最高的人的集合极为c0,依次类推,有c1,c2 … cN, 这个即是用户分类,也代表了每个产品的市场份额。

    模型是动态的,而不是静态的

  • 占有更大市场份额的厂家,如果该份额也能给他带来更大的利润,他可以利用他多的利润,扩大生产规模,改进生产工艺,降低成本,或者是投入研发,让他的多元组a0..aN的组合更优化 从而可以扩大的c的大小。
  • 甚至即使不考虑任何生产规模的扩大,和技术的创新。如果没有门槛,优势企业可以利用其额外的利润,生产和劣势企业一样的产品,低于其生产成本销售,打压劣势企业。最终获得所有市场份额。 所以对于企业来说,门槛非常重要。
  • 综合前面说的优势企业额外的利润,和门槛因素,我认为在存在一个阈值,即优势企业的优势超过劣势企业一定的值后,优势企业扩张,吞并的确实就不可阻止。

模型实践

  1. 理想汽车分析,选用价格相近的车比较,同时把油耗,驾驶舒适度,能量补充等多个因为综合在一起,方便说明方法。 |车型/用户|市区用车效用值|长途用车效用值|空间|保值性|其他| |—|–:|–:|—| | 特斯拉model 3 | 90 | 30 | 60 | 60 | 丰田汉兰达混动 | 50 | 90 | 90 | 70 | 理想One | 60 | 50 | 85 | 40 | 都市忙碌的年轻人 | 80% | 3% | 2% | 15% | 优选对象 model 3| | 都市有时间经常长途自驾游的年轻人 | 10% | 60% | 20% | 10% | 优选对象 汉兰达混动 | 都市一般时间市区,一般时间自驾游,有点小钱,但还是要打工的年轻人 | 40% | 40% | 10% | 10% | 理想One 结论:理想One可能对很小的一部分人,是最优解,但是实在太小了,很可能是被吞并的那个,并不看好理想资本市场的长期表现。

2.中药分析 |车型/用户|市区用车效用值|长途用车效用值|空间|保值性|其他| |—|–:|–:|—| | 特斯拉model 3 | 90 | 30 | 60 | 60 | 丰田汉兰达混动 | 50 | 90 | 90 | 70 | 理想One | 60 | 50 | 85 | 40 | 都市忙碌的年轻人 | 80% | 3% | 2% | 15% | 优选对象 model 3| | 都市有时间经常长途自驾游的年轻人 | 10% | 60% | 20% | 10% | 优选对象 汉兰达混动 | 都市一般时间市区,一般时间自驾游,有点小钱,但还是要打工的年轻人 | 40% | 40% | 10% | 10% | 理想One

导读

本文介绍了微服务框架中”控制面”要解决哪些问题,跟”数据面”在职责上如何分工,并提出了一个较为简单清晰的框架设计。
阅读本文,可以便于理解ServiceComb, Spring Cloud,Istio的”控制面”的功能和架构原理。
同时,Apache ServiceComb社区希望整合改造现有的控制面组件,提供一个,开源的,强扩展性强,开箱即用的,高性能的,用户友好的Control Panel整合组件。我们也热切的希望 有兴趣的同学能加入ServiceComb社区,我们一起完成该项目。

控制面的职责解析

现在主流的分布式微服务架构,把微服务的架构分为数据面+控制面,其中控制面功能较为复杂,通常包含多个组件。数据面和控制面的职责划分如下: pannels

另外一个角度观察控制面的职责。所谓”控制”,其核心的流程无外乎 采集信息->根据某个规则引擎进行分析决策->反馈控制。这一套流程按照空间和时间进行划分将包括3个层次。

  1. In-process的实时控制。适用于对性能要求较高,逻辑简单的控制流程。某一个微服务仅采集自身的信息,根据控制面下发的治理规则,在进程内部进行分析判断,并进行控制。举例:RPC失败重试机制。
  2. 跟历史事件相关的控制。比如如果在最近1小时内超时的比例大于10%,则进行限流。这个可以在in-process中发生,也可以在控制面中发生。
  3. 跟全局相关的控制。比如某一个Service的下游的Service所有的实例的平均响应时间超过了某一个阈值,则对该Service进行降级。

目前的微服务框架对1支持的成熟度较高,对2,3的提供更好的支持是微服务的一个发展方向。建议在发展2,3的时候,充分借鉴1的框架,流程,概念。这样能极大简化2,3的开发和使用。

按照工作流查看各个组件

control-pannels 工作流的概要说明:

  1. 探针会不停的监控进程的状态,所有的监控消息,会交给in-process的实时规则引擎和执行机构处理。部分关注的监控消息,会包装成一个监控事件,并异步的通过网络发送给 “上报事件网关”进行处理。
  2. “上报事件网关” 把所有的上报事件转化成统一格式,并缓存所有的上报事件,把上报事件发送给时序数据库进行持久化并处理后续可能的查询操作。
  3. 进过时序数据库的”事件”会被复制3份,分别发送给,前端,自动控制器,报警器。
  4. 前端有多个监控组件构成,每一个监控组件,接受一个事件流作为输入,并绘制相应的监控图形界面。
  5. 自动控制器被构造成handler链的形式,每个handler被某一个事件触发,可能还会产生一个对时序数据库的查询,根据触发事件,和查询结果,对数据面发送控制指令。该指令同样需要经过时序数据库保存,和网关转化(图上为了简化未画出) 这个流程统一的用于实现”跟历史事件相关的自动控制”和”跟全局相关的自动控制”。
  6. 报警可以看成一种特殊的”自动控制”,前半段是一样的,后半段不是给数据面发送控制消息,而是给报警的组件(如邮件系统,短信系统)发送消息,通知运维人员相应的报警事件。
  7. 前端中有人工的控制界面。即运维人员,能通过前端页面方便快速的给数据面发送控制消息,并查看控制反馈。
  8. 前端中有录入in-process实时规则引擎的前端组件,用于录入规则(一般是以配置的形式),并下发给数据面。

组件的详细介绍

  1. 网关
    • 描述
      • 网关主要作用有3个 a:监控对象寻址。b:对接探针。c:控制协议的转化
      • 其中协议转化又包括2方向:
        Event: 从监控对象上报的信息的抽象成一个事件(event),包括产生事件的源头,事件类型,事件发生时间,事件参数等信息。
        Cmd: 对于从后端向监控对象发送命令抽象为指令,也可以抽象成一个remote call或Http Api调用,可以用contract(open api)描述该接口,主要包括参数和返回。
        多个Cmd可以组合成一个复合Cmd。
      • 无论Event还是Cmd均需要进过时序数据库持久化,方便后续的查询和审计。
    • 关键点
      • 性能, NOI, 多实例部署。
      • 可用性,故障自动切换和恢复。
      • 不停机可扩充协议。Envoy的webAssembly是比较好的技术选型。
      • QOS。吞吐量保证。
  2. 事件和指令队列和持久化-时序数据库
    • 概述 缓存事件,提供事件顺序和持久化。接受后端指令产生非原始事件(可带有定时器)。缓存,持久化指令。
    • 关键点 使用时序数据库持久化,事件和指令。 需要在事务性,性能,可用性之间找平衡。
  3. 自动控制器
    • 自动控制器(规则引擎)。按规则链设计。每个规则,由一个事件触发。编程的范式如下:
      • step1 事件的参数的进行运算
      • step2 用事件的参数+一个查询模版对时序数据库的查询。
      • step3 对时序数据库查询的结果进行运算。
      • step4 通过前3步中的参数和结果生成cmd的参数,发起一次cmd的调用。
    • 报警器类似
  4. 页面(前端),包括前端控制组件和前端显示组件,这2个组件应该结合呈现。 所谓控制面板,就是”监视”+”控制”。这个在真实世界有很多例子。如发电站的控制台,飞机的控制面板,汽车的导航+中央控制系统。
    这里有一个例子如下图: old fashion control panel 仪表是”监视机构”,而按钮,旋钮,滑动条是”控制机构”。有几个设计原则
    • 对同一类,或者相关信息的”监视机构”和”控制机构”应放在一起。形成一个”监控组”。举例:温度表和温度调节器就应该放在一起,”看见”温度升高,就马上调整温度, 符合用户习惯。
    • 不同的”监视机构”适合与展示不同种类的信息。比如:如果关心温度的历史变化,应该是曲线图+当前温度的页面比较合适。如果是关心温度的变化范围,是否 太高超过了警戒线或太低影响效率(类似汽车的水温表),那么带有范围的指针式仪表比较合适,可以加上带有颜色数字方便阅读,指针可以清晰的显示当前值距离范围界限的距离。 要构建一个好的”监视前端”,我们需要积累多种”范式”,或者说”组件”。同样的逻辑也适合”前端控制机构”。
    • 不同的监控组也应该按组间的相关性组织空间和逻辑的关系。
    • “监视机构”— “前端展示块”,对应一个事件流+一个时序数据库的查询。
    • “控制机构”— “前端控制块”,就是手动控制器, 由用户设置的参数。并发起CMD调用,参数可以有默认值。
    • “控制机构”— “前端控制块”— “手动控制器” 的编程范式为: step1 用户输入参数 step2 时序数据库查询结果(可选) step3 组合1,2生成Cmd的参数。
  5. In-Process的实时治理规则的下发,通常是以”配置中心”下发配置的方式进行。重点是配置项目的组织和管理,可参考流行的配置中心的设计。

关于以上设计的实现

  1. 个人觉得Istio相对来说有更加”现代化”的控制面实现。ServiceComb在实现”控制面”时,可以多参考Istio.
  2. 充分利用开源社区的力量,”控制面”涉及的组件众多,比如时序数据库,自己在开发一个不现实,充分利用开源社区的已有的组件。把开发力量利用投入到最有创新性的点上去。

目标

一个开源的,开箱即用的,用户友好的通用注册中心。

组件

  1. 注册中心
    • 概述
      注册中心的核心是维护注册表,实时通知订阅者注册表的变化,心跳存活性检测。注册表|—服务名—|—实例IP:端口—|—实例的状态—|—-其他信息—-|
  2. 注册中心的UI后台
    • 概述 提供UI的API的接口,严格安装restful格式提供 + open API的契约提供。所有UI的功能的后台。
    • 关键点 读取服务的契约contracts. 读取服务实例信息。 转发请求。 测试用例的增删改查。 测试用例运行结果的保存和读取。?
  3. 注册中心UI前台
    • 概述 提供UI的前台,采用angular JS + typescript+ bootstrap + fontawsome.
    • 关键点 注册表的可视化展示与监控 契约的列表展示。 测试用例的选取和运行。 测试用例的增删改查。

ServiceComb组件

  1. Toolkit
    Toolkit
  2. Fence
    Fence
  3. Samples
    Samples
  4. Kie
    Kie
  5. Mesher
    Mesher
  6. ServiceCenter
    ServiceCenter
  7. JavaChassis
    JavaChassis
  8. SagaActuator
    SagaActuator
  9. Website
    WebSite
  10. Doc
    Doc
  11. Pack
    Pack

Istio

  1. IstioProxy
    IstioProxy
  2. Istio
    Istio