Spring Cloud Zuul MySQL 实现动态路由以及手动刷新
介绍
实现zuul的动态路由可通过两种方式
- 基于配置中心实现配置文件动态刷新
- 基于数据库存储配置文件,发布
RoutesRefreshedEvent
事件,触发SimpleRouteLocator
重新加载配置
代码参考:https://github.com/iyezhou/zuul-gateway-demo
实现步骤
数据库初始化
CREATE TABLE `zuul_route` (
`id` varchar(50) NOT NULL,
`path` varchar(255) NOT NULL,
`service_id` varchar(50) DEFAULT NULL,
`url` varchar(255) DEFAULT NULL,
`strip_prefix` tinyint(1) DEFAULT '1',
`retryable` tinyint(1) DEFAULT '0',
`enabled` tinyint(1) NOT NULL DEFAULT '1',
`description` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into `zuul_route`(`id`,`path`,`service_id`,`url`,`strip_prefix`,`retryable`,`enabled`,`description`) values ('pppp','/client/**',NULL,'http://localhost:7070',1,0,1,'url');
配置文件
server:
port: 8080
eureka:
client:
serviceUrl:
defaultZone: http://127.0.0.1:8000/eureka/ #注册中心地址
registry-fetch-interval-seconds: 15 #客户端拉取服务端的频率
spring:
application:
name: zuul
datasource:
url: jdbc:mysql://rm-bp1e5s5co.mysql.rds.aliyuncs.com:3306/zuul?useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.jdbc.Driver
username: rook
password: Hou5
ribbon:
eureka:
enabled: true
数据库访问
public class ZuulRouteEntity {
private String id;
private String path;
private String serviceId;
private String url;
private boolean stripPrefix = true;
private Boolean retryable;
private Boolean enabled;
private String description;
}
@Component
public class PropertiesDao {
@Autowired
private JdbcTemplate jdbcTemplate;
private final static String SQL = "SELECT * FROM zuul_route WHERE enabled = TRUE";
public Map<String, ZuulRoute> getProperties() {
Map<String, ZuulRoute> routes = new LinkedHashMap<>();
List<ZuulRouteEntity> list = jdbcTemplate.query(SQL, new BeanPropertyRowMapper<>(ZuulRouteEntity.class));
list.forEach(entity -> {
if (StringUtils.isEmpty(entity.getPath())) {
return;
}
ZuulRoute zuulRoute = new ZuulRoute();
BeanUtils.copyProperties(entity, zuulRoute);
routes.put(zuulRoute.getPath(), zuulRoute);
});
return routes;
}
}
重写理由配置加载方法
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.zuul.filters.RefreshableRouteLocator;
import org.springframework.cloud.netflix.zuul.filters.SimpleRouteLocator;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute;
import org.springframework.util.StringUtils;
import java.util.LinkedHashMap;
import java.util.Map;
public class DynamicZuulRouteLocator extends SimpleRouteLocator implements RefreshableRouteLocator {
@Autowired
private ZuulProperties properties;
@Autowired
private PropertiesDao propertiesDao;
public DynamicZuulRouteLocator(String servletPath, ZuulProperties properties) {
super(servletPath, properties);
this.properties = properties;
}
@Override
public void refresh() {
doRefresh();
}
@Override
protected Map<String, ZuulRoute> locateRoutes() {
LinkedHashMap<String, ZuulRoute> routesMap = new LinkedHashMap<>();
routesMap.putAll(super.locateRoutes());
routesMap.putAll(propertiesDao.getProperties());
LinkedHashMap<String, ZuulRoute> values = new LinkedHashMap<>();
routesMap.forEach((key, value) -> {
String path = key;
if (!path.startsWith("/")) {
path = "/" + path;
}
if (StringUtils.hasText(this.properties.getPrefix())) {
path = this.properties.getPrefix() + path;
if (!path.startsWith("/")) {
path = "/" + path;
}
}
values.put(path, value);
});
return values;
}
}
@Configuration
public class DynamicZuulConfig {
@Autowired
private ZuulProperties zuulProperties;
@Autowired
private ServerProperties serverProperties;
@Bean
public DynamicZuulRouteLocator routeLocator() {
DynamicZuulRouteLocator routeLocator = new DynamicZuulRouteLocator(
serverProperties.getServlet().getContextPath(), zuulProperties);
return routeLocator;
}
}
刷新接口
@RestController
public class RefreshController {
@Autowired
private ApplicationEventPublisher publisher;
@Autowired
private RouteLocator routeLocator;
@Autowired
private ZuulHandlerMapping zuulHandlerMapping;
@GetMapping("refreshRoute")
public String refreshRoute() {
RoutesRefreshedEvent routesRefreshedEvent = new RoutesRefreshedEvent(routeLocator);
publisher.publishEvent(routesRefreshedEvent);
return "refresh success";
}
@GetMapping("watchRoute")
public Object watchNowRoute() {
//可以用debug模式看里面具体是什么
return zuulHandlerMapping.getHandlerMap();
}
}
版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/04/02/spring-cloud-zuul-mysql-implements-dynamic-routing-and-manual-refresh/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。
THE END
1
二维码
打赏
海报
Spring Cloud Zuul MySQL 实现动态路由以及手动刷新
介绍
实现zuul的动态路由可通过两种方式
基于配置中心实现配置文件动态刷新
基于数据库存储配置文件,发布RoutesRefreshedEvent事件,触发SimpleRouteLocator……
文章目录
关闭
共有 0 条评论