<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-gatewayartifactId>
dependency>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
dependency>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-configartifactId>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-configuration-processorartifactId>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.yamlgroupId>
<artifactId>snakeyamlartifactId>
dependency>
package com.ksaas.cloud.gateway.config;
import lombok.Data;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* 包含 动态路由配置 的属性
*
* @author kylin
* @see DynamicRouteConfiguration
* @since 1.0.0
*/
@Data
@Component
@ConfigurationProperties(prefix = "ksaas.dynamic.route")
@ConditionalOnBean(DynamicRouteConfiguration.class)
public class DynamicRouteProperties {
/**
* nacos 配置管理 dataId
*/
private String dataId;
/**
* nacos 配置管理 group
*/
private String group;
/**
* nacos 服务地址
*/
private String ipAddr;
/**
* 启动动态路由的标志,默认关闭
*/
private boolean enabled = false;
}
在resources/MATA-INFO下创建
spring-configuration-metadata.json
{
"groups": [
{
"sourceType": "com.ksaas.cloud.gateway.config.DynamicRouteConfiguration",
"name": "动态路由配置属性",
"type": "com.ksaas.cloud.gateway.config.DynamicRouteConfiguration"
}
],
"hints": [
{
"name": "ksaas.dynamic.route.enabled",
"values": [
{
"value": true
},
{
"value": false
}
]
}
],
"properties": [
{
"sourceType": "com.ksaas.cloud.gateway.config.DynamicRouteConfiguration",
"name": "ksaas.dynamic.route.dataId",
"type": "java.lang.String",
"desc": "dataId specified in Nacos configuration management"
},
{
"sourceType": "com.ksaas.cloud.gateway.config.DynamicRouteConfiguration",
"name": "ksaas.dynamic.route.group",
"type": "java.lang.String",
"desc": "group specified in Nacos configuration management"
},
{
"sourceType": "com.ksaas.cloud.gateway.config.DynamicRouteConfiguration",
"name": "ksaas.dynamic.route.ipAddr",
"type": "java.lang.String",
"desc": "nacos host address"
},
{
"sourceType": "com.ksaas.cloud.gateway.config.DynamicRouteConfiguration",
"name": "ksaas.dynamic.route.enabled",
"type": "java.lang.Boolean",
"desc": "Flag that enables dynamic route"
}
]
}
####1、yaml读取工具
package com.ksaas.cloud.gateway.util;
import org.yaml.snakeyaml.Yaml;
/**
* Yaml 工具
*
* @author kylin
*/
public abstract class YamlHelper {
private YamlHelper() {}
public static Yaml getInstance() {
return InnerClass.YAML;
}
private static class InnerClass {
private static final Yaml YAML = new Yaml();
}
}
package com.ksaas.cloud.gateway.config;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.AbstractListener;
import com.alibaba.nacos.api.exception.NacosException;
import com.ksaas.cloud.gateway.util.YamlHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.Assert;
import reactor.core.publisher.Mono;
import javax.annotation.PostConstruct;
import java.util.List;
/**
* 动态路由配置
*
* @author kylin
* @see route\example.yml 动态路由yml内容格式参考
* @see DynamicRouteProperties 动态路由参数配置说明
* @since 1.0.0
*/
@Slf4j
@Configuration
@ConditionalOnProperty(name = "ksaas.dynamic.route.enabled", matchIfMissing = true)
public class DynamicRouteConfiguration {
private DynamicRouteProperties bean;
private RouteDefinitionWriter writer;
private ApplicationEventPublisher publisher;
public DynamicRouteConfiguration(DynamicRouteProperties bean, RouteDefinitionWriter writer, ApplicationEventPublisher publisher) {
this.bean = bean;
this.writer = writer;
this.publisher = publisher;
}
@PostConstruct
private void init() {
Assert.notNull(bean.getDataId(), "ksaas.dynamic.route.dataId null异常");
Assert.notNull(bean.getGroup(), "ksaas.dynamic.route.group is null异常");
Assert.notNull(bean.getIpAddr(), "ksaas.dynamic.route.ipAddr is null异常");
dynamicRouteByNacosListener();
}
private void dynamicRouteByNacosListener() {
try {
ConfigService configService = NacosFactory.createConfigService(bean.getIpAddr());
String content = configService.getConfigAndSignListener(
bean.getDataId(),
bean.getGroup(),
5000,
new AbstractListener() {
@Override
public void receiveConfigInfo(String configInfo) {
updateConfig(configInfo);
}
});
updateConfig(content);
} catch (NacosException e) {
log.error("nacos 获取动态路由配置和监听异常", e);
}
}
private void updateConfig(String content) {
log.info("nacos 动态路由更新: {}", content);
try {
getRouteDefinitions(content).forEach(routeDefinition -> {
log.info("动态路由配置: {}", routeDefinition);
writer.delete(Mono.just(routeDefinition.getId()));
writer.save(Mono.just(routeDefinition)).subscribe();
publisher.publishEvent(new RefreshRoutesEvent(this));
});
} catch (Exception e) {
log.error("更新动态路由配置异常: ", e);
}
}
private List<RouteDefinition> getRouteDefinitions(String content) {
// 如果文件是json,这里则直接把内容转会为json即可
return JSON.parseArray(JSON.toJSONString(
YamlHelper.getInstance().load(content)
), RouteDefinition.class);
}
}
nacos 2.2.0 及以下版本配置文件必须是bootstrap级别,不然只会找localhost:8848地址
server:
port: 9000
spring:
application:
# 应用名称
name: spring-gateway
cloud:
# 使用 Naoos 作为服务注册发现、配置中心
nacos:
server-addr: 192.168.1.150:8848
# 路由网关配置
gateway:
# 设置与服务注册发现组件结合,这样可以采用服务名的路由策略
discovery:
locator:
enabled: true
# 自定义动态路由配置,对应nacos配置列表参数
ksaas:
dynamic:
route:
dataId: gateway_dynamic_route_config
group: refresh_gateway_dynamic_route_config
ipAddr: ${spring.cloud.nacos.server-addr}
enabled: true
# 配置日志级别,方别调试
logging:
level:
org.springframework.cloud.gateway: debug
直接在nacos配置中心,创建即可,dataId 和 group创建对应的yml文件即可
- 想做成json,可以直接把下面内容去网上转换位json即可
- id: route1
filters:
- args:
parts: 1
name: StripPrefix
predicates:
- args:
pattern: /consumer-h/**
name: Path
uri: lb://consumer-h
- id: route2
filters:
- args:
parts: 1
name: StripPrefix
predicates:
- args:
pattern: /lilei/**
name: Path
uri: lb://nacos-test
- id: route3
filters:
- args:
parts: 1
name: StripPrefix
predicates:
- args:
pattern: /lilei4/**
name: Path
uri: https://www.baidu.com/
id:采用自定义路由 ID(有固定用法,不同的 id 有不同的功能,详见:https://cloud.spring.io/spring-cloud-gateway/2.0.x/single/spring-cloud-gateway.html#gateway-route-filters)
filters:url过滤器,例如添加请求参数,删除前缀等,参考接口:GatewayFilterFactory
predicates:翻译过来是“谓词”的意思,必须,主要作用是匹配用户的请求,有很多种用法,参考接口:GatewayPredicate
uri:采用 LoadBalanceClient 方式请求,以 lb:// 开头,后面的是注册在 Nacos 上的服务名
gateway:
discovery:
locator:
enabled: true