上一讲中,分享了当前 3 个技术发展趋势,以及其对编译技术的影响。今天我们把其中的云计算和编程模式、编译技术的之间的关系、前景再展开探讨一下。

总的来说,现在编写程序是越来越云化了,所以,我们简单地称作云编程就好了。

关于云编程,有很多有趣的问题:

1. 编程本身是否也能上云?在云上编程会跟本地开发有什么不同?

2. 如何编写云应用,来充分发挥云平台的能力?分为哪些不同的模式?

3. 为什么编写云应用那么复杂?如何降低这些复杂度?云原生应用的开发平台,能否解决这些问题?

本节就带你深入讨论这些问题,希望借此帮助你对编程和云计算技术的关系做一个梳理,促使你更好地利用云计算技术。

首先,来看看如何实现云上编程。

实现云上编程

90 年代初,宿舍几个人合买了一台 386 电脑。那个时候,记得自己不太喜欢微软提供的 MFC 编程框架,这和 386 电脑没有浮点运算器,编译起来比较慢有关,编译一次使用 MFC 框架的,C++ 程序的时间,足够我看一页报纸的了。

喜欢编程的人,为了获得流畅的性能,电脑配置总是很高,虽然这足以满足 C/C++ 时代的编程需要,但进入 Java 时代后,因为应用结构越来越复杂,工程师们有时需要在笔记本或桌面电脑上,安装各种复杂的中间件,甚至还要安装数据库软件,这时,电脑的配置即便再高,也很难安装和配置好这么复杂的环境。那么到了云计算时代,挑战就更大了,比如,你能想象在电脑上安装 Hadoop 等软件,来做大数据功能的开发吗?

其实,编写一个小的应用还好,但现在的应用越来越复杂,所需的服务端资源越来越多。以最近参与的一个项目为例,这个项目是采用微服务架构的一个企业应用,要想实现可扩展的性能、更好的功能复用,就要用到数据库、消息队列、容器服务、RPC 服务、分布式事务服务、API 服务等等很多基础设施,在自己的电脑上配置所有这些环境,是不大可能的。

因此,工程师们已经习惯于,在云上搭建开发和测试环境,这样,可以随需获取各种云端资源。

因为编程跟云的关系越发紧密,有些开发工具已经跟云平台有了一定的整合,方便开发者按需获取云端资源。比如,微软的 Visual Studio 支持直接使用 Azure 云上的资源。

再进一步,IDE 本身也可以云化,我们可以把它叫做“云 IDE”。你的电脑只负责代码编辑的工作,代码本身放在云上,编译过程以及所需的类库也放在云上。Visual Studio Code 就具备 UI 和服务端分离的能力。还有一些服务商提供基于浏览器的 IDE,也是实现了前后端的分离。

我认为,未来的 IDE 可能会越来越云化,因为云 IDE 有很多优势,能给你带来很多好处。

1. 易于管理的编程环境

编程环境完全配置在云上,不用在本地配置各种依赖项。

这一点,会给编程教育这个领域,提供很大的帮助。因为,学习编程的人能够根据需要,打开不同的编程环境,立即投入学习。反之,如果要先做很多复杂的配置才能开始学习,学习热情就会减退,一些人也就因此止步了。

其实,在软件开发团队中,你经常会看到这样一个现象:新加入项目组的成员,要花很长的时间,才能把开发环境搭建起来。因为他们需要安装各种软件,开通各种账号等等。那么,如果是基于云 IDE 开发的,这些麻烦都可以省掉。

2. 支持跨平台编程

有些编程所需要的环境,在本地很难配置,在云中开发就很简单。比如,可以用 Windows 电脑为 Linux 平台开发程序,甚至你可以在云上,为你的无人机开发程序,并下载到无人机上。

在为手机编程时,比较复杂的一项工作是,适配各种不同型号的手机。这时,你只需要通过云 IDE,整合同样基于云的移动应用测试环境,就可以在成百上千种型号的手机上测试你的应用了。

3. 更强的计算能力

有些软件的编译非常消耗 CPU,比如,完整编译 LLVM 可能需要一两个小时,而充分利用服务器的资源可以让编译速度更快。如果你从事 AI 方面的开发,体会会更深,AI 需要大量的算力,并且 GPU 和 TPU 都很昂贵,我们很难自己去搭建这样的开发环境。而基于云开发,你可以按需使用云上的 GPU、TPU 和 CPU 的计算能力。

4. 有利于开发过程的管理

开发活动集中到云上以后,会有利于各种管理工作。比如,很多软件项目是外包开发的,那么你可以想象,基于云编程的平台,甲乙双方的项目管理者,都可以获得更多关于开发过程的大数据,也更容易做好源代码的保护。

5. 更好的团队协作

越来越多的人已经习惯在网上编写文档,平心而论,线上文档工具并没有本地的 Office 软件功能强大,是什么因素让我们更加偏爱线上文档工具呢?就是它的协作功能。团队中的成员可以同时编辑一个文档,还可以方便地将这个文档在团队中分享。

而我比较希望见到这样的场景,那就是,程序员们可以基于同一个代码文件,进行点评和交互式的修改,这相当于基于云的结对编程,对于加强团队的知识分享、提升软件质量都会有好处。

基于上述几点,个人猜测:编程这项工作,会越来越与云紧密结合。这样一来,不仅仅能方便地调取云端的资源,越来越多的编程环境也会迁移到云上。

既然提到了在云上编程的方式,那么接下来,我们从编译技术的视角,来探讨一下,如何编写能充分运用云计算强大威力的应用,这样,你会对云计算有一个更加全面的认知。

如何编写云应用?

学习编译原理,你可能会有一个感受,那就是编程可以在不同的抽象层次上进行。也就是说,你可以通过抽象,把底层复杂的技术细节转换成上层简单的语义。

程序员最早是直接编写机器码,指令和寄存器都要直接用 0101 来表示。后来,冯·诺依曼的一个学生,发明了用助记符的方法(也就是汇编语言)简化机器码的编写。用汇编语言编程的时候,你仍然要使用指令和寄存器,但可以通过名称来引用,比如34 讲中,用 pushq %rbp 这样的汇编指令来表示机器码 0x55。这就增加了一个抽象层次,用名称代替了指令和寄存器的编码。

而高级语言出现后,我们不再直接访问寄存器,而是使用变量、过程和作用域,抽象程度进一步增加。

总结起来,就是我们使用的语言抽象程度越来越高,每一次抽象对下一层的复杂性做了屏蔽,因此使用起来越来越友好。而编译技术,则帮你一层层地还原这个抽象过程,重新转换成复杂的底层实现。

云计算的发展过程跟编译技术也很类似。云计算服务商们希望通过层层的抽象,来屏蔽底层的复杂性,让云计算变得更易用。

而且,通常来说,在较低的抽象层次上,你可以有更大的掌控力,而在更高的抽象层次上,则会获得更好的方便性。

虚拟机是人们最早使用云资源的方式,一台物理服务器可以分割成多个虚拟机。在需要的时候,可以创建同一个虚拟机镜像的多个实例,形成集群。因为虚拟机包含了一套完整的操作系统,所以占据空间比较大,启动一个实例的速度比较慢。

我们一般是通过编写脚本来管理软件的部署,每种软件的安装部署方式都不相同,系统管理的负担比较重。

最近几年,容器技术变得流行起来。容器技术可以用更轻量级的方式,分配和管理计算资源。一台物理服务器可以运行几十、上百个容器,启动新容器的速度也比虚拟机快了很多。

跟虚拟机模式相比,容器部署和管理软件模块的方式标准化了,我们通过 Kubernetes 这样的软件,编写配置文件来管理容器。从编译原理的角度出发,这些配置文件就是容器管理的 DSL,它用标准化的方式,取代了原来对软件配置进行管理的各种脚本。

无服务器(Serverless)架构,或者叫做 FaaS(Function as a Service),做了进一步的抽象。你只要把一个个功能写成函数,就能被平台调用,来完成 Web 服务、消息队列处理等工作。这些函数可能是运行在容器中的,通过 Kubernetes 管理的,并且按照一定的架构来协调各种服务功能。

但这些技术细节都不需要你关心,你会因此丧失一些掌控力,比如,你不能自己去生成很多个线程做并行计算。不过,也因为需要你关心的技术细节变少了,编程效率会提高很多

上面三个层次,每一级都比上一级的抽象层次更高。就像编译技术中,高级语言比汇编语言简单一样,使用无服务架构要比直接使用虚拟机和容器更简单、更方便。

但即使到了 FaaS 这个层次,编写一个云应用仍然不是一件简单的事情,你还是要面临很多复杂性,比如,处理应用程序与大容量数据库的关系,实现跨公有云和私有云的应用等等。那么能否再进一步抽象并简化云应用的开发?是否能通过针对云原生应用的编程平台,来实现这个目标呢?

为了探究这个问题,我们需要进一步审视一下,现在云编程仍然有哪些,需要被新的抽象层次消除掉的复杂性。

对云原生编程平台的需求:能否解决云应用的复杂性?

在《人月神话》里,作者把复杂性分为两种:

一种叫做本质复杂性(Essential Complexity),指的是你要解决的问题本身的复杂性,是无法避免的。

一种叫做附属复杂性(Accidental Complexity),是指我们在解决本质问题时,所采用的解决方案而引入的复杂性。在我们现在的系统中,90% 的工作量都是用来解决附属复杂性的。

经常会被问到这样的问题:做一个电商系统,成本是多少?而我给出的回答是:可能几千块,也可能很多亿。

如果你理解我的答案,那意味着比较理解当前软件编程的复杂性问题。因为软件系统的复杂性会随着规模急剧上升。

像阿里那样的电商系统,需要成千上万位工程师来维护。它在双 11 的时候,一天的成交量要达到几千亿,接受几亿用户的访问,在性能、可靠性、安全性、数据一致性等维度,都面临巨大的挑战。最重要的是,复杂性不是线性叠加的,可能是相乘的。

比如,当一个软件服务 1 万个用户的时候,增加一个功能可能需要 100 人天的话;针对服务于 1 百万用户的系统,增加同样的功能,可能需要几千到上万人天。同样的,如果功能不变,只是用户规模增加,你同样要花费很多人天来修改系统。那么你可以看出,整体的复杂性是多个因素相乘的结果,而不是简单相加。

这跟云计算的初衷是相悖的。云计算最早承诺,当我们需要更多计算资源的时候,简单增加一下就行了。然而,现有软件的架构,其实离这个目标还很远。那有没有可能把这些复杂性解耦,使得复杂性的增长变成线性或多项式级别(这里是借助算法复杂性的理论)的呢?

再带你细化地看一下附属复杂性的一些构成,以便加深你对造成复杂性的根源的理解。

1. 基础设施的复杂性

编写一个简单的程序,你只需要写写业务逻辑、处理少量数据,采用很简单的架构就行了。但是编写大型应用,你必须关心软件运行的基础设施,比如,你是用虚拟机还是容器?你还要关心很多技术构成部分,比如 Kubernetes、队列、负载均衡器、网络、防火墙、服务发现、系统监控、安全、数据库、分片、各种优化,等等。

这些基础设施产生的复杂性,要花费你很多时间。像无服务器架构这样的技术,已经能够帮你屏蔽部分的复杂性,但还不够,仍然有很多复杂性因素需要找到解决方案。举个例子

大多数商业应用都要很小心地处理跟数据库的关系,因为一旦数据出错(比如电商平台上的商品价格出错),就意味着重大的商业损失。你要根据应用需求设计数据库结构;要根据容量设计数据库分片的方案;要根据数据分析的需求设计数据仓库方案,以及对应的 ETL 程序。

一个经常出现的情况是,数据处理的逻辑分布在几个微服务中,要让它们对数据的修改满足事务特征,所以你要在代码里添加与分布式事务有关的逻辑。

那么,能否由云原生的开发平台来自动处理所有这些事情?我们只需要做业务对象(比如订单)的逻辑设计,把上述所有技术细节都隐藏起来呢?

2. 部署复杂性

大型软件从编写代码,到部署,再到生产环境运行,是一个复杂的过程。

源代码可能有多个分支,需要进行合并;

需要能够正确地编译;

编译后的成果,要打包成可部署的对象,比如容器镜像;

要对需要发布的模块进行测试,确保不会因为这次发布而造成很多 bug;

要对数据库的结构、基础数据等做必要的修改;

新版本的软件上线,有时候不是全部上线,而是先让一部分用户使用,然后再针对所有用户;

如果上线的特性出现问题,需要能够回滚到原来的版本。

是不是很复杂?那么,这样的复杂性,是否也可以由云原生的开发平台隐藏起来呢?

3.API 的复杂性

我们在写云应用的时候,需要通过 API 来调用别的服务。你需要处理与之相关的各种问题,包括 API 访问的权限、访问次数的限制、错误处理、不同的 RPC 协议和调用约定,以及相同的功能在不同的云平台上使用不同的 API。

那么我的问题是:能否让 API 调用跟普通语言的函数调用一样简单,让开发平台来处理上述复杂性呢?

回答上面 3 个问题,并不简单。但是,根据计算机语言的发展规律,我们总是会想办法建立更高的抽象层次,把复杂性隐藏在下层。就像高级语言隐藏了寄存器和内存管理的复杂性一样。

这样看来,解决云计算的复杂性,要求新的编程语言从更高的一个抽象层次上,做编译、转换和优化。我们只需要编写业务逻辑就可以了,当应用规模扩大时,真的只需要增加计算资源就行了;当应用需求变化时,也只需要修改业务逻辑,而不会引起技术细节上的很多工作量。能解决这些问题的软件,就是云原生的编程语言及其基础设施。

而现在的技术进步已经提供了很好的基础,容器技术、无服务器架构、处理大数据的 Map/Reduce 架构等,为云原生的编程语言准备好了素材。

我相信,在很多应用领域,我们其实可以降低对掌控力的要求,从而获取更大的方便性的。比如,对于大多数企业应用来说(比如 ERP、CRM 等),进行的都是以业务数据为核心的处理,也就是以数据库为核心的处理。

这些应用都具备相对一致的模式,通过更高的抽象层次,去除各种附属复杂性是有可能的。像这样的针对数据库编程的特定领域的云原生编程平台,会比较容易成功。

课程小结

本节带你围绕“云编程”这个话题,剖析了云计算技术怎样和编程结合。希望以下几个观点会对你有所启发:

1. 编程环境会逐渐跟云平台结合起来,不仅仅是调用云上的资源,还可能实现编程环境本身的云化。

2. 编译技术能够在不同的抽象层次上,处理计算问题,云计算技术也有类似的不同级别的抽象层次。一般来说,抽象层次越高,对技术细节的掌控力就越低,但是获得的便利性就越高。

3. 附属复杂性会让成本和工作量呈指数级上升,云原生编程平台的核心任务是去除附属复杂性。而我对于在特定领域,成功应用云原生编程平台,持乐观态度。

一课一思

那么,如果以后的编程环境都搬到云上,你会喜欢吗?为什么?另外,你的实际项目中遇到过哪些复杂性问题属于附属复杂性?你认为该如何解决这些复杂性?

云计算技术对编程模式的影响及其与编译技术的关系是本文的主要讨论内容。作者指出,云编程将带来许多优势,包括易于管理的编程环境、支持跨平台编程、更强的计算能力、有利于开发过程的管理以及更好的团队协作。文章通过讨论云上编程的实现方式和优势,为读者提供了对云计算技术的全面认知。从编程抽象层次的演变到云计算的发展历程,文章以编译技术为线索,阐述了云计算服务商们希望通过层层的抽象来屏蔽底层的复杂性,让云计算变得更易用。文章最后提出了进一步抽象并简化云应用开发的问题,引发了对针对云原生应用的编程平台的思考。通过对云编程的发展历程和未来趋势的探讨,为读者呈现了云计算技术的前沿动态和发展方向。文章深入探讨了云计算中的附属复杂性问题,并提出了对云原生编程平台的需求,以解决云应用的复杂性。文章以此引发读者对云计算复杂性问题的思考,并探讨了云原生编程平台的潜在解决方案。文章内容丰富,深入浅出,对云计算技术的发展趋势和应用前景进行了全面而深入的阐述。 

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐