借助Dubbo过滤器实现服务间传值

你知道的越多,不知道的也越多!

基于现在的微服务架构,一个系统背后可能是几十个service去做支撑。那如何在多个服务间传递值呢?

场景描述: 一个用户下单某个商品,中间涉及到的服务有 (1)网关service -> (2)某个业务service -> (3)订单中心service -> (4)支付中心service… 这几个服务其实都需要用到用户身份。 首先网关service需要完成 用户身份校验的工作,当解析出用户信息的时候,如何传递到下游服务呢?

这里就可以使用Dubbo的Filter机制啦,终于可以讲重点了~ 自己随手写了一个Filter,大致步骤如下:

    写一个类去实现org.apache.dubbo.rpc.Filter,并重写里面的Invoke方法; 项目META-INF/dubbo里新建一个文件,文件名=org.apache.dubbo.rpc.Filter,文件内容为key=value的形式,key随便写,value为上面的实现类的全路径。 最后将项目打包,让需要使用该过滤器的项目pom即可生效。

关键代码: 消费端和提供端都进行过滤。

package com.yuki.dubbo.zdy.filter;

import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;

import java.util.HashMap;
import java.util.Map;

/**
 * 自定义dubbo的过滤器
 */
//作用于消费者和提供者
@Activate(group = {
          
   CommonConstants.CONSUMER, CommonConstants.PROVIDER})
public class MyFilter implements Filter {
          
   


    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
          
   
        long start = System.currentTimeMillis();
        try {
          
   
            dealContextParam(RpcContext.getContext());
            return invoker.invoke(invocation);
        } finally {
          
   
            System.out.println("过滤器统计耗时:" + (System.currentTimeMillis() - start) + "ms");
        }
    }

    /**
     * 处理rpc调用上下文里的参数
     *
     * @param rpcContext
     */
    public void dealContextParam(RpcContext rpcContext) {
          
   
        //消费者端进行存值
        if (RpcContext.getContext().isConsumerSide()) {
          
   
            Map<String, String> data = new HashMap<>();
            data.put("userId", "123456");
            data.put("userName", "我是一个小小Yuki啊啊啊");
            rpcContext.setAttachments(data);
        } else {
          
   
            //提供者取值,然后可以存入到全局变量中供使用,例如ThreadLocal<xx>
            Map<String, String> attachments = rpcContext.getAttachments();
            System.out.println("提供者拿到的参数:" + attachments);
        }
    }
}

运行结果: 核心类:RpcContext

可以使用RpcContext.getContext().isConsumerSide() 和RpcContext.getContext().isProviderSide()可以很好的区分当前引入的项目是消费端还是提供端。

思考: 之前对Dubbo不是很了解,一直以为Filter只能作用在消费端,可用来做日志处理,或者耗时统计等。最近看了它的分层图,猛然发现两端都有个Filter。并且消费端和提供端最终处理都会经过Invoker。

经验分享 程序员 微信小程序 职场和发展