SpringCloud Gateway 使用 Mysql(R2DBC) 存储路由信息
表结构
1 2 3 4 5 6 7
| CREATE TABLE `sys_route` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键自动增加', `proxy_address` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '要代理的地址', `location` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '请求前缀', `strip_prefix` tinyint(4) NOT NULL COMMENT 'strip_prefix', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
代码配置
application.properties 配置文件
1 2 3 4 5 6
| server.port=80
spring.r2dbc.url=r2dbc:mysql://127.0.0.1:3306/gateway-sample spring.r2dbc.username=root spring.r2dbc.password=147258369
|
DBRouteDomain 实体类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| package net.wchar.code.sample.gateway.domain;
import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.data.annotation.Id; import org.springframework.data.relational.core.mapping.Column; import org.springframework.data.relational.core.mapping.Table;
@Data @Builder @NoArgsConstructor @AllArgsConstructor @Table(DBRouteDomain.TABLE_NAME) public class DBRouteDomain {
public static final String TABLE_NAME = "sys_route";
@Id private Long id;
@Column(value = "proxy_address") private String proxyAddress;
@Column(value = "location") private String location;
@Column(value = "strip_prefix") private Integer stripPrefix; }
|
DBRouteRepository 访问数据库类
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| package net.wchar.code.sample.gateway.repository;
import net.wchar.code.sample.gateway.domain.DBRouteDomain; import org.springframework.data.repository.reactive.ReactiveCrudRepository; import org.springframework.stereotype.Repository;
@Repository public interface DBRouteRepository extends ReactiveCrudRepository<DBRouteDomain, Long> {
}
|
DBRouteConfiguration 配置类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| package net.wchar.code.sample.gateway.config;
import lombok.AllArgsConstructor; import net.wchar.code.sample.gateway.domain.DBRouteDomain; import net.wchar.code.sample.gateway.repository.DBRouteRepository; import org.springframework.cloud.gateway.route.Route; import org.springframework.cloud.gateway.route.RouteLocator; import org.springframework.cloud.gateway.route.builder.Buildable; import org.springframework.cloud.gateway.route.builder.PredicateSpec; import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import reactor.core.publisher.Flux;
@Configuration public class DBRouteConfiguration { @Bean public RouteLocator routeLocator(DBRouteRepository dbRouteRepository, RouteLocatorBuilder routeLocatorBuilder) { return new DBRouteLocatorImpl(dbRouteRepository, routeLocatorBuilder); }
@AllArgsConstructor private static class DBRouteLocatorImpl implements RouteLocator {
private final DBRouteRepository dbRouteRepository; private final RouteLocatorBuilder routeLocatorBuilder;
@Override public Flux<Route> getRoutes() { RouteLocatorBuilder.Builder routesBuilder = routeLocatorBuilder.routes(); return dbRouteRepository.findAll() .map(route -> routesBuilder.route(String.valueOf(route.getId()), predicateSpec -> setPredicateSpec(route, predicateSpec))) .collectList() .flatMapMany(builders -> routesBuilder.build() .getRoutes()); }
private Buildable<Route> setPredicateSpec(DBRouteDomain dbRouteDomain, PredicateSpec predicateSpec) { return predicateSpec.path(dbRouteDomain.getLocation()).and().method( HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT, HttpMethod.DELETE, HttpMethod.PATCH, HttpMethod.HEAD, HttpMethod.OPTIONS, HttpMethod.TRACE ).filters(f -> f.stripPrefix(dbRouteDomain.getStripPrefix())).uri(dbRouteDomain.getProxyAddress()); } } }
|
运行测试
在表中添加一条数据
1 2
| id | proxy_address | location | strip_prefix 1 | https://www.baidu.com | /baidu | 1
|
访问 http://localhost/baidu
到这一步就算是成功了,那要是在数据库添加一条数据,该怎么刷新路由呢?
哈哈,只需发射一个事件即可让gateway重新加载即可
1
| //( @Autowired ApplicationEventPublisher) applicationEventPublisher.publishEvent(new RefreshRoutesEvent(this));
|
完整代码: https://github.com/wchar-net/gateway-use-mysql-sample