该回答引用GPTᴼᴾᴱᴺᴬᴵ
如果不使用服务注册中心,可以手动在配置文件中添加多个目标服务的地址,并通过自定义路由器工厂类实现负载均衡。
假设有两个服务实例,地址分别为http://localhost:3001和http://localhost:3002,可以在配置文件中添加两个路由:
cloud:
gateway:
routes:
- id: ms_03_1
uri: http://localhost:3001
predicates:
- Path=/service/**
filters:
- StripPrefix=1
- id: ms_03_2
uri: http://localhost:3002
predicates:
- Path=/service/**
filters:
- StripPrefix=1
为了实现负载均衡,需要自定义路由器工厂类,并将其配置到GatewayAutoConfiguration中。以下是一个示例:
@Configuration
public class GatewayConfig {
@Bean
public RouteLocator routeLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("ms_03", r -> r.path("/service/**")
.filters(f -> f.stripPrefix(1))
.uri("lb://ms_03"))
.build();
}
@Bean
public LoadBalancerClient loadBalancerClient() {
return LoadBalancerClientFactory.getLazyInstance().getLoadBalancerClient("ms_03");
}
@Bean
public LoadBalancerProperties loadBalancerProperties() {
return new LoadBalancerProperties();
}
@Bean
public GatewayProperties gatewayProperties() {
GatewayProperties properties = new GatewayProperties();
properties.setRoutes(Collections.singletonList(new RouteDefinition()));
return properties;
}
@Bean
public GatewayPropertiesRouteDefinitionLocator routeDefinitionLocator(GatewayProperties properties) {
return new GatewayPropertiesRouteDefinitionLocator(properties);
}
@Bean
public RouteDefinitionRouteLocator routeDefinitionRouteLocator(GatewayPropertiesRouteDefinitionLocator locator,
LoadBalancerClient loadBalancerClient,
LoadBalancerProperties loadBalancerProperties) {
return new RouteDefinitionRouteLocator(locator, new RibbonClientLoadBalancerClientFactory(loadBalancerClient),
loadBalancerProperties, new GatewayProperties());
}
@Bean
public CachingRouteLocator cachingRouteLocator(RouteDefinitionRouteLocator routeDefinitionRouteLocator) {
return new CachingRouteLocator(routeDefinitionRouteLocator);
}
@Bean
public DefaultRouteDefinitionLocator defaultRouteDefinitionLocator(List<RouteDefinitionLocator> locators) {
return new DefaultRouteDefinitionLocator(locators);
}
@Bean
public GatewayPropertiesCustomizer gatewayPropertiesCustomizer() {
return new GatewayPropertiesCustomizer() {
@Override
public void customize(GatewayProperties properties) {
RouteDefinition route1 = new RouteDefinition();
route1.setId("ms_03_1");
route1.setUri(URI.create("lb://ms_03"));
route1.setPredicates(Collections.singletonList(new PathRoutePredicateFactory().apply(p -> p.setPattern("/service/**"))));
properties.getRoutes().add(route1);
RouteDefinition route2 = new RouteDefinition();
route2.setId("ms_03_2");
route2.setUri(URI.create("lb://ms_03"));
route2.setPredicates(Collections.singletonList(new PathRoutePredicateFactory().apply(p -> p.setPattern("/service/**"))));
properties.getRoutes().add(route2);
}
};
}
@Bean
public RoutePredicateFactory<?> routePredicateFactory() {
return
@Bean
public RoutePredicateFactory<?> routePredicateFactory() {
return new PathRoutePredicateFactory();
}
@Bean
public DiscoveryClientRouteDefinitionLocator discoveryClientRouteDefinitionLocator(DiscoveryClient discoveryClient, DiscoveryLocatorProperties properties) {
return new DiscoveryClientRouteDefinitionLocator(discoveryClient, properties);
}
@Bean
public LoadBalancerClientFilter loadBalancerClientFilter(LoadBalancerClient loadBalancerClient, LoadBalancerProperties properties) {
return new LoadBalancerClientFilter(loadBalancerClient, properties);
}
@Bean
public LoadBalancerProperties loadBalancerProperties() {
return new LoadBalancerProperties();
}
@Bean
public LoadBalancerClient loadBalancerClient(ServiceInstanceChooser serviceInstanceChooser, LoadBalancerProperties properties) {
return new RibbonLoadBalancerClient(serviceInstanceChooser, properties);
}
@Bean
public ServiceInstanceChooser serviceInstanceChooser() {
return new RandomServiceInstanceChooser();
}
@Bean
public DiscoveryLocatorProperties discoveryLocatorProperties() {
return new DiscoveryLocatorProperties();
}
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route(r -> r.path("/myservice/ms_03/**")
.uri("lb://ms_03")
.id("ms_03"))
.build();
}
注:上述代码使用了 Ribbon 作为负载均衡的实现,需要在pom.xml中添加相应的依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>