Spring Cloud之负载均衡
原理:依据服务实例的响应时间为每个实例分配一个权重,响应时间越短,权重越高,该实例被选中处理请求的概率也就越大。通过这种方式优先将请求分配给性能较好、响应较快的实例,从而提高系统的整体响应速度。适用场景:当服务实例的性能存在明显差异时,使用该策略可以优化系统性能,提升用户体验。例如,在一个集群中部分服务器硬件配置较高、性能较好,而部分服务器性能相对较弱,就可以采用此策略。自定义示例思路。
一、基本概念
- 负载均衡:是一种将工作负载分布到多个计算资源上的技术,旨在优化资源使用、最大化吞吐量、最小化响应时间并避免任何单个资源的过载。在微服务架构中,负载均衡器负责将客户端的请求分发到多个服务实例上。
- 客户端负载均衡与服务端负载均衡
- 服务端负载均衡:客户端将请求发送到负载均衡器(如 Nginx、HAProxy),负载均衡器根据一定的算法将请求转发到后端的服务实例。客户端只知道负载均衡器的地址,而不知道具体的服务实例地址。
- 客户端负载均衡:客户端维护一份服务实例列表,通过内置的负载均衡算法直接选择一个服务实例进行请求。Spring Cloud 采用的是客户端负载均衡的方式。
二、Spring Cloud 中的负载均衡实现
1. Spring Cloud 提供了两种负载均衡机制:
1). Ribbon:Spring Cloud Netflix 提供的客户端负载均衡器,已在新版 Spring Cloud 中被弃用。
2). Spring Cloud LoadBalancer:Spring Cloud 提供的官方负载均衡实现,从 Spring Cloud 2020 开始推荐使用。
2. Spring Cloud LoadBalancer
Spring Cloud LoadBalancer 是 Spring Cloud 团队开发的一个用于客户端负载均衡的组件,旨在替代 Ribbon。它提供了更简单的抽象和更轻量级的实现,并且支持响应式编程模型。
工作原理
Spring Cloud LoadBalancer 作为 Spring Cloud 生态里的客户端负载均衡组件,主要在服务调用方应用程序中运行。它先与服务注册中心集成,定期从注册中心拉取目标服务的可用实例列表并缓存于本地。当服务调用方发起请求,LoadBalancerClient
会被触发,其从本地缓存获取实例列表,依据预设的负载均衡算法(如轮询、随机等,也支持自定义)选择一个合适的服务实例。之后使用 RestTemplate
或 WebClient
等工具将请求路由到所选实例进行处理。若所选实例不可用,可能会按配置重试并选择其他实例。为保证信息准确和性能,它会定期或在注册中心变化时刷新本地缓存。
使用 Spring Cloud LoadBalancer 进行负载均衡
- 添加依赖:在
pom.xml
中添加以下依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
- 配置 WebClient:使用
@LoadBalanced
注解为WebClient.Builder
开启负载均衡功能。
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient;
@Configuration
public class AppConfig {
@LoadBalanced
@Bean
public WebClient.Builder loadBalancedWebClientBuilder() {
return WebClient.builder();
}
}
- 调用服务:使用
WebClient
调用服务,URL 中使用服务名代替具体的 IP 地址和端口。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
@RestController
public class ConsumerController {
@Autowired
private WebClient.Builder webClientBuilder;
@GetMapping("/consumer")
public Mono<String> consumer() {
return webClientBuilder.build()
.get()
.uri("http://service-provider/hello")
.retrieve()
.bodyToMono(String.class);
}
}
三、负载均衡策略
Spring Cloud 提供了多种负载均衡策略,主要通过 Spring Cloud LoadBalancer 来实现,以下为你详细介绍这些常见的负载均衡策略:
内置基础策略
1. 轮询策略(RoundRobinLoadBalancer)
- 原理:该策略按照固定的顺序依次选择服务实例。例如,若有服务实例 A、B、C,请求会按照 A -> B -> C -> A -> B -> C 这样的顺序循环分配,每个实例被选中的机会均等。
- 适用场景:适用于所有服务实例性能相近的场景,能将请求均匀地分散到各个实例上,充分利用每个实例的资源,避免某个实例负载过高。
- 代码配置示例:在 Spring Cloud 中,默认使用的就是轮询策略,通常只需简单配置即可使用:
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient;
@Configuration
public class LoadBalancedConfig {
@LoadBalanced
@Bean
public WebClient.Builder loadBalancedWebClientBuilder() {
return WebClient.builder();
}
}
2. 随机策略(RandomLoadBalancer)
- 原理:从可用的服务实例列表中随机挑选一个实例来处理请求。每次选择都是独立随机的,不受之前选择结果的影响。
- 适用场景:当服务实例的性能差异不大,且不希望出现顺序依赖时可以使用。比如在某些测试环境中,为了模拟不同的访问情况,采用随机策略可以更真实地测试系统的稳定性。
- 代码配置示例:
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;
import java.util.Random;
@Configuration
public class RandomLoadBalancerConfig {
@Bean
ReactorServiceInstanceLoadBalancer randomLoadBalancer(LoadBalancerClientFactory clientFactory) {
return new RandomLoadBalancer(clientFactory.getLazyProvider("", ServiceInstanceListSupplier.class));
}
}
可扩展与自定义相关策略
3. 加权响应时间策略(可自定义实现)
- 原理:依据服务实例的响应时间为每个实例分配一个权重,响应时间越短,权重越高,该实例被选中处理请求的概率也就越大。通过这种方式优先将请求分配给性能较好、响应较快的实例,从而提高系统的整体响应速度。
- 适用场景:当服务实例的性能存在明显差异时,使用该策略可以优化系统性能,提升用户体验。例如,在一个集群中部分服务器硬件配置较高、性能较好,而部分服务器性能相对较弱,就可以采用此策略。
- 自定义示例思路:
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.*;
import reactor.core.publisher.Mono;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
public class WeightedResponseTimeLoadBalancer implements ReactorServiceInstanceLoadBalancer {
private final ConcurrentHashMap<String, Long> responseTimes = new ConcurrentHashMap<>();
private final ServiceInstanceListSupplier serviceInstanceListSupplier;
public WeightedResponseTimeLoadBalancer(ServiceInstanceListSupplier serviceInstanceListSupplier) {
this.serviceInstanceListSupplier = serviceInstanceListSupplier;
}
@Override
public Mono<Response<ServiceInstance>> choose(Request request) {
return serviceInstanceListSupplier.get(request).next().map(this::chooseInstance);
}
private Response<ServiceInstance> chooseInstance(List<ServiceInstance> instances) {
// 这里需要实现根据响应时间计算权重、选择实例的具体逻辑
// 例如,计算总权重,然后根据权重随机选择实例等
return new DefaultResponse(instances.get(0));
}
}
在配置类中注册自定义的负载均衡器:
import org.springframework.cloud.client.loadbalancer.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class CustomLoadBalancerConfig {
@Bean
ReactorServiceInstanceLoadBalancer customLoadBalancer(LoadBalancerClientFactory clientFactory) {
return new WeightedResponseTimeLoadBalancer(clientFactory.getLazyProvider("", ServiceInstanceListSupplier.class));
}
}
4. 区域感知策略(ZoneAwareLoadBalancer,类似概念可自定义实现)
- 原理:考虑服务实例所在的区域信息,优先选择与客户端处于同一区域的服务实例。如果同一区域内没有可用实例,再考虑其他区域的实例。这样可以减少网络延迟,提高系统的响应速度。
- 适用场景:适用于分布式系统中服务实例分布在不同地理区域的场景,例如跨数据中心、跨地域的服务调用。
- 自定义示例思路:需要在服务注册时记录实例的区域信息,在负载均衡选择实例时,先筛选出与客户端同一区域的实例列表,再根据其他规则(如轮询、随机等)从该列表中选择实例。若同一区域无可用实例,则扩大范围到其他区域进行选择。
四、高级特性
1. 深入理解Spring Cloud LoadBalancer核心原理
要深入掌握 Spring Cloud LoadBalancer 的架构设计以及服务实例的发现、存储和更新机制,可以从其整体架构、核心组件功能、服务实例的发现过程、存储形式以及更新的触发与处理方式等方面来理解,下面为你详细介绍:
整体架构概述
Spring Cloud LoadBalancer 是 Spring Cloud 生态中用于客户端负载均衡的组件,它遵循 Spring Cloud Common 定义的负载均衡抽象。其整体架构围绕着服务实例的管理和请求的负载均衡展开,主要由服务实例发现模块、负载均衡器和客户端请求拦截器等部分组成。客户端应用程序通过这些组件与服务注册中心交互,获取服务实例信息,并将请求分发到合适的服务实例上。
核心组件及其功能
- ServiceInstanceListSupplier:该接口负责提供服务实例列表。它是服务实例发现的核心抽象,不同的实现类可以从不同的服务注册中心(如 Eureka、Consul、Nacos 等)获取服务实例信息。例如,
DiscoveryClientServiceInstanceListSupplier
会从 Spring Cloud 的DiscoveryClient
中获取服务实例列表。 - ReactorServiceInstanceLoadBalancer:这是负载均衡器的核心接口,定义了选择服务实例的方法。Spring Cloud LoadBalancer 提供了多种实现,如
RoundRobinLoadBalancer
(轮询策略)、RandomLoadBalancer
(随机策略)等,也支持自定义实现。 - LoadBalancerClient:作为客户端使用负载均衡器的入口,它封装了与负载均衡器的交互逻辑,客户端可以通过它来获取一个合适的服务实例。
服务实例的发现机制
- 集成服务注册中心:Spring Cloud LoadBalancer 通过与服务注册中心集成来发现服务实例。服务提供者在启动时会将自身的实例信息(包括服务名、IP 地址、端口等)注册到服务注册中心。
- 实例信息获取:
ServiceInstanceListSupplier
会定期或在需要时从服务注册中心拉取指定服务的所有可用实例列表。例如,当客户端发起对某个服务的请求时,ServiceInstanceListSupplier
会触发获取实例列表的操作。
服务实例的存储机制
- 本地缓存:为了提高性能,Spring Cloud LoadBalancer 会将从服务注册中心获取的服务实例列表缓存在本地。
ServiceInstanceListSupplier
的实现类会负责管理这个缓存,将获取到的实例信息存储在内存中。 - 数据结构:通常使用列表(List)来存储服务实例信息,每个服务实例由
ServiceInstance
接口的实现类表示,包含了服务实例的基本信息,如服务 ID、主机地址、端口等。
服务实例的更新机制
- 定期刷新:
ServiceInstanceListSupplier
会按照配置的时间间隔定期从服务注册中心刷新服务实例列表,确保本地缓存的实例信息是最新的。例如,可以通过配置spring.cloud.loadbalancer.cache.ttl
来设置缓存的过期时间。 - 事件驱动更新:当服务注册中心发生实例注册、注销等变化时,会发布相应的事件。Spring Cloud LoadBalancer 可以监听这些事件,并在事件触发时及时更新本地缓存的服务实例列表,保证负载均衡的准确性。
示例代码理解
以下是一个简单的代码示例,展示了如何使用 Spring Cloud LoadBalancer 进行负载均衡:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@Configuration
class LoadBalancerConfig {
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
@RestController
class LoadBalancerController {
@Autowired
private LoadBalancerClient loadBalancerClient;
@Autowired
private RestTemplate restTemplate;
@GetMapping("/testLoadBalancing")
public String testLoadBalancing() {
// 通过负载均衡器选择一个服务实例
ServiceInstance serviceInstance = loadBalancerClient.choose("target-service");
if (serviceInstance != null) {
String url = serviceInstance.getUri() + "/api/resource";
return restTemplate.getForObject(url, String.class);
}
return "No available service instances";
}
}
在这个示例中,LoadBalancerClient
会根据负载均衡策略选择一个合适的服务实例,RestTemplate
会将请求发送到该实例上。同时,Spring Cloud LoadBalancer 会在后台自动处理服务实例的发现、存储和更新等操作。
2.请求拦截与路由机制
在 Spring Cloud 中,客户端拦截请求并根据负载均衡策略将其路由到合适的服务实例是实现分布式系统高可用和高性能的关键。下面将详细介绍其工作原理以及 LoadBalancerClient
和 ReactorServiceInstanceLoadBalancer
等核心接口的作用。
整体工作流程
Spring Cloud 客户端负载均衡的整体工作流程可以概括为:客户端发起请求 -> 请求被拦截 -> 从服务注册中心获取服务实例列表 -> 根据负载均衡策略选择一个服务实例 -> 将请求路由到该实例。
请求拦截机制
基于 RestTemplate 的拦截
当使用 RestTemplate
发起请求时,如果在 RestTemplate
上添加了 @LoadBalanced
注解,Spring Cloud 会自动为其添加一个 LoadBalancerInterceptor
拦截器。这个拦截器会在请求发送之前对请求进行拦截处理。
示例代码如下:
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class LoadBalancedConfig {
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
LoadBalancerInterceptor
会检查请求的 URL 是否使用了服务名(例如 http://service-name/api/endpoint
),如果是,则触发负载均衡逻辑。
基于 WebClient 的拦截
对于响应式编程,使用 WebClient
时,Spring Cloud 会通过 LoadBalancerExchangeFilterFunction
对请求进行拦截。同样,需要在创建 WebClient
时使用 @LoadBalanced
注解。
示例代码如下:
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient;
@Configuration
public class LoadBalancedWebClientConfig {
@LoadBalanced
@Bean
public WebClient.Builder loadBalancedWebClientBuilder() {
return WebClient.builder();
}
}
核心接口工作原理
LoadBalancerClient
- 作用:
LoadBalancerClient
是 Spring Cloud 中用于执行负载均衡操作的核心接口。它提供了choose
方法,用于根据服务名从服务实例列表中选择一个合适的服务实例。 - 工作原理:当
LoadBalancerInterceptor
或LoadBalancerExchangeFilterFunction
拦截到请求后,会调用LoadBalancerClient
的choose
方法。LoadBalancerClient
内部会依赖ServiceInstanceListSupplier
获取服务实例列表,然后使用ReactorServiceInstanceLoadBalancer
选择一个服务实例。
示例代码如下:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class LoadBalancerController {
@Autowired
private LoadBalancerClient loadBalancerClient;
@GetMapping("/testLoadBalancing")
public String testLoadBalancing() {
ServiceInstance serviceInstance = loadBalancerClient.choose("target-service");
if (serviceInstance != null) {
// 使用选择的服务实例处理请求
return "Selected instance: " + serviceInstance.getUri();
}
return "No available service instances";
}
}
ReactorServiceInstanceLoadBalancer
- 作用:
ReactorServiceInstanceLoadBalancer
是 Spring Cloud LoadBalancer 中用于实现负载均衡策略的核心接口。它定义了choose
方法,用于从服务实例列表中选择一个服务实例。 - 工作原理:
ReactorServiceInstanceLoadBalancer
的不同实现类代表了不同的负载均衡策略,如轮询、随机等。LoadBalancerClient
在调用choose
方法时,会委托给具体的ReactorServiceInstanceLoadBalancer
实现类来完成实例选择。
例如,RoundRobinLoadBalancer
实现了轮询策略,它会按顺序依次选择服务实例:
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.*;
import reactor.core.publisher.Mono;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
public class RoundRobinLoadBalancer implements ReactorServiceInstanceLoadBalancer {
private final AtomicInteger position;
private final ServiceInstanceListSupplier serviceInstanceListSupplier;
public RoundRobinLoadBalancer(ServiceInstanceListSupplier serviceInstanceListSupplier) {
this.serviceInstanceListSupplier = serviceInstanceListSupplier;
this.position = new AtomicInteger(new java.util.Random().nextInt(1000));
}
@Override
public Mono<Response<ServiceInstance>> choose(Request request) {
return serviceInstanceListSupplier.get(request).next()
.map(serviceInstances -> processInstanceResponse(serviceInstances));
}
private Response<ServiceInstance> processInstanceResponse(List<ServiceInstance> instances) {
if (instances.isEmpty()) {
return new EmptyResponse();
}
int pos = Math.abs(this.position.incrementAndGet());
ServiceInstance instance = instances.get(pos % instances.size());
return new DefaultResponse(instance);
}
}
路由请求
一旦通过 LoadBalancerClient
选择了合适的服务实例,LoadBalancerInterceptor
或 LoadBalancerExchangeFilterFunction
会将请求的 URL 中的服务名替换为所选服务实例的实际地址(IP 地址和端口),然后再将请求发送出去,从而实现请求的路由。
综上所述,Spring Cloud 通过拦截请求、使用 LoadBalancerClient
和 ReactorServiceInstanceLoadBalancer
等核心接口,实现了根据负载均衡策略将请求路由到合适服务实例的功能。
3. 负载均衡与熔断限流结合
(1)与 Hystrix 结合
Hystrix 是 Netflix 开源的熔断、限流和降级组件,与 Ribbon 结合可以在服务调用失败或超时的情况下进行熔断和降级处理。可以使用 @HystrixCommand
注解来为服务调用方法添加熔断和降级逻辑。
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@HystrixCommand(fallbackMethod = "fallback")
@GetMapping("/consumer")
public String consumer() {
return restTemplate.getForObject("http://service-provider/hello", String.class);
}
public String fallback() {
return "Fallback response";
}
}
(2)与 Resilience4j 结合
Resilience4j 是一个轻量级的容错库,支持熔断、限流、重试等多种容错机制。可以与 Spring Cloud LoadBalancer 结合使用,通过配置 Resilience4j 的熔断器和限流器来保护服务调用。
import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
@RestController
public class ReactiveConsumerController {
@Autowired
private WebClient.Builder webClientBuilder;
@CircuitBreaker(name = "service-provider", fallbackMethod = "fallback")
@GetMapping("/reactive-consumer")
public Mono<String> reactiveConsumer() {
return webClientBuilder.build()
.get()
.uri("http://service-provider/hello")
.retrieve()
.bodyToMono(String.class);
}
public Mono<String> fallback(Exception e) {
return Mono.just("Fallback response");
}
}
3. 健康检查与服务实例过滤
(1)服务实例健康检查
Spring Cloud 可以集成 Eureka、Consul 等服务发现组件,这些组件会对服务实例进行健康检查。可以通过配置服务实例的健康检查端点,让服务发现组件定期检查服务实例的健康状态。例如,在 Spring Boot 应用中,可以使用 Actuator 提供的 /health
端点来进行健康检查。
(2)服务实例过滤
在负载均衡时,可以根据服务实例的健康状态、元数据等信息进行过滤。例如,只选择健康状态为 UP 的服务实例进行请求。在 Ribbon 中,可以通过自定义 ServerListFilter
来实现服务实例的过滤;在 Spring Cloud LoadBalancer 中,可以通过自定义 ServiceInstanceListSupplier
来实现。
import com.netflix.loadbalancer.AbstractServerListFilter;
import com.netflix.loadbalancer.Server;
import java.util.ArrayList;
import java.util.List;
public class CustomServerListFilter extends AbstractServerListFilter<Server> {
@Override
public List<Server> getFilteredListOfServers(List<Server> servers) {
List<Server> filteredServers = new ArrayList<>();
for (Server server : servers) {
if (server.isAlive()) {
filteredServers.add(server);
}
}
return filteredServers;
}
}
4.与其他组件集成
(1)与 Gateway 集成
Spring Cloud Gateway 是 Spring Cloud 生态中的 API 网关,它可以与负载均衡器集成,将客户端的请求路由到多个服务实例。可以在 Gateway 的配置中使用 lb://
前缀来启用负载均衡。
spring:
cloud:
gateway:
routes:
- id: service-provider-route
uri: lb://service-provider
predicates:
- Path=/service-provider/**
(2)与 Sleuth 和 Zipkin 集成
在微服务架构里,Spring Cloud 负载均衡负责把客户端请求合理分发到多个服务实例,Sleuth 用于为每个请求生成唯一标识并跟踪请求调用链路,Zipkin 则收集和展示这些跟踪信息。三者集成能实现请求全链路追踪,帮助开发者监控系统性能、定位故障和优化服务调用。
1) 项目依赖添加
在每个微服务模块的 pom.xml
(Maven 项目)文件里添加相关依赖:
<dependencies>
<!-- Spring Cloud LoadBalancer -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<!-- Spring Cloud Sleuth -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<!-- Spring Cloud Zipkin -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
<!-- 以 Nacos 作为服务注册中心为例 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
2) 配置文件设置
在各微服务的 application.yml
或 application.properties
中添加如下配置:
spring:
application:
name: your-service-name # 服务名称
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 # Nacos 服务地址
loadbalancer:
ribbon:
enabled: false # 禁用 Ribbon,使用 Spring Cloud LoadBalancer
sleuth:
sampler:
probability: 1.0 # 采样率,1.0 表示采集所有请求
zipkin:
base-url: http://localhost:9411 # Zipkin 服务地址
3) 启动 Zipkin 服务
可以通过 Docker 快速启动 Zipkin 服务:
docker run -d -p 9411:9411 openzipkin/zipkin
启动后,访问 http://localhost:9411
能打开 Zipkin 的 Web 界面。
4) 负载均衡调用服务
使用 Spring Cloud LoadBalancer 进行服务调用,以下是使用 RestTemplate
的示例:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@Configuration
class LoadBalancerConfig {
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
@RestController
class LoadBalancerController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/callService")
public String callService() {
return restTemplate.getForObject("http://target-service/api/endpoint", String.class);
}
}
5) 验证集成效果
- 启动各个微服务和 Zipkin 服务。
- 调用带有负载均衡的服务接口,如上述示例中的
/callService
。 - 访问 Zipkin 的 Web 界面(
http://localhost:9411
),在搜索框输入服务名等条件查询调用链路信息,能看到请求在不同服务间的调用过程、每个服务的处理时间等。
6) 注意要点
- 版本匹配:确保 Spring Cloud、Spring Boot、Sleuth 和 Zipkin 等组件版本兼容,可参考官方文档选择合适版本。
- 采样率调整:根据实际业务情况和系统性能调整采样率。高采样率能获取更全面跟踪信息,但会增加系统开销;低采样率可降低开销,但可能丢失部分请求跟踪信息。
- 网络连通性:保证各个微服务能正常访问 Zipkin 服务地址,否则跟踪信息无法正常发送到 Zipkin 服务器。
更多推荐
所有评论(0)