sbc(六) Zuul GateWay 网关应用(中)

简介: 看过之前SBC系列的小伙伴应该都可以搭建一个高可用、分布式的微服务了。

服务路由


对此 Zuul 提供了一种基于服务的路由方式。我们只需要维护请求地址与服务 ID 之间的映射关系即可,并且由于集成了 Ribbon , Zuul 还可以在路由的时候通过 Eureka 实现负载调用。


具体配置:


zuul.routes.sbc-user.path=/api/user/**
zuul.routes.sbc-user.serviceId=sbc-user


这样当输入 http://localhost:8383/api/user/getUserInfo/1 时就会路由到注册到 Eureka 中服务 ID 为 sbc-user 的服务节点,如果有多节点就会按照 Ribbon 的负载算法路由到其中一台上。


以上配置还可以简写为:


# 服务路由 简化配置
zuul.routes.sbc-user=/api/user/**


这样让我们访问

http://127.0.0.1:8383/api/user/userService/getUserByHystrix 时候就会根据负载算法帮我们路由到 sbc-user 应用上,如下图所示:



启动了两个 sbc-user 服务。


请求结果:



一次路由就算完成了。


在上面的配置中有看到 /api/user/** 这样的通配符配置,具体有以下三种配置需要了解:


  • ? 只能匹配任意的单个字符,如 /api/user/? 就只能匹配 /api/user/x  /api/user/y /api/user/z 这样的路径。


  • * 只能匹配任意字符,如 /api/user/* 就只能匹配 /api/user/x /api/user/xy /api/user/xyz


  • ** 可以匹配任意字符、任意层级。结合了以上两种通配符的特点,如 /api/user/** 则可以匹配 /api/user/x /api/user/x/y /api/user/x/y/zzz这样的路径,最简单粗暴!


谈到通配符匹配就不得不提到一个问题,如上面的 sbc-user 服务由于后期迭代更新,将 sbc-user 中的一部分逻辑抽成了另一个服务 sbc-user-pro。新应用的路由规则是 /api/user/pro/**,如果我们按照:


zuul.routes.sbc-user=/api/user/**
zuul.routes.sbc-user-pro=/api/user/pro/**


进行配置的话,我们想通过 /api/user/pro/ 来访问 sbc-user-pro 应用,却由于满足第一个路由规则,所以会被 Zuul 路由到 sbc-user 这个应用上,这显然是不对的。该怎么解决这个问题呢?


翻看路由源码

org.springframework.cloud.netflix.zuul.filters.SimpleRouteLocator 中的 locateRoutes() 方法:


/**
     * Compute a map of path pattern to route. The default is just a static map from the
     * {@link ZuulProperties}, but subclasses can add dynamic calculations.
     */
    protected Map<String, ZuulRoute> locateRoutes() {
        LinkedHashMap<String, ZuulRoute> routesMap = new LinkedHashMap<String, ZuulRoute>();
        for (ZuulRoute route : this.properties.getRoutes().values()) {
            routesMap.put(route.getPath(), route);
        }
        return routesMap;
    }


发现路由规则是遍历配置文件并放入 LinkedHashMap 中,由于 LinkedHashMap 是有序的,所以为了达到上文的效果,配置文件的加载顺序非常重要,因此我们只需要将优先匹配的路由规则放前即可解决。


过滤器


过滤器可以说是整个 Zuul 最核心的功能,包括上文提到路由功能也是由过滤器来实现的。


摘抄官方的解释: Zuul 的核心就是一系列的过滤器,他能够在整个 HTTP 请求、响应过程中执行各样的操作。


其实总结下来就是四个特征:


  • 过滤类型


  • 过滤顺序


  • 执行条件


  • 具体实现


其实就是 ZuulFilter 接口中所定义的四个接口:


String filterType();
int filterOrder();
boolean shouldFilter();
Object run();


官方流程图(生命周期):



简单理解下就是:


当一个请求进来时,首先是进入 pre 过滤器,可以做一些鉴权,记录调试日志等操作。之后进入 routing 过滤器进行路由转发,转发可以使用 Apache HttpClient 或者是 Ribbon


post 过滤器呢则是处理服务响应之后的数据,可以进行一些包装来返回客户端。


error 则是在有异常发生时才会调用,相当于是全局异常拦截器。


自定义过滤器


接下来实现一个文初所提到的鉴权操作:

新建一个 RequestFilter 类继承与 ZuulFilter 接口


/**
 * Function: 请求拦截
 *
 * @author crossoverJie
 *         Date: 2017/11/20 00:33
 * @since JDK 1.8
 */
public class RequestFilter extends ZuulFilter {
    private Logger logger = LoggerFactory.getLogger(RequestFilter.class) ;
    /**
     * 请求路由之前被拦截 实现 pre 拦截器
     * @return
     */
    @Override
    public String filterType() {
        return "pre";
    }
    @Override
    public int filterOrder() {
        return 0;
    }
    @Override
    public boolean shouldFilter() {
        return true;
    }
    @Override
    public Object run() {
        RequestContext currentContext = RequestContext.getCurrentContext();
        HttpServletRequest request = currentContext.getRequest();
        String token = request.getParameter("token");
        if (StringUtil.isEmpty(token)){
            logger.warn("need token");
            //过滤请求
            currentContext.setSendZuulResponse(false);
            currentContext.setResponseStatusCode(400);
            return null ;
        }
        logger.info("token ={}",token) ;
        return null;
    }
}


非常 easy,就简单校验下请求中是否包含 token,不包含就返回 401 code。


相关文章
|
2月前
|
监控 负载均衡 安全
微服务(五)-服务网关zuul(一)
微服务(五)-服务网关zuul(一)
|
11天前
|
负载均衡 Java 应用服务中间件
Gateway服务网关
Gateway服务网关
24 1
Gateway服务网关
|
10天前
|
人工智能 Kubernetes API
应用网关的演进历程和分类
唯一不变的是变化,在现代复杂的商业环境中,企业的业务形态与规模往往处于不断变化和扩大之中。这种动态发展对企业的信息系统提出了更高的要求,特别是在软件架构方面。为了应对不断变化的市场需求和业务扩展,软件架构必须进行相应的演进和优化。网关作为互联网流量的入口,其形态也在跟随软件架构持续演进迭代中。我们下面就聊一聊网关的演进历程以及在时下火热的 AI 浪潮下,网关又会迸发怎样新的形态。
|
2月前
|
负载均衡 Java 网络架构
实现微服务网关:Zuul与Spring Cloud Gateway的比较分析
实现微服务网关:Zuul与Spring Cloud Gateway的比较分析
102 5
|
2月前
|
测试技术 微服务
微服务(八)-服务网关zuul(四)
微服务(八)-服务网关zuul(四)
|
2月前
|
监控 前端开发 Java
微服务(七)-服务网关zuul(三)
微服务(七)-服务网关zuul(三)
|
2月前
|
负载均衡 前端开发 安全
微服务(六)-服务网关zuul(二)
微服务(六)-服务网关zuul(二)
|
3月前
|
安全 API
【Azure API 管理】APIM Self-Host Gateway 自建本地环境中的网关数量超过10个且它们的出口IP为同一个时出现的429错误
【Azure API 管理】APIM Self-Host Gateway 自建本地环境中的网关数量超过10个且它们的出口IP为同一个时出现的429错误
|
2月前
|
负载均衡 Java Nacos
SpringCloud基础2——Nacos配置、Feign、Gateway
nacos配置管理、Feign远程调用、Gateway服务网关
SpringCloud基础2——Nacos配置、Feign、Gateway
|
2月前
|
Java 开发者 Spring
Spring Cloud Gateway 中,过滤器的分类有哪些?
Spring Cloud Gateway 中,过滤器的分类有哪些?
48 3