• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

配置gateway+nacos动态路由管理流程

java 搞代码 4年前 (2022-01-09) 10次浏览 已收录 0个评论
文章目录[隐藏]

配置gateway+nacos动态路由

第一步:首先是设置配置文件的配置列表

然后在配置读取配置类上增加刷新注解@RefreshScope

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
 * @author :lhb
 * @date :Created in 2020-09-09 08:59
 * @description:GateWay路由配置
 * @modified By:
 * @version: $
 */
@Slf4j
@RefreshScope
@Component
@ConfigurationProperties(prefix = "spring.cloud.gateway")
public class GatewayRoutes {
    /**
     * 路由列表.
     */
    @NotNull
    @Valid
    private List<RouteDefinition> routes = new ArrayList<>();
    /**
     * 适用于每条路线的过滤器定义列表
     */
    private List<FilterDefinition> defaultFilters = new ArrayList<>();
    private List<MediaType> streamingMediaTypes = Arrays
            .asList(MediaType.TEXT_EVENT_STREAM, MediaType.APPLICATION_STREAM_JSON);
    public List<RouteDefinition> getRoutes() {
        return routes;
    }
    public void setRoutes(List<RouteDefinition> routes) {
        this.routes = routes;
        if (routes != null && routes.size() > 0 && log.isDebugEnabled()) {
            log.debug("Routes supplied from Gateway Properties: " + routes);
        }
    }
    public List<FilterDefinition> getDefaultFilters() {
        return defaultFilters;
    }
    public void setDefaultFilters(List<FilterDefinition> defaultFilters) {
        this.defaultFilters = defaultFilters;
    }
    public List<MediaType> getStreamingMediaTypes() {
        return streamingMediaTypes;
    }
    public void setStreamingMediaTypes(List<MediaType> streamingMediaTypes) {
        this.streamingMediaTypes = streamingMediaTypes;
    }
    @Override
    public String toString() {
        return "GatewayProperties{" + "routes=" + routes + ", defaultFilters="
                + defaultFilters + ", streamingMediaTypes=" + streamingMediaTypes + '}';
    }
}

第二步:配置监听nacos监听器

import cn.hutool.co<span>本文来源gaodai#ma#com搞*!代#%^码$网*</span>re.exceptions.ExceptionUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.scope.refresh.RefreshScope;
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.ApplicationEventPublisherAware;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
 * @author :lhb
 * @date :Created in 2020-09-08 16:39
 * @description:监听nacos配置变更
 * @modified By:
 * @version: $
 */
@Slf4j
@Component
public class GateWayNacosConfigListener implements ApplicationEventPublisherAware {
    @Autowired
    private RouteDefinitionWriter routedefinitionWriter;
    private ApplicationEventPublisher publisher;
    private static final Map<String, RouteDefinition> ROUTE_MAP = new ConcurrentHashMap<>();
    @Autowired
    private GatewayRoutes gatewayRoutes;
    @Resource
    private RefreshScope refreshScope;
    @Value(value = "${spring.cloud.nacos.config.server-addr}")
    private String serverAddr;
    @Value(value = "${spring.cloud.nacos.config.group:DEFAULT_GROUP}")
    private String group;
    @Value(value = "${spring.cloud.nacos.config.namespace}")
    private String namespace;
    private String routeDataId = "gateway-routes.yml";
    @PostConstruct
    public void onMessage() throws NacosException {
        log.info("serverAddr={}", serverAddr);
        Properties properties = new Properties();
        properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr);
        properties.put(PropertyKeyConst.NAMESPACE, namespace);
        ConfigService configService = NacosFactory.createConfigService(properties);
        this.publisher(gatewayRoutes.getRoutes());
        log.info("gatewayProperties=" + JSONObject.toJSONString(gatewayRoutes));
        configService.addListener(routeDataId, group, new Listener() {
            @Override
            public Executor getExecutor() {
                return null;
            }
            @Override
            public void receiveConfigInfo(String config) {
                log.info("监听nacos配置: {}, 旧的配置: {}, 新的配置: {}", routeDataId, gatewayRoutes, config);
                refreshScope.refresh("gatewayRoutes");
                try {
                    TimeUnit.SECONDS.sleep(5);
                } catch (InterruptedException e) {
                    log.error(ExceptionUtil.getMessage(e));
                }
                publisher(gatewayRoutes.getRoutes());
            }
        });
    }
    private boolean rePut(List<RouteDefinition> routeDefinitions) {
        if (MapUtils.isEmpty(ROUTE_MAP) && CollectionUtils.isEmpty(routeDefinitions)) {
            return true;
        }
        if (CollectionUtils.isEmpty(routeDefinitions)) {
            return true;
        }
        Set<String> strings = ROUTE_MAP.keySet();
        return strings.stream().sorted().collect(Collectors.joining())
                .equals(routeDefinitions.stream().map(v -> v.getId()).sorted().collect(Collectors.joining()));
    }
    /**
     * 增加路由
     *
     * @param def
     * @return
     */
    public Boolean addRoute(RouteDefinition def) {
        try {
            log.info("添加路由: {} ", def);
            routedefinitionWriter.save(Mono.just(def)).subscribe();
            ROUTE_MAP.put(def.getId(), def);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }
    /**
     * 删除路由
     *
     * @return
     */
    public Boolean clearRoute() {
        for (String id : ROUTE_MAP.keySet()) {
            routedefinitionWriter.delete(Mono.just(id)).subscribe();
        }
        ROUTE_MAP.clear();
        return false;
    }
    /**
     * 发布路由
     */
    private void publisher(String config) {
        this.clearRoute();
        try {
            log.info("重新更新动态路由");
            List<RouteDefinition> gateway = JSONObject.parseArray(config, RouteDefinition.class);
            for (RouteDefinition route : gateway) {
                this.addRoute(route);
            }
            publisher.publishEvent(new RefreshRoutesEvent(this.routedefinitionWriter));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 发布路由
     */
    private void publisher(List<RouteDefinition> routeDefinitions) {
        this.clearRoute();
        try {
            log.info("重新更新动态路由: ");
            for (RouteDefinition route : routeDefinitions) {
                this.addRoute(route);
            }
            publisher.publishEvent(new RefreshRoutesEvent(this.routedefinitionWriter));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher app) {
        publisher = app;
    }
}

第三步:配置nacos的yml文件

spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        # 认证中心
        - id: firefighting-service-user
          uri: lb://firefighting-service-user
          predicates:
            - Path=/user/**
          #          - Weight=group1, 8
          filters:
            - StripPrefix=1
          # 转流服务
        - id: liveStream
          uri: http://192.168.1.16:8081
          predicates:
            - Path=/liveStream/**
          #          - Weight=group1, 8
          filters:
            - StripPrefix=1
        - id: firefighting-service-directcenter
          uri: lb://firefighting-service-directcenter
          predicates:
            - Path=/directcenter/**
          filters:
            - StripPrefix=1
        - id: firefighting-service-datainput
          uri: lb://firefighting-service-datainput
          predicates:
            - Path=/datainput/**
          filters:
            - StripPrefix=1
        - id: firefighting-service-squadron
          uri: lb://firefighting-service-squadron
          predicates:
            - Path=/squadron/**
          filters:
            - StripPrefix=1
        - id: firefighting-service-iot
          uri: lb://firefighting-service-iot
          predicates:
            - Path=/iot/**
          filters:
            - StripPrefix=1
        - id: websocket
          uri: lb:ws://firefighting-service-notice
          predicates:
            - Path=/notice/socket/**
          filters:
            - StripPrefix=1
        - id: firefighting-service-notice
          uri: lb://firefighting-service-notice
          predicates:
            - Path=/notice/**
          filters:
            # 验证码处理
            #            - CacheRequest
            #            - ImgCodeFilter
            - StripPrefix=1
        - id: websocket
          uri: lb:ws://firefighting-service-notice
          predicates:
            - Path=/notice/socket/**
          filters:
            - StripPrefix=1
        - id: firefighting-service-supervise
          uri: lb://firefighting-service-supervise
          predicates:
            - Path=/supervise/**
          filters:
            - StripPrefix=1
        - id: firefighting-service-new-supervise
          uri: lb://firefighting-service-new-supervise
          predicates:
            - Path=/new/supervise/**
          filters:
            - StripPrefix=2
        - id: firefighting-service-train
          uri: lb://firefighting-service-train
          predicates:
            - Path=/train/**
          filters:
            - StripPrefix=1
        - id: firefighting-support-user
          uri: lb://firefighting-support-user
          predicates:
            - Path=/support/**
          filters:
            - StripPrefix=1
        - id: firefighting-service-firesafety
          uri: lb://firefighting-service-firesafety
          predicates:
            - Path=/firesafety/**
          filters:
            - StripPrefix=1
        - id: firefighting-service-bigdata
          uri: lb://firefighting-service-bigdata
          predicates:
            - Path=/bigdata/**
          filters:
            - StripPrefix=1
        - id: firefighting-service-act-datainput
          uri: lb://firefighting-service-act-datainput
          predicates:
            - Path=/act_datainput/**
          filters:
            - StripPrefix=1
        - id: firefighting-service-publicity
          uri: lb://firefighting-service-publicity
          predicates:
            - Path=/publicity/**
          filters:
            - StripPrefix=1
        - id: firefighting-service-preplan
          uri: lb://firefighting-service-preplan
          predicates:
            - Path=/preplan/**
          filters:
            - StripPrefix=1
        - id: firefighting-service-uav
          uri: lb://firefighting-service-uav
          predicates:
            - Path=/uav/**
          filters:
            - StripPrefix=1
        - id: firefighting-service-ard-mgr
          uri: lb://firefighting-service-ard-mgr
          predicates:
            - Path=/ard_mgr/**
          filters:
            - StripPrefix=1
        - id: admin-server
          uri: lb://admin-server
          predicates:
            - Path=/adminsServer/**
          filters:
            - StripPrefix=1

nacos的智能路由实现与应用

一. 概述


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:配置gateway+nacos动态路由管理流程
喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址