基于SpringCloudGateway的动态路由配置

该项目基于SpringBoot+Eureka+Mybaties实现动态路由。

1、引入SpringCloudGateway的maven依赖:

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-gateway</artifactId>
	<version>2.1.2.RELEASE</version>
    <exclusions>
		<exclusion>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-gateway-core</artifactId>
		</exclusion>
	</exclusions>
</dependency>
<dependency>
	<artifactId>spring-cloud-gateway-core</artifactId>
	<groupId>org.springframework.cloud</groupId>
	<version>2.1.2.RELEASE</version>
</dependency>
<!-- 引入健康监控依赖 -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-actuator</artifactId>
	<version>2.1.2.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<version>8.0.15</version>
	<scope>runtime</scope>
</dependency>
<!--阿里数据库连接池 -->
<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>druid-spring-boot-starter</artifactId>
	<version>1.1.14</version>
</dependency>
<!-- mybatis -->
<dependency>
	<groupId>tk.mybatis</groupId>
	<artifactId>mapper-spring-boot-starter</artifactId>
	<version>2.1.5</version>
</dependency>

若引入其他base项目,请排除对 spring-boot-starter-web 的依赖:

<exclusions>
	<exclusion>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</exclusion>
</exclusions>

2、基础数据结构构建

路由配置表结构:

CREATE TABLE `gateway_route` (
  `id` bigint(20) NOT NULL COMMENT '主键',
  `route_name` varchar(500) NOT NULL COMMENT '路由名称',
  `predicates` varchar(500) DEFAULT NULL COMMENT '路由断言',
  `filters` varchar(500) DEFAULT NULL COMMENT '过滤器',
  `service_uri` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '服务定位符 lb://XXX',
  `route_order` int(6) DEFAULT NULL COMMENT '优先级',
  `status` int(3) NOT NULL DEFAULT '1' COMMENT '状态: 1-有效,2-无效',
  `create_by` varchar(30) NOT NULL COMMENT '创建人',
  `create_time` datetime NOT NULL COMMENT '创建日期',
  `modify_by` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '更新人',
  `modify_time` datetime DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='服务路由';
//数据如下:
INSERT INTO gateway_route (`id`, `route_name`, `predicates`, `filters`, `service_uri`, `route_order`, `status`, `create_by`, `create_time`, `modify_by`, `modify_time`) VALUES ('202009011800', 'sys', '[{\"name\": \"Path\",\"args\": {\"pattern\": \"/sys/**\"}}]', '[{\"name\": \"RewritePath\",\"args\": {\"regexp\": \"/sys/(?<remaining>.*)\",\"replacement\": \"/${remaining}\"}}]', 'lb://appl-zb-hospital-system', '0', '1', 'sys', '2020-09-01 17:59:21', NULL, NULL);

3、项目配置:

spring:
  datasource:
	type: com.alibaba.druid.pool.DruidDataSource
	driverClassName: com.mysql.cj.jdbc.Driver
	url: jdbc:mysql://XX.XX.XX.XX:3306/dbName?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
	username: root
	password: password

server:
  port: xxx
  ssl:
	#ssl配置,若gateway使用HTTPS,需要添加如下配置,
	#注意若使用该方式 服务实例向Eureka注册时应开启安全通信的端口
	key-store: classpath:xxx.pfx
	key-store-password: xxx
	key-store-type: xxx
	enabled: true

mybatis:
  #对应项目中的model对应位置
  type-aliases-package: com.xxx.gateway.model
  #对应项目中xxxMapper.xml对应位置,一般为 resources/mapper/
  mapper-locations: classpath*:mapper/**/*Mapper.xml

logging:
  level:
	#打印输出执行sql 对应xxxxMapper.java 路径
	com.xxxx.gateway.mapper: debug

4、项目相关Bean的配置:

@EnableDiscoveryClient
@EnableEurekaClient
//@MapperScan("com.xxxx.gateway.mapper") 扫描 mybaties对应的 xxxxMapper.java 亦可在对应类上使用@Mapper注解
@SpringBootApplication
public class GatewayApplication {
	public static void main(String[] args) {
		SpringApplication.run(GatewayApplication.class, args);
	}
	//路由定义定位器,用以加载路由信息到内存中
	@Bean
	public InMemoryRouteDefinitionRepository routeDefinitionRepository() {
		return new InMemoryRouteDefinitionRepository();
	}

}

5、路由信息加载(GatewayServiceImpl):

@Autowired
private InMemoryRouteDefinitionRepository routeDefinitionRepository;

@Autowired
private GatewayRouteMapper gatewayRouteMapper;

/**
 * 加载数据库路由信息到内存
 * @return
 * @throws Exception
 */
@Override
public String loadRouteDefinition() throws Exception {
    try {
        //获取数据库中路由配置信息
        List<GatewayRoute> gatewayRouteList = gatewayRouteMapper.getRoutes();
        for (GatewayRoute gatewayRoute: gatewayRouteList) {
			//将库中路由信息封装为RouteDefinition对象,加载到内存中
            RouteDefinition definition  = assembleRouteDefinition(gatewayRoute);
            if(definition!=null){
                routeDefinitionRepository.save(Mono.just(definition)).subscribe();
            }
        }
        return "success";
    } catch (Exception e) {
        log.error("Exception: ",e);
        return "failure";
    }
}

/**
 * 封装成为 RouteDefinition 对象
 * @param gatewayDefine
 * @return
 */
private RouteDefinition assembleRouteDefinition(GatewayRoute gatewayRoute) {
    RouteDefinition definition = new RouteDefinition();
    definition.setId(gatewayRoute.getId());
    definition.setOrder(gatewayRoute.getRouteOrder());
    if(StringUtils.isEmpty(gatewayRoute.getPredicates()) || StringUtils.isEmpty(gatewayRoute.getFilters())
            || StringUtils.isEmpty(gatewayRoute.getServiceUri())){
        return null;
    }
    if(gatewayRoute.getPredicateDefinition().size()>0)
        definition.setPredicates(gatewayRoute.getPredicateDefinition());
    if(gatewayRoute.getFilterDefinition().size()>0)
        definition.setFilters(gatewayRoute.getFilterDefinition());
    URI uri = UriComponentsBuilder.fromUriString(gatewayRoute.getServiceUri()).build().toUri();
    definition.setUri(uri);
    return definition;
}

6、启动路由加载配置:

@Component
public class ApplicationStartup implements ApplicationRunner {

    private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationStartup.class);

    @Autowired
    private GatewayService gatewayService;

    @Override
    public void run(ApplicationArguments args) throws Exception {
		//调用上述方法
        gatewayService.loadRouteDefinition();
    }
}

之后启动项目,查看加载路由信息:

https://localhost:xxx/actuator/gateway/routes

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值