命令式和声明式,哪个才是你的菜

今天的主题是讨论一下“命令式”思想和“声明式”思想在分布式系统和微服务架构运维中的应用。

主要大纲 1. “命令式”和“声明式”的概念

2. 命令式思想在分布式系统和微服务架构中遇到的困境

3. 以Kubernetes的设计思想为例,介绍声明式思想的优势

4. 普元的实践

“命令式”和“声明式”的概念

“命令式”和“声明式”这两个概念最初来自于编程语言,这两个概念并不常见,所以我们首先将他们明确一下。

第一个是“命令式”:

“命令式”有时也被称作“指令式”,好像有一个是台湾翻译,我不确定是哪一个了。“命令式”强调的是how,如果你是在写命令式的程序,那么你将step-by-step的告诉计算机如何完成一项工作,大多数的程序都是这样的。

在命令式场景下,计算机是不具备“智能”的,只是很机械的完成你交代的事情,至于结果如何,要看你的水平。就像上图,煎饼好吃不好吃、会不会糊锅,要看厨师对原料和火候的掌握。

另一个是“声明式”:

“声明式”有时也被成为“描述式”或者“申明式”,为告诉计算机你想要什么,“声明”你想要的what,由计算机自己去设计执行路径,需要计算机或者是“运行时”具备一定的“智能”。在这种情况下,计算机显然不会实现所有你想要的what,用专业术语说就是“非图灵完备”,但是针对特定的任务,“声明式”要远比“命令式”方便,其实大多数声明式语言都是针对特定任务的领域专用语言,即DSL。当然,随着深度学习驱动的自动编程技术的兴起,我们有可能在任意领域使用“声明式”完成任务,这是后话,暂且不提。

最常见的声明式语言就是SQL—— 告诉计算机你想要的结果集,SQL语言的运行时,即数据库,帮你设计获取这个结果集的执行路径,并返回结果集。众所周知,使用SQL语言获取数据,要比自行编写处理过程去获取数据容易的多。

下面是一个最简单的例子:

在这个例子里我们可以看到,使用其他通用语言“命令式”的完成查询,要比使用SQL语言“声明式”的完成查询复杂的多。在数据量很大的时候两种方法的复杂度差距会更加明显,数据库可以帮助你收集数据分布的统计信息、维护索引和选择最佳执行路径,以保证查询性能,如果你自行编码完成这些工作,那代码量会有成千上万行。

“声明式”虽然为一个编程语言的概念,但是也可以上升到一个比较高的层面,作为一个设计软件的思想或思路,就好像你可以使用“命令式”的C语言,编写一个可以“声明式”使用的数据库一样。

但是我们很少使用“声明式”思想去设计软件。下面是我能想到的几个原因:

最重要的原因是第三个,归纳和提取完备的what,是件很困难、很技术化的工作,令人望而却步。

但是在很多特定的领域,我们往往更加喜欢实现“声明式”思想的工具,比如前面提到的SQL语言。

原因也很简单,因为这些工具的编写者,已经把实践“声明式”思想的最大障碍—— 归纳和提取what,替你完成了。

命令式思想在分布式系统和微服务架构中遇到的困境

现在我们跳出编程的概念,看下“声明式”思想在系统和微服务架构的运维还有DevOps等领域的应用。

首先看一个运维故事:

再看另外一个运维故事:

开个小玩笑,这里不是黑Puppet,也不是鼓吹Docker,我想表达的是,如果你以“命令式”的思路,编写一个过程化的脚本去部署应用,很可能会发生意想不到的事情,造成部署失败;而如果以“声明式”的思路,去制作和部署一个Docker镜像,那么成功率将大大提高。当然,Puppet也支持“声明式”,Docker也可以按“命令式”去使用,比如不太友好的Entrypoint脚本,但是这些都不是重点。

重点是:使用“命令式”思路去部署一个分布式系统或者微服务架构,已经变得非常困难。

比如部署下面这个系统:

“命令式”运维存在这下述问题,这些问题在分布式系统和微服务架构中日趋严重。

在分布式系统和微服务架构中,edge case更加复杂,环境更加动态,想在脚本中处理这些问题,你需要成为一个事无巨细的绝顶高手。如果同时还想实现部署结果的一致性、事务性和版本化,那简直是不可能完成的任务,就好像只是为了查询一笔数据,却要去编写一个数据库。

如果使用“声明式”的思路,问题则简单的多:

“声明式”运维的表现,就是编写一个配置文件,描述想要的部署结果,然后由平台解析这个配置文件并自动生成这个部署结果。描述部署结果的配置文件比过程化的脚本更加易于理解,可以由开发人员自行编写。由开发人员参与的Ops,才叫DevOps。

配置文件一目了然,多人维护不是问题,有错误也很容易被发现。配置文件本身就是文档。部署结果为配置文件所描述,如果达不到这个结果,那么部署失败并回退到部署之前的状态,所以部署天然具备了一致性和事务性。

当然,上述优势需要平台去保证,Kubernetes就是这样的一个平台。

以Kubernetes的设计思想为例,介绍声明式思想的优势

接下来就以Kubernetes为例,说明一下平台软件的“声明式”设计思想。

Kubernetes非常强调声明式思想,在其文档的第一篇就明确提出:

使用Kubernetes时,用户不需要去定义do A then B then C这种workflow,而是直接去描述一个desired state,然后Kubernetes帮助用户去达到这个state。至于如何达到这个state,用户不必关心。这种设计使Kubernetes更加易用和健壮,更具弹性和扩展性。

在Kubernetes的设计原则中,也把Declarative列在首位。

State your desired results, let the system actuate.

Kubernetes实现了多个Control Loop,观测系统的运行状态,如果偏离了预期状态,Kubernetes会自动进行校正。

举一个简单的例子,Kubernetes会维护一个集群系统内的可用节点数,使其等于用户的定义数量,如果有节点发生故障,Kubernetes会自行产生新节点替换故障节点,以保证可用节点数不变。

“声明式”思想在分布式系统和微服务架构中如此重要,所以我们的一位英国小伙伴在办公桌上钉了这样一个纸条时刻提醒自己:

普元的实践

可是说归说,做归做,我们该如何去实践“声明式”思想呢?

普元将“声明式”思想贯彻到了数字化企业云平台的开发工作中,与此同时,普元还有一个秘密武器,普元前些年做了一个很牛的元数据管理产品,现在把它用在了声明信息的管理上,以高效管理声明信息,帮助实现大规模分布式系统和微服务架构的“声明式”运维工作。

最后,我们有一个OneMore Thing,是声明式思想的一个延伸概念 —— Choreography。

在前面提到的Whatis Kubernetes文档中,说“Kubernetes不仅是一个orchestration system”,而是“more akin tochoreography”。那么orchestration和choreography这两个概念代表什么呢?

Orchestration的本意是乐队指挥:

Choreography的本意是舞蹈编舞:

这两个概念的最大区别就是,乐队指挥是个中央控制点,而舞蹈中是不存在这样一个控制点的—— 舞蹈演员根据舞伴的动作来确定自己的下一个动作。

这两个概念用到IT中,也是非常的贴切,差异就在系统中有无乐队指挥那样的中央控制点。

可以看到,Orchestration是由一个中央引擎执行一个工作流,来达到一个预期状态,更贴近“命令式”概念;而Choreography则定义了交互协议—— 参与方根据相关方的动作来确定自己的下一个动作,来达到一个预期状态,更贴近“声明式”概念。

所以在Whatis Kubernetes中,特别强调Kubernetes的实践思路是more akin to choreography。

另外,很多文章将Orchestration翻译为“编排”,其实并不准确。

在大规模的分布式系统和微服务架构中,是很难实现一个“上帝视角”的中央控制点的,所以在实践“声明式”思想的时候,要时刻记得choreography。

今天的分享就到这里,谢谢大家。

关于作者:

宋潇男

EAII-企业架构创新研究院 专家委员

现任普元云计算架构师,曾在华为负责云计算产品与解决方案的规划和管理工作。曾负责国家电网第一代云资源管理平台以及中国银联基于OpenStack的金融云的技术方案、架构设计和技术原型工作。

原文发布于微信公众号 - EAWorld(eaworld)

原文发表时间:2017-01-06

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏java工会

每个程序员都应该了解的十句话

我们可以因为掌握了最新的JavaScript框架Ahem、Angular的IoC容器技术或者某些编程语言甚至操作系统而欢欣雀跃,但是这些东西并不是作为程序员的我...

12400
来自专栏web前端教室

对即将入职前端工作的新人有哪些建议?

问题描述,略。。。 ------------------------------ 看你的问题描述,你应该是在扫射式的学习WEB开发的相关技术, 你学的应该会很努...

47680
来自专栏北京马哥教育

代码行数最多的 Python 项目是?

21640
来自专栏程序员的知识天地

新手程序员须知30个技巧!少走弯路

最近不少读者问我,自己新手程序员上路,面对工作有时候无从下手,很吃力,有没有一些小技巧,可以提供给他(她)。小编当然是知无不言,只有能帮的,小编都竭尽所能啦!

13620
来自专栏大数据和云计算技术

实用调度工具Airflow

引言 前面写过一篇文章《端午搬砖:聊聊调度云服务》,主要讲云服务的。如果企业也业务上云,可以优先选用这些服务,减少工作量。 而在传统企业内部,数据集成是基础,更...

1K60
来自专栏知识分享

1-51单片机开发板介绍(所讲内容,功能介绍)

21430
来自专栏Java学习网

每一个程序员都应当了解的11句话

每一个程序员都应当了解的11句话   1.技术只是解决问题的选择,而不是解决问题的根本   我们可以因为掌握了最新的JavaScript框架ahem、Angul...

23480
来自专栏Python绿色通道

Python爬虫实战题荟萃

公众号Python爬虫系列文章基础写完了,所以就有了一些实战题目,有兴趣的可以来去围观一下.,为什么要进行Python项目实战 项目实战第二季

25920
来自专栏郭耀华‘s Blog

【分享】熟练的Java程序员应该掌握哪些技术?

Java程序员应该掌握哪些能力才能算是脱离菜鸟达到熟练的程度?   1、语法:Java程序员必须比较熟悉语法,在写代码的时候IDE的编辑器对某一行报错应该能...

34650
来自专栏IT派

Python项目可以有多大?最多可以有多少行代码?

导读:总是看到有人说,动态一时爽,重构火葬场。然而这世界上有的是著名的开源项目, 也有像 Github、Instagram 这样流量巨大的知名网站是基于动态语言...

17440

扫码关注云+社区

领取腾讯云代金券