dubbo源码浅析-服务消费(服务端接收处理)

本文深入解析Dubbo服务端接收和处理客户端请求的全过程,包括NettyCodecAdapter内部类处理、业务线程池策略、消息核心逻辑处理及结果返回机制。探讨了多个Filter的作用,如ContextFilter、EchoFilter等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


紧接上文分析下客户端发送之后,服务端的接收和处理

分析入口

  • NettyCodecAdapter内部类InternalDecoder#messageReceived

在这里插入图片描述进到这里是因为我们在开启netty服务时候,在netty channel的pipeline中按照顺序指定了继承与SimpleChannelUpstreamHandler的编解码handler和业务handler(远程暴露),意味着客户端请求的时候,会首先经过编解码handler,然后到达业务处理handler。暂时不分析编解码

   Channels.fireMessageReceived(ctx, msg, event.getRemoteAddress());

通过netty的事件传播,到达下一个UpstreamHandler(业务处理handler),这段代码是业务入口。
在这里插入图片描述

接收流程分析

  • NettyHandler#messageReceived()在这里插入图片描述将netty的channel包装成dubbo自身封装的channel
    使用dubbo自身的ChannelHandler去处理消息
  • AbstractPeer#received()在这里插入图片描述在这里插入图片描述
  • MultiMessageHandler#received()在这里插入图片描述这个handler为解决TCP半包问题
  • HeartbeatHandler#received() 过滤心跳消息
  • AllChannelHandler#received() 在这里插入图片描述AllChannelHandler对应一种线程派发策略在这里插入图片描述在这里插入图片描述拿到ExecutorService,是new一个ChannelEventRunnable扔到线程池处理。
  • ChannelEventRunnable#run() 接下来交由业务线程池处理在这里插入图片描述业务线程根据状态不同执行不同的操作,处理的状态有CONNECTED、DISCONNECTED、SENT、RECEIVED,CAUGHT。
  • DecodeHandler#received()在这里插入图片描述
  • HeaderExchangeHandler#received()在这里插入图片描述重点在这里
Response response = handleRequest(exchangeChannel, request);

因为是twoWay所以在处理完请求之后会通过channel将结果发送到客户端

  • HeaderExchangeHandler#handleRequest()在这里插入图片描述
    核心逻辑如下
Object result = handler.reply(channel, msg);

handler是DubboProtocol内部类ExchangeHandlerAdapter.reply()在这里插入图片描述

客户端消息处理核心逻辑
  1. 获取Invoker在这里插入图片描述首先组装serviceKey,然后从协议的exporterMap中获取exporter,从exporter中获取Invoker
  2. 执行invoker.invoke(inv),执行invoke又可以分为两个阶段,第一阶段:执行Invoker过滤器链(只是给出,暂不分析);
    在这里插入图片描述
    (1)EchoFilter
    (2)ClassLoaderFilter
    (3)GenericFilter
    (4)ContextFilter
    (5)TraceFilter
    (6)TimeoutFilter
    (7)MonitorFilter
    (8)ExceptionFilter
    第二阶段:执行服务代理类的具体方法
    在这里插入图片描述因为默认ProxyFactory使用javassist,因此具体可执行的Invoker是JavassistProxyFactory的一个匿名内部类在这里插入图片描述
    覆写JavassistProxyFactory的doInvoker方法,完成执行具体服务的功能(具体执行细节后续分析),将执行结果包装一个RpcResult进行返回;经过过滤器的后置处理,invoker.invoke(inv)处理完毕。
    到此,消息处理的核心逻辑处理完毕。
返回服务处理结果

接下来会将服务调用结果通过rpc的方式发送给客户端, channel.send(response)
在这里插入图片描述

  1. NettyChannel.send()在这里插入图片描述依托于NettyChannel内部维护的netty的channel进行数据的写入,
 ChannelFuture future = channel.write(message);

具体netty如何写回暂不分析,到此,服务端接收处理整个流程完结。

服务端处理流程总结

服务端处理请求的简要流程:根据配置的remoting组件接收到客户端的请求数据,然后根据指定的消息派发策略判断是否放入线程池中处理,确认处理方式之后,即如果需要扔到线程池中处理,则新建Runnable任务,根据不同的请求状态去做具体的处理(用户可以根据业务去选择线程池类型,比如dubbo提供有自身封装的FixedThreadPool、CachedThreadPool,用户也可自己扩展,以及做一些具体参数的指定),在具体处理过程中,首先从当前协议exporterMap中获取exporter,然后获取相应的Invoker,最后执行Invoker,如果有返回值的话,将执行结果从remoting发送到客户端,流程完结。
需要关注的是:服务端处理过程中可以根据具体业务场景去指定不同的线程模型,也可以配置不同的通信方式(netty,mina等),也可以指定不同的派发策略。

几个Filter的简单说明(后续会做具体分析)

因为ContextFilter的存在可以在具体调用过程中,得到上下文信息用于业务处理,因为EchoFilter的存在,可以在服务调用前检测服务是否可用(回声测试,每个服务自动实现EchoService),可以自定义filter,实现对服务调用消费的监控。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值