前言分布式云应用(也称微服务)在流行的同时,也给应用本身的设计和运维带来了巨大的复杂性。在之前的单体服务时代,这种复杂性还可能隐藏在自身内部,但在微服务时代,这种复杂性几乎蔓延到了数百个“松耦合”的服务中。虽然每个微服务都可以用不同的语言构建,并且可以快速横向扩展,但作为一个整体,与单个服务相比,分布式的特性往往会带来规划、部署和安全方面的困难。这些问题也给云原生应用的管理和开发带来了挑战。我们不禁要思考,如何保证云原生应用的持续健康,如何在不增加开发和维护成本的情况下,取其精华,去其糟粕,同时保持面向服务设计的优势?幸运的是,在微服务出现之前,我们遇到了经过几十年的积累,开发者提炼出了一套通用的解决方案来解决类似的问题:依赖管理(DependencyManagement)。事实上,我们每天都在使用依赖管理器提供的公共或私有软件包,在这些软件包的基础上添加自己的功能,最后小心翼翼地打包成标准格式,以供后续使用。笔者认为,依赖管理是释放分布式应用强大能力的关键。现在是时候引入依赖管理机制来推动云原生技术的发展了。具体来说,有五个原因。1.开发者之间的协作NPM、Pip、Maven等依赖管理器最重要的功能之一就是促进开发者之间的协作。通过提供统一的打包管理机制,依赖管理器可以让你的代码被其他团队使用或增强。此外,不仅在内部团队之间,我们还看到依赖管理被大规模使用,以促进开源社区的协作。工具和使用范围的一致性也使我们能够创建强大且易于访问的软件库,每个人都可以使用和构建。这种级别的协作已经在各种语言社区中实现,例如NPMforJavaScript和PipforPython,但在云原生社区中还没有既定的解决方案。尽管Docker定义了云服务打包的规范,但是各种容器解决方案仍然缺乏足够的信息来解决和扩展服务之间的依赖关系。如果我们想让微服务达到这种协同的效果,就像各个语言对软件库的作用一样,非常有必要加入一个合适的依赖管理机制,使其能够检索和处理各个终端服务之间的关系。2.环境自助依赖管理器的协同效果不是凭空产生的,而是得益于统一的依赖解析。统一的依赖解析之所以强大,主要是因为世界各地的开发人员可以使用相同的命令和程序来重现它们的效果。可再现性是依赖管理器的关键要素。没有这个元素,没有定制复杂的启动逻辑,开发者就无法轻易下载和操作他人创建的库和包,这将增加开发成本,成为大规模采用和分发的巨大障碍。在这一点上,微服务和各种语言库并没有太大区别。我们扩展他人工作的能力取决于我们运行或调用所需服务和应用程序的能力。目前,我们已经可以通过沙盒环境以集中QA的形式完成任务,但是还不能真正完整的重现环境,这会带来一系列的问题。由于依赖他人的服务无法轻易交付,开发者没有能力完全控制自己的开发环境,需要被迫自己编写脚本在本地或远程运行他人的应用程序。同时,各团队需要开发生产级工具,自保网络问题和安全问题。通过统一的依赖管理方案,每个团队只需要声明自己服务的网络依赖,为组织中的每个人提供相同的方式来在他们的技术栈中运行服务,同时准备好服务的Dependency,让每个开发者真正拥有能力来操纵环境。3、自动化自助服务的优势不仅意味着开发者可以控制自己的环境,还意味着开发环境可以通过程序自动化来提供和细化。只需一个命令或程序,即可解决依赖关系,丰富网络,自动保障安全。这是能否集成到CI/CD流水线中的关键。如果每个服务都可以使用统一的机制(例如,使用容器平台)运行并知道其依赖关系,那么每个Git拉取请求都可以提供一组新的环境,并无缝发布到暂存和生产环境。这意味着每个团队都可以为应用中的每个成员和每个新增的服务提供非常灵活的基于Git的自动化运维部署,即GitOps。4.安全微服务架构的安全隐患之一是每个服务都需要暴露API接口来提供功能调用。因为这些服务作为单独的进程存在,所以通过网络通信几乎是服务相互连接以及接收和处理请求的唯一方式。这意味着每个新服务都会公开一些其他人可以访问的接口,如果开发人员不小心,他们可能会错误地将接口公开给他们不应该访问的服务。防止意外暴露网络接口是依赖管理可以发挥作用的另一个领域。通过带有网络依赖关系的结构化索引,我们不仅可以自动解析服务之间的依赖关系,还可以丰富环境配置,生成相应的网络策略,保证接口的合法访问,即只有相互依赖的服务才能相互访问.这种结构化方法将大大减少开发人员了解网络安全工具的需要,并为他们提供更多创建新服务的自由。5.灵活性微服务或分布式应用程序的依赖管理的另一个好处是灵活性。一旦开发人员确定了依赖关系并将它们与自己的服务相关联,解析器本身就可以在每个部署的环境中构建唯一的关系网络。想尝试不同的API网关或服务网格?想通过每个服务的入口和出口流量跟踪链接?通过对依赖项解析器的自动分析,开发人员可以自由地试验新工具和配置,而无需更改任何现有代码。那么为什么分布式应用程序的依赖管理还没有出现呢?依赖解析将是一个非常强大的解决方案,使开发人员能够协作并为云原生应用程序做出贡献,因此我们可以使用现有的包管理器来帮助这可能吗?虽然可以使用现有工具,但解析Web应用程序的依赖项与解析二进制库之间存在明显差异。依赖的二进制库文件是在编译构建主库文件时下载的,但微服务并没有捆绑成一个单一的二进制文件,它们需要作为独立的服务运行,然后通过网络连接进行交互,形成一个完整的应用程序。这意味着解析有一个额外的步骤,并且发生在与二进制库完全不同的生命周期阶段。事实证明,最早可以正确解决分布式应用程序依赖关系的时间是在部署阶段。在部署时,我们既知道技术堆栈中所有服务之间的关系,也知道正确配置和连接服务所需的工具和目标环境的详细信息。结论综上所述,目前很难为网络依赖创建一个大规模的解析器,但这样做会给工程团队和整个云社区带来巨大的好处。如果我们要将云原生工具的方向引向正确的方向,我们需要从过去的依赖管理实践中学习。译者介绍李腾辉,51CTO社区编辑,目前就职于东南亚互联网金融独角兽,任高级Java工程师,负责金融借贷平台的架构设计和核心建设,对互联网有深入研究金融架构和微服务系统。公募基金领域不断深化。原标题:WhyDistributedAppsNeedDependencyManagement,作者:DavidThor
