• 物联网架构成长之路(54)-基于Nacos+Gateway实现动态路由


    0. 前言
      本来就负责一些小事情,但是还是要搞事情。把一个小项目切分成微服务,练练手。
      主要是以Nacos为配置中心,实现Spring Cloud GateWay的动态路由功能。然后在实现日志、鉴权等功能。动态路由,就是在Spring Cloud Gateway启动的时候,将路由配置和规则加载到内存里,但是通过集成Nacos,增加一个监听器,就可以在不重启网关,实现对应路由的配置和规则更新。实现动态路由。


    1. 集成Nacos和Spring Cloud GateWay
      pom.xml

     1         <dependency>
     2             <groupId>org.springframework.boot</groupId>
     3             <artifactId>spring-boot-starter-actuator</artifactId>
     4         </dependency>
     5         
     6         <!-- Gateway Nacos Sentinel 网关路由、配置中心、服务器注册中心、流量控制、熔断降级 -->
     7         <dependency>
     8             <groupId>org.springframework.cloud</groupId>
     9             <artifactId>spring-cloud-starter-gateway</artifactId>
    10         </dependency>
    11         <dependency>
    12             <groupId>com.alibaba.cloud</groupId>
    13             <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    14         </dependency>
    15         <dependency>
    16             <groupId>com.alibaba.cloud</groupId>
    17             <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    18         </dependency>
    19         <dependency>
    20             <groupId>com.alibaba.cloud</groupId>
    21             <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    22         </dependency>

      bootstrap.properties

    1 #dev/test/prod
    2 spring.profiles.active=dev
    3 #nacos
    4 spring.cloud.nacos.server-addr=127.0.0.1:8848
    5 spring.cloud.nacos.config.namespace=0e152861-1efa-62ea-9125-e569abc29691
    6 spring.cloud.nacos.discovery.namespace=0e152861-1efa-62ea-9125-e569abc29691
    7 spring.cloud.nacos.config.prefix=xxxx-story-gateway
    8 spring.cloud.nacos.config.file-extension=properties

    2. 配置动态路由到Nacos

      具体配置路由信息

     1 [{
     2     "id": "xxxx-story-res",
     3     "order": 1,
     4     "predicates": [{
     5         "args": {
     6             "pattern": "/res/v1/**"
     7         },
     8         "name": "Path"
     9     }],
    10     "uri": "lb://xxxx-story-res"
    11 },{
    12     "id": "xxxx-story-aiml",
    13     "order": 2,
    14     "predicates": [{
    15         "args": {
    16             "pattern": "/aiml/v1/**"
    17         },
    18         "name": "Path"
    19     }],
    20     "uri": "lb://xxxx-story-aiml"
    21 }]

    3. Java代码里增加一个BeanConfig就可以实现
      DynamicRouteConfig.java

      1 package com.wunaozai.demo.story.gateway.config;
      2 
      3 import java.util.ArrayList;
      4 import java.util.List;
      5 import java.util.Properties;
      6 import java.util.concurrent.Executor;
      7 
      8 import javax.annotation.PostConstruct;
      9 
     10 import org.slf4j.Logger;
     11 import org.slf4j.LoggerFactory;
     12 import org.springframework.beans.factory.annotation.Autowired;
     13 import org.springframework.beans.factory.annotation.Value;
     14 import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
     15 import org.springframework.cloud.gateway.route.RouteDefinition;
     16 import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
     17 import org.springframework.context.ApplicationEventPublisher;
     18 import org.springframework.context.ApplicationEventPublisherAware;
     19 import org.springframework.stereotype.Service;
     20 
     21 import com.alibaba.fastjson.JSONObject;
     22 import com.alibaba.nacos.api.NacosFactory;
     23 import com.alibaba.nacos.api.config.ConfigService;
     24 import com.alibaba.nacos.api.config.listener.Listener;
     25 
     26 import reactor.core.publisher.Mono;
     27 
     28 /**
     29  * 动态路由,可以通过获取Bean才做该类,提供增删改查已经发布功能
     30  * @author wunaozai
     31  * @Date 2020-03-16
     32  */
     33 @Service
     34 public class DynamicRouteConfig implements ApplicationEventPublisherAware {
     35 
     36     private static final Logger log = LoggerFactory.getLogger(DynamicRouteConfig.class);
     37 
     38     @Autowired
     39     private RouteDefinitionWriter routedefinitionWriter;
     40     
     41     private ApplicationEventPublisher publisher;
     42     
     43     private String dataId = "gateway-router.properties";
     44     private String group = "DEFAULT_GROUP";
     45     @Value("${spring.cloud.nacos.server-addr}")
     46     private String serverAddr;
     47     @Value("${spring.cloud.nacos.config.namespace}")
     48     private String namespace;
     49     
     50     private static final List<String> ROUTE_LIST = new ArrayList<>();
     51     
     52     @PostConstruct
     53     public void dynamicRouteByNacosListener() {
     54         try {
     55             Properties prop = new Properties();
     56             prop.put("serverAddr", serverAddr);
     57             prop.put("namespace", namespace);
     58             ConfigService config = NacosFactory.createConfigService(prop);
     59             String content = config.getConfig(dataId, group, 5000);
     60             publisher(content);
     61             config.addListener(dataId, group, new Listener() {
     62                 @Override
     63                 public void receiveConfigInfo(String config) {
     64                     publisher(config);
     65                 }
     66                 @Override
     67                 public Executor getExecutor() {
     68                     return null;
     69                 }
     70             });
     71         } catch (Exception e) {
     72             e.printStackTrace();
     73         }
     74     }
     75     
     76     /**
     77      * 增加路由
     78      * @param def
     79      * @return
     80      */
     81     public Boolean addRoute(RouteDefinition def) {
     82         try {
     83             routedefinitionWriter.save(Mono.just(def)).subscribe();
     84             ROUTE_LIST.add(def.getId());    
     85         } catch (Exception e) {
     86             e.printStackTrace();
     87         }
     88         return true;
     89     }
     90     /**
     91      * 删除路由
     92      * @return
     93      */
     94     public Boolean clearRoute() {
     95         for(String id: ROUTE_LIST) {
     96             routedefinitionWriter.delete(Mono.just(id)).subscribe();
     97         }
     98         ROUTE_LIST.clear();
     99         return false;
    100     }
    101     /**
    102      * 发布路由
    103      */
    104     private void publisher(String config) {
    105         clearRoute();
    106         try {
    107             log.info("重新更新动态路由");
    108             List<RouteDefinition> gateway = JSONObject.parseArray(config, RouteDefinition.class);
    109             for(RouteDefinition route: gateway) {
    110                 addRoute(route);
    111             }
    112             publisher.publishEvent(new RefreshRoutesEvent(this.routedefinitionWriter));
    113         } catch (Exception e) {
    114             e.printStackTrace();
    115         }
    116         
    117     }
    118     
    119     @Override
    120     public void setApplicationEventPublisher(ApplicationEventPublisher app) {
    121         publisher = app;
    122     }
    123 
    124 }

      请求不同的URL转发到不同的服务器上
      /res/v1/**
      /aiml/v1/**


      至此就完成简单的动态路由功能了。我们修改nacos上的 gateway-router.properties ,程序会自动执行 DynamicRouteConfig.java 里面的 receiveConfigInfo 方法。动态加载配置,动态发布更新路由。
      用到Gateway,一般是用来实现鉴权,限流,熔断,网关路由,日志等功能。这一篇介绍了网关路由功能,由于SpringBoot默认就有日志功能,这里就不展开说。下一篇将介绍集成Sentinel的限流和熔断。再下一篇是介绍基于SpringBoot Secret 的Oauth2.0鉴权,结合到该项目中。


    参考资料:
      https://blog.csdn.net/zhangchangbin123/article/details/89310353

    本文地址:https://www.cnblogs.com/wunaozai/p/12512753.html
    本系列目录: https://www.cnblogs.com/wunaozai/p/8067577.html
    个人主页:https://www.wunaozai.com/

  • 相关阅读:
    PostMan 安装步骤详解
    使用MySQL,运行系统报错Authentication method 'caching_sha2_password' is not supported.
    jmeter安装和环境变量配置
    Svn项目迁移到Git及Visual Studio 中git使用
    SQLServer 2008以上误操作数据库恢复方法
    ABP入门系列之3——创建实体/Code First创建数据表
    ABP入门系列之2——ABP模板项目
    uni-app使用Canvas绘图
    uni-app中picker组件的一个坑
    Nginx用法详解
  • 原文地址:https://www.cnblogs.com/wunaozai/p/12512753.html
Copyright © 2020-2023  润新知