扩展点介绍
如上图所示,从服务调用的角度来看,Dubbo 在链路中提供了丰富的扩展点,覆盖了负载均衡方式、选址前后的拦截器、服务端处理拦截器等。 简单来说 Dubbo 发起远程调用的时候,主要工作流程可以分为消费端和服务端两个部分。
消费端的工作流程如下:
-
通过 Stub 接收来自用户的请求,并且封装在 Invocation 对象中
-
将 Invocation 对象传递给 ClusterFilter(扩展点)做选址前的请求预处理,如请求参数的转换、请求日志记录、限流等操作都是在此阶段进行的
-
将 Invocation 对象传递给 Cluster(扩展点)进行集群调用逻辑的决策,如快速失败模式、安全失败模式等决策都是在此阶段进行的
- Cluster 调用 Directory 获取所有可用的服务端地址信息
- Directory 调用 StateRouter(扩展点,推荐使用) 和 Router(扩展点) 对服务端的地址信息进行路由筛选,此阶段主要是从全量的地址信息中筛选出本次调用允许调用到的目标,如基于打标的流量路由就是在此阶段进行的
- Cluster 获得从 Directory 提供的可用服务端信息后,会调用 LoadBalance (扩展点)从多个地址中选择出一个本次调用的目标,如随机调用、轮询调用、一致性哈希等策略都是在此阶段进行的
- Cluster 获得目标的 Invoker 以后将 Invocation 传递给对应的 Invoker,并等待返回结果,如果出现报错则执行对应的决策(如快速失败、安全失败等)
-
经过上面的处理,得到了带有目标地址信息的 Invoker,会再调用 Filter(扩展点)进行选址后的请求处理(由于在消费端侧创建的 Filter 数量级和服务端地址量级一致,如无特殊需要建议使用 ClusterFilter 进行扩展拦截,以提高性能)
-
最后 Invocation 会被通过网络发送给服务端
服务端的工作流程如下: -
服务端通信层收到请求以后,会将请求传递给协议层构建出 Invocation
-
将 Invocation 对象传递给 Filter (扩展点)做服务端请求的预处理,如服务端鉴权、日志记录、限流等操作都是在此阶段进行的
-
将 Invocation 对象传递给动态代理做真实的服务端调用
介绍完扩展点后,下面以拦截扩展点
为例介绍具体使用
拦截点
官方接口: org.apache.dubbo.rpc.Filter
@SPI(scope = ExtensionScope.MODULE)
public interface Filter extends BaseFilter {
}
在项目中实现该接口,自定义逻辑:
@Slf4j
@Activate(group = CommonConstants.CONSUMER)
public class ParamFilter implements Filter {
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
// 这里可以获取到消费者请求的相关信息,如服务名、请求的方法名、以及请求的参数
// 实际应用:做一些参数检查以及转换等等操作
log.info("Service-Name: " + invocation.getServiceName() + " Method: " + invocation.getMethodName() + " Parameter: " + Arrays.toString(invocation.getArguments()));
// 将请求发送给服务端
return invoker.invoke(invocation);
}
}
编写Filter的配置文件:
文件名:org.apache.dubbo.rpc.Filter
内容:
MyFilter=com.mxf.filter.ParamFilter
MyFilter: 是自定义Filter的一个别名,可以自定义
在application.yaml中配置该接口:
dubbo:
application:
name: shop-service-consumer
protocol:
name: dubbo
port: -1
registry:
id: nacos-registry
address: nacos://192.168.11.233:8848
config-center:
address: nacos://192.168.11.233:8848
metadata-report:
address: nacos://192.168.11.233:8848
consumer: #在消费端的拦截扩展点
filter: MyFilter # 注意名称要和签名定义的一致
重启项目演示
可以使用Postman请求相关接口,就可以看到输出日志:
2022-11-23 11:39:36.463 INFO 8988 --- [nio-8082-exec-1] com.mxf.filter.ParamFilter : Service-Name: com.mxf.service.ShopService Method: queryByName Parameter: [xiao]
可以看到在消费端自定义的拦截扩展点已经生效,可以获取到相关信息
待更新
集群扩展
路由扩展
负载均衡扩展