0
点赞
收藏
分享

微信扫一扫

spring cloud gateway 配置动态路由

zhoulujun 2023-08-07 阅读 27
  1. 在mysql建表存储路由信息

DROP TABLE IF EXISTS `route`;
CREATE TABLE `route`  (
  `id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
  `uri` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `predicates` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `filters` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `del` tinyint NULL DEFAULT NULL,
  `comment` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '注释',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of route
-- ----------------------------
INSERT INTO `route` VALUES ('jihua', 'http://127.0.0.1:8090/', '[{\"args\": {\"_genkey_0\": \"/jihua/**\"}, \"name\": \"Path\"}]', '[{\"args\": {\"_genkey_0\": \"1\"}, \"name\": \"StripPrefix\"}]', 0, NULL);
INSERT INTO `route` VALUES ('jihua_mysql', 'http://127.0.0.1:8090/', '[{\"args\": {\"_genkey_0\": \"/jihuamysql/**\"}, \"name\": \"Path\"}]', '[{\"args\": {\"_genkey_0\": \"1\"}, \"name\": \"StripPrefix\"}]', 0, NULL);
INSERT INTO `route` VALUES ('jihua_oracle', 'http://127.0.0.1:8090/', '[{\"args\": {\"_genkey_0\": \"/jihuaoracle/**\"}, \"name\": \"Path\"}]', '[{\"args\": {\"_genkey_0\": \"1\"}, \"name\": \"StripPrefix\"}]', 0, NULL);

  1. mybatis查询路由信息

import com.example.demo.po.Route;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

import java.util.Set;

@Mapper
public interface RouteDao {

    @Select("select * from route where del=0")
    Set<Route> selectAll();
}

  1. 创建定时任务在项目启动时初始化路由, 和每五分钟读取最新路由信息

import com.example.demo.dao.RouteDao;
import com.example.demo.po.Route;
import com.example.demo.util.JsonUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
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.cloud.gateway.route.RouteDefinitionRepository;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.util.Collections;
import java.util.List;
import java.util.Set;

@Slf4j
@Service
@EnableScheduling
public class DynamicRouteService implements ApplicationEventPublisherAware {
    @Autowired
    private RouteDefinitionRepository routeDefinitionRepository;
    @Autowired
    private RouteDao routeDao;
    private ApplicationEventPublisher publisher;

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.publisher = applicationEventPublisher;
    }

    private Set<Route> oldRouteSet = Collections.emptySet();

    @Scheduled(fixedDelay = 5 * 60 * 1000)
    void refreshRouteTask() {
        refreshRoute();
    }

    /**
     * 从数据库读取路由配置,并刷新网关路由信息
     */
    void refreshRoute() {
        Set<Route> newestRouteSet = routeDao.selectAll();
        boolean routeChangeFlag = false;
        for (Route item : newestRouteSet) {
            if (!oldRouteSet.contains(item)) {
                try {
                    log.info("新增路由: {}", JsonUtil.writeValueAsString(item));
                    RouteDefinition routeDefinition = new RouteDefinition();
                    routeDefinition.setId(item.getId());
                    routeDefinition.setUri(new URI(item.getUri()));
                    routeDefinition.setPredicates(JsonUtil.readValue(item.getPredicates(), new TypeReference<List<PredicateDefinition>>() {
                    }));
                    routeDefinition.setFilters(JsonUtil.readValue(item.getFilters(), new TypeReference<List<FilterDefinition>>() {
                    }));
                    routeDefinitionRepository.save(Mono.just(routeDefinition)).subscribe();
                    routeChangeFlag = true;
                } catch (Exception e) {
                    log.error("新增路由异常", e);
                }
            }
        }
        for (Route item : oldRouteSet) {
            if (!newestRouteSet.contains(item)) {
                routeDefinitionRepository.delete(Mono.just(item.getId())).subscribe();
                routeChangeFlag = true;
                log.info("删除路由: {}", JsonUtil.writeValueAsString(item));
            }
        }
        if (routeChangeFlag) {
            oldRouteSet = newestRouteSet;
            publisher.publishEvent(new RefreshRoutesEvent(this));
        }

    }
}

举报

相关推荐

0 条评论