美文网首页
Zuul路由配置,从配置文件到自定义路由

Zuul路由配置,从配置文件到自定义路由

作者: 作草分茶 | 来源:发表于2019-01-07 16:11 被阅读0次

    一、直接通过配置文件配置路由

    这是最简单的配置方式

    zuul:
      routes:
        baidu: 
          url: http://www.baidu.com/**
    

    这种方式将http://localhost:8080/baidu/**转到http://www.baidu.com/**

    二、修改ZuulProperties实现路由配置

    如果要转发的路由太多,不可能全部写在配置文件中,可以在数据库中获取配置,然后封装ZuulProperties。

    @Bean
    public SimpleRouteLocator zuulRouteLocator(ZuulProperties zuulProperties, IZuulRouteDataRepository dataRepository) {
        Map<String, ZuulProperties.ZuulRoute> routeMap = zuulProperties.getRoutes();
        List<ZuulRouteData> data = dataRepository.findAll();
        ZuulProperties.ZuulRoute zuulRoute;
        for (ZuulRouteData routeData : data) {
            zuulRoute = new ZuulProperties.ZuulRoute();
            // 如path = "baidu"
            String path = routeData.getPath();
            zuulRoute.setId(path);
            zuulRoute.setPath("/" + path + "/**");
            zuulRoute.setUrl(routeData.getUrl());
            zuulRoute.setRetryable(false);
            zuulRoute.setStripPrefix(true);
            zuulRoute.setSensitiveHeaders(new HashSet<>());
            routeMap.put(path, zuulRoute);
        }
        zuulProperties.setRoutes(routeMap);
        return new SimpleRouteLocator("", zuulProperties);
    }
    

    这种实现方式效果如方式一,相当于从数据库封装好ZuulProperties路由信息。

    三、自定义RouteLocator实现动态路由配置

    1. 自定义RouteLocator。数据从redis中获取。实现RefreshableRouteLocator用于动态刷新路由配置。

      @Slf4j
      public class ZuulRouteLocator extends SimpleRouteLocator implements RefreshableRouteLocator {
      
          private ZuulProperties properties;
          private StringRedisTemplate redisTemplate;
      
          public ZuulRouteLocator(String servletPath, ZuulProperties properties, StringRedisTemplate redisTemplate) {
              super(servletPath, properties);
              this.properties = properties;
              this.redisTemplate = redisTemplate;
          }
      
          @Override
          public void refresh() {
              doRefresh();
          }
      
          @Override
          protected Map<String, ZuulProperties.ZuulRoute> locateRoutes() {
              LinkedHashMap<String, ZuulProperties.ZuulRoute> routesMap = new LinkedHashMap<>();
              //从application.properties中加载路由信息
              routesMap.putAll(super.locateRoutes());
              //从db中加载路由信息
              routesMap.putAll(locateRoutesFromRedis());
              //优化一下配置
              LinkedHashMap<String, ZuulProperties.ZuulRoute> values = new LinkedHashMap<>();
              for (Map.Entry<String, ZuulProperties.ZuulRoute> entry : routesMap.entrySet()) {
                  String path = entry.getKey();
                  // Prepend with slash if not already present.
                  if (!path.startsWith(HsbConstants.PREFIX.value)) {
                      path = HsbConstants.PREFIX.value + path;
                  }
                  if (StringUtils.hasText(this.properties.getPrefix())) {
                      path = this.properties.getPrefix() + path;
                      if (!path.startsWith(HsbConstants.PREFIX.value)) {
                          path = HsbConstants.PREFIX.value + path;
                      }
                  }
                  values.put(path, entry.getValue());
                  log.info("Created route configuration,path:{},route:{}", path, JSON.toJSONString(entry.getValue()));
              }
              log.info("Created all route configuration,the count is:{}", values.size());
              return values;
          }
      
          private Map<String, ZuulProperties.ZuulRoute> locateRoutesFromRedis() {
              Map<String, ZuulProperties.ZuulRoute> routes = new LinkedHashMap<>();
              //所有第三方系统
              List<Object> thirdPartySystemList = redisTemplate.opsForHash().values("thirdPartySystem");
              ZuulProperties.ZuulRoute zuulRoute;
              for (Object msg : thirdPartySystemList) {
                  if (StringUtils.isEmpty(msg)) {
                      continue;
                  }
                  ThirdPartySystem thirdPartySystem = JSONObject.parseObject(msg.toString(), ThirdPartySystem.class);
                  if (thirdPartySystem == null) {
                      continue;
                  }
                  //系统标识,作为转发到第三方系统的唯一标识
                  String identification = thirdPartySystem.getIdentification();
                  if (StringUtils.isEmpty(identification)) {
                      continue;
                  }
                  String url = thirdPartySystem.getAddress();
                  if (StringUtils.isEmpty(url)) {
                      continue;
                  }
                  zuulRoute = new ZuulProperties.ZuulRoute();
                  zuulRoute.setSensitiveHeaders(new HashSet<>());
                  zuulRoute.setRetryable(false);
                  zuulRoute.setId(identification);
                  zuulRoute.setPath(HsbConstants.PREFIX.value + identification + "/**");
                  zuulRoute.setUrl(url);
                  zuulRoute.setStripPrefix(true);
                  routes.put(zuulRoute.getPath(), zuulRoute);
              }
              return routes;
          }
      }
      
    2. 动态刷新路由配置。

      @Service
      @Slf4j
      public class RefreshRouteService {
      
          private final ApplicationEventPublisher publisher;
      
          private final RouteLocator routeLocator;
      
          @Autowired
          public RefreshRouteService(ApplicationEventPublisher publisher, RouteLocator routeLocator) {
              this.publisher = publisher;
              this.routeLocator = routeLocator;
          }
      
          public void refreshRoute() {
              RoutesRefreshedEvent routesRefreshedEvent = new RoutesRefreshedEvent(routeLocator);
              publisher.publishEvent(routesRefreshedEvent);
              log.info("Updating route configuration");
          }
      }
      
    3. 简单的路由配置。如果路由比较多,但是不复杂,可以直接使用SimpleRouteLocator来实现。如:

    @Bean
    public SimpleRouteLocator zuulRouteLocator(ZuulProperties zuulProperties, IZuulRouteDataRepository dataRepository) {
        Map<String, ZuulProperties.ZuulRoute> routeMap = zuulProperties.getRoutes();
        List<ZuulRouteData> data = dataRepository.findAll();
        ZuulProperties.ZuulRoute zuulRoute;
        for (ZuulRouteData routeData : data) {
            zuulRoute = new ZuulProperties.ZuulRoute();
            String path = routeData.getPath();
            zuulRoute.setId(path);
            zuulRoute.setPath("/" + path + "/**");
            zuulRoute.setUrl(routeData.getUrl());
            zuulRoute.setRetryable(false);
            zuulRoute.setStripPrefix(true);
            zuulRoute.setSensitiveHeaders(new HashSet<>());
            routeMap.put(path, zuulRoute);
        }
        zuulProperties.setRoutes(routeMap);
        return new SimpleRouteLocator("", zuulProperties);
    }
    

    相关文章

      网友评论

          本文标题:Zuul路由配置,从配置文件到自定义路由

          本文链接:https://www.haomeiwen.com/subject/kgburqtx.html