北极星Polaris+Gateway动态网关配置!

北极星,polaris,gateway,动态,网关,配置 · 浏览次数 : 246

小编点评

**读取北极星配置路由** 该代码配置了网关路由,读取北极星上的配置信息并将其添加到 Spring Cloud Gateway 的路由定义中。 **配置类** * `ReadRouterConfig` 是一个 `@ConfigurationProperties` 注解的类,它包含一个 `rule`属性,其中包含北极星上的配置信息。 **启动加载配置问阿金** * `MyApplicationRunner` 实现 `ApplicationRunner` 接口,并使用 `@Autowired` 注解来注入 `ReadRouterConfig` 和其他依赖项。 * `run`方法中,它读取 `readRouterConfig` 中的 `rule`属性,并使用 `listenerPolaris.addNewRule` 方法将它们添加到网关路由中。 * 如果 `routeUpdates` 不为空,则使用 `dynamicRouteService.add` 方法将它们添加至网关路由中。 **主要代码段** ```java @ConfigurationProperties(prefix = "routes") @Component @Data public class ReadRouterConfig { private List rule; } ``` ```java @Autowired private ReadRouterConfig readRouterConfig; ``` ```java @Autowired private ListenerPolaris listenerPolaris; ``` ```java @Autowired private DynamicRouteServiceImpl dynamicRouteService; ``` **其他说明** * 代码中使用 `log` 组件记录配置加载过程的日志信息。 * `@Order` 注解控制路由的排序,此处假设配置加载在启动程序之前加载。

正文

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"]  #读取的文件名

北极星控制台配置
image

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动态网关配置!相似的内容:

北极星Polaris+Gateway动态网关配置!

springcloudtencetn 父工程: pom

[转帖]腾讯北极星 Polaris 试用

https://www.cnblogs.com/QIAOXINGXING001/p/15482012.html 了解、试用 昨天稀土开发者大会2021提到了腾讯开源的北极星, 试用一下; 官网: 北极星 源码: Polarismesh2021年7月21日开源, 目前(2021-10)700多star

破局DevOps|8大北极星指标指引研发效能方向

放弃那些动辄就上百个的研发度量指标吧,8大北极星指标指引你的研发效能方向,1个北极星指标公式让你清晰了解​公司研发效能现状。 每当研发效能/DevOps业务做规划的时候,有的人就会毫无头绪,不知道如何下手,不知道方向在哪里,价值怎么衡量。本文将介绍如何借助北极星指标这个工具来帮我们完成这项工作,并以

相较于Scrum, 我更推崇精益Kanban,帮助团队建立价值交付流,识别瓶颈问题

> 最近在学习实践精益Kanban方法,结合自己团队实践Srum的经历,整理些资料二者的差异。相较于Scrum, 我更推崇精益Kaban。 Agile是一套理论和原则,就像天边的北极星。Devops是一种软件开发和运维团队间自动化和集成过程的方法。当实现Agile和Devops方法时,Kanban和

项目管理之八大绩效域------笔记(五)

18.7 度量绩效域 度量绩效域涉及评估项目绩效和采取应对措施相关的活动和职能度量是评估项目绩效,并采取适当的应对措施,以保持最佳项目绩效的过程。 一、 预期目标: ①对项目状况充分理解;(随时对项目有充分了解) ②数据充分,可支持决策; ③及时采取行动,确保项目最佳绩效; ④能够基于预测和评估作出

项目管理之八大绩效域------笔记(四)

18.5 项目工作绩效域 在整个项目期间 一、预期目标: ①高效且有效的项目绩效; ②适合项目和环境的项目过程; ③干系人适当的沟通和参与; ④对实物资源进行了有效管理; ⑤对采购进行了有效管理; ⑥有效处理了变更; ⑦通过持续学习和过程改进提高了团队能力. 二、绩效要点: 1.项目过程 1.1 需

项目管理之八大绩效域------笔记(三)

18.3 开发方法和生命周期绩效域 跟开发方法,项目交付节奏和生命周期相关的活动和职能. 一、预期目标: ①开发方法与项目可交付物相符合; ②将项目交付与干系人价值紧密关联; ③项目生命周期由促进交付节奏的项目阶段和产生项目交付物所需的开发方法组成。(项目周期的设计符合项目的交付节奏和开发方法) 二

项目管理之八大绩效域-------笔记(二)

八大绩效域详细解析 18.1 干系人绩效域 跟干系人所有相关的活动. 一、预期目标 ①与干系人建立高效的工作关系 ②干系人认同项目目标 ③支持项目的干系人提高了满意度,并从中收益 ④反对项目的干系人没有对项目产生负面影响 三四是一个意思,就是支持你的人更支持你,反对你的人没有负面影响. 实际工作 这

项目管理十二原则

价值驱动的项目管理知识体系 第七版是新的基于价值的一个项目管理体系。 包括了基于过程的项目管理,也包括了这个基于价值的新的项目管理体系。 十二原则就是项目经理看待项目管理的十二个角度,十二个底线 项目管理原则 国家原则就是绝对不能突破的。 什么是原则? 原则属于价值观层面,它会影响或直接指导人的行动

项目管理之八大绩效域-------笔记(一)

绪论 一、核心术语 1.预期目标 给干系人绩效域一个KPI(预期目标)来对其衡量其做的好不好,这个KPI就叫做预期目标. 2.指标及检查方法 要对目标是否做好进行评价,这个评价就是指标及检查方法 3.绩效要点 为了完成预期目标的三个KPI,应该做什么工作或者应该关注哪几个方面的活动,来达成预期目标,