借助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。