Java Dubbo服务调用扩展点Filter使用教程

 更新时间:2022年12月09日 11:10:52   作者:天使中的魔鬼M  
Dubbo是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的RPC实现服务的输出和输入功能,可以和Spring框架无缝集成

扩展点介绍

如上图所示,从服务调用的角度来看,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]

可以看到在消费端自定义的拦截扩展点已经生效,可以获取到相关信息

Dubbo实现负载均衡的扩展

官方提供的接口:

RandomLoadBalance:随机策略的LB

RoundRobinLoadBalance:轮询策略的LB

LeastActiveLoadBalance:最少活跃调用数策略的LB:举例有两台服务器,一台正在处理的任务数很多也就是负载高,那么当前负载策略就会尽量少的给这台服务器分配任务;反之,如果一台服务器处理的任务数少,就尽量优先给它分配任务。

ConsistentHashLoadBalance:一致性Hash策略的LB:。一致性Hash,相同参数的请求总是发到同一提供者,当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。

ShortestResponseLoadBalance:最短响应优先策略的LB

除了以上Dubbo提供的五种默认实现的负载均衡策略,也可以自定义负载均衡策略,只要实现Dubbo提供的LoadBalance接口,自定义实现select即可:

@SPI(RandomLoadBalance.NAME)
public interface LoadBalance {
    /**
     * select one invoker in list.
     *
     * @param invokers   invokers.
     * @param url        refer url
     * @param invocation invocation.
     * @return selected invoker.
     */
    @Adaptive("loadbalance")
    <T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation) throws RpcException;
}

用法:以轮询策略为例

第一步编写配置文件:

文件名:org.apache.dubbo.rpc.cluster.LoadBalance

RRLB=org.apache.dubbo.rpc.cluster.loadbalance.RoundRobinLoadBalance

RRLB是自定义的负载均衡名称

在application.yaml中配置LB:

dubbo:
  consumer:	# 在消费端的LB
    loadbalance: RRLB

OK,到此配置完成,当启动多个服务提供者,用一个消费者去调用,就是采取轮询的策略均匀请求到服务提供者上

其余四种实现方式一样。

到此这篇关于Java Dubbo服务调用扩展点Filter使用教程的文章就介绍到这了,更多相关Java Filter内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • springBoot集成redis的key,value序列化的相关问题

    springBoot集成redis的key,value序列化的相关问题

    这篇文章主要介绍了springBoot集成redis的key,value序列化的相关问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • SpringCLoud搭建Zuul网关集群过程解析

    SpringCLoud搭建Zuul网关集群过程解析

    这篇文章主要介绍了SpringCLoud搭建Zuul网关集群过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • Java利用Swagger2自动生成对外接口的文档

    Java利用Swagger2自动生成对外接口的文档

    这篇文章主要介绍了Java利用Swagger2自动生成对外接口的文档,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-06-06
  • java.net.http.HttpClient使用示例解析

    java.net.http.HttpClient使用示例解析

    这篇文章主要为大家介绍了java.net.http.HttpClient使用示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08
  • Java redisson实现分布式锁原理详解

    Java redisson实现分布式锁原理详解

    这篇文章主要介绍了Java redisson实现分布式锁原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • Hibernate懒加载之<class>标签上的lazy

    Hibernate懒加载之<class>标签上的lazy

    这篇文章主要介绍了Hibernate懒加载之<class>标签上的lazy,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下
    2018-02-02
  • java反射应用详细介绍

    java反射应用详细介绍

    本篇文章依旧采用小例子来说明java反射应用,因为我始终觉的,案例驱动是最好的,需要的朋友可以参考下
    2012-11-11
  • tcc分布式事务框架体系解析

    tcc分布式事务框架体系解析

    这篇文章主要为大家介绍了tcc分布式事务框架体系结构的解析说明,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2022-03-03
  • Spring+Quartz实现动态任务调度详解

    Spring+Quartz实现动态任务调度详解

    这篇文章主要介绍了Spring+Quartz实现动态任务调度详解,最近经常基于spring boot写定时任务,并且是使用注解的方式进行实现,分成的方便将自己的类注入spring容器,需要的朋友可以参考下
    2024-01-01
  • Java this 关键字的使用方法详解

    Java this 关键字的使用方法详解

    这篇文章主要介绍了Java this 关键字的使用方法详解的相关资料,希望通过本文能帮助到大家,让大家彻底理解掌握这部分内容,需要的朋友可以参考下
    2017-10-10

最新评论