Spring Cloud Zuul设置动态路由规则

最近项目中有一个需求:由于有多个服务需要接入系统,并且后续会越来越多服务接入,此时外部系统调用这些服务会比较麻烦,不同的端口,不同的路径,并且权限不好管理。此时就想到了将对这些服务的请求统一通过网关转发,统一生成一个路由前缀,并且转发前统一在网关进行鉴权。当这些服务注册到eureka时,动态的生成服务的路由规则,避免在配置文件中手动配置。

创建一个类继承SimpleRouteLocator,实现RefreshableRouteLocator接口:

import com.netflix.appinfo.InstanceInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.netflix.eureka.EurekaDiscoveryClient;
import org.springframework.cloud.netflix.zuul.filters.RefreshableRouteLocator;
import org.springframework.cloud.netflix.zuul.filters.SimpleRouteLocator;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 自定义适配器服务路由规则
 *
 * @author hsz
 */

@Slf4j
public class AdapterRouteLocator extends SimpleRouteLocator implements RefreshableRouteLocator {

    @Autowired
    private DiscoveryClient discoveryClient;

    public AdapterRouteLocator(String servletPath, ZuulProperties properties) {
        super(servletPath, properties);
    }

    @Override
    public void refresh() {
        doRefresh();
    }

    @Override
    protected Map<String, ZuulRoute> locateRoutes() {
        //重新定义一个路由映射map
        LinkedHashMap<String, ZuulRoute> routesMap = new LinkedHashMap<>();
        //获取所有服务
        List<String> services = discoveryClient.getServices();
        //设置适配器路由规则
        for (String service : services) {
            List<ServiceInstance> serviceInstances = discoveryClient.getInstances(service);
            serviceInstances.forEach(serviceInstance -> {
                EurekaDiscoveryClient.EurekaServiceInstance instance = (EurekaDiscoveryClient.EurekaServiceInstance) serviceInstance;
                InstanceInfo instanceInfo = instance.getInstanceInfo();
                if ("ADAPTER-SERVICE".equals(instanceInfo.getAppGroupName())) {
                    ZuulProperties.ZuulRoute zuulRoute = new ZuulProperties.ZuulRoute();
                    zuulRoute.setId(instanceInfo.getAppName().toLowerCase());
                    zuulRoute.setUrl(serviceInstance.getUri().toString());
                    zuulRoute.setRetryable(false);
                    String path = "/adapter/" + instanceInfo.getAppName().toLowerCase() + "/**";
                    zuulRoute.setPath(path);
                    routesMap.put(path, zuulRoute);
                }
            });
        }
        return routesMap;
    }
}

主要的逻辑都在locateRoutes()方法中。首先定义一个路由映射map,用来存放路由规则。通过DiscoveryClient获取到服务注册列表,将组名为“ADAPTER-SERVICE”的适配器服务过滤出来解析并构造路由放入到map中,最后这个routesMap就是自定义的路由规则。

Zuul在自动配置加载时会默认注入了2个自带RouteLocator:
CompositeRouteLocator:包含了其他所有的RouteLocator,匹配路径时也是通过这个类的getMatchingRoute方法依次调用其他RouteLocator的getMatchingRoute方法类匹配,只要匹配到第一个就返回,不会再往下匹配;
DiscoveryClientRouteLocator:这个路由器包括两部分规则,一个是加载的父类SimpleRouteLocator中的规则,即配置文件中的路由配置;一个是根据服务注册列表生成的,匹配路径是“/服务名/**”,如果配置了ignored-services: ‘*’,则不会生成这个规则。并且如果有匹配路径是“/**”的,则将它移到最后面。

PreDecorationFilter前置过滤器通过CompositeRouteLocator来获取匹配的路由。

最后用配置类使这个路由规则生效

import com.fdjw.msgateway.route.AdapterRouteLocator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author hsz
 */

@Configuration
public class RouteConfig {

    private final ZuulProperties zuulProperties;
    private final ServerProperties server;

    @Autowired
    public RouteConfig(ZuulProperties zuulProperties, ServerProperties server) {
        this.zuulProperties = zuulProperties;
        this.server = server;
    }

    @Bean
    public AdapterRouteLocator getRouteLocator() {
        return new AdapterRouteLocator(server.getServlet().getContextPath(), zuulProperties);
    }
}

springboot版本:2.1.3

参考链接:
https://www.cnblogs.com/trust-freedom/p/9982680.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值