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

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

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

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

  • 不可能说用参数形式吧?
    因为这样会显得参数过于冗长。这里只是用户身份,那如果是一些请求头里的信息,比如记录了客户端发送的版本号和请求来源渠道呢?肯定不建议这种方式。
    而且对日后的拓展也不好,参数Model的修改会引发Jar包的升级。

这里就可以使用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。
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值