1.2 分布式系统的核心设计要求
在前面的图1-4中,我们看到了位于中心位置的分布式服务框架。分布式服务框架是开发人员实现分布式系统的基本手段,我们在分析具体的框架时会涉及分布式系统架构设计和开发所需要考虑的核心设计要求。在本节中,我们将围绕这些要求展开讨论。
1.2.1 性能
性能体现的是一种能力,一方面表现为系统在其目前所承受体量之下的执行能力,另一方面则表现为未来流量发生变化时的弹性处理能力。对互联网应用而言,满足一定的性能要求在很多时候是其系统构建的一个核心目标。
对如何构建高性能的应用程序,通常也有一套完整的方法论和工程实践,我们可以从核心功能——响应时间、系统吞吐量、部署架构的可伸缩性、性能问题的可预测性和峰值负载等——判断系统是否存在性能问题,并找到相应的解决方案。
在分布式系统架构的构建策略上,有很多针对性能的设计方案,对核心业务链路和请求进行分解并把串行操作转变成并行化流程、对需要重复执行的处理过程进行优化、对资源和结果进行重用、使用异步处理机制、放弃事务一致性、转换数据强一致性为弱一致性等都可以在一定程度上提升系统的性能。
1.2.2 可用性
可用性指的是系统在业务需要时能够完整地提供服务并有效处理影响其可用性的故障的能力。和性能一样,对互联网应用而言,可用性非常重要。
进行可用性的规划和实现前,需要明确服务的类型,不同类型的服务对可用性的要求不尽相同。对系统升级、停机和维修、系统备份、灾难恢复等情况,也都需要有对应的实施计划。
在分布式系统的架构策略上,使用容错硬件和容错软件、引入服务的降级和限流机制、确保采用主流的集群和负载均衡机制、加强日志管理和分析、采用组件复制策略、建立完整的备份和灾难恢复解决方案等操作,都在提升可用性的考虑范围之内。
1.2.3 可扩展性
可扩展性的概念通常容易与可伸缩性相混淆。所谓可扩展,扩展的是业务;可伸缩,伸缩的是性能。可扩展性本质上也是一种能力,系统在经历不可避免的变更时需要足够灵活,而可扩展性则是指系统对自身灵活性及实现这种灵活性所要付出的成本进行平衡的能力。对互联网应用而言,可扩展性的重要程度视具体系统而定。但随着业务复杂度的提高,任何一种实现方案都需要考虑系统可扩展性的需求。
明确了可扩展性的概念之后,我们明白实现可扩展性不仅是一个技术问题,还是一个综合性的话题。
要想实现可扩展性,一个切入点是加强产品管理,从业务需求的源头把控产品的变化,在进入开发流程之前对部分业务进行梳理,以避免后续因不必要的变化产生系统变更。对于已经进入开发流程的变更需求,同样需要把握其维度和量级,并从需求交付、开发复杂度等角度,找到提升可扩展性的方法。
另一个切入点是采用合理技术,当我们采用分布式系统架构时,可扩展性设计的重点在于梳理系统的变化并把它们抽象成扩展点,并对这些扩展点创建可扩展的接口。采用异步消息等有助于实现系统解耦的技术,并尽量使用SPI(Service Provider Interface,服务提供者接口)等基于业界标准的技术,以确保系统具有较高的可扩展性。
1.2.4 服务治理
在分布式系统构建过程中,服务治理至关重要,原因在于我们会面临以下两个方面的挑战:
□ 服务实例的数量如何进行管理?
□ 服务实例的状态如何进行管理?
针对服务实例的数量,当一个系统中存在几十个甚至上百个服务时,开发人员甚至可能都无法明确其中到底有哪些服务正在运行。另外,因为很难确保所有服务都不出现问题,也就很难保证当前的服务部署方式不做调整和优化,因此各个服务自身对外暴露的状态也具有动态性。受自动扩容、服务重启等因素影响,服务实例的数量和运行时状态会经常变化,这时候就需要引入服务治理的方法和工具。
对于服务治理而言,分布式系统架构设计的重点在于对每个服务实例信息进行抽象,并构建一个独立的媒介来管理这些服务实例信息,这个媒介需要具备服务注册和发现机制。通过这种机制,我们就能够有效管理系统中所有服务实例的运行时状态,并能够把这些状态的变化同步到各个服务中。同时,针对运行时状态,我们还需要引入系统监控和链路跟踪等技术手段,从而确保对出现的异常情况进行及时的干预。