目录
介绍
集群
- 定义:集群是指将多个计算机节点(服务器)通过网络连接在一起,协同工作以提供更高的性能、可用性和可扩展性。这些节点通常运行相同的软件或服务,对外呈现为一个统一的系统。
- 特点
- 高可用性:通过冗余的节点部署,当部分节点出现故障时,其他节点可以接管其工作,确保服务不中断。
- 可扩展性:可以根据业务需求方便地添加新的节点到集群中,以提高整体性能和处理能力。
- 负载均衡:能够将工作负载均匀地分配到各个节点上,避免单个节点负载过高,充分利用集群资源。
- 应用场景:广泛应用于各种大规模计算、数据处理、网络服务等领域。如电商网站在促销活动期间,通过集群来应对大量用户的访问请求;搜索引擎公司利用集群来处理海量的网页数据和用户搜索请求。
微服务
- 定义:微服务架构是一种将大型应用程序拆分成多个小型、独立的服务的架构风格。每个微服务都围绕着特定的业务功能进行构建,并且可以独立地进行开发、部署、扩展和维护。
- 特点
- 功能单一:每个微服务只负责一项特定的业务功能,职责明确,便于理解和管理。
- 技术多样性:不同微服务可以根据自身业务特点选择合适的技术栈,充分发挥各种技术的优势。
- 独立部署和扩展:各个微服务可以独立进行部署和扩展,能够根据不同服务的负载情况灵活分配资源,提高资源利用率。
- 应用场景:适用于复杂的大型应用系统,尤其是业务功能多样、变化频繁的互联网应用。例如,大型互联网公司的电商平台,会将用户管理、商品管理、订单管理、支付等功能拆分成不同的微服务,每个微服务可以根据自身的业务特点进行独立的优化和扩展。
微服务架构是一种将大型应用程序拆分成多个小型、独立服务的架构风格。以下是其优缺点:
优点
- 高可维护性:每个微服务都相对较小且功能单一,代码量少,结构简单,便于开发人员理解和维护。当某个微服务出现问题时,开发人员可以快速定位和解决问题,而不会影响到其他服务。
- 敏捷开发与部署:不同微服务可以由不同的团队独立开发、测试和部署,各个团队可以根据自身的节奏进行迭代,提高了整体的开发效率。同时,对单个微服务的修改和部署不会影响到整个系统,使得新功能的上线和更新更加迅速。
- 技术多样性:允许不同微服务根据其具体业务需求选择最合适的技术栈,充分发挥各种技术的优势。例如,对于处理复杂业务逻辑的微服务,可以选择 Java 等成熟的编程语言;对于实时性要求较高的微服务,可以使用 Go 语言来提高性能。
- 可扩展性:可以根据每个微服务的实际负载情况进行独立的扩展。当某个微服务的业务量增长时,只需要对该微服务进行资源扩展,而不需要对整个系统进行统一扩展,避免了资源的浪费,提高了资源利用率。
- 故障隔离性好:微服务之间相互独立,当某个微服务出现故障时,只会影响到该服务本身,不会导致整个系统崩溃。其他微服务仍然可以正常运行,提高了系统的可靠性和稳定性。
缺点
- 运维复杂性增加:由于微服务数量众多,每个微服务都需要独立的运维管理,包括服务器资源管理、监控、日志管理等,这增加了运维的工作量和复杂性。运维人员需要掌握多种技术和工具,以确保各个微服务的正常运行。
- 分布式事务处理困难:在微服务架构中,不同微服务可能会涉及到不同的数据库或数据存储,当一个业务操作需要跨多个微服务进行数据更新时,保证数据的一致性就变得比较困难,需要采用分布式事务处理机制来解决,但这会增加系统的复杂性和性能开销。
- 服务间通信开销:微服务之间通过网络进行通信,这会带来一定的通信延迟和性能开销。尤其是当服务间的交互频繁时,通信开销可能会对系统性能产生较大影响。此外,还需要考虑通信的可靠性、安全性等问题。
- 服务治理难度大:随着微服务数量的增加,服务之间的依赖关系变得复杂,服务治理的难度也相应增大。需要对服务的注册、发现、路由、负载均衡、熔断等进行有效的管理和控制,以确保整个系统的稳定运行。
- 测试复杂度提高:微服务架构下,测试不再是简单的对单个应用进行测试,而是需要考虑各个微服务之间的交互和集成。需要编写更多的测试用例来覆盖不同微服务之间的接口和业务流程,测试的复杂度和工作量都大大增加。
如何管理和监控微服务架构中的多个微服务?
管理和监控微服务架构中的多个微服务需要从多个方面入手,包括服务治理、配置管理、监控与告警等,以下是具体的方法:
服务治理
- 服务注册与发现:使用服务注册中心,如 Nacos、Eureka 等。微服务在启动时向注册中心注册自身的信息,包括服务名称、IP 地址、端口号等。其他微服务可以通过注册中心快速发现所需的服务实例,实现服务之间的动态调用和通信。
- 负载均衡:在服务调用方和服务提供方之间引入负载均衡器,如 Ribbon、Nginx 等。负载均衡器可以根据一定的算法,如轮询、随机、加权轮询等,将请求均匀地分发到多个服务实例上,避免单个服务实例因负载过高而出现性能问题,提高系统的整体性能和可用性。
- 服务熔断与降级:当某个微服务出现故障或响应时间过长时,为了防止级联故障,需要使用 Hystrix 等工具实现服务熔断,即暂时切断对该服务的调用,并返回一个默认的响应。同时,也可以根据业务的重要性和资源的情况,对一些非核心服务进行降级处理,如减少某些功能或降低服务质量,以保证核心服务的正常运行。
配置管理
- 集中配置管理:使用配置中心,如 Nacos、Spring Cloud Config 等,将微服务的配置信息集中存储和管理。微服务在启动时从配置中心获取配置,方便对配置进行统一修改、发布和更新,实现配置的热更新,无需重启微服务。
- 配置版本控制:对配置信息进行版本管理,记录配置的变更历史,方便回滚和跟踪配置的变化。可以使用 Git 等版本控制系统来管理配置文件,确保配置的准确性和可追溯性。
监控与告警
- 指标监控:使用 Prometheus 等监控工具收集微服务的各项指标,如 CPU 使用率、内存使用率、请求响应时间、吞吐量、错误率等。通过对这些指标的分析,可以及时发现微服务的性能问题和潜在的故障。
- 分布式追踪:当一个请求涉及多个微服务之间的调用时,使用分布式追踪系统,如 Zipkin、Skywalking 等,来跟踪请求在各个微服务之间的流转路径和耗时,帮助定位性能瓶颈和故障点。
- 日志管理:集中收集和管理微服务的日志,使用 Elasticsearch、Kibana 等工具搭建日志管理系统,方便对日志进行查询、分析和可视化展示。通过日志可以了解微服务的运行状态、业务流程和错误信息,有助于快速定位和解决问题。
- 告警机制:设置合理的告警规则,当监控指标超过阈值或出现异常情况时,通过邮件、短信、即时通讯工具等方式及时通知相关人员。确保问题能够在第一时间被发现和处理,减少故障对业务的影响。
容器化与编排
- 容器化:将微服务打包成 Docker 容器,确保微服务在不同的环境中具有一致的运行环境,提高微服务的可移植性和部署效率。
- 编排与调度:使用 Kubernetes 等容器编排工具来管理和调度容器化的微服务。Kubernetes 可以自动完成微服务的部署、扩展、收缩、故障转移等操作,提高微服务的运维效率和管理水平。
安全管理
- 认证与授权:采用 OAuth、JWT 等认证和授权机制,对访问微服务的用户和服务进行身份验证和授权,确保只有合法的用户和服务能够访问相应的资源。
- 数据加密:对微服务之间传输的数据以及存储在数据库中的敏感数据进行加密,防止数据泄露和被篡改,保障数据的安全性。
- 网络安全:通过设置防火墙、网络隔离等措施,限制微服务之间的网络访问,防止外部攻击和内部网络安全威胁。
分布式
- 定义:分布式系统是指将一个系统的不同部分分布在多个计算机节点上进行处理,这些节点通过网络进行通信和协作,共同完成系统的任务。分布式系统中的各个节点可以位于不同的地理位置,并且可能具有不同的功能和角色。
- 特点
- 资源共享:可以将不同节点上的资源进行整合和共享,实现资源的高效利用。
- 可扩展性:能够通过增加节点的方式来扩展系统的处理能力和存储容量,以适应不断增长的业务需求。
- 复杂性:由于涉及多个节点之间的通信、协调和数据一致性等问题,分布式系统的设计、开发和维护相对复杂。
三者关系
- 微服务架构通常采用分布式的方式进行部署,每个微服务可以看作是一个分布式系统中的一个节点或组件。多个微服务通过网络相互通信,协同工作,共同构成一个完整的分布式应用系统。
- 集群可以用于部署微服务或分布式系统。将微服务或分布式系统的多个实例部署在集群中的不同节点上,可以实现负载均衡、高可用性和可扩展性等功能。
总的来说,集群侧重于多个节点的协同工作和资源整合,以提供高可用性和可扩展性;微服务强调将应用程序拆分成小型、独立的服务,以提高系统的可维护性和灵活性;分布式则更关注系统的不同部分在多个节点上的分布和协作,以处理大规模的任务和数据。它们在不同的层面和角度上为构建大型复杂的软件系统提供了有效的解决方案。
分布式和集群的区别是什么?
分布式和集群在概念、工作方式、应用场景等方面存在一些区别,具体如下:
概念
- 分布式:指的是将一个系统的不同部分分布在多个计算机节点上进行处理,这些节点通过网络进行通信和协作,共同完成系统的任务。系统中的各个节点可能具有不同的功能和角色,它们相互配合来实现整个系统的功能。
- 集群:是把多个计算机节点(服务器)通过网络连接在一起,协同工作以提供更高的性能、可用性和可扩展性。这些节点通常运行相同的软件或服务,对外呈现为一个统一的系统。
工作方式
- 分布式:任务被分解并分配到不同的节点上执行,每个节点负责处理整个任务的一部分,节点之间需要进行大量的数据交互和协调,以确保任务的正确执行。例如,在分布式数据库中,数据可能分布在多个节点上,查询操作可能需要多个节点协同工作来完成。
- 集群:通常是多个节点对相同的任务进行处理,通过负载均衡机制将任务均匀分配到各个节点上,每个节点都可以独立完成任务,节点之间的协作相对较少。比如,Web 服务器集群,通过负载均衡器将用户的请求分发到不同的 Web 服务器上,每个服务器都能独立处理用户请求。
节点角色
- 分布式:节点角色多样,不同节点承担不同的职责,如有的节点负责数据存储,有的节点负责计算,有的节点负责协调任务等。它们之间相互依赖,共同完成复杂的业务逻辑。
- 集群:节点角色通常相同,各个节点地位平等,都具备相同的功能和处理能力,主要通过冗余来提高系统的可靠性和性能。
应用场景
- 分布式:适用于处理大规模、复杂的任务,需要对任务进行分解和并行处理,以及对大量数据进行分布式存储和处理的场景,如大规模数据处理、分布式计算、分布式数据库等。
- 集群:主要用于提高系统的可用性、性能和可扩展性,适用于对单个服务或应用程序进行水平扩展的场景,如 Web 应用程序、数据库服务等,以应对高并发访问和大量数据处理的需求。
故障处理
- 分布式:由于各个节点承担不同的任务,一个节点出现故障可能会影响到整个系统的运行,需要复杂的故障恢复机制来确保数据的一致性和任务的继续执行。
- 集群:因为存在多个相同的节点,当某个节点出现故障时,负载均衡器可以将请求分配到其他正常的节点上,系统的整体功能通常不会受到太大影响,故障转移相对简单。
集群:集群系统中的单个计算机通常称为节点,
通常通过局域网连接,但也有其它的可能连接方式。
通过多台计算机完成同一个工作,达到更高的效率。
--代码都一样分担了压力。
分布式系统是一组计算机,通过网络相互连接传递消息与通信后并协调它们的行为而形成的系统。组件之间彼此进行交互以实现一个共同的目标。
--代码不一样
其实有些模块的访问是很低的(比如后台管理),那我可不这样做:将每个模块抽取独立出来,访问量大的模块用好的服务器装着,
没啥人访问的模块用差的服务器装着。
这样的好处是:
资源合理利用了(没人访问的模块用性能差的服务器,访问量大的模块单独提升性能就好了)。
- 耦合度降低了:每个模块独立出来,各干各的事(专业的人做专业的事),便于扩展
好处;
模块之间独立,各做各的事,便于扩展,复用性高。
高吞吐量。某个任务需要一个机器运行10个小时,
将该任务用10台机器的分布式跑(将这个任务拆分成10个小任务),可能2个小时就跑完了
分布式:一个业务分拆多个子业务,部署在不同的服务器上
(不同的服务器,运行不同的代码,为了同一个目的)
->减轻单体服务压力,提升服务性能和高并发量
集群和分布式并不冲突,可以有分布式集群。
其实我认为分布式/微服务/SOA这三个概念是差不多的
微服务
微服务是一种将大型复杂软件系统构建为一组小型、独立且可相互通信的服务的架构风格。以下从特点、优势、面临的挑战等方面为你详细介绍:
特点
- 小而专注:每个微服务都围绕着一个特定的业务功能或业务领域进行构建,功能单一且明确,专注于解决特定的问题。例如,在一个电商系统中,可能会有用户管理微服务、商品管理微服务、订单微服务等,每个微服务只负责自己领域内的业务逻辑。
- 独立自治:微服务之间相互独立,它们有自己独立的代码库、数据库、运行时环境等,可以独立进行开发、测试、部署和扩展。这使得不同的微服务可以由不同的团队进行开发和维护,提高了开发效率和团队的自主性。
- 轻量级通信:微服务之间通过轻量级的通信机制进行交互,通常使用 RESTful API、消息队列等方式。这种通信方式简单、灵活,能够很好地支持不同微服务之间的协作。
- 去中心化:微服务架构没有中央控制节点,各个微服务地位平等,它们通过相互协作来完成整个系统的功能。这种去中心化的架构使得系统具有更高的灵活性和可扩展性。
优势
- 易于开发和维护:由于每个微服务都相对较小且功能单一,开发人员可以更快速地理解和掌握其业务逻辑,便于进行开发、测试和调试。同时,当需要对某个功能进行修改或扩展时,只需要关注对应的微服务,不会影响到其他服务,降低了维护成本。
- 技术多样性:允许不同的微服务根据其具体业务需求选择最合适的技术栈进行开发。例如,对于计算密集型的微服务,可以选择性能高效的 C++ 或 Java 语言;对于实时性要求高的微服务,可以采用 Node.js 或 Python 等语言。这样可以充分发挥各种技术的优势,提高系统的整体性能。
- 可扩展性:可以根据不同微服务的负载情况进行独立的扩展。当某个微服务的业务流量增加时,可以单独增加该微服务的实例数量,而不需要对整个系统进行大规模的扩展,从而提高了资源的利用率,降低了成本。
- 可靠性和容错性:微服务架构中,当某个微服务出现故障时,只会影响到该服务本身,不会导致整个系统崩溃。其他微服务仍然可以正常运行,通过适当的容错机制和故障转移策略,可以保证系统的整体可用性。
挑战
- 运维复杂性增加:由于微服务数量较多,每个微服务都有自己的运行环境和依赖关系,这使得运维工作变得更加复杂。需要对每个微服务进行监控、管理和维护,包括服务器的部署、日志的收集、性能的优化等,对运维人员的技术水平和管理能力提出了更高的要求。
- 分布式事务处理困难:在微服务架构中,数据通常分布在多个不同的微服务中,当涉及到多个微服务之间的数据交互和一致性保证时,分布式事务的处理会变得比较复杂。需要采用合适的分布式事务解决方案,如两阶段提交、TCC(Try - Confirm - Cancel)等,但这些方案都有一定的局限性和复杂性。
- 服务间通信开销:微服务之间的通信会带来一定的性能开销,尤其是在网络延迟较高或通信频繁的情况下。需要合理设计微服务之间的通信机制,优化通信协议和数据传输方式,以减少通信开销对系统性能的影响。
- 服务治理难度大:随着微服务数量的增加,服务的注册与发现、负载均衡、配置管理、服务监控等服务治理问题变得越来越重要和复杂。需要建立完善的服务治理体系,采用相应的工具和框架来管理和协调各个微服务,确保系统的稳定运行。
粒度小、服务自治、团队自治、单一职责、数据隔离。
缺点:运维部署难、网络延迟、系统测试变得复杂
解决:微服技术栈
优点
● 降低复杂度:将原来耦合在一起的复杂业务拆分为单个服务。
● 独立部署:基于它们所提供的服务,它们可以被独立地部署到应用中。
● 容错:即便其中某个服务发生了故障,整个系统还可以继续工作。
● 灵活扩展:可以根据需求扩展某一个组件,不需要将所有组件全部扩展。
粒度小服务服务之间耦合度更低,服务多管理起来,主要是服务的治理。
是一种架构风格,它提倡将单一应用程序划分成一组小的服务,每个服务运行在自己进程中,服务间通信机制采用轻量级通讯机制(通常是基于 HTTP 的 RESTful API ) 。每个服务都围绕着具体业务进行构建,并且能够独自动化的独立部署。
这些服务可以使用不同的编程语言,不同数据库,以保证最低限度的集中式管理。rpc协议: Dubbo、Thrift、GRPC、Netty
通常情况下,这些小型服务都是围绕着某个特定的业务进行构建的,每一个服务只专注于完成一项任务并把它做好 ,即“专业的人做专业的事”。
本文链接:浅谈集群、分布式、微服务的异同 | 码农网微服务最大的问题: 网络不可靠
微服务拆分
微服务拆分是将一个大型的单体应用分解为多个小型、独立的微服务的过程。以下是关于微服务拆分的一些关键要点:
拆分原则
- 单一职责原则:每个微服务应该只负责一项特定的业务功能,确保功能的明确性和独立性,例如将用户管理、订单管理、商品管理等不同功能分别拆分成独立的微服务。
- 高内聚、低耦合:微服务内部的功能和数据应该具有高度的相关性和紧密的联系(高内聚),而微服务之间的依赖关系应该尽可能少(低耦合),以降低微服务之间的相互影响,提高系统的可维护性和可扩展性。
- 业务边界原则:根据业务领域的边界来划分微服务,每个微服务对应一个清晰的业务边界,例如按照不同的业务子领域,如电商系统中的营销、采购、仓储等进行拆分。
拆分方法
- 基于业务功能拆分:这是最常见的方法,按照业务流程和功能模块进行划分。比如在一个社交媒体应用中,可以拆分为用户认证与授权微服务、内容发布与管理微服务、社交关系管理微服务等。
- 基于数据模型拆分:根据数据的独立性和关联性来拆分微服务。如果某些数据实体之间的关联紧密,且与其他数据实体相对独立,那么可以将处理这些数据的功能封装在一个微服务中。例如,在一个电商系统中,订单数据和商品数据可以分别由订单微服务和商品微服务来管理。
- 基于性能和资源需求拆分:对于一些对性能要求较高或资源消耗较大的功能模块,可以将其拆分成独立的微服务,以便能够根据其具体需求进行单独的性能优化和资源分配。例如,图像视频处理功能可能需要大量的计算资源,可将其拆分为一个独立的微服务,部署在专门的高性能服务器上。
拆分步骤
- 业务梳理:对整个业务系统进行全面的分析和梳理,明确各个业务功能模块之间的关系和流程,确定业务边界。
- 确定微服务边界:根据拆分原则和方法,初步确定每个微服务的功能范围和边界,明确每个微服务所负责的业务功能和数据。
- 设计微服务接口:定义微服务之间的通信接口和协议,确保微服务之间能够高效、安全地进行数据交互和协作。接口设计应尽可能简洁、明确,并遵循一定的规范和标准。
- 实现微服务:根据设计方案,分别实现各个微服务。可以选择适合每个微服务业务特点的技术栈进行开发,同时要注意代码的质量和可维护性。
- 测试与集成:对每个微服务进行单独的单元测试和集成测试,确保微服务的功能正确性和稳定性。然后将各个微服务集成在一起,进行系统级的测试,验证整个系统的功能和性能是否满足要求。
- 部署与监控:将微服务部署到生产环境中,并建立完善的监控体系,对微服务的运行状态、性能指标、资源使用情况等进行实时监控和分析,及时发现和解决问题。
注意事项
- 避免过度拆分:虽然微服务架构具有很多优点,但过度拆分可能会导致系统复杂度增加、运维成本上升以及微服务之间的通信开销增大等问题。因此,在拆分时要权衡利弊,确保拆分的粒度合理。
- 数据一致性问题:微服务架构中,数据可能分布在多个不同的微服务中,因此需要关注数据一致性问题。可以采用分布式事务、最终一致性等策略来保证数据的一致性。
- 服务治理:随着微服务数量的增加,服务治理变得尤为重要。包括服务注册与发现、负载均衡、熔断器、配置管理等功能,需要建立相应的服务治理框架来管理和协调各个微服务。
纵向 按业务拆分, 横向抽取公共,提高复用;横向、纵向(分库分表一样)
思想:高内聚,低耦合
拆分出多个模块以后,就会出现各种各样的问题,
而SpringCloud提供了一整套的解决方案,---服务治理
在系统架构设计中,横向和纵向拆分是两种常见的分库分表策略。
纵向拆分主要基于业务领域进行模块划分,而横向拆分则侧重于提取公共功能,以提高代码复用率。这两种拆分方式都遵循"高内聚、低耦合"的设计原则。
然而,当系统被拆分为多个模块后,往往会面临各种新的挑战。针对这些问题,SpringCloud提供了一套完整的服务治理解决方案,有效解决了微服务架构中的各类难题。
什么时候拆分微服务?
以下是一些考虑拆分微服务的场景:
- 业务功能复杂且独立:当业务系统中存在多个功能模块,它们之间的业务逻辑相对独立,并且每个模块都有明确的职责和边界时,适合将这些功能模块拆分成微服务。例如,在一个综合的企业信息管理系统中,人力资源管理、财务管理、项目管理等功能相互独立,可拆分成不同的微服务。
- 团队规模和协作需求:如果开发团队规模较大,不同的功能模块由不同的团队负责开发和维护,为了提高团队的工作效率和独立性,减少相互之间的干扰和依赖,可以将这些功能模块拆分成微服务。每个团队可以独立地进行微服务的开发、测试和部署,通过微服务之间的接口进行协作。
- 性能优化需求:当系统中某些功能模块对性能要求较高,或者在高并发情况下容易出现性能瓶颈时,可以将这些功能模块拆分成独立的微服务,以便针对其特点进行单独的性能优化。例如,在一个电商系统中,商品搜索和推荐功能可能需要处理大量的数据和高并发请求,将其拆分成独立的微服务,可以采用分布式缓存、搜索引擎等技术来提高性能。
- 业务发展和扩展需求:随着业务的不断发展和变化,系统需要不断添加新的功能和特性。如果采用单体架构,可能会导致系统越来越庞大和复杂,难以进行扩展和维护。此时,将系统拆分成微服务,可以更灵活地应对业务的变化,方便地添加新的微服务来满足新的业务需求。例如,电商平台增加直播带货功能,可将直播相关功能拆分成新的微服务。
- 技术栈多样性需求:当不同的业务功能对技术栈有不同的要求时,拆分微服务可以让每个微服务选择最适合自身的技术栈。例如,实时数据处理部分可能适合使用流计算框架如 Apache Flink,而传统的业务逻辑处理可以使用 Spring Boot 等框架,通过微服务架构可以充分发挥不同技术栈的优势。
如何拆分微服务?
拆分微服务需要综合考虑业务、技术等多方面因素,以下是一些常见的方法和步骤:
1. 领域驱动设计(DDD)
- 核心思想:围绕业务领域概念构建微服务,将业务领域划分为不同的子领域,每个子领域对应一个微服务。
- 实施步骤:首先,对业务进行深入分析,识别出核心业务概念和流程,确定领域边界。例如,在电商系统中,可划分为商品、订单、用户、支付等子领域,每个子领域有明确的业务边界和职责。
2. 按功能模块拆分
- 核心思想:根据系统的功能模块进行划分,将功能相对独立、内聚性高的模块拆分成微服务。
- 实施步骤:梳理系统的功能架构,明确各个功能模块的职责和相互关系。比如,在一个企业管理系统中,可将人力资源管理、财务管理、客户关系管理等功能模块分别拆分成独立的微服务。
3. 按数据模型拆分
- 核心思想:依据数据的独立性和完整性来划分微服务,每个微服务管理独立的数据库或数据集合。
- 实施步骤:分析系统的数据模型,找出具有独立数据结构和业务语义的数据实体。例如,在社交媒体系统中,用户数据、帖子数据、评论数据等可分别由不同的微服务来管理,确保数据的一致性和完整性。
4. 考虑性能和资源需求
- 核心思想:将对性能要求高或资源消耗大的功能分离出来,形成单独的微服务,以便进行针对性的优化和资源分配。
- 实施步骤:通过性能测试和监控,识别出系统中的性能瓶颈点。例如,在一个视频流应用中,视频转码和播放功能对计算资源和网络带宽要求较高,可将其拆分成独立的微服务,部署在高性能服务器上。
5. 遵循接口和交互原则
- 核心思想:确保微服务之间通过清晰、稳定的接口进行通信,接口设计要遵循一定的规范和标准。
- 实施步骤:在拆分微服务时,定义好微服务之间的接口和交互方式,如 RESTful API、消息队列等。例如,一个订单微服务和库存微服务之间,通过 API 接口来传递订单信息和库存更新消息。
6. 持续优化和演进
- 核心思想:微服务架构是一个不断演进的过程,需要根据业务发展和系统运行情况进行持续优化和调整。
- 实施步骤:建立监控和反馈机制,收集微服务的运行数据和业务反馈,及时发现问题并进行优化。例如,随着业务量的增长,发现某个微服务的负载过高,可以进一步拆分或优化该微服务。
目标:高内聚、低耦合(单一职责)
方式:纵向拆分、横向拆分
高内聚:职责单一,相互关联度高、完整度高。
低耦合:功能相对独立,不依赖其他服务。【跨服务合作排除】。
满足高内聚自然低耦合。
- 自顶向下,拆分原则
拆解领域模型。 (UML) . 领域建模
- 服务粒度适中:服务不要太细
演进式拆分:刚开始不要划分太细,可以随着迭代过程来逐步优化
- 以业务模型切入:比如产品,用户,订单为一个模型来切入
- 避免环形依赖与双向依赖:尽量不要做服务之间的循环依赖
- 数据耦合,对于需要跨机事务的拆分,要重点分析,是否可以通过服务功能的调整避免(如将两段式提交变成数据副本的最终一致性),如果确实不行,对拆分的必要性进行确认
微服务之前只能通过接⼝进⾏服务调⽤,⽽不能绕过接⼝直接访问对⽅的数据。
(查询的会,看情况)
拆分方式:纵向划分、横向拆分。
纵向(垂直):业务模块来拆分
横向(水平):抽取公共,提高复用性【登录、发短信】
二、持续演进。
服务数量快速增长带来架构复杂度急剧升高,开发、测试、运维等环节很难快速适应,会导致故障率大幅增加,可用性降低。非必要情况,应逐步划分、持续演进、避免服务数量的爆炸式增长。这等同于灰度发布的效果,先拿出几个不太重要的功能拆分出一个服务做试验,即便出现故障,影响范围也不会太大。
三、服务自治、接口隔离。
尽量消除对其他服务的强依赖,这样可以降低沟通成本,提升服务稳定性。服务通过标准的接口隔离,隐藏内部实现细节。这样可以让服务保持独立开发、测试、部署、运行,以服务为单位持续交付。
四、自动化驱动。
部署和运维的成本会随着服务的增多呈指数级增长,每个服务都需要部署、监控、日志分析等运维工作,成本会显著提升。因此,在服务划分之前,应该首先构建自动化的工具及环境。开发人员应该以自动化为驱动力,简化服务在创建、开发、测试、部署、运维上的重复性工作,通过工具实现更可靠的操作,避免微服务数量增多带来的开发、管理复杂度问题。
拆分后碰到的第一个问题是什么,如何解决?
微服务拆分后遇到的首个常见问题通常是服务间通信与集成的复杂性,这主要体现在以下几个方面及对应的解决办法:
1. 服务间调用的网络延迟与可靠性
- 问题表现:拆分后服务间通过网络调用,响应变慢;单个服务故障可能导致级联失败(如 A 服务依赖 B,B 故障导致 A 也不可用)。
- 解决方案:
- 引入服务注册与发现(如 Nacos、Eureka):自动注册和更新服务实例的位置信息,避免硬编码服务地址。
- 实现负载均衡(如 Ribbon、Spring Cloud LoadBalancer):将请求均匀分发到多个服务实例,提高可用性。
- 熔断与降级(如 Sentinel、Hystrix):当依赖的服务不可用时,快速失败或返回默认值,防止级联故障。
2. 分布式事务与数据一致性
- 问题表现:跨服务的业务操作(如订单创建 + 库存扣减)无法通过本地事务保证一致性,可能导致数据不一致。
- 解决方案:
- 最终一致性模式:通过异步消息队列(如 RocketMQ、Kafka)实现数据最终一致,例如订单创建后发送消息通知库存服务扣减。
- TCC 补偿模式:将一个业务操作拆分为 Try、Confirm、Cancel 三个阶段,例如先冻结库存(Try),订单确认后扣减(Confirm),失败则回滚(Cancel)。
- 柔性事务框架:使用 Seata 等框架简化分布式事务的实现。
3. 服务间接口定义与版本管理
- 问题表现:服务间接口变更可能导致调用方崩溃,例如 A 服务修改了返回参数,而 B 服务未同步更新。
- 解决方案:
- 契约优先(Contract - First)开发:使用 OpenAPI/Swagger 定义接口规范,生成客户端代码,确保接口变更时双方同步更新。
- 版本控制:在接口中添加版本号(如 URL 路径或请求头),支持多版本共存,例如
/api/v1/users
和/api/v2/users
。 - 灰度发布:新接口先在部分实例上部署,验证通过后再全量上线。
4. 调试与监控复杂度增加
- 问题表现:请求链路跨多个服务,难以定位问题,例如用户反馈某个功能异常,但无法确定是哪个服务出了问题。
- 解决方案:
- 分布式链路追踪(如 Zipkin、Skywalking):记录请求在各个服务间的调用路径和耗时,快速定位瓶颈或故障点。
- 统一日志管理(如 ELK Stack):集中收集和分析所有服务的日志,便于排查问题。
- 指标监控(如 Prometheus + Grafana):监控服务的性能指标(如 QPS、响应时间、错误率),设置告警阈值。
5. 部署与运维成本上升
- 问题表现:服务数量增多,部署和管理复杂度爆炸式增长,例如需要维护数十个服务的配置、资源分配和扩容。
- 解决方案:
- 容器化与编排(Docker + Kubernetes):将服务打包为容器,通过 Kubernetes 自动化部署、扩缩容和故障恢复。
- 基础设施即代码(IaC):使用 Terraform 或 Ansible 管理基础设施,确保环境一致性。
- 服务网格(Service Mesh):如 Istio,提供流量管理、认证授权等功能,降低服务间通信的复杂度。
实践建议
- 从小规模开始:先拆分非核心服务(如通知、文件处理),验证架构和流程后再逐步拆分核心服务。
- 建立标准化流程:制定服务间通信规范、接口变更流程、灰度发布策略等,避免混乱。
- 投资监控工具:在拆分初期就引入链路追踪、日志聚合等工具,避免后期问题难以排查。