SpringCloud - zuul网关常见问题解决方案

token不向后传递的问题。(单体 -> 微服务 改造)

在老项目改造微服务过程中,建立zuul网关,发送的"Cookie", "Set-Cookie", "Authorization" 这三个请求头会被自动过滤,但是有些旧的服务需要这些请求头信息。

源码:

    private Set<String> sensitiveHeaders = new LinkedHashSet(Arrays.asList("Cookie", "Set-Cookie", "Authorization"));

一般情况下,我们会把token放在请求头中想后台服务传递。
可以通过zuul项目中通过配置文件解决:

zuul:
    #一下配置,表示忽略下面的值向微服务传播,以下配置为空表示:所有请求头都透传到后面微服务。
  sensitive-headers:

老项目改造中路由的问题

问题示例:
单体项目改造微服务,app端不改变调用后端服务器的 restful 接口URI,但是由于后端改造,导致app端和server端接口无法对应,
app端调用的接口 /user/xxx 要求访问 server端 /user/yyy ,虽然可以在zuul网关中做 路径绝对映射 配置,但是在微服务过多的情况下,会导致yml文件过于冗余,而且不易扩展。

因此采用自定义过滤器的方式,具体实现步骤:

  1. 过滤器route
  2. 获取请求过来的URL
  3. 请求的URL和 目的地做映射
  4. 设置RequestContext中的ServiceId和url

代码demo演示:

@Component
public class RibbonFilter extends ZuulFilter {


    @Override
    public String filterType() {
        return FilterConstants.ROUTE_TYPE;
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() throws ZuulException {
        //获取到当前请求上下文
        RequestContext currentContext = RequestContext.getCurrentContext();
        HttpServletRequest request = currentContext.getRequest();
        String uri = request.getRequestURI();
		
		//demo演示写死了,生产中可以写动态
        if (uri.contains("/sms-test31")){
            //设置serviceId
            currentContext.set(FilterConstants.SERVICE_ID_KEY,"service-sms");
            //设置uri,即controller路径
            currentContext.set(FilterConstants.REQUEST_URI_KEY,"/sms-test3");

        }
        return null;
    }
}

动态路由(不同用户路由到不同服务)

问题示例:
如果一个项目在北京和上海两个地方分别有一个计价系统,两个地区的计价规则不一样。
需求北京地区走北京的计价,上海地区走上海的计价。

该问题类似于灰度发布,AB测试的功能,但是和灰度发布不同的是:灰度发布请求的服务是同一个,所以只需要用 Tag 来区分新老版本即可。而该问题要求不同用户请求不同的服务,北京计价和上海计价是不同的服务。
在AKF拆分中,把用户进行了分片。同样可以在zuul的过滤器中来做。

demo代码:

    /**
     * zuulfile的run
     * @return
     * @throws ZuulException
     */
    @SneakyThrows
    @Override
    public Object run() throws ZuulException {
        //获取到当前请求上下文
        RequestContext currentContext = RequestContext.getCurrentContext();
        HttpServletRequest request = currentContext.getRequest();
        String uri = request.getRequestURI();
		
		//根据自己的特务定义删选条件
        if (uri.contains("/zuul-api-driver")){
        	//转发到固定的服务地址
            currentContext.setRouteHost(new URI("http://xxx.xxx.xxx").toURL());

        }
        return null;
    }

需要注意的是,需要在yml文件中添加要请求的地址,因为Eureka中没有这个名称的服务,zuul网关中也没有映射该地址,就会报404错误,示例:

zuul:
  routes:
    service-sms: /zuul-api-driver/**

注:
通过网关访问找不到服务报404错误大概有两种情况

  1. 服务提供方没有这个uri地址。
  2. zuul网关中没有配置匹配的地址。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值