北极星Polaris+Gateway动态网关配置!
springcloudtencetn 父工程:
pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.gton</groupId>
    <artifactId>cloud</artifactId>
    <packaging>pom</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <modules>
        <module>gateway</module>
        <module>usermanager</module>
        <module>commodity</module>
        <module>back-stage-management</module>
        <module>common</module>
    </modules>
    <name>cloud</name>
    <description>Spring Cloud Tencent +北极星(服务管理 流量管理 故障容错 配置管理) 微服务架构系统</description>
    <properties>
        <java.version>11</java.version>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <spring-cloud-tencent-version>1.7.0-2021.0.3</spring-cloud-tencent-version>
        <spring-cloud-dependencies-version>2021.0.3</spring-cloud-dependencies-version>
        <projectlombok-version>1.18.16</projectlombok-version>
        <spring-boot.version>2.6.9</spring-boot.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.tencent.cloud</groupId>
                <artifactId>spring-cloud-tencent-dependencies</artifactId>
                <version>${spring-cloud-tencent-version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud-dependencies-version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.16</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>11</source>
                    <target>11</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
gateway导入pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>cloud</artifactId>
        <groupId>com.gton</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>gateway</artifactId>
    <properties>
        <fastJson-version>2.0.18</fastJson-version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <!--网关路由-->
        <dependency>
            <groupId>com.tencent.cloud</groupId>
            <artifactId>spring-cloud-starter-tencent-polaris-router</artifactId>
        </dependency>
        <!--服务注册与发现-->
        <dependency>
            <groupId>com.tencent.cloud</groupId>
            <artifactId>spring-cloud-starter-tencent-polaris-discovery</artifactId>
        </dependency>
        <!--服务限流-->
        <dependency>
            <groupId>com.tencent.cloud</groupId>
            <artifactId>spring-cloud-starter-tencent-polaris-ratelimit</artifactId>
        </dependency>
        <!--北极星配置中心-->
        <dependency>
            <groupId>com.tencent.cloud</groupId>
            <artifactId>spring-cloud-starter-tencent-polaris-config</artifactId>
        </dependency>
        <!--北极星熔断-->
        <dependency>
            <groupId>com.tencent.cloud</groupId>
            <artifactId>spring-cloud-starter-tencent-polaris-circuitbreaker</artifactId>
        </dependency>
        <!--负载均衡-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
        <!-- bootstrap最高级启动配置读取 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-circuitbreaker-spring-retry</artifactId>
        </dependency>
        <!--使用gateway做网关-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.fastjson2</groupId>
            <artifactId>fastjson2</artifactId>
            <version>${fastJson-version}</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
</project>
网关配置:
spring:
  application:
    name: gateway
  cloud:
    gateway:
      discovery:
        locator:
          # 开启从注册中心动态创建路由的功能,利用微服务名进行路由
          enabled: true
    polaris:
      address: grpc://localhost:8091 #北极星注册中心地址
      namespace: polaris-cloud-market #北极星注册中心的使用命名空间,自定义
      config:
        auto-refresh: true #当配置发布后,动态刷新
        address:  grpc://localhost:8093  # 当配置中心和 注册中心地址不一致时可以选择,否着可以不填
        groups:
          - name: gatewayOnly #读取的文件所在分组
            files: ["router.properties","myconfig.yaml"]  #读取的文件名
北极星控制台配置

gateway网关的路由操作类:
package com.gton.service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionLocator;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import reactor.core.publisher.Mono;
import java.util.List;
/**
 * @description:动态更新路由网关service
 * @author: GuoTong
 * @createTime: 2022-10-05 22:24
 * @since JDK 1.8 OR 11
 **/
@Slf4j
@Service
public class DynamicRouteServiceImpl implements ApplicationEventPublisherAware {
    @Autowired
    private RouteDefinitionWriter routeDefinitionWriter;
    @Autowired
    private RouteDefinitionLocator routeDefinitionLocator;
    /**
     * 发布事件
     */
    @Autowired
    private ApplicationEventPublisher publisher;
    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.publisher = applicationEventPublisher;
    }
    /**
     * 删除路由
     *
     * @param id
     * @return
     */
    public String delete(String id) {
        try {
            log.info("gateway delete route id {}", id);
            this.routeDefinitionWriter.delete(Mono.just(id)).subscribe();
            this.publisher.publishEvent(new RefreshRoutesEvent(this));
            return "delete success";
        } catch (Exception e) {
            return "delete fail";
        }
    }
    /**
     * 更新路由
     *
     * @param definitions
     * @return
     */
    public String updateList(List<RouteDefinition> definitions) {
        log.info("gateway update route {}", definitions);
        // 删除缓存routerDefinition
        List<RouteDefinition> routeDefinitionsExits = routeDefinitionLocator.getRouteDefinitions().buffer().blockFirst();
        if (!CollectionUtils.isEmpty(routeDefinitionsExits)) {
            routeDefinitionsExits.forEach(routeDefinition -> {
                log.info("delete routeDefinition:{}", routeDefinition);
                delete(routeDefinition.getId());
            });
        }
        definitions.forEach(this::updateById);
        return "success";
    }
    /**
     * 更新路由
     *
     * @param definition
     * @return
     */
    public String updateById(RouteDefinition definition) {
        try {
            log.info("gateway update route {}", definition);
            this.routeDefinitionWriter.delete(Mono.just(definition.getId()));
        } catch (Exception e) {
            return "update fail,not find route  routeId: " + definition.getId();
        }
        try {
            routeDefinitionWriter.save(Mono.just(definition)).subscribe();
            this.publisher.publishEvent(new RefreshRoutesEvent(this));
            return "success";
        } catch (Exception e) {
            return "update route fail";
        }
    }
    /**
     * 增加路由
     *
     * @param definition
     * @return
     */
    public String add(RouteDefinition definition) {
        log.info("gateway add route {}", definition);
        routeDefinitionWriter.save(Mono.just(definition)).subscribe();
        this.publisher.publishEvent(new RefreshRoutesEvent(this));
        return "success";
    }
}
监听路由变化
package com.gton.listener;
import com.alibaba.fastjson2.JSONObject;
import com.gton.service.DynamicRouteServiceImpl;
import com.tencent.cloud.polaris.config.annotation.PolarisConfigKVFileChangeListener;
import com.tencent.cloud.polaris.config.listener.ConfigChangeEvent;
import com.tencent.polaris.api.utils.CollectionUtils;
import com.tencent.polaris.configuration.api.core.ChangeType;
import com.tencent.polaris.configuration.api.core.ConfigPropertyChangeInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.stereotype.Component;
import java.net.URI;
import java.util.*;
/**
 * @description: 监听Polaris的配置更新
 * @author: GuoTong
 * @createTime: 2022-11-24 22:25
 * @since JDK 1.8 OR 11
 **/
@Component
@Slf4j
@SuppressWarnings("all")
public class ListenerPolaris {
    @Autowired
    private DynamicRouteServiceImpl dynamicRouteService;
    /**
     * PolarisConfigKVFileChangeListener Example .
     * 监听北极星中心变更路由
     *
     * @param event instance of {@link ConfigChangeEvent}
     */
    @PolarisConfigKVFileChangeListener(interestedKeyPrefixes = "routes")
    public void onChange(ConfigChangeEvent event) {
        // 封装需要更新的路由规则数据
        List<RouteDefinition> routeUpdates = new ArrayList<>();
        // 获取配置修改的所有key
        Set<String> changedKeys = event.changedKeys();
        // 保留已经处理的
        Set<String> intIndex = new HashSet<>();
        for (String changedKey : changedKeys) {
            // 获取修改的实体
            ConfigPropertyChangeInfo changeInfo = event.getChange(changedKey);
            if (changeInfo.getChangeType() == ChangeType.ADDED) {
                String newValue = changeInfo.getNewValue();
                // 添加新路由
                addNewRule(routeUpdates, newValue);
            }
            // 删除老路由(弃用)
            if (changeInfo.getChangeType() == ChangeType.DELETED) {
                String newValue = changeInfo.getNewValue();
                JSONObject jsonObject = JSONObject.parseObject(newValue);
                String id = jsonObject.getString("id");
                dynamicRouteService.delete(id);
            }
            if (CollectionUtils.isNotEmpty(routeUpdates)) {
                routeUpdates.forEach(item -> dynamicRouteService.add(item));
            }
        }
    }
    /**
     * Description: 添加新路由
     *
     * @param routeUpdates
     * @param changeInfo
     * @author: GuoTong
     * @date: 2022-11-25 15:32:59
     * @return:void
     */
    public void addNewRule(List<RouteDefinition> routeUpdates, String newValue) {
        RouteDefinition routeDefinition = new RouteDefinition();
        JSONObject jsonObject = JSONObject.parseObject(newValue);
        routeDefinition.setId(jsonObject.getString("id"));
        routeDefinition.setUri(URI.create(jsonObject.getString("uri")));
        List<PredicateDefinition> predicates = routeDefinition.getPredicates();
        String predicates1 = jsonObject.getString("predicates");
        if (predicates1.contains(";")) {
            String[] split = predicates1.split(";");
            for (String vars : split) {
                String[] var3 = vars.split("=");
                PredicateDefinition predicateDefinition = new PredicateDefinition();
                predicateDefinition.setName(var3[0]);
                Map<String, String> args = predicateDefinition.getArgs();
                args.put(var3[0], var3[1]);
                predicates.add(predicateDefinition);
            }
        } else {
            String[] split = predicates1.split("=");
            PredicateDefinition predicateDefinition = new PredicateDefinition();
            predicateDefinition.setName(split[0]);
            Map<String, String> args = predicateDefinition.getArgs();
            args.put(split[0], split[1]);
            predicates.add(predicateDefinition);
        }
        List<FilterDefinition> filters = routeDefinition.getFilters();
        String var6 = jsonObject.getString("filters");
        if (var6.contains(";")) {
            String[] var7 = var6.split(";");
            for (String var8 : var7) {
                String[] split = var8.split("=");
                FilterDefinition filterDefinition = new FilterDefinition();
                filterDefinition.setName(split[0]);
                Map<String, String> args = filterDefinition.getArgs();
                args.put(split[0], split[1]);
                filters.add(filterDefinition);
            }
        } else {
            String[] split = var6.split("=");
            FilterDefinition filterDefinition = new FilterDefinition();
            filterDefinition.setName(split[0]);
            Map<String, String> args = filterDefinition.getArgs();
            args.put(split[0], split[1]);
            filters.add(filterDefinition);
        }
        routeUpdates.add(routeDefinition);
    }
}
初始化读取配置
package com.gton.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
/**
 * @description: 读取北极星配置路由
 * @author: GuoTong
 * @createTime: 2022-11-25 15:55
 * @since JDK 1.8 OR 11
 **/
@ConfigurationProperties(prefix = "routes")
@Component
@Data
public class ReadRouterConfig {
    /**
     * Description:  网关路由动态配置
     *
     * @author: GuoTong
     * @date: 2022-11-25 16:08:23
     * @param rule
     * @return:
     */
    private List<String> rule;
}
启动加载配置问阿金
package com.gton.config;
import com.gton.listener.ListenerPolaris;
import com.gton.service.DynamicRouteServiceImpl;
import com.tencent.polaris.api.utils.CollectionUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
/**
 * @program: PersonalDesign
 * @description: 项目一启动就执行
 **/
@Slf4j
@Component
@Order(value = 1)
public class MyApplicationRunner implements ApplicationRunner {
    @Autowired
    private ReadRouterConfig readRouterConfig;
    @Autowired
    private ListenerPolaris listenerPolaris;
    @Autowired
    private DynamicRouteServiceImpl dynamicRouteService;
    @Override
    public void run(ApplicationArguments args) throws Exception {
        log.info("开始网关路由配置加载。。。。。。");
        // 读取北极星上的配置信息
        List<String> rule = readRouterConfig.getRule();
        List<RouteDefinition> routeUpdates = new ArrayList<>();
        // 北极星上的配置处理
        rule.forEach(item -> listenerPolaris.addNewRule(routeUpdates, item));
        if (log.isDebugEnabled()) {
            log.debug("加载的路由配置是->{}", routeUpdates);
        }
        // 启动完成注册相关路由配置
        if (CollectionUtils.isNotEmpty(routeUpdates)) {
            routeUpdates.forEach(item -> dynamicRouteService.add(item));
        }
        log.info("网关路由配置加载结束。。。。。。");
    }
}
到此结束!!!!
北极星Polaris+Gateway动态网关配置!的更多相关文章
- Nacos下动态路由配置
		
前言 Nacos最近项目一直在使用,其简单灵活,支持更细粒度的命令空间,分组等为麻烦复杂的环境切换提供了方便:同时也很好支持动态路由的配置,只需要简单的几步即可.在国产的注册中心.配置中心中比较突出, ...
 - Linux IP和网关配置
		
操作环境 SuSE11/SuSE10 配置方法一<永久有效,重启不失效> 通过修改/etc/sysconfig/network/ifcfg-eth*文件直接配置,服务器重启不失效,建议使用 ...
 - DHCP:动态主机配置协议
		
DHCP(Dynamic Host Configuration Protocol,动态主机配置协议)是一个局域网的网络协议,使用UDP协议工作, 主要有两个用途:给内部网络或网络服务供应商自动分配IP ...
 - DHCP(动态主机配置协议)工作流程
		
一.DHCP的作用 我们先来看一下什么是DHCP,DHCP(Dynamic Host Configuration Protocol,动态主机配置协议)它可以为客户机自动分配IP地址.子网掩码以及缺省网 ...
 - Spring Cloud Gateway 服务网关快速上手
		
Spring Cloud Gateway 服务网关 API 主流网关有NGINX.ZUUL.Spring Cloud Gateway.Linkerd等:Spring Cloud Gateway构建于 ...
 - Spring Cloud Alibaba | Nacos动态网关路由
		
Spring Cloud Alibaba | Gateway基于Nacos动态网关路由 本篇实战所使用Spring有关版本: SpringBoot:2.1.7.RELEASE Spring Cloud ...
 - spring cloud 2.x版本 Gateway动态路由教程
		
摘要 本文采用的Spring cloud为2.1.8RELEASE,version=Greenwich.SR3 本文基于前面的几篇Spring cloud Gateway文章的实现. 参考 Gatew ...
 - 动态主机配置协议-DHCP
		
一.DHCP 概述 当局域网中有大量的PC时.如果我们逐个为每台PC去手动配置IP.那这就是一个吃力也未必讨好的办法 累死你 而DHCP 刚好可以解决这个问题.DHCP全称(动态主机配置协议).使用的 ...
 - Spring Cloud 系列之 Gateway 服务网关(二)
		
本篇文章为系列文章,未读第一集的同学请猛戳这里:Spring Cloud 系列之 Gateway 服务网关(一) 本篇文章讲解 Gateway 网关的多种路由规则.动态路由规则(配合服务发现的路由规则 ...
 - 【转载】茶叶蛋干货!《超容易的Linux系统管理入门书》(连载十)进行动态主机配置DHCP
		
使用动态主机配置协议DHCP(Dynamic Host Configuration Protocol)则可以避免网络参数变化后一些繁琐的配置,客户端可以从DHCP服务端检索相关信息并完成相关网络配置, ...
 
随机推荐
- Webdriver安装记
			
和之前的博文对照,这是一篇不一样的博文 因为终于开始实际应用啦! 首先,要安装Python Python在哪找--官网有链接的:Python Release Python 3.6.3 | Python ...
 - PHP 使用AES加密,并扩展失效时间检测
			
/** * 具有时间校验的AES加密 * @param string $string 要处理的字符串 * @param int $timeout 超时时间,单位秒 * @param string $t ...
 - Django CSRF验证失败. 请求被中断.
			
当页面中form使用POST方式向后台提交时,报如下错误: 禁止访问 (403) CSRF验证失败. 请求被中断. Help Reason given for failure:  CSRF toke ...
 - MySQL集群搭建(3)-MMM高可用架构
			
1 MMM 介绍 1.1 简介 MMM 是一套支持双主故障切换以及双主日常管理的第三方软件.MMM 由 Perl 开发,用来管理和监控双主复制,虽然是双主架构,但是业务上同一时间只允许一个节点进行写入 ...
 - Docker容器优雅重启
			
默认情况下,当 Docker 守护进程终止时,它将关闭正在运行的容器.您可以配置守护程序,以便容器在守护程序不可用时保持运行.此功能称为live-restore.live-restore选项有助于减少 ...
 - SQL通用语法和SQL分类
			
SQL通用语法 1.SQL 语句可以单行或多行书写,以分号结尾 2.可使用空格和缩进来增强语句的可读性 3.MySQL 数据库的SQL语句不区分大小写,关键字建议使用大写 4.3种注释 单行注释: - ...
 - PAT (Basic Level) Practice 1033 旧键盘打字 分数 20
			
旧键盘上坏了几个键,于是在敲一段文字的时候,对应的字符就不会出现.现在给出应该输入的一段文字.以及坏掉的那些键,打出的结果文字会是怎样? 输入格式: 输入在 2 行中分别给出坏掉的那些键.以及应该输入 ...
 - vulnhub靶场之THE PLANETS: EARTH
			
准备: 攻击机:虚拟机kali.本机win10. 靶机:THE PLANETS: EARTH,网段地址我这里设置的桥接,所以与本机电脑在同一网段,下载地址:https://download.vulnh ...
 - Pycharm安装使用
			
目录 使用pycharm软件 配置调整 下载链接地址:https://www.jetbrains.com/pycharm/download/#section=windows 根据自己的系统需要安装对应 ...
 - 生产系统CPU飙高问题排查
			
现状 生产系统CPU占用过高,并且进行了报警 排查方法 执行top命令,查看是那个进程导致的,可以确定是pid为22168的java应用导致的 执行top -Hp命令,查看这个进程的那个线程导致cpu ...