基于服务发现的路由
在新服务网关Gateway动态路由中,我们基于数据库和Redis实现了动态路由。本小节将基于服务发现的方式实现服务路由。在Gateway提供的全局过滤器中的LoadBalancerClientFilter,会帮助我们完成基于服务发现的路由。
项目依赖
<!--Eureka客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
复制
配置文件
spring:
application:
name: gateway-demo
server:
port: 9001
#将Gateway注册至服务注册中心
eureka:
client:
service-url:
defaultZone: http://localhost:8701/eureka/,http://localhost:8702/eureka/
复制
Gateway应用启动后,注册至服务注册中心。Gateway模块拥有了从服务注册中心获取服务实例列表中包含的服务实例相关功能。此时我们可以通过http://GATEWAY_HOST:GATEWAY_PORT/SERVICE_ID进行服务实例调用(SERVICE_ID需大写)。经过如下配置后
spring:
cloud:
gateway:
discovery:
locator:
enabled: true//是否开启与服务发现组件交互功能(默认为false)
lower-case-service-id: true//是否开启服务实例标识转小写功能(默认为false)
application:
name: gateway-demo
server:
port: 9001
#将Gateway注册至服务注册中心
eureka:
client:
service-url:
defaultZone: http://localhost:8701/eureka/,http://localhost:8702/eureka/
复制
可以通过SERVICE_ID小写的方式进行服务实例调用。如果服务实例标识名称过长,可以通过服务实例别名的方式进行服务实例路由转发调用。
配置类方式配置
@Configuration
public class EurekaClientGatewayConfigRoute {
@Bean
public RouteLocator customEurekaClientGatewayRouteConfig(RouteLocatorBuilder builder)
{
return builder.routes().route("user-routes",
r->r.path("/user/**").uri("lb://user")).build();
}
}
复制
配置文件方式创建
spring:
cloud:
gateway:
routes:
- id: user-route
uri: lb://user
predicates:
- Path=/user/**
discovery:
locator:
enabled: true//是否开启与服务发现组件交互功能(默认为false)
lower-case-service-id: true//是否开启服务实例标识转小写功能(默认为false)
application:
name: gateway-demo
server:
port: 9001
#将Gateway注册至服务注册中心
eureka:
client:
service-url:
defaultZone: http://localhost:8701/eureka/,http://localhost:8702/eureka/
复制
服务实例别名方式进行路由转发的配置中,需要将开启与服务发现组件交互功能及服务实例标识转小写功能均配置为false,否则等于创建了两种服务路由方式对用户服务实例进行调用。
基于服务度量的动态路由
引入服务度量依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
复制
在Gateway中,提供的度量控制器名称为gateway,为了能够查看到端点,需要在YAML文件中进行如下配置以暴露端点:
#度量端点暴露配置
management:
endpoints:
web:
exposure:#暴露端点
include: gateway#暴露端点配置(与org.springframework.cloud.gateway.actuate.GatewayEndPointController中的id属性值一致)
复制
启动Gateway应用,查看服务路由信息
@GetMapping({"/routes"})
public Flux<Map<String, Object>> routes() {
return this.routeLocator.getRoutes().map(this::serialize);
}
Map<String, Object> serialize(Route route) {
HashMap<String, Object> r = new HashMap();
r.put("route_id", route.getId());
r.put("uri", route.getUri().toString());
r.put("order", route.getOrder());
r.put("predicate", route.getPredicate().toString());
if (!CollectionUtils.isEmpty(route.getMetadata())) {
r.put("metadata", route.getMetadata());
}
ArrayList<String> filters = new ArrayList();
for(int i = 0; i < route.getFilters().size(); ++i) {
GatewayFilter gatewayFilter = (GatewayFilter)route.getFilters().get(i);
filters.add(gatewayFilter.toString());
}
r.put("filters", filters);
return r;
}
复制
除了暴露Gateway基本的服务路由端点集合信息,还包含其他端点
度量端点 | 方法 | 方法描述 |
/actuator/gateway/refresh | POST | 刷新当前路由 |
/actuator/gateway/globalfilters | GET | 获取全局过滤器信息 |
/actuator/gateway/routes | GET | 获取服务路由集合 |
/actuator/gateway/routes/{id} | POST | 新增或更新路由信息 |
/actuator/gateway/routes/{id} | DELETE | 根据ID删除路由信息 |
/actuator/gateway/routes/{id} | GET | 根据ID获取路由信息 |
/actuator/gateway/routes/{id}/combinedfilters | GET | 根据ID获取对应路由的所有过滤器 |
配置类
此处仅作为使用示例,具体使用过程中需要在控制器接收对应路由描述信息(RouteDefinition)参数
@Configuration
public class GatewayEndPointConfig {
/**
*保存ID为point-route的路由信息
*/
public static void saveRoutes()
{
RestTemplate restTemplate=new RestTemplate();
RouteDefinition definition=routeDefinition();
HttpEntity<RouteDefinition> routeDefinitionHttpEntity=new HttpEntity<>(definition);
String uri="http://localhost://9001/actuator/gateway/routes/point-route";
ResponseEntity<Void> responseEntity=restTemplate.postForEntity(uri,routeDefinitionHttpEntity,Void.class);
}
/**
* 定义路由描述信息
* @return 路由描述信息
*/
private static RouteDefinition routeDefinition()
{
RouteDefinition definition=new RouteDefinition();
definition.setId("point-route");
definition.setUri(URI.create("lb://user"));
definition.setOrder(1000);
//服务断言信息(此处使用类型为Path断言)
PredicateDefinition predicateDefinition=new PredicateDefinition("Path=/user/**");
List<PredicateDefinition> predicateDefinitionList=new ArrayList<PredicateDefinition>();
predicateDefinitionList.add(predicateDefinition);
definition.setPredicates(predicateDefinitionList);
FilterDefinition filterDefinition=new FilterDefinition("AddRequestHeader=id,1");
List<FilterDefinition> filterDefinitionList=new ArrayList<>();
filterDefinitionList.add(filterDefinition);
definition.setFilters(filterDefinitionList);
return definition;
}
/**
* 删除ID为point-route的路由信息
*/
public static void deleteRoute()
{
RestTemplate restTemplate=new RestTemplate();
RouteDefinition definition=routeDefinition();
HttpEntity<RouteDefinition> routeDefinitionHttpEntity=new HttpEntity<>(definition);
String uri="http://localhost://9001/actuator/gateway/routes/point-route";
restTemplate.delete(uri);
}
}
复制
整合Hystrix
项目依赖
<!--熔断器-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
复制
应用程序入口使用@EnableCircuitBreaker注解配置使用Hystrix
熔断器配置
spring:
cloud:
gateway:
routes:
- id: hystrix-route
uri: localhost://8100/test/hystrix
predicates:
- Path=/test/hystrix
filters:
-name: Hystrix
args:
name: fallbackCmd
fallbackUri: forward://fallbackOperate
#设置Hystrix相关配置参数
hystrix:
command:
fallbackCmd:
execution:
isolation:
thread:
#断路器的超时时间ms,默认1000
timeoutInMilliseconds: 2000
circuitBreaker:
#是否启动熔断器,默认为true,false表示不要引入Hystrix。
enabled: true
#当在配置时间窗口内达到此数量的失败后,进行短路
requestVolumeThreshold: 20
#出错百分比阈值,当达到此阈值后,开始短路。默认50%)
errorThresholdPercentage: 50%
#短路多久以后开始尝试是否恢复,默认5s)-单位ms
sleepWindowInMilliseconds: 30000
复制
控制器
@RestController
public class GatewayHystrixfallbackController {
@GetMapping("/fallbackOperate")
public ResultMessage gatewayFallback()
{
return new ResultMessage(false,"服务调用超时,执行快速失败");
}
}
复制
文章转载自CodeWu,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
2025年4月中国数据库流行度排行榜:OB高分复登顶,崖山稳驭撼十强
墨天轮编辑部
1375次阅读
2025-04-09 15:33:27
2025年3月国产数据库大事记
墨天轮编辑部
748次阅读
2025-04-03 15:21:16
2025年3月国产数据库中标情况一览:TDSQL大单622万、GaussDB大单581万……
通讯员
545次阅读
2025-04-10 15:35:48
征文大赛 |「码」上数据库—— KWDB 2025 创作者计划启动
KaiwuDB
460次阅读
2025-04-01 20:42:12
数据库,没有关税却有壁垒
多明戈教你玩狼人杀
414次阅读
2025-04-11 09:38:42
优炫数据库成功应用于国家电投集团青海海南州新能源电厂!
优炫软件
387次阅读
2025-03-21 10:34:08
天津市政府数据库框采结果公布!
通讯员
319次阅读
2025-04-10 12:32:35
最近我为什么不写评论国产数据库的文章了
白鳝的洞穴
317次阅读
2025-04-07 09:44:54
国产数据库需要扩大场景覆盖面才能在竞争中更有优势
白鳝的洞穴
283次阅读
2025-04-14 09:40:20
从HaloDB体验到国产数据库兼容性
多明戈教你玩狼人杀
269次阅读
2025-04-07 09:36:17