前言
最近在项目中碰到这样一个需求,我们公司需要在中台系统中,添加一个gateway的动态路由添加功能。就是说要在中台系统里添加一条数据,这条数据对应一个gateway路由,然后gateway服务就需要把这个路由加进去,不然的话这个路由就访问不到,由于是动态,所以gateway服务的配置文件路由不能写死,浏览了一些文章后,才发现有动态路由这个功能,果然活到老学到老啊兄弟们,既然这么牛皮那不得给大家安排一下,话不多说,看教程。
DynamicRouteServiceImpl文件
创建DynamicRouteServiceImpl文件并实现ApplicationEventPublisherAware。
@Slf4j
@Service
public class DynamicRouteServiceImpl implements ApplicationEventPublisherAware {
@Autowired
private RouteDefinitionWriter routeDefinitionWriter;
private ApplicationEventPublisher publisher;
/**
* 添加路由实体类
*
* @param definition
* @return
*/
public boolean add(RouteDefinition definition) {
routeDefinitionWriter.save(Mono.just(definition)).subscribe();
this.publisher.publishEvent(new RefreshRoutesEvent(this));
return true;
}
/**
* @param definition 路由实体类
* @return
*/
public boolean update(RouteDefinition definition) {
try {
routeDefinitionWriter.delete(Mono.just(definition.getId())).subscribe();
} catch (Exception e) {
log.error("update 失败。没有找到对应的路由ID :{}", definition.getId());
}
routeDefinitionWriter.save(Mono.just(definition)).subscribe();
this.publisher.publishEvent(new RefreshRoutesEvent(this));
return true;
}
/**
* serviceId
*
* @param id
* @return
*/
public boolean del(String id) {
routeDefinitionWriter.delete(Mono.just(id)).subscribe();
this.publisher.publishEvent(new RefreshRoutesEvent(this));
return true;
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.publisher = applicationEventPublisher;
}
}
RefreshRouteService文件
新建RefreshRouteService文件并实现ApplicationEventPublisherAware
@Component
@Slf4j
public class RefreshRouteService implements ApplicationEventPublisherAware {
private ApplicationEventPublisher publisher;
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
this.publisher = publisher;
}
/**
* 刷新路由表
*/
public void refreshRoutes() {
publisher.publishEvent(new RefreshRoutesEvent(this));
}
}
新建GatewayRoutesController
@RestController
@RequestMapping("/gateway")
public class GatewayRoutesController {
@Autowired
private RefreshRouteService refreshRouteService;
@Autowired
private DynamicRouteServiceImpl dynamicRouteService;
@GetMapping("/refreshRoutes")
public CommonResult refreshRoutes() {
refreshRouteService.refreshRoutes();
return CommonResult.builder().message("成功").build();
}
/**
* @param
* @return
*/
@RequestMapping(value = "routes/add", method = RequestMethod.POST)
public CommonResult add(@RequestBody RouteDefinition routeDefinition) {
boolean flag = dynamicRouteService.add(routeDefinition);
if (flag) return CommonResult.builder().message("成功").build();
return CommonResult.builder().message("失败").build();
}
/**
* @param definition
* @return
*/
@RequestMapping(value = "routes/update", method = RequestMethod.POST)
public CommonResult update(@RequestBody RouteDefinition definition) {
boolean flag = dynamicRouteService.update(definition);
if (flag) return CommonResult.builder().message("成功").build();
return CommonResult.builder().message("失败").build();
}
/**
* @param serviceId
* @return
*/
@RequestMapping(value = "routes/del", method = RequestMethod.POST)
public CommonResult update(@RequestParam("serviceId") String serviceId) {
boolean flag = dynamicRouteService.del(serviceId);
if (flag) return CommonResult.builder().message("成功").build();
return CommonResult.builder().message("失败").build();
}
}
至此gateway的动态路由就已经完成了,当需要添加路由时只需执行routes/add接口 传入相对应的参数格式即可