学习
实践
活动
专区
工具
TVP
写文章
专栏首页EAWorld命令式和声明式,哪个才是你的菜

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

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

主要大纲 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

本文参与 腾讯云自媒体分享计划 ,欢迎热爱写作的你一起参与!

作者:宋潇男
原始发表时间:2017-01-06
如有侵权,请联系 cloudcommunity@tencent.com 删除。
登录 后参与评论
0 条评论

相关文章

  • 社区生态如何让React做大做强,再创辉煌

    「Christopher Chedeau」在12年作为前端开发加入Facebook(后文简称FB),彼时FB的策略为:

    公众号@魔术师卡颂
  • 关于 K8S API Resources: Group 和 Version 该怎么写

    Kubernetes 使用声明式 API 来使得系统更加的健壮。但是这也意味着如果我们要创建一个对象,我们可以通过 CLI 或者 REST 的方式告诉系统我们需...

    runzhliu
  • 大数据看吃货:最热门的20道中国菜出炉,你吃过几样?

    作为一个餐饮文化大国,中国菜式之多、味型之广、做法之精巧繁复,在世界范围内都是首屈一指。长期以来,中国各地的菜肴由于受到当地环境、气候、物产、风俗以及饮食习惯的...

    华章科技
  • (二十一)敏捷项目管理和传统项目管理有何区别?

    敏捷项目管理VS传统项目管理

    砖家认证
  • TensorFlow、MXNet、PaddlePaddle三个开源库对比

    本文从定位、框架使用、分布式构成三个方面比较了TensorFlow、MXNet、PaddlePaddle三个框架。

    IT派
  • 按照缓冲区的顺序,分散读取和非阻塞式网络通信区别

    分散读取(Scattering Reads)是指从Channel 中读取的数据“分散”到多个Buffer 中。

    用户7108768
  • 谷歌、亚马逊和百度的深度学习野心:TensorFlow、MXNet、PaddlePaddle 三大框架对比

    【新智元导读】本文作者陈汝丹从定位、框架使用、分布式构成三个方面比较了 TensorFlow、MXNet、PaddlePaddle三个常用开源框架。 本文转载自...

    新智元
  • 哇!这就是HDFS!

    今天是小史生日,为了庆祝自己今年喜提A厂offer,小史叫了二十多个人一起庆生,吕老师、小史姐姐、小林都去啦。

    Java3y
  • 每个 JavaScript 工程师都应当知道的 10 个面试题以人为本1. 能说出来两种对于 JavaScript 工程师很重要的编程范式么?2. 什么是函数式编程?3. 类继承和原型继承有什么区别?

    美的让人心动
  • Javascript[0x06] -- 基于Javascript范畴代码风格和规范的总结

    抓重点: 这么多要看到猴年马月去,找一个对的上眼的深入学习下,切勿都学,没这个必要,粗略扫读,有针对性阅读!

    江涛学编程
  • 基于ArkUI eTS开发的坚果食谱(NutRecipes)

    Url:https://way.jd.com/jisuapi/search?keyword=白菜&num=10&start=0&appkey=7c913be32...

    徐建国
  • 【i.MX6ULL】驱动开发9——Linux IO模型分析

    前面两篇介绍按键的文章,无论是用GPIO来读取,还是用中断的方式,其应用程序通过循环读取的方式获取按键值,都会使得CPU的占用率很高。本篇先来介绍Linux中几...

    xxpcb
  • Docker六脉神剑 (五) Docker Swarm集群搭建及基础服务部署

    集群(cluster)技术是一种较新的技术,通过集群技术,可以在付出较低成本的情况下获得在性能、可靠性、灵活性方面的相对较高的收益,其任务调度则是集群系统中的核...

    憧憬博客
  • 大数据看中国“八大菜系”:谁最受欢迎?(附餐饮经济地图)

    ? 俗话说“民以食为天”。在中国,虽然大家对“吃”有着一致的重视,但各地在食料、烹饪技法和风味上却大不相同,而“菜系”就是对这种饮食地域差异最直接的特征体现。...

    CDA数据分析师
  • Maven optional 关键字透彻图解

    本来想写一篇「如何自定义Spring Boot Starter」,但是为了更好理解 Starter 的一些设计理念和其中的关键点,所以提前将一些细节内容单独提取...

    用户4172423
  • Maven optional 关键字透彻图解

    本来想写一篇「如何自定义Spring Boot Starter」,但是为了更好理解 Starter 的一些设计理念和其中的关键点,所以提前将一些细节内容单独提取...

    码农小胖哥
  • Spring Boot 2.7.0正式发布,2.5停止维护,又一波新特性~

    点击上方“芋道源码”,选择“设为星标” 管她前浪,还是后浪? 能浪的浪,才是好浪! 每天 10:33 更新文章,每天掉亿点点头发... 源码精品专栏 原创 |...

    芋道源码
  • 认识下IO五兄弟,BIO、NIO、AIO、IO多路复用、 信号驱动IO

    在上一篇文章中,我们了解了操作系统中内核程序和用户程序之间的区别和联系,还提到了内核空间和用户空间,当我们需要读取一条数据的时候,首先需要发请求告诉内核,我需要...

    用户4283147

扫码关注腾讯云开发者

领取腾讯云代金券