专栏名称: 云技术实践
关注云计算,云技术,云运维,云存储,存储,分布式,OpenStack,SDN,Ceph,虚拟化,运维,分享在云计算/虚拟化/运维项目实施中的资讯、经验、技术,坚持干货。
目录
相关文章推荐
Java架构师技术  ·  SpringBoot+Flowable:一个 ... ·  昨天  
Java架构师技术  ·  SpringBoot+Flowable:一个 ... ·  昨天  
架构师之路  ·  别TM浪费算力了,这样才能最大限度发挥dee ... ·  5 天前  
高可用架构  ·  漫谈DeepSeek及其背后的核心技术 ·  3 天前  
美团技术团队  ·  CVPR 2025 NTIRE赛事 | ... ·  4 天前  
51好读  ›  专栏  ›  云技术实践

《构建基于Go和React的云原生Web应用与微服务》文末彩蛋:送书

云技术实践  · 公众号  · 架构  · 2017-08-04 11:45

正文

云之道

生大材,不遇其时,其势定衰。生平庸,不化其势,其性定弱。

——老子


正如前言中提到的,本书的目的是教大家如何构建云原生(cloud native)应用程序。然而cloud native这个词,本身带有很多我们想要摒弃的既有观念,例如明确地关注应用而不是人和设计哲学,并且依赖于原始的“12要素法则”[1]来定义和描绘应用程序。


虽然以应用为中心的设计原则肯定是有价值的,但cloud native的文化是发源于构建和设计应用程序的这群人之中的。如果这些人接受了正确的设计哲学,那么他们显然可以更优雅地构建应用程序。艺术家的作品体现出了其在创作时的激情,而Web应用程序和微服务也应如此。


构建云应用程序不仅要学习新的库或编程语言,还涉及掌握新的学科、建立和培养新的习惯,并要以不同的方式看待世界。汉字“道”有许多解释,但用于哲学时,它表示方式或途径,尤指一个人做事的方式和途径,例如生活方式或构建软件的方式。为了形容我们所信仰的cloud native开发和架构哲学,我们将其称之为云之道。


本章将介绍云之道,这种方式有许多典型的优点。本书中构建的一切,从文字到代码再到支持站点,都流露出我们对道的热爱。希望大家在读完本书后,也能对道有和我们一样的感受。

接下来将讨论以下内容。

  • 云之道的优点。

  • 选择使用Go语言开发云端微服务的理由。


1 云之道的优点


与人们普遍的看法相反,我们所做的事并不都是很特别的。有些事情甚至会磨灭我们的激情,成为一种烦恼。我们努力工作,经历添加功能、部署、祈祷它们正常运行的艰难时刻,却忽视了自己构建的是艺术品的事实,不再给它们注入应有的爱和热情。


在某种程度上,这些事会在所有人职业生涯的某些时刻发生。我们期盼出现一位鼓舞人心的老板、一种新的技术或语言甚至一个新的工作来扭转这一切,将我们从深渊中解救出来。


对我们来说,这种解救便是云之道。它改变了我们对软件开发的看法,以及看待世界的方式。我们又可以感受到自己所构建的艺术,软件开发再次成为乐趣,开发者绝不会再用以前的方式来构建应用程序。


纵观软件开发阶段,不管是出于商业目的、创业或是兴趣爱好,或是介于三者之间,其实都已经有一整套既定的准则,遵循它就可以在最大程度上创建云上的可扩展、可靠、可预期的软件。


本书是关于cloud native软件开发的,所以在整本书中,所生成的每个代码示例和讨论的每个主题都将会具有下文提到的优点,当然这些优点并不是只适用于云软件。事实上,从文字、代码到支持网站,我们在完成这本书的过程中都遵循这些规范。


遵循简单


云之道

所做的任何事都要简单化。


质疑一切事物似乎违背简单性。但当所构建的一切都已相当复杂时,绝对没有必要再为工作引入额外的复杂性流程。


质疑每个工具。考虑这个工具是可以简化系统,还是会在系统其他地方引入额外复杂性。如果答案是后者,那么就抛弃这个工具,忽略使用它的原因。

质疑所有的代码。如果它过于复杂以至于无法阅读,请替换造成这种复杂性的编程语言或框架。如果在代码背后有很多隐藏的“戏法”,无法辨别出它会在何时何地如何发生,那么请修改代码。


以下是检验简单性的测试。

  • IDE是否可选?

  • 能否通过命令行构建和部署?

  • 团队的新成员能否快速理解代码?


工具和IDE必须可以自动化地执行例行任务、减少阻碍或时间来简化手动任务,从而使我们能够更好地工作和生活。工具绝不能是强制性的,如果代码必须用特定的IDE才能生成或者编译,那绝对不是在秉承云之道,也没有在遵循简单性原则。


任何可以通过命令行完成的工作,都可以使用脚本或者持续集成工具自动化地完成。因此,如果能使用命令行来构建、测试和部署应用程序,那么就可以自动化执行所有这些任务。


这似乎是一个尖锐的观点,大家有权反对。然而,至少在读完这本书之前,可以尝试在所有开发工作中遵循这些准则,它一定不会令你感到失望。

那些声称无须使用云端或无须遵循简单性的人都将对他们创造的或不愿摒弃的复杂性而感到羞愧。

测试优先,测试一切


云之道

采用测试驱动进行开发。测试一切,处处测试。


测试是抵御程序偏离期望方式而运行的首要且最好的方法。


几乎每个人都赞同进行测试,但在应该进行什么程度的测试这一点上,很少有团队能达成一致。在解答这个问题之前请先思考:为什么需要测试软件?


当然,我们想要编写完美的软件,希望客户满意,想通过软件赚取大量金钱。但是,测试的核心不是这些。在根本层面上,测试可以给我们信心。


你是否经历过这种时刻:在某种场合下,有人要在一些重要的和有影响力的人面前展示你的应用程序?你是否还记得在关键功能测试之前感受到的恐慌?


恐惧

缺少测试是产生恐惧的根本原因。


感到恐惧是因为担心出现以下情况:应用程序执行的不确定性会影响到整个系统,导致难以估量的压力、系统故障,最坏的情况是在生产系统中出现客户可感知的问题。


我们需要做的是树立信心,以信心取代恐惧。对系统的信心是不断累积起来的,它始于最小的可测试单元。从那一刻开始,随着代码库的扩展,信心不断建立,并通过测试不断完善。


图1.1进行了详细说明。一个类通过了完全的单元测试,我们就对这个类树立了完全的信心,接着对库中所有的类进行单元测试,这样就对整个库树立了完全的信心。相反地,如果无法信任应用程序的构建块,那么对整个应用程序的信心就会降低。从类、库到服务,如果缺乏测试,我们的信心就会呈指数下降。

图1.1   在微服务生态圈中测试信心的区域


只有完全信任构成这个代码库的所有库类,才能对整个服务树立信心。最后,只有当服务生态系统内的每个服务都经过充分测试(无论是内部还是多个服务边界间的集成测试)时,我们才能信任整个服务生态系统。


大家可能经常会遇到这类情况:团队负责人认为不值得在测试上耗费大量时间。进行测试会产生很大的开销,这很容易通过电子表格计算。为了反驳这种观点,可以参考以下的案例。


当在本地构建应用程序时,可以使用所有能想到的工具。可以连接调试器,可以设置和命中断点。在某些情况下,甚至可以暂停一个应用程序,操纵内存中的数据,然后恢复。这给了我们产生信心的错觉,在调试器上花费的时间使得集成和单元测试被认为是不必要的。


再考虑以下场景:我们正在构建的不是软件的一小部分,并且软件部署在离我们只有几英尺的电脑中。想象一下,假如我们实际上构建的是一艘将要发射到外太空的太空船,一旦启动,就无法再接触它,无法抓住螺丝刀再进行最后一刻的调整。如果在远离基地的几百万英里外,如某些部件发生灾难性的故障,那么太空船的整个旅程就将结束。


在云端部署时,无法进行大量的手工控制。它虽不像发射卫星那么复杂,但是失去了对实例的实际控制,不能设置断点,通常也无法进行运行时自我检查。

如果下次再有人挥舞电子表格,声称测试成本太高,我们只需回复和询问他们产品在每个阶段构建完成与完全失败的成本,因为这是测试的实际成本。

回到信心层面,如果对程序正常运行充满信心,那么就可以将这种信心作为发挥其他优势的基石,如持续交付(下面讨论)。


这一切的前提是,我们应该采用测试驱动开发[2]。必须测试所构建的每个服务的一切内容,不管是内部还是外部的,以此建立对服务的信心。

尽早发布,频繁发布


云之道

将每次代码提交都当作潜在的生产发布, 并通过持续交付流水线进行部署。


在上一节中,我们讨论了那些使用我们开发的应用程序的人的恐惧,这往往是我们缺乏对应用程序正常运行的信心所导致。接下来还需要面对另一种恐惧:发布的恐惧。


有些公司按照发布世界一流活动的标准制定发布规范。他们提前几个月开始计划,急救人员处于待命状态,救护车和消防队员也全部就绪,几乎每一个人,哪怕仅检查过一行代码或监督代码提交的人,都在午夜时守在电话旁,执行应用发布。仿佛吉尼斯世界纪录丛书就摆在电话旁,以便纪录历史上发生的第一次成功发布。


采用这种方式的公司会尝试在发布时投入更多的资源、更多的人、更多的基础设施和控制来缓解出现的问题。有时甚至会推迟发布,降低发布频率。这其实恰恰与应该做的完全相反。


克服发布恐惧的唯一方式是更频繁地发布。


要使团队中的每名开发人员都坚信,每次对源码管理系统的提交都会在几天之内到达生产系统,这会产生一连串的好处。首先,这样能培养严格性和纪律性,这是大多数人的代码中所缺少的。此外,如果知道代码会被快速发布,那么开发者更有可能会测试代码,因为不想对生产系统的发布失去信心,不是吗?

自动化一切


云之道

所有可以自动化的,都应被自动化。


现在我们充满信心,因为代码已经通过测试,并以有利于测试的方式被编写。即使频繁地发布,也不再担心时刻处于发布的阴影下。我们开始更好地生活,同时也提高了生产力。


任何每天做的超过一次的事情,都适合自动化。


发布本身是最重要和最需要被自动化的流程。在代码提交的几分钟之内,一些自动化系统应该测试代码,验证代码是否符合标准,并将一个稳定的构建工件部署到环境中,以用于手动和集成测试。


我们以手工方式执行的操作很容易出错。容易分散注意力、忘记执行步骤,可能会按照错误的顺序执行操作,也可能会引入额外的不必要的步骤。一旦确定一个自动化流程,它就能为我们树立更多的信心。


应该做到这一点:在向源码管理系统提交代码后,警铃没有大作,黑武士的头像没有闪亮,充满愤怒的邮件没有发送,我们由此树立信心——变更没有导致单元或集成测试失败。当然还有更多的测试需要在产品上线之前完成,但是我们对即将通过准生产验证流程的发布提交充满信心。


综上所述,关于自动化的最终建议如下。

流程中任何时常重复的部分,如果不能被按钮或者脚本代替,那么就属于过于复杂、脆弱或两者兼有的部分。


只有当拥抱自动化,并可以自动将代码提交到云端时,才能真正开始从云端开发中受益,并从构建单一的微服务扩展到构建微服务生态系统。


建立服务生态系统


云之道

任何事物都是服务,包括应用。


在讨论生态系统之前,我们要先发泄一下对微服务[3]的不满。与任何流行语一样,它已被过度使用和注水。我们坚信所有服务都应该是微服务,所以前缀“micro”是完全不必要的。


多年以来,我们喜欢构建庞然大物。即使在“n-tier”或“3-tier”应用程序流行之时,这些n-tier应用程序仍然是一体式的,它们只是更具组织化而已。


在单体式应用程序中,系统的每个关注点和功能性的需求都包含在一个庞大的结构中,这违背了云的基本原则:简单、易于自动化和易于发布。


在单体中,每次变更都需要发布整个应用程序,这促使我们想要极力避免“all hands”的发布方式。这样的应用程序很难维护,它的启动和停止速度很慢,而且依赖关系紧密耦合,通常很难部署到云端。


微服务只是遵循了单一责任原则(SRP)这一松散定义的服务。SRP源自面向对象的设计模式,即一个服务只负责一个功能。


应用程序也只是具有一个或多个呈现GUI(例如HTML)的微服务而已。

全书正是基于微服务这一概念编写的,并且讨论了什么应该是服务,而什么不是,以及如何将已有的单体应用程序切割成粒度更小的服务。


云的优势在于,我们无须构建巨型的、单体的应用程序,取而代之的是构建可以在一个生态系统中共存的服务。这有助于养成一些好习惯,例如构建强版本约束的RESTful接口、在发布流程中包含服务交互测试、为未知功能和未知客户提供灵活的支持。


为什么使用Go


大家已经通过前面的介绍了解了云之道,接下来,你可能会想:为什么使用Go?是什么使得Go成为用于构建云端服务和应用程序的理想语言?


以下三个主要原因使得我们选择Go作为构建云端应用程序的首选语言:简单、开源和易于自动化。


简单


Go的简单性存在一种引人注目的美。表面上,它甚至可以传递ANSI C的简化变量,但它也足够强大,以至于可以满足当今最苛刻的软件需求。


这种简单不仅流于表面——Go避免了不必要的复杂性、额外流程和一些令人讨厌的步骤。Go不像Java或.NET那样编译生成中间字节码,它直接生成本地二进制文件。因此,这种简单性不是以牺牲什么为代价,它实际上是提高了性能。


当克服了对于Go不支持类、纯函数式编程[4]这种最初恐惧,大家最终一定会像我们一样重新爱上编程。


开源


Go不仅是一种开源语言,它的背后更有社区的拥护和支持。正如接下来我们将在本书中看到的,通过GitHub和其他仓库共享开源模块是Go语言及其核心工具的首要理念。


易于自动化和IDE自由化







请到「今天看啥」查看全文