
02 SpringCloud 笔记
Spring Cloud
微服务
什么是微服务?
答:
- 微服务是一种 架构思想,它将应用程序拆分为一系列 小型、独立 的服务,每个服务负责处理一项特定业务功能
- 这种架构风格的特点是 服务之间松散耦合、独立部署和运行。微服务架构使得开发人员可以更加专注于单个服务的开发与测试,降低了系统的复杂性,提高了系统的可维护性和可扩展性。同时,每个服务可以根据具体的业务需求选择合适的语言、工具进行构建,提高了系统的灵活性和可维护性
- 在微服务架构中,服务之间通过轻量级的通信机制(如:
RPC、HTTP等)进行通信,每个服务都可以独立地进行部署、扩展和升级,从而提高了系统的可靠性和可用性。总的来说,微服务架构思想使得应用程序更加灵活、可维护和可扩展,为构建高效、可靠的大型应用程序提供了有力支持
微服务相较于传统的web项目有什么优势?
答:
- 传统的
Web项目尽管也是遵循模块化开发,但最终它们会打包并部署为单体式应用。例如:Java应用程序会被打包成WAR,部署在Tomcat或者Jetty上 - 这种单体应用比较适合于小项目,优点是:
- 开发简单直接,集中式管理
- 基本不会重复开发
- 功能都在本地,没有分布式的管理开销和调用开销
- 它的缺点也十分明显,特别对于互联网公司来说:
- 开发效率低:所有的开发在一个项目改代码,递交代码相互等待,代码冲突不断
- 代码维护难:代码功能耦合在一起,新人不知道何从下手
- 部署不灵活:构建时间长,任何小修改必须重新构建整个项目,这个过程往往很长
- 稳定性不高:一个微不足道的小问题,可以导致整个应用挂掉
- 扩展性不够:无法满足高并发情况下的业务需求
- 主流的设计一般会采用微服务架构。其思路不是开发一个巨大的单体式应用,而是将应用分解为小的、互相连接的微服务。一个微服务完成某个特定功能,每个微服务都有自己的业务逻辑。一些微服务还会提供
API接口给其他微服务和应用客户端使用 - 微服务架构的优点:
- 解决了复杂性问题:开发的速度要快很多,更容易理解和维护
- 单独开发每个服务,与其他服务互不干扰
- 可以独立部署每个微服务
- 微服务的缺点:
- 多服务运维难度
- 系统部署依赖
- 服务间通信成本
- 数据一致性
- 系统集成测试
微服务带来了哪些挑战?
答:
- 成本挑战:
- 基础设施成本增加:微服务应用通常需要更多的基础设施资源,例如:服务器、容器管理、负载均衡器等,这可能导致运营成本增加
- 开发和维护成本:管理多个微服务的开发、测试、部署和维护需要更多的工程师资源,这可能导致开发和维护成本上升
- 复杂性挑战:
- 分布式系统复杂性:微服务应用是分布式系统,涉及多个独立运行的服务,这增加了系统的复杂性,包括网络通信、故障处理和事务管理等方面
- 服务发现和治理:管理多个微服务的发现、注册、版本控制和路由需要额外的复杂性,例如使用服务网格或API网关
- 部署挑战:
- 自动化部署需求:为了有效地部署多个微服务,需要建立自动化的部署流程,这可能需要额外的工作和资源
- 版本控制和回滚:管理不同版本的微服务以及版本之间的兼容性可能会变得复杂,特别是在需要回滚时
- 一致性挑战:
- 数据一致性:不同微服务可能拥有各自的数据存储,确保数据一致性和同步可能需要复杂的解决方案,如分布式事务或事件驱动的一致性
- 事务管理:管理跨多个微服务的事务变得复杂,确保事务的一致性和隔离性需要额外的努力和技术
- 监控和故障排除挑战:
- 性能监控:在微服务环境中,跟踪性能问题和故障排除可能更加困难,因为问题可能涉及多个服务,需要强大的监控和诊断工具
- 故障排除:需要有效的方法来跟踪和诊断跨多个服务的故障,以便快速恢复
- 微服务不是万金油,是用来处理海量用户、业务复杂和需求频繁变更场景下的一种架构风格。引用一句话 “好的架构是演化出来的,而不是设计出来的”。任何一种架构的引入,都会带来利弊两个方面的影响,如何平衡才最重要
实现微服务要解决的四个问题?
客户端如何访问这些服务?
答:
- 原来的服务都是可以进行单独调用,现在按功能拆分成独立的服务,变成了一个独立的
Java进程了。客户端如何访问后台 N 个服务呢? - 一般在后台 N 个服务和
UI之间会一个代理或者叫APIGateway,它的作用包括:- 提供统一服务入口,让微服务对前台透明
- 聚合后台的服务,节省流量,提升性能
- 提供安全,过滤,流控等
API管理功能
服务之间如何通信?
答:
- 因为所有微服务都是独立的
Java进程跑在独立的虚拟机上,所以服务间的通信就是IPC(inter processcommunication,进程间通信),已经有很多成熟的方案。现在基本最通用的有两种方式:- 同步调用
RESTRPC
- 异步消息调用(
Kafka、ActiveMQ、RocketMQ)
- 同步调用
这么多服务,怎么找?
答:
- 在微服务架构中,一般每一个服务都是有多个拷贝,来做负载均衡。一个服务随时可能下线,也可能应对临时访问压力增加新的服务节点。服务之间如何相互感知?服务如何管理?这就是服务发现的问题了
- 一般都是通过
zookeeper等类似技术做服务注册信息的分布式管理。当服务上线时,服务提供者将自己的服务信息注册到ZooKeeper(或类似框架),并通过心跳维持长链接,实时更新链接信息。服务调用者通过ZooKeeper寻址,根据可定制算法,找到一个服务,还可以将服务信息缓存在本地以提高性能。当服务下线时,ZooKeeper会发通知给服务客户端- 客户端做:优点是架构简单,扩展灵活,只对服务注册器依赖。缺点:是客户端要维护所有调用服务的地址,有技术难度,一般大公司都有成熟的内部框架支持,比如:
Dubbo - 服务端做:优点是简单,所有服务对于前台调用方透明,一般在小公司在云服务上部署的应用采用的比较多
- 客户端做:优点是架构简单,扩展灵活,只对服务注册器依赖。缺点:是客户端要维护所有调用服务的地址,有技术难度,一般大公司都有成熟的内部框架支持,比如:
服务挂了怎么办?
答:
- 分布式最大的特性就是网络是不可靠的。通过微服务拆分能降低这个风险,不过如果没有特别的保障,结局肯定是噩梦
- 当我们的系统是由一系列的服务调用链组成的时候,我们必须确保任一环节出问题都不至于影响整体链路。相应的手段有很多:
- 重试机制
- 限流
- 熔断机制
- 负载均衡
- 降级(本地缓存)
微服务的通讯方式有哪些?
答:
- 微服务的通讯方式主要有以下几种:
RESTful API:基于HTTP协议的RESTful API是最常用的微服务通讯方式之一。服务之间通过HTTP请求和响应进行通讯,实现数据交换。这种方式简单、通用,适用于各种场景,但可能不适合对实时性要求非常高的场景RPC(远程过程调用):RPC允许一个服务像调用本地方法一样调用另一个服务的方法。它通过将方法调用封装成网络数据包并在不同的进程之间传输,实现不同服务之间的互相调用。RPC方式可以提高调用的效率和性能,但可能需要更多的配置和管理工作- 消息队列通讯:如
RabbitMQ、Kafka、RocketMQ等,服务之间不直接调用,而是通过消息队列进行异步消息传递,实现服务之间的解耦和异步处理 - 事件驱动通讯:服务之间通过事件触发通讯,一旦某个服务发生了某个事件,就会触发其他服务的响应。这种方式可以实现服务的松耦合和事件的实时处理,典型的实现如
Event Bus WebSocket(长连接通信):使用WebSocket实现双向通信,常用于实时推送场景,服务间可以维持长期的TCP连接进行数据交换
- 其中,
RESTfuI API和RPC是微服务间最常用的通讯方式,但它们的使用场景又略有不同: RESTfuI API通常用于外部接口或第三方接口通讯。RESTfuI API目前主流的实现方式有以下两种:RestTemplate:Spring内置的用于执行HTTP请求的类。Spring Cloud OpenFegin:Openfeign是Spring Cloud对Feign库的封装,提供声明式的HTTP客户端,简化了服务调用的编码工作
RPC通常用于内部微服务之间的方法调用。RPC目前主流的通讯方式有以下两种:Dubbo:阿里巴巴公司开源的一个Java高性能优秀的服务框架,它基于TCP或HTTP的RPC远程过程调用,支持负载均衡和容错,自动服务注册和发现gRPC:Google开发的高性能、通用的开源RPC框架,它主要面向移动应用开发并基于HTTP/2协议标准设计。gRPC使用ProtoBuf(Protocol Buffers)作为序列化工具和接口定义语言,要求在调用前需要先定义好接口契约,并使用工具生成代码,然后在代码中调用这些生成的类进行服务调用
分布式和微服务有什么区别?
答:
- 它们的本质的区别体现在 “目标” 上
- 分布式架构 的目标就是 访问量很大一台机器承受不了,或者是成本问题,不得不使用多台机器来完成服务的部者
- 微服务 的目标只是 让各个模块拆分开来,不会被互相影响,比如:模块的升级或者出现
BUG或者是重构等等都不要影响到其他模块,微服务它是可以在一台机器上部署
- 分布式 也是 微服务 的一种,微服务 也属于 分布式
单体应用、SOA 和微服务架构有什么区别?
答:

- 单体应用、
SOA和 微服务架构 都是不同的架构风格,适用于不同的情况- 单体应用像一个整体,所有的功能都打包在一个应用中。这种架构风格容易部署和测试,但随着系统规模的挑大,它的灵活性和可维护性会降低
SOA是一种面向服务的架构风格,将系统划分为多个独立的服务。这些服务可以通过网络调用,并且可以跨平台、跨语言进行交互。SOA的优点是提供了跨系统的服务复用和松散耦合的交互方式,但实现SOA需要投入大量的工作,包括服务的定义、接口的选择、协议的制定等- 微服务架构进一步将系统划分为多个小型、独立的服务,每个服务都是一个单独的应用程序,可以独立部署运行和扩展。微服务架构具有更高的灵活性和可维护性,适用于复杂的大型系统,强调服务的自治和独立性但是,实施微服务架构也需要投入大量的工作,包括服务的定义、通信机制的选择、服务的管理等
现在有哪些流行的微服务解决方案?
答:
- 目前最主流的微服务开源解决方案有三种:
Dubbo:Dubbo是一个高性能、轻量级的Java微服务框架,最初由阿里巴巴(Alibaba)开发并于 2011 年开源。它提供了 服务注册与发现、负载均衡、容错、分布式调用 等功能,后来一度停止维护,在近两年,又重新开始迭代,并推出了Dubbo3Dubbo使用基于RPC(Remote Procedure Call)的通信模型,具有较高的性能和可扩展性。它支持多种传输协议(如TCP、HTTP、Redis)和序列化方式(如JSON、Hessian、Protobuf),可根据需求进行配置Dubbo更多地被认为是一个高性能的RPC(远程过程调用)框架,一些服务治理功能依赖于第三方组件实现,比如使用ZooKeeper、Apollo等等
Spring Cloud Netflix:Spring Cloud Netflix是Spring Cloud的一个子项目,结合了Netflix开源的多个组件,但是Netflix自 2018 年停止维护和更新Netflix OSS项目,包括Eureka、Hystrix等组件,所以Spring Cloud Netflix也逐渐进入了维护模式- 该项目包含了许多流行的
Netflix组件,如:Eureka(服务注册与发现)、Ribbon(客户端负载均衡)、Hystrix(断路器)、Zuul(API网关)等。它们都是高度可扩展的、经过大规模实践验证的微服务组件
Spring Cloud Alibaba:Spring Cloud Alibaba是Spring Cloud的另一个子项目,与阿里巴巴的分布式应用开发框架相关。它提供了一整套与Alibaba生态系统集成的解决方案- 该项目包括
Nacos(服务注册与发现、配置管理)、Sentinel(流量控制、熔断降级)、RocketMQ(消息队列)等组件,以及与Alibaba Cloud(阿里云)的集成。它为构建基于Spring Cloud的微服务架构提供了丰富的选项 - 据说
SpringCloud Alibaba项目的发起人已经跑路去了腾讯,并发起了SpringCloud Tecent项目,社区发展存在隐忧

说下微服务有哪些组件?
答:
- 微服务的各个组件和常见实现:
- 注册中心:用于服务的注册与发现,管理微服务的地址信息。常见的实现包括:
Spring Cloud Netflix:Eureka、ConsulSpring Cloud Alibaba:Nacos
- 配置中心:用于集中管理微服务的配置信息,可以动态修改配置而不需要重启服务。常见的实现包括:
Spring Cloud Netflix:Spring Cloud ConfigSpring Cloud Alibaba:Nacos Config
- 远程调用:用于在不同的微服务之间进行通信和协作。常见的实现保包括:
RESTful API:如RestTemplate、FeignRPC(远程过程调用):如Dubbo、gRPC
API网关:作为微服务架构的入口,统一暴露服务,并提供路由、负载均衡、安全认证等功能。常见的实现包括:Spring Cloud Netflix:Zuul、GatewaySpring Cloud Alibaba:Gateway、Apisix等
- 分布式事务:保证跨多个微服务的一致性和原子性操作。常见的实现包括:
Spring Cloud Alibaba:Seata
- 熔断器:用于防止微服务之间的故障扩散,提高系统的容错能力。常见的实现包括:
Spring Cloud Netflix:HystrixSpring Cloud Alibaba:Sentinel、Resilience4j
- 限流和降级:用于防止微服务过载,对请求进行限制和降级处理。常见的实现包括:
Spring Cloud Netflix:HystrixSpring Cloud Alibaba:Sentinel
- 分布式追踪和监控:用于跟踪和监控微服务的请求流程和性能指标。常见的实现包括:
Spring Cloud Netflix:Spring Cloud Sleuth+ZipkinSpring Cloud Alibaba:SkyWalking、Sentinel Dashboard
- 注册中心:用于服务的注册与发现,管理微服务的地址信息。常见的实现包括:
微服务架构如何运行的?
答:

- 客户端:来自不同设备的不同用户发送请求
- 身份提供商:验证用户或客户身份并颁发安全令牌
API网关:处理客户端请求- 静态内容:容纳系统的所有内容
- 管理:在节点上平衡服务并识别故障
- 服务发现:查找微服务之间通信路径的指南
- 内容交付网络:代理服务器及其数据中心的分布式网络
- 远程服务:启用驻留在IT设备网络上的远程访问信息
Spring Cloud
Spring Cloud 是什么?
答:
Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性,巧妙地简化了分布式系统- 基础设施的开发,如:服务发现注册、配置中心、智能路由、消息总线、负载均衡、断路器、数据监控等,都可以用
Spring Boot的开发风格做到一键启动和部署 Spring Cloud并没有重复制造轮子,它只是将各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屛蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包
Spring Cloud的优缺点有哪些?
答:
- 优点:
- 服务拆分粒度更细,有利于资源重复利用,有利于提高开发效率
- 可以更精准的制定优化服务方案,提高系统的可维护性
- 微服务架构采用去中心化思想,服务之间采用
Restful等轻量级通讯,比ESB更轻量适于互联网时代,产品迭代周期更短
- 缺点:
- 微服务过多,治理成本高,不利于维护系统
- 分布式系统开发成本高(容错,分布式事务等),对团队的挑战大
Spring Boot和Spring Cloud的区别?
答:
Spring Boot专注于快速、方便的开发单个微服务个体,Spring Cloud关注全局的服务治理框架Spring Boot可以离开Spring Cloud独立使用开发项目, 但是Spring Cloud离不开Spring Boot,属于依赖的关系
Spring、Spring Boot 和 Spring Cloud 的关系是什么?
答:
Spring最初最核心的两大核心功能Spring IoC和Spring AOP成就了Spring,Spring在这两大核心的功能上不断的发展,才有了Spring事务、Spring MVC等一系列伟大的产品,最终成就了Spring帝国,到了后期Spring几乎可以解决企业开发中的所有问题Spring Boot是在强大的Spring帝国生态基础上面发展而来,发明Spring Boot不是为了取代Spring,是为了让人们更容易地使用SpringSpring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如:服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署Spring Cloud是为了解决微服务架构中服务治理而提供的一系列功能的开发框架,并且Spring Cloud是完全基于Spring Boot而开发,Spring Cloud利用Spring Boot特性整合了开源行业中优秀的组件,整体对外提供了一套在微服务架构中服务治理的解决方案
Spring Cloud 由什么组成?
答:

Spring Cloud由以下几个核心组件构成:Eureka:Eureka是Spring Cloud提供的服务注册和发现的组件Ribbon:Ribbon是一个客户端负载均衡器,可以用于在多个服务实例之间分发请求,提高系统的可用性和性能Feign:Feign是一个声明式的服务调用客户端,它使得编写服务间调用的代码更加简洁和可读Hystrix:Hystrix是一种断路器模式的实现,用于防止由于服务故堂而导致整个系统的崩溃,它可以提供降级策略、请求缓存、线程池隔离等功能Zuul & Gateway:Zuul是一个API网关,用于路由和过滤传入的请求。它可以提供安全性、监控和负载均衡的功能Spring Cloud Config:Spring Cloud Config可以用于集中式管理微服务应用程序的配置,支持动态更新配置Spring Cloud Bus:Spring Cloud Bus使用消息总线来连接分布式应用程序中的各个组件,从而实现配置的集中化管理和更新Spring Cloud Sleuth:Spring Cloud Sleuth集成了分布式追踪工具,如Zipkin,用于跟踪请求在微服务系统中的流动,以帮助诊断和分析问题
服务注册与发现
为什么需要服务注册发现?
答:
- 在分布式系统中,服务的数量和规模通常很大,同时服务的部署和变化也非常频繁。因此,手动管理和调用这些服务会变得非常困难和繁琐。服务注册与发现的作用就是解决这个问题,它提供了一种机制,让服务可以自动注册到注册中心,并且可以通过注册中心进行查询和调用
- 服务注册与发现的核心思想是通过注册中心来维护服务提供者和服务消费者之间的映射关系。当服务提供者启动时,它会向注册中心注册自己的信息,包括:服务名、
IP地址、端口号 等信息。当服务消费者需要调用某服务时,它可以向注册中心发起查询请求,查询对应服务的地址信息,然后通过该地址发送请求 - 使用服务注册与发现的好处是:
- 自动化管理:服务的自动注册和发现可以减少手动管理服务的工作量,提高系统的可靠性和稳定性,同时也可以减少出错的机会
- 负载均衡:注册中心可以提供负载均衡的功能,当有多个服务提供者时,它可以自动帮助消费者进行负载均衡
- 服务治理:通过服务注册中心,可以方便地进行服务的监控、管理和治理,例如限流、降级、熔断等操作
- 服务拓扑发现:服务注册中心可以提供服务拓扑发现的功能,帮助开发者更好地理解和管理服务之间的关系
SpringCloud可以选择哪些注册中心?
答:
SpringCloud可以与多种注册中心进行集成,常见的注册中心包括:Eureka:Eureka是Netfix开源的服务发现框架,具有高可用、弹性、可扩展等特点,并与Spring Cloud集成良好,已闭源。AP(可用性和分区容忍性)Consul:Consul是一种分布式服务发现和配置管理系统,由HashiCorp开发。它提供了服务注册、服务发现、健康检查、键值存储等功能,并支持多数据中心部署。CP(一致性和分区容忍性)ZooKeeper:ZooKeeper是Apache基金会开源的分布式协调服务,可以用作服务注册中心。它具有高可用.一致性、可靠性等特点。CP(一致性和分区容忍性)Nacos:Nacos是阿里巴巴开源的一个动态服务发现、配置管理和服务管理平台。它提供了服务注册和发现.配置管理、动态DNS服务等功能。 既支持AP,也支持CPetcd:etcd是CoreOS开源的一种分布式键值存储系统,可以被用作服务注册中心。它具有高可用、强一致性、分布式复制等特性。CP(一致性和分区容忍性)
什么是Eureka?
答:
Eureka是Netffix开发的服务注册发现框架,SpringCloud将它集成在自己的子项目spring-cloud-netflflix中,实现SpringCloud的服务注册发现功能Eureka Client是一个Java客户端,用于简化与Eureka Server的交互。Eureka Server提供服务发现的能力,各个微服务启动时,会通过Eureka Client向Eureka Server进行注册自己的信息(例如:网络信息),Eureka Server会存储该服务的信息- 微服务启动后,会周期性地向
Eureka Server发送心跳(默认周期为30秒)以续约自己的信息。如果Eureka Server在一定时间内没有接收到某个微服务节点的心跳,Eureka Server将会注销该微服务节点(默认90秒)
Eureka实现原理说一下?
答:
Eureka的实现原理,大概可以从这几个方面来看:- 服务注册与发现:当一个服务实例启动时,它会向
Eureka Server发送注册请求,将自己的信息注册到注册中心。Eureka Server会将这些信息保存在内存中,并提供REST接口供其他服务查询。服务消费者可以通过查询服务实例列表来获取可用的服务提供者实例,从而实现服务的发现 - 服务健康检查:
Eureka通过心跳机制来检测服务实例的健康状态。服务实例会定期向Eureka Server发送心跳,也就是续约,以表明自己的存活状态。如果Eureka Server在一定时间内没有收到某个服务实例的心跳,则会将其标记为不可用,并从服务列表中移除,下线实例 - 服务负载均衡:
Eureka客户端在调用其他服务时,会从本地缓存中获取服务的注册信息。如果缓存中没有对应的信息,则会向Eureka Server发送查询请求。Eureka Server会返回一个可用的服务实例列表给客户端,客户端可以使用负载均衡算法选择其中一个进行调用
- 服务注册与发现:当一个服务实例启动时,它会向
- 其它的注册中心,如
Nacos、Consul等等,在服务注册和发现上,实现原理都是大同小异
Eureka怎么实现高可用?
答:
- 多实例部署:通过将多个
Eureka Server实例部署在不同的节点上,可以实现高可用性。当其中一个实例发生故障时,其他实例仍然可以提供服务,并保持注册信息的一致性 - 服务注册信息的复制:当一个服务实例向
Eureka Server注册时,每个Eureka Server实例都会复制其他实例的注册信息,以保持数据的一致性。当某个Eureka Server实例发生故障时,其他实例可以接管其工作,保证整个系统的正常运行 - 自我保护机制:
Eureka还具有自我保护机制。当Eureka Server节点在一定时间内没有接收到心跳时,它会进入自我保护模式。在自我保护模式下,Eureka Server不再剔除注册表中的服务实例,以保护现有的注册信息。这样可以防止由于网络抖动或其他原因导致的误剔除,进一步提高系统的稳定性
Eureka自我保护模式是什么?
答:
- 默认情况下,如果
Eureka Server在一定时间内没有接收到某个微服务实例的心跳,Eureka Server将会注销该实例(默认90秒)。但是当网络分区故障发生时,微服务与Eureka Server之间无法正常通信, 以上行为可能变得非常危险了- 因为微服务本身其实是健康的,此时本不应该注销这个微服务
Eureka通过 “自我保护模式” 来解决这个问题- 当
Eureka Server节点在短时间内丢失过多客户端时(可能发生了网络分区故障),那么这个节点就会进入自我保护模式。一旦进入该模式,Eureka Server就会保护服务注册表中的信息,不再删除服务注册表中的数据(也就是不会注销任何微服务)。当网络故障恢复后,该Eureka Server节点会自动退出自我保护模式
- 当
- 综上,自我保护模式是一种应对网络异常的安全保护措施。它的架构哲学是宁可同时保留所有微服务(健康的微服务和不健康的微服务都会保留),也不盲目注销任何健康的微服务。使用自我保护模式,可以让
Eureka集群更加的健壮、稳定
Spring Cloud如何实现服务的注册?
答:
- 服务发布时,指定对应的服务名,将服务注册到注册中心(
Eureka、Zookeeper) - 如果是使用
Eureka作为注册中心,则Eureka Server需要在启动类上添加@EnableEurekaServer注解,其他服务(即:Eureka Client)在启动类上添加@EnableDiscoveryClient注解,然后用ribbon或feign进行服务直接的调用
Eureka和ZooKeeper的区别是什么?
答:
Zookeeper保证了CP,Eureka保证了AP(A:高可用、C:一致性、P:分区容错性)Eureka满足可用性,Zookeeper满足一致性:Zookeeper要求各个服务之间同步完成之后才会返回给用户结果,如果服务出现网络波动导致监听不到心跳,会立即从服务列表中剔除,服务不可用Eureka如果遇到网络故障,基于Eureka的自我保护机制,不会立即剔除服务,虽然用户获取的服务不一定是可用的,但是至少可以获取到服务列表。用户访问服务列表后还可以利用重试机制,找到正确的服务。更符合分布式服务高可用的要求
Eureka集群节点间相互平等,Zookeeper有主从之分:- 如果
Zookeeper集群中有服务容机,会重新基于选举机制选出新的主节点,因此可能会导致整个集群因为选主而阻塞,服务不可用 Eureka集群有服务宕机,因为各个节点之间是平等的,其他服务器不受影响
- 如果
Eureka中服务发现者是去主动地拉取服务,Zookeeper服务发现者是基于监听机制:Eureka中获取服务列表后会缓存起来,每隔 30秒 重新拉取服务列表Zookeeper是监听节点的信息变化,当服务节点信息发生变化的时候,客户端立即收到通知
Consul 是什么?
答:
Consul是一套开源的分布式服务发现和配置管理系统,由Hashicorp公司用Go语言开发。提供了微服务系统中的服务治理、配置中心、控制总线等功能。这些功能中的每一个都可以根据需要单独使用,也可以一起使用以构建全方位的服务网格,总之Consul提供了一种完整的服务网格解决方案- 它具有很多优点。包括:基于
raft协议,比较简洁;支持健康检査,同时支持HTTP和DNS协议,支持跨数据中心的WAN集群 提供图形界面 跨平台,支持Linux、Mac、Windows
Consul 有哪些特性?
答:
- 服务发现:提供
HTTP和DNS两种服务发现方式 - 健康监测:支持多种方式,
HTTP、TCP、Docker、Shell脚本定制化监控 KV存储:key、value的存储方式- 多数据中心:支持多数据中心
- 可视化
Web界面
Eureka、Consul、Zookeeper 有什么区别?
答:
| 属性 | Eureka | Consul | Zookeeper |
|---|---|---|---|
| 语言 | Java | Go | Java |
| CAP | AP | CP | CP |
| 服务健康检查 | 可配置支持 | 支持 | 支持 |
| 对外暴露接口 | HTTP | HTTP/DNS | 客户端 |
| Spring Cloud | 可集成 | 可集成 |
CAP的含义:
- C:Consistency(强一致性)
- A:Availability(可用性)
- P:Partition tolerance(分区容错性)
Eureka、ZooKeeper、Nacos 比较?
答:
| 特性 | Eureka | ZooKeeper | Nacos |
|---|---|---|---|
| 开发公司 | Netflix | Apache 基金会 | 阿里巴巴 |
| CAP | AP(可用性和分区容忍性) | CP(一致性和分区容忍性) | 既支持AP,也支持CP |
| 功能 | 服务注册与发现 | 分布式协调、配置管理、分布式锁 | 服务注册与发现、配置管理、服务管理 |
| 定位 | 适用于构建基于 HTTP 的微服务架构 | 通用的分布式协调服务框架 | 适用于微服务和云原生应用 |
| 访问协议 | HTTP | TCP | HTTP/DNS |
| 自我保护 | 支持 | - | 支持 |
| 数据存储 | 内嵌数据库、多个实例形成集群 | ACID 特性的分布式文件系统 ZAB 协议 | 内嵌数据库、MySQL 等 |
| 健康检查 | Client Beat | Keep Alive | TCP/HTTP/MYSQL/Client Beat |
| 特点 | 简单易用、自我保护机制 | 高性能、强一致性 | 动态配置管理、流量管理、灰度发布等 |
- 可以看到
Eureka和ZooKeeper的最大区别是一个支持AP,一个支持CP,Nacos既支持既支持AP,也支持CP它们在功能和实现方式上存在一些不同:Nacos除了作为注册中心外,还提供了配置管理、服务发现和事件通知等功能。Nacos默认情况下采用AP架构保证服务可用性,CP架构底层采用Raft协议保证数据的一致性。Nacos适合作为微服务注册中心和配置管理中心,支持快速发现、配置管理和服务治理等功能Eureka是只提供注册中心功能的工具,它的设计理念是AP,即保证服务的可用性,不保证一致性。Eureka的各个节点之间相互注册,只要有一台Eureka节点存在,整个微服务就可以通讯- 而
Zookeeper相比前两者,除了注册中心的功能,还提供了分布式协调服务,比如通知、公告、配置管理等。Zookeeper采用CP设计,可以保证数据的一致性,但是牺牲了一部分服务的可用性。Zookeeper适用于需要分布式协调服务的场景,如配置管理、命名服务等
详细链接:服务注册与发现原理剖析(Eureka、Zookeeper、Nacos)
Nacos 的服务注册表结构是怎样的?
答:
Nacos采用了 数据的分级存储模型,最外层是Namespace,用来隔离环境。然后是Group,用来对服务分组。接下来就是服务(Service)了,一个服务包含多个实例,但是可能处于不同机房,因此Service下有多个集群(Cluster),Cluster下是不同的实例(Instance)- 对应到
Java代码中,Nacos采用了一个多层的Map来表示。结构为Map<String, Map<String, Service>>,其中最外层Map的key就是namespaceId,值是一个Map。内层Map的key是group拼接serviceName,值是Service对象。Service对象内部又是一个Map,key是集群名称,值是Cluster对象。而Cluster对象内部维护了Instance的集合
Nacos中的Namespace是什么?如何使用它来组织和管理微服务?
答:
Nacos中的Namespace是用于隔离不同环境或应用之间的配置和服务信息的概念。通过使用Namespace,可以将不同的环境(例如:开发、测试和生产)或不同的应用程序(例如:Web应用和移动应用)的配置和服务信息分离开来,以避免冲突和错误- 在
Nacos中,每个Namespace都有自己独立的配置和服务注册表。这意味着,如果有多个应用程序需要使用Nacos,可以将它们分别放置在不同的Namespace中。每个Namespace都有自己的命名空间ID,用于标识该Namespace。要使用Namespace,在Nacos客户端初始化时,需要指定要使用的Namespace ID - 通过使用
Namespace,可以对不同Namespace下的服务进行分组和管理,例如:可以使用Nacos提供的Group功能对同一Namespace下的服务进行分组,方便管理和查找。同时,使用Namespace还可以对不同环境下的配置进行隔离,避免不同环境之间的配置冲突
负载均衡
为什么需要负载均衡?
答:
- 在分布式系统中,服务通常会部署在多个节点上,每个节点的负载不一定相同,当服务请求量较大时,可能会导致某些节点的负载过高,从而影响服务的性能和响应速度。负载均衡的作用就是解决这个问题
- 负载均衡是一种将请求分发到多个节点上的技术,它可以使每个节点的负载均衡,从而提高整个系统的性能和响应速度
负载均衡的实现方式有哪些?
答:
负载均衡可以有多种实现方式,其中常见的有如下几种:
- 客户端负载均衡:在客户端实现负载均衡,当客户端需要调用服务时,它会从多个服务提供者中选择一个最优的节点进行调用。这种方式通常需要使用负载均衡算法,例如:轮询、随机、一致性哈希 等
- 服务端负载均衡:在服务端实现负载均衡,当客户端请求到达服务端时,服务端会根据一定的规则选择一个最优的节点进行处理。这种方式通常需要使用负载均衡器,例如:
Nginx、HAProxy等
在Spring Cloud中,怎么实现服务的负载均衡?
答:
在 Spring Cloud 中,可以使用 Ribbon 实现服务的负载均衡。Ribbon 是一个客户端负载均衡器,它可以根据配置的负载均衡策略选择合适的服务实例进行调用
负载均衡有什么策略?
答:
- 轮询算法(
Round Robin):轮询算法是最简单的负载均衡算法之一。它按照顺序将请求依次分配给每个后端服务器,循环往复。当请求到达时,负载均衡器按照事先定义的顺序选择下一个服务器。轮询算法适用于后端服务器具有相同的处理能力和性能的场景 - 加权轮询算法(
Weighted Round Robin):加权轮询算法在轮询算法的基础上增加了权重的概念。每个后端服务器都被赋予一个权重值,权重值越高,被选中的概率就越大。这样可以根据服务器的处理能力和性能调整请求的分配比例,使得性能较高的服务器能够处理更多的请求 - 随机算法(
Random):随机算法将请求随机分配给后端服务器。每个后端服务器有相等的被选中概率,没有考虑服务器的实际负载情况。这种算法简单快速,适用于后端服务器性能相近且无需考虑请求处理能力的场景 - 加权随机算法(
Weighted Random):加权随机算法在随机算法的基础上引入了权重的概念。每个后端服务器被赋予一个权重值,权重值越高,被选中的概率就越大。这样可以根据服务器的处理能力和性能调整请求的分配比例。 - 最少连接算法(
Least Connection):最少连接算法会根据后端服务器当前的连接数来决定请求的分配。负载均衡器会选择当前连接数最少的服务器进行请求分配,以保证后端服务器的负载均衡。这种算法适用于后端服务器的处理能力不同或者请求的处理时间不同的场景 - 哈希算法(
Hash):哈希算法会根据请求的某个特定属性(如:客户端IP地址、请求URL等)计算哈希值,然后根据哈希值选择相应的后端服务器
常见的负载均衡器,比如 Ribbion、Gateway 等等,基本都支持这些负载均衡算法
什么是Ribbon?
答:
Ribbon 是 Spring Cloud Netfix 组件中一个基于 HTTP 和 TCP 的客户端负载均衡工具,它基于 Netfix Ribbon 实现。当多个服务提供者时,Ribbon 可以根据负载均衡的算法,比如:简单轮询、随机连接等,自动地选择需要调用的服务地址

Ribbon 和 nginx 的区别是什么?
答:
Nginx是服务器负载均衡,客户端所有请求都会交给Nginx,然后由Nginx实现转发请求。即:负载均衡是由服务端实现的Ribbon本地负载均衡,在调用微服务接口时候,会在注册中心上获取注册信息服务列表之后缓存到JVM本地,从而在本地实现RPC远程服务调用技术
远程调用
能说下HTTP和RPC的区别吗?
答:
严格来讲,HTTP 和 R 不是一个层面的东西:
HTTP(Hypertext Transfer Protocol:是一种应用层协议,主要强调的是网络通信RPC(Remote Procedure Call,远程过程调用)是一种用于分布式系统之间通信的协议,强调的是服务之间的远程调用
一些 RPC 框架比如 gRPC,底层传输协议其实也是用的 HTTP2,包括 Dubbo3,也兼容了 gRPC,使用了HTTP2 作为传输层的一层协议
| 区别 | HTTP | RPC |
|---|---|---|
| 定义 | HTTP(超文本传输协议)是一种用于传输超文本的协议。 | RPC(远程过程调用)是一种用于实现分布式系统中不同节点之间通信的协议。 |
| 通信方式 | 基于请求-响应模型,客户端发送请求,服务器返回响应。 | 基于方法调用模型,客户端调用远程方法并等待结果。 |
| 传输协议 | 基于TCP协议,可使用其他传输层协议如TLS/SSL进行安全加密。 | 可以使用多种传输协议,如TCP、UDP等。 |
| 数据格式 | 基于文本,常用的数据格式有JSON、XML等。 | 可以使用各种数据格式,如二进制、JSON、Protocol Buffers等。 |
| 接口定义 | 使用RESTful风格的接口进行定义,常用的方法有GET、POST、PUT、DELETE等。 | 使用IDL(接口定义语言)进行接口定义,如Protocol Buffers、Thrift等。 |
| 跨语言性 | 支持跨语言通信,可以使用HTTP作为通信协议实现不同语言之间的通信。 | 支持跨语言通信,可以使用IDL生成不同语言的客户端和服务端代码。 |
| 灵活性 | 更加灵活,适用于不同类型的应用场景,如Web开发、API调用等。 | 更加高效,适用于需要高性能和低延迟的分布式系统。 |
在微服务体系里:
- 基于
HTTP风格的远程调用通常使用框架如Feign来实现 - 基于
RPC的远程调用通常使用框架如Dubbo来实现
什么是Feign?
答:
Feign是一个声明式的Web服务客户端,它简化了使用基于HTTP的远程服务的开发Feign是在RestTemplate和Ribbon的基础上进一步封装,使用RestTemplate实现HTTP调用,使用Ribbon实现负载均衡Feign的主要特点和功能包括:- 声明式
API:Feign允许开发者使用简单的注解来定义和描述对远程服务的访问。通过使用注解,开发者可以轻松地指定URL、HTTP方法、请求参数、请求头等信息,使得远程调用变得非常直观和易于理解 - 集成负载均衡:
Feign集成了Ribbon负载均衡器,可以自动实现客户端的负载均衡。它可以根据服务名和可用实例进行动态路由,并分发请求到不同的服务实例上,提高系统的可用性和可伸缩性 - 容错机制:
Feign支持集成Hystrix容错框架,可以在调用远程服务时提供容错和断路器功能。当远程服务不可用或响应时间过长时,Feign可以快速失败并返回预设的响应结果,避免对整个系统造成级联故障
- 声明式
为什么Feign第一次调用耗时很长?
答:
- 主要原因是由于
Ribbon的懒加载机制,当第一次调用发生时,Feign会触发Ribbon的加载过程,包括从服务注册中心获取服务列表、建立连接池等操作,这个加载过程会增加首次调用的耗时
那怎么解决这个问题呢?
- 可以在应用启动时预热
Feign客户端,自动触发一次无关紧要的调用,来提前加载Ribbon和其他相关组件。这样就相当于提前进行了第一次调用
Fegin怎么做负载均衡?Ribbon?
答:
- 在
Feign中,负载均衡是通过集成Ribbon来实现的 Ribbon是Netflix开源的一个客户端负载均衡器,可以与Feign无缝集成,为Feign提供负载均衡的能力Ribbon在发起请求前,会从 “服务中心” 获取服务列表(清单),然后按照一定的负载均衡策略去发起请求,从而实现客户端的负载均衡。Ribbon本身也维护着 “服务提供者” 清单的有效性。如果它发现 “服务提供者” 不可用,则会重新从 “服务中心” 获取有效的 “服务提供者” 清单来及时更新
Feign 和 Dubbo 的区别?
答:

- 需要注意的是,
Feign和Dubbo并不是互斥的关系。实际上,Dubbo可以使用HTTP协议作为通信方式,而Feign也可以集成RPC协议进行远程调用。选择使用哪种远程调用方式取决于具体的业务需求和技术栈的选择
Feign 与 OpenFeign 的区别?
答:
-
Feign是Netfix公司写的,是Spring Cloud组件中的一个轻量级RESTful的HTTP服务客户端 -
Feign内置了Ribbon,用来做客户端负载均衡,去调用服务注册中心的服务 -
Feign的使用方式是:使用Feign的注解定义接口,调用这个接口,就可以调用服务注册中心的服务1
2
3
4<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency> -
OpenFeign是Spring Cloud自己研发的,在Feign的基础上支持了SpringMVC的注解,如@RequesMapping等等。Openfeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务1
2
3
4<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
Ribbon 和 Feign 调用服务的区别是什么?
答:
Ribbon:Ribbon是Netflix开源的基于HTTP和TCP等协议负载均衡组件Ribbon可以用来做客户端负载均衡,调用注册中心的服务Ribbon的使用需要代码里手动调用目标服务
Feign:Feign是Spring Cloud组件中的一个轻量级RESTful的HTTP服务客户端Feign内置了Ribbon,用来做客户端负载均衡,去调用服务注册中心的服务Feign的使用方式是:使用Feign的注解定义接口,调用这个接口,就可以调用服务注册中心的服务
服务容灾
什么是断路器?为什么需要断路器
答:
- 在微服务架构中,服务之间形成调用链路、链路中的任何一个服务提供者都可能面临着 相应超时、宕机等不可用的情况,在高并发的情况下,这种情况会随着并发量的上升恶化,形成 “雪崩效应”,而 断路器 正是用来解决这一个问题的组件
- 断路器 基本原理为:
- 正常情况下,断路器关闭,服务消费者正常请求微服务
- 一段事件内,失败率达到一定阈值(比如:50% 失败,或者失败了50次),断路器将断开,此时不再请求服务提供者,而是只是快速失败的方法(断路方法)
- 断路器打开一段时间,自动进入 “半开” 状态,此时,断路器可允许一个请求方法服务提供者,如果请求调用成功,则关闭断路器,否则继续保持断路器打开状态
- 断路器保证了局部发生的错误,不会扩展到整个系统,从而保证系统的即使出现局部问题也不会造成系统雪崩
什么是 Hystrix?
答:
Hystrix是 断路器 的落地实现,防雪崩利器,具有 服务降级、服务熔断、服务隔离、服务监控 等功能- 服务降级:对于查询操作,可以实现一个
fallback方法,当请求下游服务出现异常的时候,使用fallback方法返回的值,fallback方法的返回值一般是设置的默认值或者来自缓存 - 服务熔断:当请求下游服务失败数量超过一定比例(默认50%),断路器会切换到开路状态(
Open), 这时所有请求会直接失败而不会发送到下游服务。断路器保持在开路状态一段时间后(默认5秒),自动切换到半开路状态(HALF-OPEN)。这时会判断下一次请求的返回情况,如果请求成功,断路器切回闭路状态(CLOSED),否则重新切换到开路状态(OPEN) - 服务隔离:通过线程池(或信号量)来实现资源隔离,通常在使用的时候我们会根据调用的下游服务划分出多个线程池。例如:调用产品服务的
Command放入 A 线程池,调用账户服务的Command放入 B 线程池,这样做的主要优点是运行环境被隔离开了。这样就算调用服务的代码存在bug或者由于其他原因导致自己所在线程池被耗尽时,不会对系统的其他服务造成影响 - 服务监控:将服务执行结果和运行指标,请求数量成功数量等等这些状态进行收集,然后即可看到实时的监控数据
- 服务降级:对于查询操作,可以实现一个
微服务雪崩效应是什么?
答:
- 在微服务架构中,一个应用可能会有多个微服务组成,微服务之间的数据交互通过远程过程调用完成
- 假设:微服务 A 调用 微服务 B 和 微服务 C,微服务 B 和微服务 C 又调用其它的微服务**,如果在调用链路上某个微服务的调用响应时间过长或者不可用,对微服务 A 的调用就会占用越来越多的系统资源,进而引起系统崩溃,所谓的 “雪崩效应”**
- 一般,为了防止服务雪崩,可以采用这些措施:
- 服务高可用部署:确保各个服务都具备高可用性,通过冗余部署、故障转移等方式来减少单点故障的影响
- 限流和熔断:对服务之间的请求进行限流和熔断,以防止过多的请求涌入导致后端服务不可用
- 缓存和降级:合理使用缓存来减轻后端服务的负载压力,并在必要时进行服务降级,保证核心功能的可用性
服务降级,你了解吗?
答:
- 所谓降级,就是当某个服务熔断之后,服务器将不再被调用,此时客户端可以自己准备一个本地的
fallback回调返回一个缺省值。也可以理解为兜底方法 - 会发生降级的情况:
- 程序运行异常
- 超时
- 服务熔断触发服务降级
- 线程池、信号量打满也会导致服务降级
服务熔断,你了解吗?
答:
- 在复杂的分布式系统中,微服务之间的相互调用,有可能出现各种各样的原因导致服务的阻塞,在高并发场景下。服务的阻塞意味着线程的阻塞,导致当前线程不可用,服务器的线程全部阻塞,导致服务器崩溃,由于服务之间的调用关系是同步的,会对整个微服务系统造成服务雪崩
- 为了解决某个微服务的调用响应时间过长或者不可用进而占用越来越多的系统资源引起雪崩效应就需要进行服务熔断和服务降级处理
- 所谓的服务熔断指的是某个服务故障或异常一起类似显示世界中的 “保险丝” 当某个异常条件被触发就直接熔断整个服务,而不是一直等到此服务超时
- 服务熔断就是相当于我们电闸的保险丝,一旦发生服务雪崩的,就会熔断整个服务,通过维护一个自己的线程池,当线程达到阈值的时候就启动服务降级,如果其他请求继续访问就直接返回
fallback的默认值
服务限流,你了解吗?
答:
- 限流可以认为是服务降级的一种,限流就是限制系统的输入和输出流量以达到保护系统的目的
- 一般来说系统的吞吐量是可以被测算的,为了保证系统的稳固运行,一旦达到的需要限制的值,就需要限制流量并采取少量措施以完成限制流量的目的
- 比方:推迟解决,拒绝解决,或者部分拒绝解决等等。秒杀高并发等操作,严禁一窝蜂的一样拥挤,排队有序进行,一秒钟N个,有序进行
什么是降级熔断?为什么要进行熔断?
答:
- 熔断降级 是一种 分布式系统 的 保护机制,用于应对服务不稳定或不可用的情况
- 熔断 是指 当某个服务的调用失败次数或异常比例达到一定阈值时,自动切断对该服务的调用,让请求快速失败,避免影响其他服务而导致雪崩效应。熔断后,一段时间内不再调用该服务,直到服务恢复正常或者超过最大等待时间
- 降级 是指 当某个服务不可用或响应缓慢时,提供一个备用的处理逻辑,例如:返回默认值、缓存值、错误提示等,以保证服务的可用性和容错性。降级可以在熔断时触发,也可以在其他情况下触发,例如:系统负载过高、资源紧张等
- 熔断降级 的目的是 为了保护系统的稳定性和可用性,防止故障扩散和蔓延,提高用户体验和信任度
有哪些熔断降级的方案实现?
答:
| 框架 | 实现方案 | 特点 |
|---|---|---|
Spring cloud |
Netflix Hystrix |
提供线程隔离、服务降级、请求缓存、请求合并等功能;可与 Spring Cloud 其他组件无缝集成;官方已宣布停止维护,推荐使用Resilience4j 代替 |
Spring Cloud |
Resilience4j |
轻量级服务熔断库;提供类似于 Hystrix 的功能;具有更好的性能和更简洁的API;可与 Spring Cloud 其他组件无缝集成 |
Spring Cloud Alibaba |
Sentinel |
阿里巴巴开源的流量控制和熔断降级组件;提供实时监控、流量控制、熔断降级等功能;与 SpringCloud Alibaba生态系统紧密集成 |
Dubbo |
Dubbo 自带熔断降级机制 |
Dubbo 框架本身提供的熔断降级机制;可通过配置实现服务熔断和降级;与 Dubbo 的 RPC 框架紧密集成 |
Hystrix 怎么实现服务容错?
答:
-
尽管已经不再更新,但是
Hystrix是非常经典的服务容错开源库,它提供了多种机制来保护系统:- 服务熔断(
Circuit Breaker):Hystrix通过设置阈值来监控服务的错误率或响应时间。当错误率或响应时间超过预设的阈值时,熔断器将会打开,后续的请求将不再发送到实际的服务提供方,而是返回预设的默认值或错误信息。这样可以快速隔离故障服务,防止故障扩散,提高系统的稳定性和可用性 - 服务降级(
Fallback):当服务熔断打开时,Hystrix可以提供一个备用的降级方法或返回默认值,以保证系统继续正常运行。开发者可以定义降级逻辑,例如:返回缓存数据、执行简化的逻辑或调用其他可靠的服务,以提供有限但可用的功能 - 请求缓存(
Request Caching):Hystrix可以缓存对同一请求的响应结果,当下次请求相同的数据时,直接从缓存中获取,避免重复的网络请求,提高系统的性能和响应速度 - 请求合并(
Request Collapsing):Hystrix可以将多个并发的请求合并为一个批量请求,减少网络开销和资源占用。这对于一些高并发的场景可以有效地减少请求次数,提高系统的性能 - 实时监控和度量(
Real-time Monitoring and Metrics):Hystrix提供了实时监控和度量功能,可以对服务的执行情况进行监控和统计,包括错误率、响应时间、并发量等指标。通过监控数据,可以及时发现和解决服务故障或性能问题 - 线程池隔离(
Thread Pool Isolation):Hystrix将每个依赖服务的请求都放在独立的线程池中执行,避免因某个服务的故障导致整个系统的线程资源耗尽。通过线程池隔离,可以提高系统的稳定性和可用性
- 服务熔断(
-
服务降级示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
/**
*服务降级示例
**/
public class MyService {
public string myServiceMethod() {
// 实际的服务调用逻辑...
}
public String fallbackMethod() {
// 降级方法的逻辑,当服务调用失败时会执行此方法
// 可以返回默认值或执行其他备用逻辑 ...
}
}
Sentinel 是什么?它是如何工作的?
答:
Sentinel是阿里巴巴开源的一款分布式服务架构的轻量级流量控制产品,它主要以 流量 为 切入点,从流量控制、熔断降级、系统负载保护 等多个维度来帮助保护服务的稳定性Sentinel的基本概念包括 资源、规则 和 处理器- 资源 是
Sentinel的关键概念,可以是Java应用程序中的任何内容,例如:由应用程序提供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码 - 规则 是 围绕资源 的 实时状态 设定的,可以包括 流量控制规则、熔断降级规则 以及 系统保护规则,所有规则可以动态实时调整
- 资源 是
Sentinel的主要功能有:- 流量控制:
Sentinel可以控制每个服务或接口的并发请求数量,避免因为并发请求过多导致服务崩溃 - 熔断降级:当某个服务或接口不可用时,
Sentinel可以自动触发熔断机制,避免因单个服务或接口故障导致整个系统的瘫痪 - 系统负载保护:
Sentinel通过控制系统的整体负载,避免因系统过载导致服务性能下降甚至崩溃
- 流量控制:
Sentinel的工作原理主要分为三个步骤:- 数据采集:
Sentinel通过代理模式将流量数据采集到自身,并进行数据清洗和整合 - 策略计算:根据预先设定的规则和算法,
Sentinel计算并判断是否需要控制流量、熔断降级或保护系统负载 - 结果执行:根据计算结果,
Sentinel对流量进行控制、熔断降级或保护系统负载等操作,以保障服务的稳定性
- 数据采集:
- 总之,
Sentinel作为一款轻量级流量控制产品,适用于各种分布式服务架构,能够帮助您有效地保护服务的稳定性,提高系统的可用性和容错性
Sentinel 怎么实现限流的?
答:
-
Sentinel通过动态管理限流规则,根据定义的规则对请求进行限流控制。具体实现步骤如下:-
定义资源:在
Sentinel中,资源可以是URL、方法等,用于标识需要进行限流的请求1
2
3
4
5
6
7
8
9
10// 原本的业务方法.
public User getUserById(string id) {
throw new RuntimeException("getUserById command failed");
}
// blockHandler 函数,原方法调用被限流/降级/系统保护的时候调用
public User blockHandlerForGetUser(string id, BlockException ex) {
return new User("admin");
} -
配置限流规则:在
Sentinel的配置文件中定义资源的限流规则。规则可以包括 资源名称、限流阈值、限流模式(令牌桶或漏桶)等1
2
3
4
5
6
7
8
9
10
11
12private static void initFlowQpsRule(){
List<FlowRule> rules = new ArrayList<>();
FlowRule rule1=new FlowRule(); // 创建一个流控规则
rule1.setResource(resource); // 设置要限流的资源名称
rule1.setcount(20); // 设置最大 QPS 为20
rule1.setGrade(Ruleconstant.FLOW_GRADE_QPS); // 设置限流的维度为 QPS
rule1.setLimitApp("default"); // 设置限制的应用名称为"default"
rules.add(rule1); // 将规则添加到规则列表中
FlowRuleManager.loadRules(rules); // 加载规则列表,使限流规则生效
} -
监控流量:
Sentinel会监控每个资源的流量情况,包括请求的QPS(每秒请求数)、线程数、响应时间等
-
限流控制:当请求到达时,
Sentinel会根据资源的限流规则判断是否需要进行限流控制。如果请求超过了限流阈值,则可以进行限制、拒绝或进行其他降级处理
-
Sentinel 采用的什么限流算法?
答:
Sentinel使用 滑动窗口限流算法 来实现限流- 滑动窗口限流算法 是一种基于 时间窗口 的 限流算法。它将一段时间划分为多个时间窗口,并在每个时间窗口内统计请求的数量。通过动态地调整时间窗口的大小和滑动步长,可以更精确地控制请求的通过速率
Sentinel 怎么实现集群限流?
答:
Sentinel利用了Token Server和Token Client的机制来实现集群限流- 开启集群限流后,
Client向Token Server发送请求,Token Server根据配置的规则决定是否限流

Sentinel 与 Hystrix 的区别是什么?
答:
Hystrix和Sentinel都是微服务架构中实现熔断和限流的工具,它们有以下区别和特点:Hystrix是Netflix开源的熔断器实现,主要用于保护分布式系统中的服务调用- 它的主要特点:包括线程隔离、资源保护 和 降级处理。
Hystrix通过将每个服务调用放入独立的线程池中来实现线程隔离,防止一个服务的延迟或故障影响其他服务。它通过监控服务调用的成功率、延迟等指标来保护后端资源,并在失败的请求或响应超时达到一定阈值时自动打开熔断器,避免连锁故障。此外,Hystrix还提供了降级处理功能,可以在服务不可用或响应过慢时返回预定义的降级响应,保证系统的可用性
- 它的主要特点:包括线程隔离、资源保护 和 降级处理。
Sentinel是阿里巴巴开源的流量控制和系统保护工具,主要用于实现微服务架构中的 流量控制、熔断、降级 和 系统负载保护 等- 它的主要特点:包括 **实时监控 **和 动态规则配置、丰富的流量控制策略、细粒度的服务保护 以及 支持多种编程语言。
Sentinel可以实时监控服务的请求流量和各项指标,并提供实时的仪表盘和可视化的监控界面。它还支持通过API动态配置流量控制和熔断规则,可以根据实际情况进行动态调整 Sentinel提供了多种流量控制策略,包括基于QPS、线程数、并发连接数 等多种指标进行的流量控制。此外,Sentinel还支持对每个具体的服务接口进行 熔断、降级和限流 等操作,以实现精确的服务保护策略。同时,Sentinel不仅支持 Java,还支持 Go、Python 等多种编程语言,使其适用于跨语言的微服务架构
- 它的主要特点:包括 **实时监控 **和 动态规则配置、丰富的流量控制策略、细粒度的服务保护 以及 支持多种编程语言。
- 总的来说,
Hystrix注重线程隔离和资源保护,适用于保护单个服务调用。而Sentinel注重流量控制和动态规则配置,适用于对整个系统的流量进行监控和保护。根据实际需求和技术栈,可以选择适合的工具来实现微服务架构中的熔断和限流功能
服务网关
什么是服务网关?为什么需要服务网关?
答:
- 在分布式系统中,服务之间相互依赖,服务调用链路通常比较复杂,同时服务的部署和变化也非常频繁。服务网关的作用就是解决这个问题
- 服务网关 是 一种在服务调用链路上增加一个中间件的机制,它可以将多个服务的调用进行统一入口和出口的管理,从而简化服务的调用和管理。服务网关通常具有如下功能:
- 路由转发:服务网关可以通过路由转发的方式将请求分发到不同的服务实例上,从而实现负载均衡和流量控制的功能
- 安全防护:服务网关可以实现身份认证、授权、加密等安全防护功能,保障服务的安全性和可靠性
- 缓存加速:服务网关可以通过缓存加速的方式提高服务的响应速度和性能。
- 协议转换:服务网关可以实现协议的转换,例如:将
HTTP协议转换成HTTPS协议 - 日志监控:服务网关可以实现请求的日志监控和统计,方便开发者了解服务的使用情况和性能指标
Spring Cloud通过Zuul、Gateway等组件实现了服务网关,它可以带来以下好处:- 简化调用:通过服务网关,可以将多个服务的调用进行统一入口和出口的管理,从而简化服务的调用和管理
- 提高可靠性:通过服务网关,可以实现负载均衡、流量控制、安全防护等功能,从而提高服务的可靠性和稳定性
- 提高性能:通过服务网关,可以实现缓存加速、协议转换等功能,从而提高服务的响应速度和性能
- 简化配置:通过使用服务网关,可以简化服务的配置和管理,从而降低系统的维护成本
SpringCloud可以选择哪些API网关?
答:
- 使用
SpringCloud开发,可以采用以下的API网关选型:Netfix Zuul(已停止更新):Netfix Zuul是Spring Cloud早期版本中提供的默认API网关。它基于Servlet技术栈,可以进行路由、过滤、负载均衡等功能。然而,自2020年12月起,Netflix宣布停止对Zuul的维护,转而支持新的API网关项目Spring Cloud Gateway:Spring Cloud Gateway是Spring Cloud官方推荐的API网关,取代了Netflix Zuul。它基于非阻塞的WebFlux框架,充分利用了响应式编程的优势,并提供了 路由、过滤、断路器、限流 等特性。Spring Cloud Gateway还支持与Spring Cloud的其他组件集成,如;服务发现、负载均衡 等Kong:Kong是一个独立的、云原生的API网关和服务管理平台,可以与Spring Cloud集成。Kong基于Nginx,提供了强大的路由、认证、授权、监控和扩展能力。它支持多种插件和扩展,可满足不同的API管理需求APISIX:APISIX基于Nginx和Lua开发,它具有强大的路由、流量控制、插件扩展等功能。APISIX支持灵活的配置方式,可以根据需求进行动态路由、负载均衡和限流等操作
什么是限流算法,网关如何实现限流?
答:
- 限流算法是指用于限制单位时间内服务的请求数量的算法,目的是防止服务被过高的请求压力所击垮。常见的限流算法包括 计数器算法、滑动窗口算法、漏桶算法、令牌桶算法
- 网关如何实现限流:
- 利用限流算法插件 / 模块:网关可以集成限流算法插件/模块,通过配置相关参数(如:令牌桶大小、令牌生成速率等)来实现限流。例如:
Spring Cloud Gateway可以使用Redis的RateLimiter限流算法插件来实现限流 - 自定义限流逻辑:网关可以通过编程方式自定义实现限流逻辑。例如:在微服务架构中,可以在每个服务的网关层(如:
Zuul等)实现限流逻辑,或者使用限流SDK(如:Sentinel)对请求进行限流 - 利用云平台提供的限流功能:一些云平台提供了自动化的限流功能,例如:
AWS CloudWatch、Azure Application Insights等,网关可以利用这些云平台的功能来实现限流
- 利用限流算法插件 / 模块:网关可以集成限流算法插件/模块,通过配置相关参数(如:令牌桶大小、令牌生成速率等)来实现限流。例如:
什么是Spring Cloud Zuul?
答:
Zuul微服务网关是为Spring Cloud Netfix提供认证鉴权、监控、动态路由、限流、压力测试等服务的框架,可以和Eureka、Ribbon、Hystrix等组件配合使用- 主要功能:
- 认证鉴权:识别每个资源的验证要求,并拒绝那些与要求不符的请求
- 监控:追踪有意义的数据和统计结果,带来精确的生产视图
- 动态路由:动态地将请求路由到不同的后端集群
- 限流:为每一种负载类型分配对应容量,并弃用超出限定值的请求
- 压力测试:逐渐增加指向集群的流量,以了解性能
什么是Spring Cloud Gateway?
答:
Spring Cloud Gateway即Spring官方推出的一款API网关,该框架包含了Spring 5.0、SpringBoot 2.0、ProjectReactor,其中底层通信框架用的NettySpring Cloud Gateway在推出之初的时候,Netfix公司已经推出了类似功能的API网关框架Zuul,但Zuul有一个缺点是通信方式是阻塞的,虽然后来升级到了非阻塞式的Zuul2,但是由于Spring Cloud Gateway已经推出一段时间,同时自身也面临资料少、维护性较差的因素没有被广泛应用
Spring Cloud Gateway核心概念?
答:
- 在
Spring Cloud Gateway里,有三个关键组件:Route(路由):路由是Spring Cloud Gateway的基本构建块,它定义了请求的匹配规则和转发目标。通过配置路由,可以将请求映射到 后端的服务实例 或URL上。路由规则可以根据请求的路径、方法、请求头等条件进行匹配,并指定转发的目标URIPredicate(断言):断言用于匹配请求的条件,如果请求满足断言的条件,则会应用所配置的过滤器。Spring Cloud Gateway提供了多种内置的断言,如:Path(路径匹配)、Method(请求方法匹配)、Header(请求头匹配)等,同时也支持自定义断言Filter(过滤器):过滤器用于对请求进行处理和转换,可以修改请求、响应以及执行其他自定义逻辑。SpringCloud Gateway提供了多个内置的过滤器,如请求转发、请求重试、请求限流等。同时也支持自定义过滤器,可以根据需求编写自己的过滤器逻辑
- 又有两个比较重要的概念:
Gateway Handler(网关处理器):网关处理器是Spring Cloud Gateway的核心组件,负责将请求转发到匹配的路由上。它根据路由配置和断言条件进行路由匹配,选择合适的路由进行请求转发。网关处理器还会依次应用配置的过滤器链,对请求进行处理和转换Gateway Filter Chain(网关过滤器链):网关过滤器链由一系列过滤器组成,按照配置的顺序依次执行。每个过滤器可以在请求前、请求后或请求发生错误时进行处理。过滤器链的执行过程可以修改请求、响应以及执行其他自定义逻辑
为什么我们选择GateWay?
答:
- 因为
Zuul1.0已经进入了维护阶段,而且Gateway是SpringCloud团队研发的,值得信赖,Gateway是基于异步非阻塞模型上进行开发的,性能方面不需要担心。虽然Netfix早就发布了最新的Zuul 2.x,但Spring Cloud貌似没有整合计划。而且Netflix相关组件都宣布进入维护期,不知道前景如何 Spring Cloud GateWay有很多特性:- 基于
Spring Framework 5、Project Reactor和Spring Boot 2.0进行构建 - 动态路由:能够匹配任何请求属性
- 可以对路由指定
Predicate(断言)和Filter(过滤器) - 集成
Hystrix的断路器功能 - 集成
Spring Cloud服务发现功能 - 易于编写的
Predicate(断言)和Filter(过滤器) - 请求限流功能
- 支持路径重写
- 基于
Spring Cloud Gateway 与 Zuul 的区别?
答:
Zuul 1.x是一个基于阻塞I/O的API GatewayZuul 1.x基于Servlet 2.5使用阻塞架构,它不支持任何长连接(如:WebSocket)。Zuul的设计模式和Nginx较像每次I/O操作都是从工作线程中选择一个执行,请求线程被阻塞到工作线程完成,但是差别是Nginx用C++实现,Zuul用Java实现,而JVM本身会有第一次加载较慢的情况,使得Zuul的性能相对较差Zuul 2.x理念更先进,是基于Netty非阻塞和支持长连接的,但SpringCloud目前还没有整合。Zuul 2.x的性能较Zuul 1.x有较大提升Spring Cloud Gateway建立在Spring Framework 5、Project Reactor和Spring Boot 2之上,使用非阻塞APISpring Cloud Gateway还支持WebSocket,并且与Spring紧密集成拥有更好的开发体验
Spring Cloud GateWay工作流程?
答:

- 客户端向
Spring Cloud Gateway发出请求。然后在Gateway Handler Mapping中找到与请求相匹配的路由,将其发送到Gateway Web Handler Handler再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回- 过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前(
pre)或之后(post)执行业务逻辑 Filter在 “pre” 类型的过滤器可以做参数校验、权限校验、流量监控、日志输出、协议转换等,在 “post” 类型的过滤器中可以做响应内容、响应头的修改,日志的输出,流量监控等
核心逻辑:路由转发 + 执行过滤链
配置中心
什么是配置中心?为什么需要配置中心?
答:
- 在分布式系统中,服务通常需要配置一些参数和属性,例如 数据库连接、缓存配置、日志级别 等。这些配置可能会因为 环境、版本、部署 等原因而发生变化,手动管理和部署这些配置会变得非常困难和繁琐。配置中心的作用就是解决这个问题
- 配置中心 是一种 统一管理 和 动态刷新配置 的机制,它可以将配置信息集中存储在一个中心化的存储库中,例如:
Git、SVN、ZooKeeper等。当配置信息发生变化时,配置中心可以自动通知服务实例更新配置,并且支持动态刷新配置,无需重启服务实例。这样,就可以简化配置的管理和部署,提高系统的可维护性和稳定性 Spring Cloud通过Config Server实现了配置中心,它可以带来以下好处:- 集中管理:通过配置中心,可以将所有服务的配置信息集中管理,避免了手动管理的复杂性和错误
- 动态刷新:通过配置中心,可以实现配置的动态刷新,无需重启服务实例,从而提高系统的可维护性和稳定性
- 版本管理:通过配置中心,可以实现配置信息的版本管理,方便追踪和管理配置信息的变化
- 安全管理:通过配置中心,可以实现配置信息的安全管理,例如 加密、权限控制 等
- 简化配置:通过使用配置中心,可以简化配置的管理和部署,从而降低系统的维护成本
SpringCloud 可以选择哪些配置中心?
答:
和注册中心一样,SpringCloud 也支持对多种配置中心的集成。常见的配置中心选型包括:
Spring Cloud Config:官方推荐的配置中心,支持将配置文件存储在Git、SVN等版本控制系统中,并提供RESTful API进行访问和管理ZooKeeper:一个开源的分布式协调服务,可以用作配置中心。它具有 高可用性、一致性 和 通知机制 等特性Consul:另一个开源的分布式服务发现和配置管理工具,也可用作配置中心。支持多种配置文件格式,提供 健康检查、故障转移 和 动态变更 等功能Etcd:一个分布式键值存储系统,可用作配置中心。它使用基于Raft算法的一致性机制,提供分布式数据一致性保证Apolo:携程开源的配置中心,支持多种语言和框架。提供细粒度的配置权限管理、配置变更通知和灰度发布等高级特性,还有可视化的配置管理界面Nacos:阿里巴巴开源的服务发现、配置管理和服务管理平台,也可以作为配置中心使用。支持 服务注册与发现、动态配置管理、服务健康监测 和 动态DNS服务 等功能
什么是 Spring Cloud Config?
答:
-
Spring Cloud Config为分布式系统外部化配置提供了服务器端和客户端的支持,包括:Config Server和Config Client两部分。Config Server是一个可横向扩展、集中式的配置服务器,它用于集中管理应用程序各个环境下的配置,默认使用Git存储配置内容,因此可以很方便地实现对配置的版本控制 -
Config Client是Config Server的客户端,用于操作存储在Config Server中的配置属性 -
引入
Spring Cloud Config后的架构如下:
Nacos 配置中心的原理了解吗?
答:
- 配置中心,说白了就是一句话:配置信息的
CRUD - 具体的实现大概可以分成这么几个部分:
- 配置信息存储:
Nacos默认使用内嵌数据库Derby来存储配置信息,还可以采用MySQL等关系型数据库 - 注册配置信息:服务启动时,
Nacos Client会向Nacos Server注册自己的配置信息,这个注册过程就是把配置信息写入存储,并生成版本号 - 获取配置信息:服务运行期间,
Nacos Client通过API从Nacos Server获取配置信息。Server根据键查找对应的配置信息,并返回给Client - 监听配置变化:
Nacos Client可以通过注册监听器的方式,实现对配置信息的监听。当配置信息发生变化时Nacos Server会通知已注册的监听器,并触发相应的回调方法
- 配置信息存储:
Nacos 配置中心长轮询机制?
答:
- 一般来说客户端和服务端的交互分为两种:推(
Push)和拉(Pull),Nacos在Pull的基础上,采用了长轮询来进行配置的动态刷新 - 在长轮询模式下,客户端定时向服务端发起请求,检查配置信息是否发生变更。如果没有变更,服务端会 “
hold” 住这个请求,即:暂时不返回结果,直到配置发生变化或达到一定的超时时间- 如果客户端发起
Pull请求,服务端收到请求之后,先检查配置是否发生了变更: - 变更:返回变更配置
- 无变更:设置一个定时任务,延期 29.5s 执行,把当前的客户端长轮询连接加入
allSubs队列 - 在这 29.5s 内的配置变化
- 配置无变化:等待 29.5s 后触发自动检查机制,返回配置
- 配置变化:在 29.5s 内任意一个时刻配置变化,会触发一个事件机制,监听到该事件的任务会遍历
allSubs队列,找到发生变更的配置项对应的ClientLongPolling任务,将变更的数据通过该任务中的连接进行返回。相当于完成了一次PUSH操作 - 长轮询机制结合了
Pull机制和Push机制的优点
- 如果客户端发起
- 通过长轮询的方式,
Nacos客户端能够实时感知配置的变化,并及时获取最新的配置信息。同时,这种方式也降低了服务端的压力,避免了大量的长连接占用内存资源
链路跟踪
为什么要用微服务链路追踪?
答:
- 在微服务中,有的上下游可能有十几个服务,如果某一环出了问题,排查起来非常困难,所以,就需要进行链路追踪,来帮助排查问题
- 通过链路追踪,可以可视化地追踪请求从一个微服务到另一个微服务的调用情况。除了排查问题,链路追踪还可以帮助优化性能,可视化依赖关系、服务监控和告警
SpringCloud 可以选择哪些微服务链路追踪方案?
答:
Spring Cloud提供了多种选择的微服务链路追踪方案。以下是一些常用的方案:Zipkin:Zipkin是一个开源的分布式实时追踪系统,由Titter开发并贡献给开源社区。Spring Cloud Sleuth提供了与Zipkin的集成,可以通过在微服务中添加相应的依赖和配置,将追踪信息发送到Zipkin服务器,并通过Zipkin UI进行可视化展示和查询Jaeger:Jaeger是Uber开源的分布式追踪系统,也被纳入了CNCF(云原生计算基金会)的维护。通过使用Spring Cloud Sleuth和Jaeger客户端库,可以将追踪信息发送到Jaeger并进行可视化展示和查询SkyWalking:Apache SkyWalking是一款开源的应用性能监控与分析系统,提供了对Java、.NET和Node.js等语言的支持。它可以与Spring Cloud Sleuth集成,将追踪数据发送到SkyWalking服务器进行可视化展示和分析Pinpoint:Pinpoint是Naver开源的分布式应用性能监控系统,支持Java和.NET。它提供了与Spring Cloud Sleuth的集成,可以将追踪数据发送到Pinpoint服务器,并通过其UI进行分析和监控
- 这些方案都可以与
Spring Cloud sleuth进行集成,Spring Cloud sleuth是Spring Cloud中的一个组件,提供了在微服务调用时生成追踪信息的能力
分布式事务
什么情况下需要用到分布式事务?有哪些方案?
答:
- 分布式事务 是指在 多个网络节点 或 服务 之间进行 数据一致性处理 的情况。以下是一些可能需要使用分布式事务的场景:
- 微服务之间通过远程调用完成事务操作:当不同的微服务之间需要进行数据一致性保证时,就需要使用分布式事务
- 例如:一个电商微服务中的订单服务和库存服务需要通过远程调用进行事务操作,保证库存数量和订单信息的同步更新,避免出现超卖或缺货的情况
- 单体系统访问多个数据库实例:当一个系统需要访问多个数据库实例时,例如:用户信息和订单信息分别存储在两个不同的数据库实例中,需要通过分布式事务保证数据一致性,避免出现数据不一致的情况
- 多服务访问同一个数据库实例:当多个服务访问同一个数据库实例时,例如:订单微服务和库存微服务都需要访问同一个数据库,也可能需要使用分布式事务。因为跨
JVM进程的多个服务同时持有不同的数据库连接进行数据库操作,可能会出现数据不一致的情况
- 微服务之间通过远程调用完成事务操作:当不同的微服务之间需要进行数据一致性保证时,就需要使用分布式事务
- 在这些场景下,我们需要使用分布式事务来保证数据的一致性。常用的分布式事务方案包括 两阶段提交(
2PC)、三阶段提交(3PC)、TCC、Saga、本地消息表 等。其中,两阶段提交 和 三阶段提交 都是基于锁机制实现的,而TCC、Saga和 本地消息表 则是基于业务逻辑实现的。选择哪种方案取决于业务需求、系统复杂性和性能等多个因素
什么是Seata?谈谈你对Seata的理解?
答:
Seata是一款开源的分布式事务解决方案,它主要用于解决在分布式系统中全局事务的一致性问题- 在分布式系统中,由于一次业务操作需要跨多个数据源或进行远程调用,往往会产生分布式事务问题。例如:在一个电商微服务系统中,订单服务和库存服务需要协同工作,如果订单服务已经创建成功,但库存服务因为某些原因失败了,就会导致数据不一致的问题。
Seata就是为解决这个问题而产生的 Seata的主要特点:无侵入以及高性能。它对业务无侵入,可以减少技术架构上的微服务化所带来的分布式事务问题对业务的侵入,同时高性能则是减少分布式事务解决方案所带来的性能消耗- 在
Seata的事务处理中主要有三个重要的角色:事务的协调者(TC)、事务的管理者(TM)和事务的作业管理器(RM)- 事务协调者(
TC)主要负责管理全局的分支事务的状态,用于全局性事务的提交和回滚。它会对所有的分支事务进行注册,然后根据各个分支事务的状态来决定是否提交或者回滚全局事务 - 事务管理者(
TM)用于开启、提交或回滚事务。它会根据业务逻辑来决定何时开启一个新的事务,并在适当的时候提交或回滚该事务 - 资源管理器(
RM)用于分支事务上的资源管理,向TC注册分支事务,上报分支事务的状态,接收TC的命令来提交或者回滚分支事务
- 事务协调者(
Seata 支持哪些模式的分布式事务?
答:
-
Seata以下几种模式的分布式事务:-
AT(Atomikos)模式:AT模式是Seata默认支持的模式,也是最常用的模式之一。在AT模式下,Seata通过在业务代码中嵌入事务上下文,实现对分布式事务的管理。Seata会拦截并解析业务代码中的SQL语句,通过对数据库连接进行拦截和代理,实现事务的管理和协调
-
TCC(Try-Confirm-Cancel)模式:TCC模式是一种基于补偿机制的分布式事务模式。在TCC模式中,业务逻辑需要实现Try、Confirm和Cancel三个阶段的操作。Seata通过调用业务代码中的Try、Confirm和Cancel方法,并在每个阶段记录相关的操作日志,来实现分布式事务的一致性
-
SAGA模式:SAGA模式是一种基于事件驱动的分布式事务模式。在SAGA模式中,每个服务都可以发布和订阅事件,通过事件的传递和处理来实现分布式事务的一致性。Seata提供了与SAGA模式兼容的Saga框架,用于管理和协调分布式事务的各个阶段
-
XA模式:XA模式是一种基于两阶段提交(Two-Phase Commit)协议的分布式事务模式。在XA模式中,Seata通过与数据库的XA事务协议进行交互,实现对分布式事务的管理和协调。XA模式需要数据库本身支持XA事务并且需要在应用程序中配置相应的XA数据源
-
了解Seata的实现原理吗?
答:

Seata的实现原理主要包括三个核心组件:事务协调器(Transaction Coordinator)、事务管理器(Transaction Manager)和 资源管理器(Resource Manager)- 事务协调器(
Transaction Coordinator):事务协调器负责协调和管理分布式事务的整个过程。它接收事务的开始和结束请求,并根据事务的状态进行协调和处理。事务协调器还负责记录和管理事务的全局事务ID(Global Transaction ID)和 分支事务ID(Branch Transaction ID) - 事务管理器(
Transaction Manager):事务管理器负责全局事务的管理和控制。它协调各个分支事务的提交或回滚,并保证分布式事务的一致性和隔离性。事务管理器还负责与事务协调器进行通信,并将事务的状态变更进行持久化 - 资源管理器(
Resource Manager):资源管理器负责管理和控制各个参与者(Participant)的事务操作。它与事务管理器进行通信,并根据事务管理器的指令执行相应的事务操作,包括提交和回滚
- 事务协调器(
Seata的实现原理基于两阶段提交(Two-Phase Commit)协议,具体的机制如下:- 一阶段:在事务提交的过程中,首先进行预提交阶段。事务协调器向各个资源管理器发送预提交请求,资源管理器执行相应的事务操作并返回执行结果。在此阶段,业务数据和回滚日志记录在同一个本地事务中提交,并释放本地锁和连接资源
- 二阶段:在预提交阶段成功后,进入真正的提交阶段。此阶段主要包括 提交异步化 和 回滚反向补偿 两个步骤:
- 提交异步化:事务协调器发出真正的提交请求,各个资源管理器执行最终的提交操作。这个阶段的操作是非常快速的,以确保事务的提交效率
- 回滚反向补偿:如果在预提交阶段中有任何一个资源管理器返回失败结果,事务协调器发出回滚请求,各个资源管理器执行回滚操作,利用一阶段的回滚日志进行反向补偿
Seata的事务执行流程是什么样的?
答:
Seata 事务的执行流程可以简要概括为以下几个步骤:
- 事务发起方(
Transaction Starter)发起全局事务:事务发起方是指发起分布式事务的应用程序或服务。它向Seata的事务协调器发送全局事务的开始请求,生成全局事务ID(Global Transaction ID) - 事务协调器创建全局事务记录:事务协调器接收到全局事务的开始请求后,会为该事务创建相应的全局事务记录,并生成 分支事务
ID(Branch Transaction ID) - 分支事务注册:事务发起方将 全局事务
ID和 分支事务ID发送给各个参与者(Participant),即:资源管理器。参与者将分支事务ID注册到本地事务管理器,并将事务的执行结果反馈给事务协调器 - 执行业务逻辑:在分布式事务的上下文中,各个参与者执行各自的本地事务,即执行业务逻辑和数据库操作
- 预提交阶段:事务发起方向事务协调器发送预提交请求,事务协调器将预提交请求发送给各个参与者
- 执行本地事务确认:参与者接收到预提交请求后,执行本地事务的确认操作,并将本地事务的执行结果反馈给事务协调器
- 全局事务提交或回滚:事务协调器根据参与者反馈的结果进行判断,如果所有参与者的本地事务都执行成功,事务协调器发送真正的提交请求给参与者,参与者执行最终的提交操作;如果有任何一个参与者的本地事务执行失败,事务协调器发送回滚请求给参与者,参与者执行回滚操作
- 完成全局事务:事务协调器接收到参与者的提交或回滚结果后,根据结果更新全局事务的状态,并通知事务发起方全局事务的最终结果
Seata的事务回滚是怎么实现的?
答:
Seata的事务回滚是通过回滚日志实现的。每个参与者在执行本地事务期间生成回滚日志,记录了对数据的修改操作- 当需要回滚事务时,事务协调器向参与者发送回滚请求,参与者根据回滚日志中的信息执行撤销操作,将数据恢复到事务开始前的状态
- 回滚日志的管理和存储是
Seata的核心机制,可以选择将日志存储在不同的介质中。通过回滚日志的持久化和恢复,Seata确保了事务的一致性和恢复性
其他
你们的服务怎么做监控和告警?
答:
- 使用
Prometheus和Grafana来实现整个微服务集群的监控和告警:Prometheus:Prometheus是一个开源的监控系统,具有灵活的数据模型和强大的查询语言,能够收集和存储时间序列数据。它可以通过HTTP协议定期拉取微服务的指标数据,并提供可扩展的存储和查询功能Grafana:Grafana是一个开源的可视化仪表板工具,可以与Prometheus结合使用,创建实时和历史数据的仪表板。Grafana提供了丰富的图表和可视化选项,可以帮助用户更好地理解和分析微服务的性能和状态
你们的服务怎么做日志收集?
答:
- 日志收集有很多种方案,我们用的是
ELK:Elasticsearch:Elasticsearch是一个分布式搜索和分析引擎,用于存储和索引大量的日志数据。它提供了快速的搜索和聚合功能,可以高效地处理大规模的日志数据Logstash:Logstash是一个用于收集、过滤和转发日志数据的工具。它可以从各种来源(如:文件、网络、消息队列等)收集日志数据,并对数据进行处理和转换,然后将其发送到Elasticsearch进行存储和索引Kibana:Kibana是一个用于日志数据可视化和分析的工具。它提供了丰富的图表、仪表盘和搜索功能,可以帮助用户实时监控和分析日志数据,发现潜在的问题和趋势
- 简单说,这三者里
Elasticsearch提供数据存储和检索能力,Logstash负责将日志收集到ES,Kibana负责日志数据的可视化分析- 在每个微服务中配置日志输出:将微服务的日志输出到标准输出(
stdout)或日志文件 - 使用
Logstash收集日志:配置Logstash收集器,通过配置输入插件(如文件输入、网络输入等)监听微服务的日志输出,并进行过滤和处理 - 将日志数据发送到
Elasticsearch:配置Logstash的输出插件,将经过处理的日志数据发送到Elasticsearch进行存储和索引 - 使用
Kibana进行可视化和分析:通过Kibana连接到Elasticsearch,创建仪表盘、图表和搜索查询,实时监控和分析微服务的日志数据
- 在每个微服务中配置日志输出:将微服务的日志输出到标准输出(
- 除了应用最广泛的
ELK,还有一些其它的方案比如Fluentd、Graylog、Loki、Filebeat,一些云厂商也提供了付费方案,比如阿里云的sls
说下你对DDD的理解?
答:
- 领域驱动设计(
DDD)是一种软件开发方法,旨在帮助开发人员更好地理解和设计复杂的软件系统。它的主要目的是让开发人员和领域专家能够更好地协作,以满足业务需求 DDD的关键概念包括领域模型和限界上下文。领域模型描述了业务领域的规则和逻辑,让开发人员更好地理解业务需求;限界上下文则定义了一个特定的业务领域内的模型和代码,使其可以独立于其他上下文进行开发和维护- 此外,
DDD还强调了分层架构和事件溯源的重要性。分层架构将系统划分为不同层次,各层次有不同的职责和角色,便于开发和维护;事件溯源则是一种存储和处理业务事件的技术,支持审计、合规和业务分析等需求 - 总之,
DDD是一种设计和开发复杂软件系统的 方法,它通过建立领域模型、分层架构、限界上下文和事件溯源等技术,使得开发人员能够更好地理解和满足业务需求





