写点什么

🍃【SpringCloud 基础使用】Nacos 与 Gateway 实现动态路由

发布于: 2021 年 05 月 28 日
🍃【SpringCloud基础使用】Nacos与Gateway实现动态路由

每日一句

人生就是一种追求,一种努力,一种期盼。渴望着把梦想变成现实,将虚幻化为真实。生活,因梦而美好;人生,因梦而苦闷。然而,再难的道,也有尽头;再长的路,也有出口,坚持就会有光明。

动态网关配置

一. Maven 依赖

<!-- 网关依赖 --><dependency>    <groupId>org.springframework.cloud</groupId>    <artifactId>spring-cloud-starter-gateway</artifactId></dependency><!-- nacos注册中心 --><dependency>    <groupId>com.alibaba.cloud</groupId>    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!-- nacos配置中心 --><dependency>    <groupId>com.alibaba.cloud</groupId>    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><!-- 简化set/get --><dependency>    <groupId>org.projectlombok</groupId>    <artifactId>lombok</artifactId></dependency><!-- 支持yml、properties文件提示 --><dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-configuration-processor</artifactId>    <optional>true</optional></dependency><!-- yaml解析包 --><dependency>    <groupId>org.yaml</groupId>    <artifactId>snakeyaml</artifactId></dependency>
复制代码

二.创建配置提示

1、DynamicRouteProperties 类
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; }
复制代码
2、创建 yml 参数规则

在 resources/META-INF 下创建 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(); }}
复制代码

2.configuration 类

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); }
}
复制代码

四.配置 bootstrap.yml

nacos 2.2.0 及以下版本配置文件必须是 bootstrap 级别,不然只会找 localhost:8848 地址

server:  port: 9000spring:  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/
复制代码

补充文件说明:

如果服务名和路由相同时

  • 可不用配置动态路由,nacos 会自动做好路由

  • 需要配置:spring.cloud.gateway.discovery.locator.enabled=true

如果服务名和路由不同时

  • 需要自己在 nacos 配置管理创建一个 yml 格式的配置,创建时的参数根据自己的配置设定来创建{@link DynamicRouteConfigBean}

动态路由 yml 配置文件说明

  • 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


发布于: 2021 年 05 月 28 日阅读数: 68
用户头像

我们始于迷惘,终于更高水平的迷惘。 2020.03.25 加入

🏆 【酷爱计算机技术、醉心开发编程、喜爱健身运动、热衷悬疑推理的”极客狂人“】 🏅 【Java技术领域,MySQL技术领域,APM全链路追踪技术及微服务、分布式方向的技术体系等】 🤝未来我们希望可以共同进步🤝

评论

发布
暂无评论
🍃【SpringCloud基础使用】Nacos与Gateway实现动态路由