这几个月主要在忙 CITA-Cloud
的事情。现在相关的白皮书已经发布,也在 GIAC2020
大会上做了相关的分享。白皮书和分享主要讲的还是思考后比较成熟的结果,其实中间一些思考过程或者不太成熟的中间产物也是很有意义的,这里也稍微聊一下,算是补充一些背景知识吧。
缘起
CITA-Cloud
原本的名字是 CITA-NG
,下一代 CITA
的意思。
最初的问题是 CITA
面临着商业化的压力,虽然我们设置了 CITA
的商业版承接一些定制化的需求,但是这样要维护两套代码,而且定制化需求分散在代码仓库的各处,维护起来比较痛苦。因此更好的方式是设计一个精简的联盟链核心,然后做各种扩展组件,核心是免费的,但是扩展组件可以是商业化的。这样既可以实现商业化,又不会显著增加维护的工作量。
区块链的核心
这个问题在底层链技术白皮书里面已经讲的很清楚了,这里再稍微回顾一下,补充一些背景信息。
思考的源头就是我们碰到了一些组件替换的情况。比如 CITA
最开始的网络服务是简单的直连网络,后来碰到复杂的网络情况,需要替换为 p2p
网络。还有一些替换共识算法的需求,或者新出现了更好的共识算法,我们自己想要替换。我们会发现,像网络和共识这样的模块不管怎么替换,其实都不影响区块链的整体功能,这就是“功能性模块”的由来。当然模块间还是存在细节上的耦合,导致替换的时候工作量还不小。因此设计的主要目的就是解耦。
另外一个导致模块间耦合的原因是流程,比如出块,同步等流程,在现有 CITA
里都是横跨多个模块的。因此在新的设计中,把相关的内容都集中到控制面这个大的服务中,其实也是为了解耦。
这个问题其实还可以继续深入下去,尤其是引入一些比较新的密码学技术——比如以太坊的 zk-rollup
,目标是精简区块链的 coda
——区块链的外表会有非常大的差别。似乎不变的只有区块结构,链式结构,以及它们需要是可验证的。至于具体是什么方式的验证,可以是重算一遍,也可以是密码学上的验证,其实都可以。
微服务
通常的区块链软件都是单体的,但是 CITA
从一开始就选择了微服务的方式,由此也带来了很多问题,配置,微服务之间的协同都比较困难。之前都是通过在代码里面加入重试逻辑来解决的,导致代码逻辑很复杂。这次花了一些时间调研了一下微服务框架,发现现在的微服务框架已经非常成熟了,能够在框架层面解决很多问题。目前使用的是 Consul
,参见仓库,用法比较简单,后续会深入了解,尽量发挥框架的作用。
云原生
前面用了 Consul
之后,发现这种把元信息集中存储,再通过 sidecar
的方式监控元信息,动态生成本地服务需要的配置文件的方式非常灵活,也非常易用。然后就开始调研一些相关的云原生技术。 ‘
其实之前也有关注到一些云原生技术。最近两年有一个很不好的趋势,就是把尽量多的功能都集中到区块链里面。比如给 jsonrpc
加上一些鉴权功能,存储的落盘加密,磁盘动态扩容,复杂网络支持等等。倒不是这些功能不好不实用,只是这些问题都有更专业的解决方案。 jsonrpc
的鉴权完全可以在前面架一个登录服务来解决;落盘加密可以用文件系统本身的加密功能解决;磁盘扩容已经有很多成熟的分布式存储方案;复杂的网络环境也有很多成熟的解决方案。在这个过程中发现,这些区块链非核心功能,很多都在云原生社区有了很好的解决方案,可以直接复用。
看了一些 k8s
的资料发现,跟区块链还是有非常多相似的地方。我觉得算是分布式系统在业务系统中应用的一个范式。虽然 etcd
在 k8s
里的比重非常小,当然区块链在整个业务场景里面的比重也不大。但是其中保存的却是对于更复杂的外围业务系统来说非常重要的元信息,要保证这些数据的高可用/可信。
k8s
还有一个特点就是它的声明式 API
。我们不需要给出具体的操作的命令,只要描述我们期望的集群里应用的状态, k8s
会自动去监控集群状态触发一些调整让其更接近期望的状态。作为对比, swarm
还是传统的用户显示指定操作的方式。它们的对比有点类似于声明式编程语言与命令式编程语言的区别。
但是对于熟悉区块链的人来说,这种声明式其实非常自然,甚至是有点无奈。区块链从一开始就面临着链上链下的问题,类似当初互联网的 O2O
——线上线下打通问题。我们现在可以很方便的在网上点一份外卖,并进行支付,但是外卖没法自己顺着网线跑过来,还是需要外卖小哥送过来。点外卖其实就是声明式,声明我需要一份什么样的饭,需要送到什么地方,线上部分就只能到此为止了。剩下的需要线下的厨师和外卖小哥来解决之前声明的问题。
声明式可以算是一个抽象,描述问题和解决问题的解耦。有人专门提出并描述问题,比如运维人员,比如点外卖的人;有人专门解决问题,比如 k8s
的 controller
,比如外卖小哥。他们相互之间不用管对方是具体是怎么做的,点外卖的人不用管外卖小哥是骑车还是走路,只要解决问题就行。
这其实也是 k8s
能够战胜 swarm
的一个原因,有了这种抽象, k8s
更加容易形成一个规范,更加有扩展性。 k8s
自带的资源其实就是一些非常基础的 slover
,而它的扩展其实就是这些基础 slover
的组合。而且 k8s
还提炼了写 slover
的一种模式,叫谐振器,就像数值求解方程中的牛顿迭代法,说得更直白一点就是面多了加水,水多了加面。
云原生领域还诞生了非常多的“广告语”,比如“不可变基础设施”,还有微服务的12个原则等等。这里面其实有非常多是可以借鉴甚至直接映射过来的。
未来
首先我觉得联盟链和云原生将来肯定会融合的,因为两者真的是太像了。虽然一个是去中心化的系统,一个是传统的分布式系统,但是是同一个范式,只是面临的场景不同,导致具体技术的选择不同。
云原生面临越来越多的去中心化场景;而联盟链也面临着怎么跟传统中心化的业务系统对接的问题。两者正在慢慢往共同的一个折中的位置靠近。
我设想中的未来的场景是:企业内的系统还是用云原生技术,主要关注内部集群运维管理的问题;联盟链在上面一层,就像一个微服务框架一样,把不同企业的 IT
系统串起来。联盟链关注的是更大更上层的商业模式,比如供应链金融,由一个核心企业,若干上游企业,若干下游企业,还有几个金融机构组成,这些企业之间如何协作,如何开展全流程的业务。
一旦把这个模式提炼出来,并且形成完整的解决方案,所有供应链金融场景就可以往里面套。就像标准合同的作用一样,本来企业合作要花费很多精力和时间去讨论合作的细节,现在只要说我们选哪个模板,剩下的就不用多说了,可以大大减少企业合作的成本。另外传统的合作方式是针对具体几家企业签订的合作联盟,一旦其中有一家退出,整个联盟基本也就解散了。因为引入新的替代的供应商要重新开始一轮一轮的谈判,工作量不比新组建一个联盟小。但是合作模式标准化之后,就可以按照其角色快速替换供应商,甚至可以平时就养着多个备胎,时不时进行个考评来个优胜略汰。这对联盟的稳定性是有非常大帮助的。