微服务常见面试题总结
本文作者:夏日。
1 概念
1.1 你对微服务是怎么理解的
微服务是一种软件架构风格,将应用程序拆分为一组小型、自治的服务。每个服务都专注于一个特定的业务功能,并通过轻量级通信机制(如 HTTP RESTful API)进行通信。微服务架构的核心理念是将大型单体应用拆解为更小、更可管理的组件,每个组件都可以独立开发、部署和扩展。
微服务与单体服务的区别在于规模和部署方式。微服务将应用程序拆分为更小的、自治的服务单元,每个服务都有自己的数据库和代码库,可以独立开发、测试、部署和扩展,带来了更大的灵活性、可维护性、可扩展性和容错性。
1.2 微服务带来了哪些挑战?
- 系统复杂性增加:一个服务拆成了多个服务,整体系统的复杂性增加,需要处理服务之间的通信、部署、监控和维护等方面的复杂性。
- 服务间通信开销:微服务之间通过网络进行通信,传递数据需要额外的网络开销和序列化开销,可能导致性能瓶颈和增加系统延迟。
- 数据一致性和事务管理:每个微服务都有自己的数据存储,数据一致性和跨服务的事务管理变得更加复杂,需要额外解决分布式事务和数据同步的问题。
- 部署和运维复杂性:微服务架构涉及多个独立部署的服务,对于部署、监控和容错机制的要求更高,需要建立适当的部署管道和自动化工具,以简化部署和运维过程。
- 团队沟通和协作成本:每个微服务都由专门的团队负责,可能增加团队之间的沟通和协作成本。需要有效的沟通渠道和协作机制,确保服务之间的协调和一致性。
- 服务治理和版本管理:随着微服务数量的增加,服务的治理和版本管理变得更加复杂。需要考虑服务的注册发现、负载均衡、监控和故障处理等方面,以确保整个系统的可靠性和稳定性。
- 分布式系统的复杂性:微服务架构涉及构建和管理分布式系统,而分布式系统本身具有一些固有的挑战,如网络延迟、分布式一致性和容错性。
1.3 说下微服务有哪些组件?🔥
-
注册中心:用于服务的注册与发现,管理微服务的地址信息。
- Spring Cloud Netflix:Eureka、Consul
- Spring Cloud Alibaba:Nacos
-
配置中心:用于集中管理微服务的配置信息,可以动态修改配置而不需要重启服务(
@RefreshScope
)。- Spring Cloud Netflix:Spring Cloud Config
- Spring Cloud Alibaba:Nacos Config
-
远程调用:用于在不同的微服务之间进行通信和协作。
- RESTful API:如 RestTemplate、Feign
- RPC(远程过程调用):如 Dubbo、gRPC
-
API 网关:作为微服务架构的入口,统一暴露服务,并提供路由、负载均衡、安全认证等功能。
- Spring Cloud Netflix:Zuul、Gateway
- Spring Cloud Alibaba:Gateway、Apisix 等
-
分布式事务:保证跨多个微服务的一致性和原子性操作。
- Spring Cloud Alibaba:Seata
-
熔断器:用于防止微服务之间的故障扩散,提高系统的容错能力。
- Spring Cloud Netflix:Hystrix
- Spring Cloud Alibaba:Sentinel、Resilience4j
-
限流和降级:用于防止微服务过载,对请求进行限制和降级处理。
- Spring Cloud Netflix:Hystrix
- Spring Cloud Alibaba:Sentinel
-
分布式追踪和监控:用于跟踪和监控微服务的请求流程和性能指标。
- Spring Cloud Netflix:Spring Cloud Sleuth + Zipkin
- Spring Cloud Alibaba:SkyWalking、Sentinel Dashboard
2 注册中心
2.1 注册中心有什么用?🔥
- 服务注册:各个服务在启动时向注册中心注册自己的网络地址、服务实例信息和其他相关元数据。这样,其他服务就可以通过注册中心获取到当前可用的服务列表。
- 服务发现:客户端通过向注册中心查询特定服务的注册信息,获得可用的服务实例列表。这样客户端就可以根据需要选择合适的服务进行调用,实现了服务间的解耦。
- 负载均衡:注册中心可以对同一服务的多个实例进行负载均衡,将请求分发到不同的实例上,提高整体的系统性能和可用性。
- 故障恢复:注册中心能够监测和检测服务的状态,当服务实例发生故障或下线时,可以及时更新注册信息,从而保证服务能够正常工作。
- 服务治理:通过注册中心可以进行服务的配置管理、动态扩缩容、服务路由、灰度发布等操作,实现对服务的动态管理和控制。
2.2 SpringCloud可以选择哪些注册中心?
SpringCloud 可以与多种注册中心进行集成,常见的注册中心包括:
- Eureka:Eureka 是 Netflix 开源的服务发现框架,具有高可用、弹性、可扩展等特点,并与 Spring Cloud 集成良好。
- Consul:Consul 是一种分布式服务发现和配置管理系统,由 HashiCorp 开发。它提供了服务注册、服务发现、健康检查、键值存储等功能,并支持多数据中心部署。
- ZooKeeper:ZooKeeper 是 Apache 基金会开源的分布式协调服务,可以用作服务注册中心。它具有高可用、一致性、可靠性等特点。
- Nacos:Nacos 是阿里巴巴开源的一个动态服务发现、配置管理和服务管理平台。它提供了服务注册和发现、配置管理、动态 DNS 服务等功能。
- etcd:etcd 是 CoreOS 开源的一种分布式键值存储系统,可以被用作服务注册中心。它具有高可用、强一致性、分布式复制等特性。
2.3 说下Eureka 和 Nacos的区别?🔥
我的项目采用的 nacos 作为注册中心,选择 nacos 的一个重要原因就是它也支持配置中心。
- 共同点:Nacos 与 eureka 都支持服务注册和服务发现,都支持服务提供者利用心跳监测的方式做健康检测
Nacos 与 Eureka 的区别
- Nacos 支持服务端主动检测提供者状态:对于临时实例和 Eureka 一样采用心跳监测,而非临时实例 Nacos 会主动检测服务提供者状态,默认为临时实例。
- 临时实例心跳不正常会被剔除,非临时实例则不会被剔除。
- Nacos 在服务列表变更时可以主动推送消息给服务消费者,服务列表更新更及时
- Nacos 集群默认采用 AP 方式,当集群中存在非临时实例时,采用 CP 模式;Eureka 采用 AP 方式
总的来说,Eureka 着重于服务注册与发现的简单易用,适用于基于 Spring Cloud 的微服务架构;Nacos 结合了服务注册与发现、配置管理等多种功能,适用于云原生应用场景;ZooKeeper 提供了强一致性和分布式协调的功能,适用于更复杂的分布式系统。
2.4 Eureka实现原理了解吗?
- 服务注册与发现: 当一个服务实例启动时,它会向 Eureka Server 发送注册请求,将自己的信息注册到注册中心。Eureka Server 会将这些信息保存在内存中,并提供 REST 接口供其他服务查询。服务消费者可以通过查询服务实例列表来获取可用的服务提供者实例,从而实现服务的发现。
- 服务健康检查: Eureka 通过心跳机制来检测服务实例的健康状态。服务实例会定期向 Eureka Server 发送心跳,也就是续约,以表明自己的存活状态。如果 Eureka Server 在一定时间内没有收到某个服务实例的心跳,则会将其标记为不可用,并从服务列表中移除,下线实例。
- 服务负载均衡: Eureka 客户端在调用其他服务时,会从本地缓存中获取服务的注册信息。如果缓存中没有对应的信息,则会向 Eureka Server 发送查询请求。Eureka Server 会返回一个可用的服务实例列表给客户端,客户端可以使用负载均衡算法选择其中一个进行调用。
3 配置中心
3.1 为什么微服务需要配置中心?🔥
-
集中管理配置: 每个微服务都需要一些配置信息,如数据库连接信息、端口号等。使用配置中心可以将这些配置信息集中管理,方便统一配置和修改。
-
动态更新配置: 配置中心可以实现配置的动态更新,当配置信息发生变化时,自动通知到各个微服务实例,无需重启服务即可生效。
-
环境隔离和配置版本管理: 微服务通常会部署在不同的环境中,如开发、测试、生产环境等,每个环境可能需要不同的配置信息,配置中心支持配置版本管理。
-
动态路由和灰度发布: 部分配置信息可能影响服务的路由策略或流量控制,如限流配置、路由规则等。通过配置中心,可以实现动态路由和灰度发布功能,根据配置信息的变化调整服务的流量分发策略。
-
安全性和敏感信息加密: 部分配置信息可能包含敏感信息,如密码、密钥等。配置中心可以提供安全的配置管理机制,支持敏感信息的加密存储和访问控制,确保配置信息的安全性。
3.2 SpringCloud可以选择哪些配置中心?
- Spring Cloud Config:官方推荐的配置中心,支持将配置文件存储在 Git、SVN 等版本控制系统中,并提供 RESTful API 进行访问和管理。
- Nacos: Alibaba 开源的服务注册与配置中心,支持服务注册与发现、配置管理、动态路由等功能。Nacos 提供了配置中心的功能,可以将配置信息存储在 Nacos 的配置管理模块中,并通过 Nacos 客户端来访问配置信息。
3.3 Nacos配置中心的原理了解吗?
-
配置信息存储:Nacos 默认使用内嵌数据库 Derby 来存储配置信息,还可以采用 MySQL 数据库。
-
注册配置信息:服务启动时,Nacos Client 会向 Nacos Server 注册自己的配置信息,这个注册过程就是把配置信息写入存储,并生成版本号。
-
获取配置信息:服务运行期间,Nacos Client 通过 API 从 Nacos Server 获取配置信息。Server 根据键查找对应的配置信息,并返回给 Client。
-
监听配置变化:Nacos Client 可以通过注册监听器的方式,实现对配置信息的监听。当配置信息发生变化时,Nacos Server 会通知已注册的监听器,并触发相应的回调方法。
3.4 Nacos配置中心长轮询机制?
在长轮询模式下,客户端定时向服务端发起请求,检查配置信息是否发生变更。如果没有变更,服务端会"hold"住这个请求,即暂时不返回结果,直到配置发生变化或达到一定的超时时间。
-
客户端向Nacos配置中心发送一个长轮询请求,请求中包含客户端的配置信息和一个超时时间。
-
Nacos配置中心接收到请求后,检查当前的配置信息是否有变更。如果没有变更,Nacos会将该请求挂起,等待配置变更或达到超时时间。
-
当有配置变更时,Nacos会立即响应该挂起的请求,并返回新的配置信息给客户端。
-
如果超时时间到达而且没有配置变更,Nacos会返回一个空响应给客户端,客户端收到空响应后会立即发送新的长轮询请求。
通过长轮询机制,客户端可以实时地获取到配置变更,而不需要频繁地向Nacos配置中心发送请求。这样可以减少网络开销和服务器负载,提高配置更新的实时性和效率。
4 远程调用
4.1 能说下HTTP和RPC的区别吗?🔥
- | 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 是应用层协议,用于传输超文本数据,基于请求-响应模型,常用于 Web 开发、API 调用等场景;RPC 是远程过程调用协议,用于实现分布式系统中不同节点之间的通信,基于方法调用模型,常用于构建面向服务的微服务架构。
4.2 Feign和Dubbo的区别?🔥
- | Feign | Dubbo |
---|---|---|
定义 | Feign 是一个声明式的 Web 服务客户端,用于简化 HTTP API 的调用。 | Dubbo 是一个分布式服务框架,用于构建面向服务的微服务架构。 |
通信方式 | 基于 HTTP 协议,使用 RESTful 风格的接口进行定义和调用。 | 基于 RPC 协议,支持多种序列化协议如 gRPC、Hessian 等。 |
服务发现 | 通常结合服务注册中心(如 Eureka、Consul)进行服务发现和负载均衡。 | 通过 ZooKeeper、Nacos 等进行服务注册和发现,并提供负载均衡功能。 |
服务治理 | 不直接提供服务治理功能,需要结合其他组件或框架进行服务治理。 | 提供服务注册与发现、负载均衡、容错机制、服务降级等服务治理功能。 |
跨语言性 | 支持跨语言通信,可以使用 HTTP 作为通信协议实现不同语言之间的通信。 | 支持跨语言通信,通过 Dubbo 的 IDL 生成不同语言的客户端和服务端代码。 |
生态系统 | 集成了 Spring Cloud 生态系统,与 Spring Boot 无缝集成。 | 拥有完整的生态系统,包括注册中心、配置中心、监控中心等组件。 |
适用场景 | 适用于构建 RESTful 风格的微服务架构,特别适合基于 HTTP 的微服务调用。 | 适用于构建面向服务的微服务架构,提供更全面的服务治理和容错机制。 |
4.3 服务端负载均衡器和客户端负载均衡器的区别?🔥
-
服务端负载均衡器:在服务端负载均衡模式下,负载均衡器位于服务端,用于分发客户端的请求到后端的多个服务实例。
- 服务端负载均衡器通常是作为服务网关或反向代理的一部分存在,负责接收客户端请求并根据负载均衡策略将请求转发到后端的不同服务实例。
- 典型的服务端负载均衡器包括Nginx、HAProxy等。
-
客户端负载均衡器:在客户端负载均衡模式下,负载均衡器位于客户端,用于选择合适的服务实例来发送请求。
- 客户端负载均衡器通常集成在客户端的代码中,根据负载均衡策略从服务发现中心获取服务实例列表,并根据负载情况选择合适的服务实例发送请求。
- 客户端负载均衡器可以更灵活地根据实际的业务需求选择服务实例,并且减轻了服务端的压力,提高了系统的可扩展性。
4.4 说一下Feign?🔥
Feign 是一个声明式的 Web 服务客户端,它简化了使用基于 HTTP 的远程服务的开发。
- 声明式 API:Feign 允许开发者使用简单的注解来定义和描述对远程服务的访问。通过使用注解,开发者可以轻松地指定 URL、HTTP 方法、请求参数、请求头等信息,使得远程调用变得非常直观和易于理解。
- 集成负载均衡:Feign 集成了 Ribbon 负载均衡器,可以自动实现客户端的负载均衡。它可以根据服务名和可用实例进行动态路由,并分发请求到不同的服务实例上,提高系统的可用性和可伸缩性。
- 容错机制:Feign 支持集成了 Hystrix ,可以在调用远程服务时提供容错和断路器功能。当远程服务不可用或响应时间过长时,Feign 可以快速失败并返回预设的响应结果,避免对整个系统造成级联故障。
4.5 为什么Feign第一次调用耗时很长?
主要原因是由于 Ribbon 的懒加载机制,当第一次调用发生时,Feign 会触发 Ribbon 的加载过程,包括从服务注册中心获取服务列表、建立连接池等操作,这个加载过程会增加首次调用的耗时。
那怎么解决这个问题呢?
可以在应用启动时预热 Feign 客户端,自动触发一次无关紧要的调用,来提前加载 Ribbon 和其他相关组件。这样,就相当于提前进行了第一次调用。
4.6 Feign怎么实现认证传递?
比较常见的一个做法是,使用拦截器传递认证信息。可以通过实现RequestInterceptor
接口来定义拦截器,在拦截器里,把认证信息添加到请求头中,然后将其注册到 Feign 的配置中。
4.7 Fegin怎么做负载均衡?
Feign 默认使用 Ribbon 来实现负载均衡。
Ribbon 是 Netflix 开源的一个客户端负载均衡器,可以与 Feign 无缝集成,为 Feign 提供负载均衡的能力。Ribbon 通过从服务注册中心获取可用服务列表,并通过负载均衡算法选择合适的服务实例进行请求转发,实现客户端的负载均衡。
只需要在使用 Feign 时,指定服务的名称即可,Feign 会自动利用 Ribbon 来进行负载均衡的选择。
4.8 说说有哪些负载均衡算法?🔥
-
轮询(Round Robin):按照顺序将请求依次分配给每个服务实例。轮询算法简单高效,适用于负载均衡场景,但不考虑服务实例的实际负载情况。
-
加权轮询(Weighted Round Robin):在轮询的基础上,为每个服务实例分配一个权重值,根据权重值来决定每个实例接收到的请求数量。权重值越高的实例,接收到的请求越多。
-
随机(Random):随机选择一个服务实例来处理请求,每个实例被选中的概率相等。随机算法简单,但无法保证请求的均衡分配。
-
加权随机(Weighted Random):在随机的基础上,为每个服务实例分配一个权重值,根据权重值来决定每个实例被选中的概率。权重值越高的实例,被选中的概率越大。
-
最小连接数(Least Connections):根据当前连接数来选择服务实例,选择连接数最少的实例进行请求转发。这种算法适用于长连接的场景,能够有效地降低服务实例的负载。
-
IP Hash:根据客户端的 IP 地址计算哈希值,然后将请求发送到相应的服务实例。这种算法保证相同 IP 的请求都会被发送到同一个服务实例,适用于需要保持会话一致性的场景。
-
一致性哈希(Consistent Hashing):根据请求的内容或者哈希函数将请求分配到一致性哈希环上的某个节点上,这样可以保证相同的请求总是被分配到同一个节点上。一致性哈希算法适用于需要在服务实例动态增减时保持请求的一致性分配的场景。
5 服务容灾
5.1 什么是服务雪崩?🔥
在微服务中,假如一个或者多个服务出现故障,如果这时候,依赖的服务还在不断发起请求,或者重试,那么这些请求的压力会不断在下游堆积,导致下游服务的负载急剧增加。不断累计之下,可能会导致故障的进一步加剧,可能会导致整个系统崩溃,这就叫服务雪崩。
一般,为了防止服务雪崩,可以采用这些措施:
- 服务高可用部署:确保各个服务都具备高可用性,通过冗余部署、故障转移等方式来减少单点故障的影响。
- 限流和熔断:对服务之间的请求进行限流和熔断,以防止过多的请求涌入导致后端服务不可用。
- 缓存和降级:合理使用缓存来减轻后端服务的负载压力,并在必要时进行服务降级,保证核心功能的可用性。
5.2 什么是服务熔断?什么是服务降级?🔥
服务熔断是一种容错机制。当某个服务失败次数达到一定阈值时,熔断器会打开,后续的请求将不再访问这个服务,而是直接返回。经过一段时间后,熔断器会尝试半开状态,允许有限的请求尝试访问服务,如果服务能够正常响应,则关闭熔断器,否则继续保持打开状态。
服务降级是指当系统出现异常或压力过大时,为了保证核心功能的正常运行,系统会主动关闭或降低一些非核心功能的可用性或服务质量。服务降级的目的是为了释放系统资源,保证核心功能的稳定运行,避免整个系统雪崩。
区别:服务熔断主要是针对服务间的调用关系,当某个服务出现故障或超时时,中断对该服务的调用,防止故障扩散和影响其他服务;而服务降级主要是针对系统自身的功能,当系统面临高负载或故障时,暂时关闭一些不重要的功能,保证系统的核心功能能够正常运行。
5.3 Hystrix怎么实现服务容错?
- 服务熔断:Hystrix 通过设置阈值来监控服务的错误率或响应时间。当错误率或响应时间超过预设的阈值时,熔断器将会打开,后续的请求将不再发送到实际的服务提供方,而是返回预设的默认值或错误信息。这样可以快速隔离故障服务,防止故障扩散,提高系统的稳定性和可用性。
- 服务降级:当服务熔断打开时,Hystrix 可以提供一个备用的降级方法或返回默认值,以保证系统继续正常运行。开发者可以定义降级逻辑,例如返回缓存数据、执行简化的逻辑或调用其他可靠的服务,以提供有限但可用的功能。
- 请求缓存:Hystrix 可以缓存对同一请求的响应结果,当下次请求相同的数据时,直接从缓存中获取,避免重复的网络请求,提高系统的性能和响应速度。
- 请求合并:Hystrix 可以将多个并发的请求合并为一个批量请求,减少网络开销和资源占用。这对于一些高并发的场景可以有效地减少请求次数,提高系统的性能。
- 实时监控和度量:Hystrix 提供了实时监控和度量功能,可以对服务的执行情况进行监控和统计,包括错误率、响应时间、并发量等指标。通过监控数据,可以及时发现和解决服务故障或性能问题。
- 线程池隔离:Hystrix 将每个依赖服务的请求都放在独立的线程池中执行,避免因某个服务的故障导致整个系统的线程资源耗尽。通过线程池隔离,可以提高系统的稳定性和可用性。
5.4 Sentinel 是什么?它是如何工作的?
Sentinel 是一款由阿里巴巴开源的流量控制和服务保护组件,主要用于保护分布式系统中的微服务架构。它提供了实时的流量控制、熔断降级、系统负载保护等功能,可以帮助开发者有效地保护和管理微服务应用。
-
流量控制: Sentinel 可以对微服务的入口流量进行实时监控和限制。开发者可以通过配置规则来定义流量控制策略,从而保护后端服务不被过载和打崩。
-
熔断降级: Sentinel 可以自动识别出故障或异常的服务,并对其进行熔断降级。
-
系统负载保护:当系统负载超过阈值时,Sentinel 可以自动限制流量或者拒绝请求,从而避免系统过载和崩溃。
-
实时监控和统计: Sentinel 提供了实时的监控和统计功能,可以监控服务的流量、响应时间、错误率等关键指标,并生成实时的统计报告和告警信息。
5.5 Sentinel怎么实现限流的?
Sentinel 通过动态管理限流规则,根据定义的规则对请求进行限流控制。具体实现步骤如下:
- 定义资源:在 Sentinel 中,资源可以是 URL、方法等,用于标识需要进行限流的请求。
- 配置限流规则:在 Sentinel 的配置文件中定义资源的限流规则。规则可以包括资源名称、限流阈值、限流模式(令牌桶或漏桶)等。
- 监控流量:Sentinel 会监控每个资源的流量情况,包括请求的 QPS(每秒请求数)、线程数、响应时间等。
- 限流控制:当请求到达时,Sentinel 会根据资源的限流规则判断是否需要进行限流控制。如果请求超过了限流阈值,则可以进行限制、拒绝或进行其他降级处理。
5.6 常见的限流算法有哪些?🔥
限流算法是一种用于控制系统访问速率的算法,用于限制在一定时间内系统能够处理的请求数量或者速率。限流算法可以帮助系统应对突发流量、防止系统过载和崩溃,保护系统的稳定性和可用性。
-
漏桶算法(Leaky Bucket):漏桶算法可以看作是一个漏水的桶,水(请求)以固定的速率流入桶中。而桶有一个固定的容量,当水流入桶时,如果桶满了,多余的水将被溢出,这时请求将被拒绝或者进行排队等待。这种算法无法应对突发的流量,因为只能以固定的速率处理请求。
-
令牌桶算法(Token Bucket):令牌桶算法中,系统以固定的速率生成令牌,并放入一个桶中。每个请求到来时,需要从桶中获取一个令牌,如果桶中没有足够的令牌,则请求被拒绝或者进行排队等待。这种算法可以应对突发流量。
-
固定窗口算法:固定窗口算法在固定的时间窗口内根据系统的负载情况对请求进行计数,当请求数量达到设定的阈值时,后续请求将被拒绝或者进行排队等待。这种算法相对简单直接,但可能无法应对突发流量。
-
滑动窗口算法:滑动窗口算法将时间划分为固定大小的窗口,每隔一定时间滑动,并在每个窗口中限制请求的数量。当请求到达时,算法会检查当前窗口中的请求数量是否超过阈值,超过则拒绝请求,否则允许通过。
一般 nginx 限流采用的漏桶算法,spring cloud gateway 支持令牌桶算法。
6 服务网关
6.1 什么是API网关?🔥
API 网关(API Gateway)是一种中间层服务器,用于集中管理、保护和路由对后端服务的访问。它充当了客户端与后端服务之间的入口点,提供了一组统一的接口来管理和控制 API 的访问。
-
路由转发:API 网关根据请求的 URL 路径或其他标识,将请求路由到相应的后端服务。通过配置路由规则,可以灵活地将请求分发给不同的后端服务。
-
负载均衡:API 网关可以在后端服务之间实现负载均衡,将请求平均分发到多个实例上,提高系统的吞吐量和可扩展性。
-
认证与授权:API 网关可以集中处理身份验证和授权,确保只有经过身份验证的客户端才能访问后端服务。它可以与身份提供者(如 OAuth、OpenID Connect)集成,进行用户认证和授权操作。
-
缓存:API 网关可以缓存后端服务的响应,减少对后端服务的请求次数,提高系统性能和响应速度。
-
监控与日志:API 网关可以收集和记录请求的指标和日志,提供实时监控和分析,帮助开发人员和运维人员进行故障排查和性能优化。
-
数据转换与协议转换:API 网关可以在客户端和后端服务之间进行数据格式转换和协议转换,如将请求从 HTTP 转换为 WebSocket,或将请求的参数进行格式转换,以满足后端服务的需求。
-
API 版本管理:API 网关可以管理不同版本的 API,允许同时存在多个 API 版本,并通过路由规则将请求正确地路由到相应的 API 版本上。
6.2 Spring Cloud Gateway核心概念?
- Route(路由):路由是 Spring Cloud Gateway 的基本构建块,它定义了请求的匹配规则和转发目标。通过配置路由,可以将请求映射到后端的服务实例或 URL 上。路由规则可以根据请求的路径、方法、请求头等条件进行匹配,并指定转发的目标 URI。
- Predicate(断言):断言用于匹配请求的条件,如果请求满足断言的条件,则会应用所配置的过滤器。Spring Cloud Gateway 提供了多种内置的断言,如 Path(路径匹配)、Method(请求方法匹配)、Header(请求头匹配)等,同时也支持自定义断言。
- Filter(过滤器):过滤器用于对请求进行处理和转换,可以修改请求、响应以及执行其他自定义逻辑。Spring Cloud Gateway 提供了多个内置的过滤器,如请求转发、请求重试、请求限流等。同时也支持自定义过滤器,可以根据需求编写自己的过滤器逻辑。
- Gateway Handler(网关处理器):网关处理器是 Spring Cloud Gateway 的核心组件,负责将请求转发到匹配的路由上。它根据路由配置和断言条件进行路由匹配,选择合适的路由进行请求转发。网关处理器还会依次应用配置的过滤器链,对请求进行处理和转换。
- Gateway Filter Chain(网关过滤器链):网关过滤器链由一系列过滤器组成,按照配置的顺序依次执行。每个过滤器可以在请求前、请求后或请求发生错误时进行处理。过滤器链的执行过程可以修改请求、响应以及执行其他自定义逻辑。
7 链路追踪
7.1 为什么要用微服务链路追踪?🔥
在微服务系统中,服务之间存在复杂的调用关系和依赖关系,一个请求可能需要经过多个不同的服务才能完成。那么就会面临一些问题:
- 问题定位:当某一个服务节点出现问题导致整个调用失败,无法快速清晰地定位出现问题的服务。
- 性能分析:服务存在相互依赖调用的关系,当某一个服务的接口耗时过长,会导致整个接口调用变的很慢,我们无法明确每一个接口的耗时。
- 服务拓扑图:随着需求迭代,服务之间调用关系变化频繁,靠人工很难梳理清楚服务之间的调用关系。
- 服务告警:当服务出现问题,我们无法做到由系统自动通知相关人员。
而分布式链路追踪就可以解决上述问题,它会将一次分布式请求的调用情况集中展示,比如各个服务节点上的耗时、请求具体到达哪台机器上、每个服务节点的请求状态、生成服务调用拓扑图等等。
7.2 SpringCloud可以选择哪些微服务链路追踪方案?
-
Zipkin: Zipkin 是一个开源的分布式实时追踪系统,由 Twitter 开发并贡献给开源社区。Spring Cloud Sleuth 提供了与 Zipkin 的集成,可以通过在微服务中添加相应的依赖和配置,将追踪信息发送到 Zipkin 服务器,并通过 Zipkin UI 进行可视化展示和查询。
-
SkyWalking: Apache SkyWalking 是一款开源的应用性能监控与分析系统,提供了对 Java、.NET 和 Node.js 等语言的支持。在 Spring Cloud 中,可以通过 SkyWalking 提供的插件来实现微服务链路追踪和监控。
-
Pinpoint: Pinpoint 是 Naver 开源的分布式应用性能监控系统,支持 Java 和 .NET。它提供了与 Spring Cloud Sleuth 的集成,可以将追踪数据发送到 Pinpoint 服务器,并通过其 UI 进行分析和监控。
-
Jaeger: Jaeger 是 Uber 开源的分布式追踪系统,也被纳入了 CNCF(云原生计算基金会)的维护。通过使用 Spring Cloud Sleuth 和 Jaeger 客户端库,可以将追踪信息发送到 Jaeger 并进行可视化展示和查询。
7.3 SkyWalking提供了哪些工具?
在分布式系统中,确定性能瓶颈是一个复杂而关键的任务。SkyWalking 提供的工具和技术来帮助进行故障排查:
-
性能监控和指标收集:SkyWalking 提供了性能监控和指标收集功能,可以监控服务之间的调用、请求响应时间、错误率等指标。
-
分布式追踪:SkyWalking 提供了分布式追踪功能,可以跟踪请求在整个系统中的调用链,帮助发现慢速调用和瓶颈服务。
-
日志分析:SkyWalking 提供了日志分析功能,可以集成各种日志系统(如ELK Stack、Logstash),并将日志与性能指标和追踪数据关联起来,以帮助进行故障排查。
-
故障模拟和压力测试:SkyWalking 提供了故障模拟和压力测试的功能,可以对服务进行压力测试并监控系统的响应时间和错误率。
-
自动化警报和通知:SkyWalking 提供了警报和通知的功能,可以根据预设的条件和规则触发警报,并通过邮件、短信等方式发送通知。
7.4 SkyWalking中的数据是如何收集和传输的🔥
Apache SkyWalking 中的数据收集和传输是通过代理端和后端收集器之间的协作来完成的。以下是数据收集和传输的主要步骤:
-
数据收集器: SkyWalking 的代理端(Agent)内置于各个应用程序中,负责收集应用程序的性能指标、分布式追踪数据和日志信息。代理端通过字节码注入或者插件方式与应用程序集成,能够在不修改源代码的情况下,自动收集和监控应用程序的运行状态。
-
数据传输协议: SkyWalking 的代理端将收集到的数据以指定的格式打包,并通过指定的传输协议将数据发送到后端收集器。
-
后端收集器: SkyWalking 的后端收集器(Collector)负责接收和处理代理端发送过来的数据。
-
数据存储和索引: 后端收集器将收集到的数据存储到持久化存储中,并建立相应的索引以支持数据的快速检索和查询。通常情况下,SkyWalking 支持存储到关系型数据库(如MySQL)、时序数据库(如Elasticsearch)或者分布式存储(如Hadoop、HBase)中。
-
数据查询和展示: 用户可以通过 SkyWalking 提供的查询接口和可视化界面对收集到的数据进行查询和分析。用户可以查看应用程序的性能指标、分布式追踪数据和日志信息,并通过图表、报表等形式展示,以帮助用户了解系统的运行状况和性能表现。
具体操作为在 JVM 中设置如下参数:
-javaagent:/skywalking-agent.jar # 加载指定的 SkyWalking 代理文件,其会注入到应用中
-Dskywalking.collector.backend_service=127.0.0.1:11800 # 代理将数据发送到这个后端收集器地址
-Dskywalking.agent.service_name=ContentApplication # SkyWalking的UI中,这个名称作为应用的标识
8 服务监控
8.1 你们的服务怎么做监控和告警?
-
日志监控: 使用日志框架(例如Log4j、Logback)记录关键业务逻辑的日志,并结合日志分析工具(例如ELK Stack、Splunk)进行日志监控和分析。通过监控日志中的异常和错误信息,可以及时发现问题并进行相应的处理。
-
指标监控: 使用监控工具(例如Prometheus、Grafana)收集和展示 Java 服务的关键指标(例如内存使用率、CPU 使用率、线程池情况等),通过设置阈值和告警规则,实现对关键指标的实时监控和告警。
-
应用性能监控(APM): 使用 APM 工具(例如AppDynamics、New Relic、Dynatrace)监控 Java 服务的性能指标(例如响应时间、请求吞吐量、数据库访问等),通过分析和可视化这些指标,可以发现系统瓶颈和性能问题。
-
异常监控: 使用异常监控工具(例如Sentry、Rollbar)捕获和记录 Java 服务中的异常信息,通过实时监控异常信息,可以及时发现并解决系统中的问题。
-
心跳检测: 使用心跳检测工具(例如Zabbix、Nagios)对 Java 服务进行定时检测,确保服务的正常运行。当服务出现异常或者宕机时,可以及时发出告警通知,进行故障排除和修复。
-
自定义监控: 根据业务需求和技术栈,开发自定义监控工具或者脚本,对 Java 服务进行定制化监控和告警。例如,通过定时发送HTTP请求来检测服务是否正常运行,或者通过定时执行Shell脚本来监控系统资源使用情况。
8.2 你们的服务怎么做日志收集?🔥
我的项目中使用的是 Log4j2 和 RabbitMQ 结合的方式。
- 首先在项目的
pom.xml
中添加 Log4j2 和 RabbitMQ 的依赖 - 在
src/main/resources
目录下创建一个log4j2.xml
文件,并设置RabbitMQ Appender
用于将日志发送到 RabbitMQ - 之后需要创建一个 RabbitMQ 消息监听器来接收并处理通过 Log4j2 发送的日志消息,按天数存储
数据量特别大时,可以使用 ELK
:
- Elasticsearch:Elasticsearch 是一个分布式搜索和分析引擎,用于存储和索引大量的日志数据。它提供了快速的搜索和聚合功能,可以高效地处理大规模的日志数据。
- Logstash:Logstash 是一个用于收集、过滤和转发日志数据的工具。它可以从各种来源(如文件、网络、消息队列等)收集日志数据,并对数据进行处理和转换,然后将其发送到 Elasticsearch 进行存储和索引。
- Kibana:Kibana 是一个用于日志数据可视化和分析的工具。它提供了丰富的图表、仪表盘和搜索功能,可以帮助用户实时监控和分析日志数据,发现潜在的问题和趋势。
简单说,这三者里Elasticsearch提供数据存储和检索能力,Logstash负责将日志收集到 ES,Kibana负责日志数据的可视化分析。
9 OAuth2
9.1 OAuth2授权模式有哪些🔥
OAuth 2.0 是一种开放标准的授权协议,用于授权第三方应用程序访问用户在另外一个服务提供商上的资源,而无需将用户的凭证(如用户名和密码)透露给第三方应用程序。OAuth 2.0 定义了多种授权模式(也称为授权流程或者授权类型),以满足不同场景下的授权需求。
- 授权码模式:授权码模式是 OAuth 2.0 中最常用的模式之一,也是最安全的一种模式。在这种模式下,客户端先申请一个 Authorization Code(授权码),然后再用该码获取 Access Token(访问令牌)。
- 隐藏/简化模式:隐藏/简化模式是一种简化的授权码模式,这种方式没有申请授权码这个中间步骤,直接将访问令牌传递给客户端,所以称为隐藏/简化模式。
- 密码模式:密码模式是一种在用户信任客户端的情况下使用的模式,因为客户端需要直接从用户那里获取用户名和密码,并将其作为 Client Credentials(客户端凭证)发送到认证服务器来换取访问令牌。但是,这可能会使用户的密码泄露,因此应该谨慎使用。
- 客户端凭证模式:客户端凭证模式是一种不基于用户的认证模式,它允许客户端直接使用 Client Credentials 向认证服务器请求令牌
9.2 使用OAuth2有什么优点和缺点
优点:
- 安全性:OAuth 2.0 采用了授权码、令牌等机制,将用户的凭证信息与第三方应用程序隔离开来,减少了凭证信息被泄露的风险。
- 灵活性:OAuth 2.0 定义了多种授权模式,如授权码模式、密码模式、客户端凭证模式等,能够满足不同场景下的授权需求,提供了更灵活的授权机制。
- 适用性广泛:OAuth 2.0 可以用于各种不同类型的应用程序和场景,包括 Web 应用程序、移动应用程序、单页应用程序等,适用性广泛。
- 用户友好:OAuth 2.0 允许用户授权第三方应用程序访问自己的资源,但不需要提供自己的凭证信息(如用户名和密码),提高了用户的安全感和体验。
缺点:
- 复杂性:OAuth 2.0 协议包含多种授权模式和流程,开发者需要理解并正确实现这些流程,可能会增加开发成本和复杂度。
- 单点故障:OAuth 2.0 授权流程通常需要依赖认证服务器来进行用户身份验证和授权,如果认证服务器出现故障或者不可用,可能会影响到整个系统的正常运行。
- 权限管理复杂:OAuth 2.0 并未提供对权限管理的明确规范,导致在实际应用中需要开发者自行实现对用户权限的管理和控制,可能会增加开发和维护的工作量。
9.3 使用OAuth2时,如何存储和传输敏感信息,例如用户名和密码
在 OAuth 2.0 的授权流程中,不会直接传输或存储用户的用户名和密码。OAuth 2.0 协议设计的初衷就是为了减少对用户凭证(如用户名和密码)的直接依赖,提高安全性。
在授权码模式下,第三方应用程序从授权服务器获取授权码,然后使用授权码换取访问令牌。在这个过程中,第三方应用程序不会直接接触到用户的用户名和密码,而是通过授权码来获取访问令牌。
9.4 OAuth2的刷新令牌🔥
为什么有刷新令牌:访问令牌只是向资源服务器申请获取资源的凭证,其有效期一般较短。当访问令牌过期后,可以使用刷新令牌进行刷新,刷新令牌的有效期一般较长。
-
刷新令牌的获取: 如果授权服务器(Authorization Server)支持刷新令牌模式,那么在获取访问令牌(Access Token)的同时,也会返回一个刷新令牌。
-
刷新令牌的使用: 当访问令牌失效时,可以使用刷新令牌向授权服务器请求新的访问令牌,而无需用户重新进行身份验证。刷新令牌的请求通常是通过特殊的端点(如
/token
端点)发送的,并且需要包含刷新令牌和客户端凭证等信息。 -
新的访问令牌的获取: 授权服务器接收到刷新令牌后,会验证刷新令牌的有效性,并生成一个新的访问令牌。新的访问令牌与之前的访问令牌具有相同的访问权限,但具有不同的过期时间。
-
更新访问令牌: 一旦新的访问令牌生成,客户端应用程序将其存储起来,并用它来替换之前失效的访问令牌。这样客户端应用程序就可以继续使用新的访问令牌来访问受保护的资源了。
需要注意的是,刷新令牌的使用是有限制的,通常情况下,刷新令牌具有一定的有效期,并且只能使用一次。一旦刷新令牌被使用过一次,就会失效,客户端应用程序需要使用新的刷新令牌来获取下一个访问令牌。另外,刷新令牌也需要进行安全存储,以防止被恶意获取和使用。
原文地址:https://blog.csdn.net/zss192/article/details/142436599
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!