本系列文章希望对现代软件行业的一些关键主题,即微服务、云原生应用程序、容器和无服务器应用程序提供实践性支持,并涵盖这些技术的实际优点和缺点。
这一系列文章由《Golang Cloud Native编程》一书的作者Mina Andrawos撰写——该书为云原生微服务提供了实用技术和架构模式。他还是《 掌握Go编程》和《现代Golang编程》视频课程的作者。
本系列文章希望对现代软件行业的一些关键主题,即微服务、云原生应用程序、容器和无服务器应用程序提供实践性支持,并涵盖这些技术的实际优点和缺点。
微服务
微服务架构作为构建现代软件应用程序的强大方法赢得了业内认同。什么是微服务?微服务将软件应用所需的功能分成多个独立的小软件服务。这些微服务中的每一个都负责一个专门的任务。为了使这些微服务一起工作以形成一个大型可扩展应用程序,它们必须在多个服务器之间进行通信和交换数据,这被称为水平扩展。
每个服务都可以部署在具有专用资源的不同服务器上,也可以部署在不同的容器中。这些服务可以用不同的编程语言编写,实现更大的灵活性,并允许每个团队专注于单个服务,最终得到质量更高的应用程序。
使用微服务的另一个显著优势是易于持续交付,或经常和随时部署软件的能力。微服务使得持续交付更容易,因为部署到一个微服务的新功能不太可能影响其他微服务。
云原生应用
微服务架构非常适合云原生应用程序——从云计算基础开始构建的应用程序。如果设计为可在分布式和可伸缩的基础设施上进行部署,那么应用程序就是云原生的。
例如,构建具有冗余微服务架构的应用程序使应用程序成为云原生的,因为此架构允许应用程序以分布式的方式进行部署,从而使其可扩展且几乎总是可用。云原生应用程序不需要总是部署到公有云(如AWS),也可以部署到分布式云类基础设施。
实际上,使应用程序完全云原生的原因不仅仅在于使用微服务。你的应用程序应该采用持续交付,能够在不中断的情况下持续向生产应用程序提供更新。你的应用程序还应该使用消息队列和容器等技术。
云原生应用程序假定可以访问众多的服务器节点,可以访问预先部署的软件服务,如消息队列或负载均衡器,易于与持续交付服务集成等。
如果你将云原生应用程序部署到AWS或Azure等商业云,你的应用程序可以选择使用只有在云中才有的软件服务。例如,DynamoDB是一个功能强大的数据库引擎,只能在AWS上用于生产应用程序。另一个例子是Azure中的DocumentDB数据库。还有像Amazon Simple Queue Service(SQS)这样的云消息队列,可用于允许AWS云中微服务之间的通信。
如前所述,云原生微服务应该被设计为允许服务之间的冗余。如果我们以事件预订应用程序为例,应用程序将如下所示:
每个微服务将分配多个服务器节点,从而部署冗余的微服务架构。如果主节点或服务因任何原因失败,则辅助节点可以接管,以确保云原生应用的持久可靠性和可用性。这种可用性对于电子商务平台等容错应用程序至关重要,因为电子商务平台的停机时间会导致收入损失。
在微服务和云计算领域一个值得一提的工具是Prometheus。Prometheus是一个开源的系统监控和警报工具,可用于监控复杂的微服务架构,并在需要采取行动时发送警报。Prometheus最初由SoundCloud创建来监控其的系统,现在逐渐发展为一个独立的项目,并成为CNCF的一部分。
容器
一个容器就是将一些软件封装在一个孤立的用户空间或“容器”中的想法。例如,一个MySQL数据库可以在一个容器内隔离,其中有所需要的环境变量和配置。默认情况下,容器外部的软件将不会看到容器内包含的环境变量或配置。同一个本地虚拟机、云虚拟机或硬件服务器上可以存在多个容器。
容器提供了在同一台计算机上运行众多独立软件服务及其所有配置、软件依赖关系、运行时、工具和附带文件的功能。在云环境中,这种能力转化为成本和功夫的节省,因为为每个微服务供应和购买服务器节点的需求会减少( 不同的微服务可以部署在同一主机上而不会相互干扰)。容器与微服务架构相结合,成为构建现代、便携、可扩展且经济高效软件的强大工具。在生产环境中,需要多个服务器节点和众多容器来实现可扩展性和冗余。
容器为云原生应用程序增加了更多优势。使用容器,你可以将微服务及其所需的所有配置、依赖关系和环境变量移动到全新的服务器节点上,而无需重新配置环境,这样就实现了强大的可移植性。
由于软件容器技术的强大和普及,一些新的操作系统,如CoreOS或Photon OS,从一开始就为容器的主机而构建。
Docker是软件行业最受欢迎的软件容器项目之一。思科、谷歌和IBM等公司在其基础设施和产品中使用Docker容器。
Kubernetes是软件容器领域的另一个值得关注的项目。Kubernetes是一个允许自动化部署、管理和伸缩容器的工具。为了便于管理其容器,谷歌建立了Kubernetes。它提供了一些强大的功能,例如容器之间的负载均衡,重启失败的容器以及编排容器使用的存储。
云原生计算的缺点
指出这些技术的缺点非常重要。严重依赖微服务的一个显著缺点是,随着数量和范围的扩大,最终它们可能变得太复杂而无法管理。有一些方法可以缓解,如利用诸如Prometheus的监视工具来检测问题和诸如Docker之类的容器技术避免污染主机环境并避免过度设计服务。但是,这些方法需要付出努力和时间。
对于云原生应用程序,如果需要迁移部分或全部应用程序,则会面临一些挑战。这有多种原因,具体取决于应用程序的部署位置。
一个原因是如果你的云原生应用程序部署在像AWS这样的公有云上,云原生API不是跨云平台的。例如,应用程序中使用的DynamoDB数据库API仅适用于AWS,而不适用于Azure,因为DynamoDB仅属于AWS。这一API也不会在本地环境中工作,因为DynamoDB只能在生产环境中使用AWS。
另一个原因是,构建一些云原生应用程序时会做出一些假设,例如在需要时实际上可以使用无限数量的服务器节点,并且可以快速提供新的服务器节点。但是在需要购买服务器、网络硬件和布线的本地数据中心环境中,这些假设有时难以保证。
就容器而言,由于与管理不断扩大微服务数量相同的原因,管理容器有时会变得相当复杂。随着容器或微服务的规模不断扩大,需要有一种机制来确定每个容器或微服务的部署位置、目的是什么以及它们需要什么资源才能继续运行。
无服务器应用
无服务器架构是一种新的软件架构范式,已通过AWS Lambda服务推广。为了完全理解无服务器应用,我们首先定义功能即服务(FaaS)。这是一个云提供商(如亚马逊或甚至本地软件,如Fission.io或funktion)提供服务的想法,用户可以请求一个远程运行的功能以执行非常特定的任务,然后在功能结束后,功能结果会返回给用户。不需要维护服务或有状态数据,功能代码由用户提供给运行该功能的服务。
利用无服务器架构设计合理的生产应用程序的想法是,不是构建多个持续运行的微服务来执行单个任务,而是构建一个有更少的与FAAS结合的微服务的应用来完成不需要服务持续运行的任务。
FAAS的构造比微服务更小。例如,对于之前介绍的事件预订应用程序,有多个微服务覆盖不同的任务。如果我们使用无服务器应用模型,那么这些微服务中的一些将被替换为许多服务于其目的的功能。例如,下面的图表展示了使用无服务器架构的应用程序:
在该图中,事件处理程序与预订处理程序一样充当微服务——微服务被一系列产生相同作用的功能所取代。这样就不再需要运行和维护两个现有的微服务。
这种单体的应用程序将适用于小到中等负载。它可以在单个服务器上运行,连接到单个数据库,并且可能会用相同的编程语言编写。
那么,如果业务繁多以及数十万或数百万用户需要处理,会发生什么?最初,短期解决方案是确保运行应用程序的服务器具有强大的硬件规格,以承受更高的垂直伸缩负载(增加硬件规格的方法包括用RAM和硬盘驱动器运行繁重应用程序)。通常情况下,随着应用程序的负载持续增长,这种方法不可持续。
单体应用的另一个挑战是由于仅限于一种或两种编程语言而导致的不灵活性。这种不灵活性会影响应用程序的整体质量和效率。例如,node.js是用于构建Web应用程序的流行JavaScript框架,而R在数据科学应用程序中很受欢迎。一个单体的应用程序很难同时使用这两种技术,而在微服务应用程序中,你可以简单地构建用R编写的数据科学服务和用Node.js编写的Web服务。
单体应用的第三个大挑战是协作。例如,在事件预订应用程序中,修改在单个前端用户接口层中的bug可能会影响其他应用程序,如搜索、事件和预订处理程序。
如果你要创建事件应用程序的微服务版本,它将采用以下形式:
此应用程序将能够在多个服务器之间进行水平缩放。每个服务都可以部署在具有专用资源的不同服务器上,或者部署在不同的容器中。
微服务如何与云原生应用程序一起工作?
微服务架构非常适合云原生应用程序。云原生应用程序简单地定义为从底层构建并运行在云平台上的应用程序。云平台具有许多优点,例如在免去IT硬件基础设施规划痛苦的情况下,就可以立即获得多个服务器节点。在微服务架构中构建应用程序是开发可扩展的云原生应用程序的重要一步。
云原生应用程序的另一个功能是利用只有在云上才有的软件服务。例如,DynamoDB是一种功能强大的数据库引擎,只能在AWS上用于生产应用程序。另一个例子是Azure中的DocumentDB数据库。还有云原生消息队列,如Amazon Simple Queue Service(SQS),可用于允许AWS云中微服务之间的通信。
云原生微服务也可以设计为允许服务之间的冗余。如果以事件预订应用程序为例,该应用程序将如下所示:
由于获得新的服务器节点不是硬件基础设施的挑战,因此可以为每个微服务分配多个服务器节点。如果主节点或服务出于任何原因失败,辅助节点可以接管,从而确保云本机应用的持久可靠性和可用性。这里的关键是可用于容错应用程序,如电子商务平台,其中停机时间会导致收入损失。
微服务云原生应用程序将微服务的优势与云计算的优势相结合,为开发人员、企业和创业公司提供巨大的价值。
另一个显著优势(除了可用性和可靠性)是持续交付。微服务使持续交付更容易的原因是因为部署到一个微服务的新功能不太可能影响其他微服务。
结论
云计算为开发高效、可扩展和可靠的软件开辟了道路。在这里,我们介绍了云计算领域的一些重要概念,如微服务、云原生应用和无服务器应用。
在设计应用程序时,架构师必须选择是构建单体应用程序、微服务云原生应用程序或是无服务器应用程序。
在本系列的第二篇文章中,我们将深入介绍云原生应用程序和容器,以及它们的缺点。本系列的第三部分将详细介绍无服务器应用程序,并展示如何将以上三者结合在一起。