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。


相关文章
|
1天前
|
Java API 微服务
服务网关Gateway
该博客文章详细介绍了Spring Cloud Gateway的使用方法和概念。文章首先阐述了API网关在微服务架构中的重要性,解释了客户端直接与微服务通信可能带来的问题。接着,文章通过具体的示例代码,展示了如何在Spring Cloud Gateway中添加依赖、编写路由规则,并对路由规则中的基本概念如Route、Predicate和Filter进行了详细解释。最后,文章还提供了路由规则的测试方法。
服务网关Gateway
|
28天前
|
JSON 前端开发 Java
SpringCloud怎么搭建GateWay网关&统一登录模块
本文来分享一下,最近我在自己的项目中实现的认证服务,目前比较简单,就是可以提供一个公共的服务,专门来处理登录请求,然后我还在API网关处实现了登录拦截的效果,因为在一个博客系统中,有一些地址是可以不登录的,比方说首页;也有一些是必须登录的,比如发布文章、评论等。所以,在网关处可以支持自定义一些不需要登录的地址,一些需要登录的地址,也可以在网关处进行校验,如果未登录,可以返回JSON格式的出参,前端可以进行相关处理,比如跳转到登录页面等。
|
14天前
|
负载均衡 Java 应用服务中间件
Gateway服务网关
本节针对微服务中另一重要组件:网关 进行了实战性演练,网关作为分布式架构中的重要中间件,不仅承担着路由分发(重点关注Path规则配置),同时可根据自身负载均衡策略,对多个注册服务实例进行均衡调用。本节我们借助GateWay实现的网关只是技术实现的方案之一,后续大家可能会接触像:Zuul、Kong等,其实现细节或有差异,但整体目标是一致的。
|
1月前
|
Kubernetes 监控 Java
有了k8s还需要gateway网关,nacos配置中心吗
在Kubernetes环境中,服务网关(如Spring Cloud Gateway)和Nacos配置中心补充了k8s的不足。Nacos提供灵活服务路由和动态配置更新,超越k8s基础服务发现。它还支持更复杂的配置管理和实时推送,以及环境隔离和版本控制。作为服务注册中心,Nacos增强k8s服务治理能力,保持技术一致性,并提供额外的安全层及监控功能。
|
1月前
|
网络协议 应用服务中间件 网络安全
[已解决]504 Gateway Time-out 网关超时
[已解决]504 Gateway Time-out 网关超时
46 0
|
2月前
|
Java API 开发者
Spring Cloud Gateway中的GlobalFilter:构建强大的API网关过滤器
Spring Cloud Gateway中的GlobalFilter:构建强大的API网关过滤器
54 0
|
2月前
|
Java Nacos 网络架构
Spring Cloud gateway 网关四 动态路由
Spring Cloud gateway 网关四 动态路由
|
1月前
|
监控 负载均衡 Java
深入理解Spring Cloud中的服务网关
深入理解Spring Cloud中的服务网关
|
3月前
|
运维 网络协议 安全
长连接网关技术专题(十):百度基于Go的千万级统一长连接服务架构实践
本文将介绍百度基于golang实现的统一长连接服务,从统一长连接功能实现和性能优化等角度,描述了其在设计、开发和维护过程中面临的问题和挑战,并重点介绍了解决相关问题和挑战的方案和实践经验。
202 1
|
3月前
|
缓存 安全 API
【亿级数据专题】「高并发架构」盘点本年度探索对外服务的百万请求量的API网关设计实现
公司对外开放的OpenAPI-Server服务,作为核心内部系统与外部系统之间的重要通讯枢纽,每天处理数百万次的API调用、亿级别的消息推送以及TB/PB级别的数据同步。经过多年流量的持续增长,该服务体系依然稳固可靠,展现出强大的负载能力。
135 9
【亿级数据专题】「高并发架构」盘点本年度探索对外服务的百万请求量的API网关设计实现