Browse Source

修改负载均衡规则

dev-V1.10.2-temp
zhuibobo 4 months ago
parent
commit
8ea7b7dbfc
  1. 7
      zdxt-web-server/zdxt-gateway-web-server/src/main/java/com/zdxt/gateway/webserver/ZdxtGatewayApplication.java
  2. 32
      zdxt-web-server/zdxt-gateway-web-server/src/main/java/com/zdxt/gateway/webserver/config/LoadBalancerConfig.java
  3. 79
      zdxt-web-server/zdxt-gateway-web-server/src/main/java/com/zdxt/gateway/webserver/config/PreferredFirstLoadBalancer.java
  4. 7
      zdxt-web-server/zdxt-gateway-web-server/src/main/resources/application-dev.yml
  5. 27
      zdxt-web-server/zdxt-gateway-web-server/src/main/resources/application-prod.yml
  6. 27
      zdxt-web-server/zdxt-gateway-web-server/src/main/resources/application.yml

7
zdxt-web-server/zdxt-gateway-web-server/src/main/java/com/zdxt/gateway/webserver/ZdxtGatewayApplication.java

@ -4,6 +4,7 @@ import com.zdxt.gateway.webserver.config.LoadBalancerConfig;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient; import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient;
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClients;
/** /**
* API网关启动类 * API网关启动类
@ -11,7 +12,11 @@ import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient;
* @author zdxt * @author zdxt
*/ */
@SpringBootApplication @SpringBootApplication
@LoadBalancerClient(name = "backend-service", configuration = LoadBalancerConfig.class) @LoadBalancerClients({
@LoadBalancerClient(name = "ent-ep-service", configuration = LoadBalancerConfig.class),
@LoadBalancerClient(name = "enf-ep-service", configuration = LoadBalancerConfig.class),
@LoadBalancerClient(name = "sup-ep-service", configuration = LoadBalancerConfig.class)
})
public class ZdxtGatewayApplication { public class ZdxtGatewayApplication {
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(ZdxtGatewayApplication.class, args); SpringApplication.run(ZdxtGatewayApplication.class, args);

32
zdxt-web-server/zdxt-gateway-web-server/src/main/java/com/zdxt/gateway/webserver/config/LoadBalancerConfig.java

@ -1,7 +1,7 @@
package com.zdxt.gateway.webserver.config; package com.zdxt.gateway.webserver.config;
import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.loadbalancer.core.RandomLoadBalancer; import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryProperties;
import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer; import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier; import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
@ -9,10 +9,18 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
/** /**
* 负载均衡配置 - 随机策略 * 负载均衡配置 - 优先级策略
* <p>
* 始终优先选择配置列表中的第一个健康实例,
* 首选实例不可用时按配置顺序从剩余健康实例中选取。
* <p> * <p>
* 替代默认的 RoundRobin 轮询策略,在存活实例间随机分配请求。 * 通过 {@link SimpleDiscoveryProperties} 读取原始配置顺序,
* 确保健康检查并发返回结果后仍能正确识别首选实例。
* *
* @author zdxt * @author zdxt
*/ */
@ -20,13 +28,23 @@ import org.springframework.core.env.Environment;
public class LoadBalancerConfig { public class LoadBalancerConfig {
@Bean @Bean
public ReactorLoadBalancer<ServiceInstance> randomLoadBalancer( public ReactorLoadBalancer<ServiceInstance> preferredFirstLoadBalancer(
Environment environment, Environment environment,
LoadBalancerClientFactory loadBalancerClientFactory) { LoadBalancerClientFactory loadBalancerClientFactory,
SimpleDiscoveryProperties discoveryProperties) {
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME); String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
return new RandomLoadBalancer(
// 从配置中获取该服务的原始实例顺序(即优先级)
List<String> preferredOrder = discoveryProperties.getInstances()
.getOrDefault(name, Collections.emptyList())
.stream()
.map(instance -> instance.getHost() + ":" + instance.getPort())
.collect(Collectors.toList());
return new PreferredFirstLoadBalancer(
loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class),
name name,
preferredOrder
); );
} }
} }

79
zdxt-web-server/zdxt-gateway-web-server/src/main/java/com/zdxt/gateway/webserver/config/PreferredFirstLoadBalancer.java

@ -0,0 +1,79 @@
package com.zdxt.gateway.webserver.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.DefaultResponse;
import org.springframework.cloud.client.loadbalancer.EmptyResponse;
import org.springframework.cloud.client.loadbalancer.Request;
import org.springframework.cloud.client.loadbalancer.Response;
import org.springframework.cloud.loadbalancer.core.NoopServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.core.ReactorServiceInstanceLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import reactor.core.publisher.Mono;
import java.util.List;
/**
* 优先级负载均衡器 - 首选优先策略
* <p>
* 根据配置文件中实例的声明顺序确定优先级,
* 始终选择优先级最高的健康实例。
* <p>
* 健康检查并发执行后返回结果顺序不确定,
* 因此通过 preferredOrder 显式匹配配置中的优先级顺序。
*
* @author zdxt
*/
@Slf4j
public class PreferredFirstLoadBalancer implements ReactorServiceInstanceLoadBalancer {
private final String serviceId;
private final ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider;
/** 配置中声明的实例顺序(host:port),索引越小优先级越高 */
private final List<String> preferredOrder;
public PreferredFirstLoadBalancer(
ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider,
String serviceId,
List<String> preferredOrder) {
this.serviceId = serviceId;
this.serviceInstanceListSupplierProvider = serviceInstanceListSupplierProvider;
this.preferredOrder = preferredOrder;
log.info("[{}] 优先级顺序: {}", serviceId, preferredOrder);
}
@Override
public Mono<Response<ServiceInstance>> choose(Request request) {
ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider
.getIfAvailable(NoopServiceInstanceListSupplier::new);
return supplier.get(request)
.next()
.map(this::selectInstance);
}
private Response<ServiceInstance> selectInstance(List<ServiceInstance> instances) {
if (instances.isEmpty()) {
log.warn("[{}] 无可用服务实例", serviceId);
return new EmptyResponse();
}
// 按配置优先级顺序遍历,找到第一个在健康列表中的实例
for (String preferred : preferredOrder) {
for (ServiceInstance instance : instances) {
String key = instance.getHost() + ":" + instance.getPort();
if (preferred.equals(key)) {
log.debug("[{}] 选择优先实例: {}, 健康实例数: {}",
serviceId, key, instances.size());
return new DefaultResponse(instance);
}
}
}
// 如果配置顺序中的实例都不在健康列表中(不应发生),取健康列表第一个
ServiceInstance fallback = instances.get(0);
log.warn("[{}] 未匹配到配置优先级实例,回退使用: {}:{}",
serviceId, fallback.getHost(), fallback.getPort());
return new DefaultResponse(fallback);
}
}

7
zdxt-web-server/zdxt-gateway-web-server/src/main/resources/application-dev.yml

@ -43,6 +43,13 @@ spring:
filters: filters:
- StripPrefix=1 - StripPrefix=1
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin, RETAIN_UNIQUE - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin, RETAIN_UNIQUE
- id: job-service
uri: http://localhost:18003
predicates:
- Path=/job-ep/**
filters:
- StripPrefix=1
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin, RETAIN_UNIQUE
# Actuator监控端点配置 # Actuator监控端点配置
management: management:

27
zdxt-web-server/zdxt-gateway-web-server/src/main/resources/application-prod.yml

@ -5,14 +5,22 @@ spring:
application: application:
name: zdxt-gateway name: zdxt-gateway
cloud: cloud:
# 静态服务实例列表(无需注册中心) # 静态服务实例列表(无需注册中心,配置顺序即优先级)
discovery: discovery:
client: client:
simple: simple:
instances: instances:
backend-service: ent-ep-service:
- uri: http://10.76.108.7:18000 - uri: http://10.76.108.7:18000
- uri: http://10.76.108.8:18002
- uri: http://10.76.108.9:18001
enf-ep-service:
- uri: http://10.76.108.8:18002
- uri: http://10.76.108.7:18000
- uri: http://10.76.108.9:18001
sup-ep-service:
- uri: http://10.76.108.9:18001 - uri: http://10.76.108.9:18001
- uri: http://10.76.108.7:18000
- uri: http://10.76.108.8:18002 - uri: http://10.76.108.8:18002
# LoadBalancer 健康检查配置 # LoadBalancer 健康检查配置
loadbalancer: loadbalancer:
@ -37,29 +45,36 @@ spring:
allowedHeaders: "*" allowedHeaders: "*"
allowCredentials: true allowCredentials: true
maxAge: 3600 maxAge: 3600
# 路由配置 - 使用 lb:// 协议启用负载均衡 # 路由配置 - 使用 lb:// 协议启用优先级负载均衡
routes: routes:
- id: enterprise-service - id: enterprise-service
uri: lb://backend-service uri: lb://ent-ep-service
predicates: predicates:
- Path=/ent-ep/** - Path=/ent-ep/**
filters: filters:
- StripPrefix=1 - StripPrefix=1
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin, RETAIN_UNIQUE - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin, RETAIN_UNIQUE
- id: supervision-service - id: supervision-service
uri: lb://backend-service uri: lb://sup-ep-service
predicates: predicates:
- Path=/sup-ep/** - Path=/sup-ep/**
filters: filters:
- StripPrefix=1 - StripPrefix=1
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin, RETAIN_UNIQUE - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin, RETAIN_UNIQUE
- id: enforcement-service - id: enforcement-service
uri: lb://backend-service uri: lb://enf-ep-service
predicates: predicates:
- Path=/enf-ep/** - Path=/enf-ep/**
filters: filters:
- StripPrefix=1 - StripPrefix=1
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin, RETAIN_UNIQUE - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin, RETAIN_UNIQUE
- id: job-service
uri: http://10.76.108.10:18003
predicates:
- Path=/job-ep/**
filters:
- StripPrefix=1
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin, RETAIN_UNIQUE
# Actuator监控端点配置 # Actuator监控端点配置
management: management:

27
zdxt-web-server/zdxt-gateway-web-server/src/main/resources/application.yml

@ -5,14 +5,22 @@ spring:
application: application:
name: zdxt-gateway name: zdxt-gateway
cloud: cloud:
# 静态服务实例列表(无需注册中心) # 静态服务实例列表(无需注册中心,配置顺序即优先级)
discovery: discovery:
client: client:
simple: simple:
instances: instances:
backend-service: ent-ep-service:
- uri: http://localhost:18000 - uri: http://localhost:18000
- uri: http://localhost:18002
- uri: http://localhost:18001
enf-ep-service:
- uri: http://localhost:18002
- uri: http://localhost:18000
- uri: http://localhost:18001
sup-ep-service:
- uri: http://localhost:18001 - uri: http://localhost:18001
- uri: http://localhost:18000
- uri: http://localhost:18002 - uri: http://localhost:18002
# LoadBalancer 健康检查配置 # LoadBalancer 健康检查配置
loadbalancer: loadbalancer:
@ -37,29 +45,36 @@ spring:
allowedHeaders: "*" allowedHeaders: "*"
allowCredentials: true allowCredentials: true
maxAge: 3600 maxAge: 3600
# 路由配置 - 使用 lb:// 协议启用负载均衡 # 路由配置 - 使用 lb:// 协议启用优先级负载均衡
routes: routes:
- id: enterprise-service - id: enterprise-service
uri: lb://backend-service uri: lb://ent-ep-service
predicates: predicates:
- Path=/ent-ep/** - Path=/ent-ep/**
filters: filters:
- StripPrefix=1 - StripPrefix=1
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin, RETAIN_UNIQUE - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin, RETAIN_UNIQUE
- id: supervision-service - id: supervision-service
uri: lb://backend-service uri: lb://sup-ep-service
predicates: predicates:
- Path=/sup-ep/** - Path=/sup-ep/**
filters: filters:
- StripPrefix=1 - StripPrefix=1
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin, RETAIN_UNIQUE - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin, RETAIN_UNIQUE
- id: enforcement-service - id: enforcement-service
uri: lb://backend-service uri: lb://enf-ep-service
predicates: predicates:
- Path=/enf-ep/** - Path=/enf-ep/**
filters: filters:
- StripPrefix=1 - StripPrefix=1
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin, RETAIN_UNIQUE - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin, RETAIN_UNIQUE
- id: job-service
uri: http://localhost:18003
predicates:
- Path=/job-ep/**
filters:
- StripPrefix=1
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin, RETAIN_UNIQUE
# Actuator监控端点配置 # Actuator监控端点配置
management: management:

Loading…
Cancel
Save