侧边栏壁纸
  • 累计撰写 4 篇文章
  • 累计创建 4 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

Spring Cloud - Gateway

cck1718
2024-04-13 / 0 评论 / 0 点赞 / 27 阅读 / 4643 字

程序配置

  • 引入依赖

<!--gateway-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</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>
<!--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>
  • bootstrap.yaml配置与普通服务配置一致

  • 结合nacos配置动态路由

nacos额外配置服务路由信息(json)

[
  {
    "id": "system",
    "uri": "lb://system-server",
    "filters": [],
    "predicates": [
      {
        "name": "Path",
        "args": {"_genkey_0": "/system/**"}
      }
    ]
  },
  {
    "id": "ai",
    "uri": "lb://ai-server",
    "filters": [],
    "predicates": [
      {
        "name": "Path",
        "args": {"_genkey_0": "/ai/**"}
      }
    ]
  }
]

创建动态路由配置类

package online.initline.boot.gateway.config;

import cn.hutool.json.JSONUtil;
import com.alibaba.cloud.nacos.NacosConfigManager;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

/**
 * @author zck
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class DynamicRouteConfig {

    // nacos配置管理
    private final NacosConfigManager nacosConfigManager;
    // 路由写入
    private final RouteDefinitionWriter routeDefinitionWriter;
    // 存储当前路由
    private final Set<String> routeIds = new HashSet<>();
    // nacos配置路由文件对应id
    private final String dataId = "gateway-routes.json";
    // 配置分组
    private final String groupId = "DEFAULT_GROUP";
    // 创建线程池
    private static final Executor EXECUTOR = Executors.newSingleThreadExecutor();

    @PostConstruct
    public void initRouteConfigListener() {
        try {
            // 项目启动时 先拉取一次配置 并配置监听器
            String configInfo = nacosConfigManager.getConfigService()
                    .getConfigAndSignListener(dataId, groupId, 5000, new Listener() {
                        @Override
                        public Executor getExecutor() {
                            return EXECUTOR;
                        }

                        @Override
                        public void receiveConfigInfo(String config) {
                            updateRouteConfig(config);
                        }
                    });
            // 第一次拉取到配置时,也需要更新路由表
            updateRouteConfig(configInfo);
        } catch (NacosException e) {
            log.error("Failed to initialize route config listener", e);
        }
    }

    private void updateRouteConfig(String configInfo) {
        try {
            // 解析配置文件
            List<RouteDefinition> routeDefinitionList = JSONUtil.toList(configInfo, RouteDefinition.class);

            // 删除旧路由表
            routeIds.forEach(id -> routeDefinitionWriter.delete(Mono.just(id)).subscribe());
            routeIds.clear();

            // 更新路由表
            routeDefinitionList.forEach(routeDefinition -> {
                routeDefinitionWriter.save(Mono.just(routeDefinition)).subscribe();
                // 记录路由id 便于下次删除
                routeIds.add(routeDefinition.getId());
            });

        } catch (Exception e) {
            log.error("Failed to update route config", e);
        }
    }
}

0

评论区