dubbo 2.6.2接收到消费者服务调用详细过程

pipeline.addLast("decoder", adapter.getDecoder());

pipeline.addLast("encoder", adapter.getEncoder());

pipeline.addLast("handler", nettyHandler);

根据NettyServer 的这段代码可以知道 当接收到消息时会先通过decoder解码 就是

NettyCodecAdapter .InternalDecoder 这个内部类

如果是远程服务调用请求会得到一个MultiMessage{

messages:[ Request{ DecodeableRpcInvocation}, Request{ DecodeableRpcInvocation}...]

}

这样的的一个消息实例

接下来就是:

NettyHandler.messageReceived (ChannelHandlerContext ctx, MessageEvent e)

NettyChannel channel = NettyChannel.getOrAddChannel(ctx.getChannel(), url, handler);

根据netty 的channel 冲缓存中获取NettyChannel 没有则创建

NettyChannel nc = new NettyChannel(ch, url, handler);

 

handler.received(channel, e.getMessage());

该handler 根据netty的创建可以知道为:

NettyServer{

                   AllChannelHandler{

                            MultiMessageHandler{

                                    HeartbeatHandler {

                                              DecodeHandler{

                                                       HeaderExchangeHandler {

                                                                  DubboProtocol 内部类实现

                                                        }

                                               }

                                      }

                            }

                   }

         }

NettyServer执行如下:

@Override

public void received(Channel ch, Object msg) throws RemotingException {

    if (closed) {

        return;

    }

    handler.received(ch, msg);

}

AllChannelHandler 如下:

ExecutorService cexecutor = getExecutorService();
cexecutor.execute(new ChannelEventRunnable(channel, handler, ChannelState.RECEIVED, message));
 

这儿的cexecutor 就是在创建server时候缓存在AllChannelHandler中的

public ChannelEventRunnable(Channel channel, ChannelHandler handler, ChannelState state, Object message) {

    this(channel, handler, state, message, null);

}
 
public ChannelEventRunnable(Channel channel, ChannelHandler handler, ChannelState state, Object message, Throwable exception) {

    this.channel = channel;

    this.handler = handler;

    this.state = state;

    this.message = message;

    this.exception = exception;

}

创建了ChannelEventRunnable对象并赋值属性

this.channel = 新建或缓存的与netty的channel对应的 NettyChannel;

 

 

 


this.handler = MultiMessageHandler{

                                    HeartbeatHandler {

                                              DecodeHandler{

                                                       HeaderExchangeHandler {

                                                                  DubboProtocol 内部类实现

                                                        }

                                               }

                                      }

                            }

this.state = ChannelState.RECEIVED;

this.message = MultiMessage{

messages:[ Request{ DecodeableRpcInvocation}, Request{ DecodeableRpcInvocation}...]

}

ChannelEventRunnable 类实现了Runnable 提交到了cexecutor中 会有线程来执行run方法

由于 this.state = ChannelState.RECEIVED;

case RECEIVED:

    try {

        handler.received(channel, message);

    } catch (Exception e) {
      //...

    }

    break;

所以执行了MultiMessageHandler

public void received(Channel channel, Object message) throws RemotingException {

    if (message instanceof MultiMessage) {

        MultiMessage list = (MultiMessage) message;

        for (Object obj : list) {

            handler.received(channel, obj);

        }

    } else {

        handler.received(channel, message);

    }

}

我们的message是MultiMessage 对象所以会循环调用 循环出来的消息时Request{ DecodeableRpcInvocation}类型实例

然后执行HeartbeatHandler

该消息 不是HeartbeatRequest也不是HeartbeatResponse 所以执行下面这段

handler.received(channel, message);

然后执行DecodeHandler

@Override

public void received(Channel channel, Object message) throws RemotingException {

    if (message instanceof Decodeable) {

        decode(message);

    }



    if (message instanceof Request) {

        decode(((Request) message).getData());

    }



    if (message instanceof Response) {

        decode(((Response) message).getResult());

    }



    handler.received(channel, message);

}

Request{ DecodeableRpcInvocation}是Request 会执行decode(((Request) message).getData()); 但是已经解码 所以直接返回

然后执行HeaderExchangeHandler类

ExchangeChannel exchangeChannel = HeaderExchangeChannel.getOrAddChannel(channel);
 
if (message instanceof Request) {

    // handle request.

    Request request = (Request) message;

    if (request.isEvent()) {

        handlerEvent(channel, request);

    } else {

        if (request.isTwoWay()) {

            Response response = handleRequest(exchangeChannel, request);

            channel.send(response);

        } else {

            handler.received(exchangeChannel, request.getData());

        }

    }

}

 

 

然后会将NettyChannell包装成 HeaderExchangeChannel

此时

channel = HeaderExchangeChannel{

         channel: NettyChannell{

                  channel :netty框架的channel

         }                         

}

message = Request{ DecodeableRpcInvocation}

request.isTwoWay() 是true

Response response = handleRequest(exchangeChannel, request);

channel.send(response);

Response handleRequest (ExchangeChannel channel, Request req)

先创建一个

Response res = new Response(req.getId(), req.getVersion());

 

然后执行DubboProtocol. reply方法

Invocation inv = (Invocation) message;

Invoker<?> invoker = getInvoker(channel, inv);

// need to consider backward-compatibility if it's a callback

if (Boolean.TRUE.toString().equals(inv.getAttachments().get(IS_CALLBACK_SERVICE_INVOKE))) {

    String methodsStr = invoker.getUrl().getParameters().get("methods");

    boolean hasMethod = false;

    if (methodsStr == null || methodsStr.indexOf(",") == -1) {

        hasMethod = inv.getMethodName().equals(methodsStr);

    } else {

        String[] methods = methodsStr.split(",");

        for (String method : methods) {

            if (inv.getMethodName().equals(method)) {

                hasMethod = true;

                break;

            }

        }

    }

    if (!hasMethod) {

        logger.warn(new IllegalStateException();

        return null;

    }

}

RpcContext.getContext().setRemoteAddress(channel.getRemoteAddress());

return invoker.invoke(inv);

 

String serviceKey = serviceKey(port, path, inv.getAttachments().get(Constants.VERSION_KEY), inv.getAttachments().get(Constants.GROUP_KEY));

 

DubboExporter<?> exporter = (DubboExporter<?>) exporterMap.get(serviceKey);

 

return exporter.getInvoker();

 

根据调用接口和端口号等配置信息得到serviceKey

然后冲缓存中获取DubboExporter实例并得到这次调用的invoker

return invoker.invoke(inv);

返回对应调用结果

地调的返回结果封装到Response对象中 调用 channel参数的send方法发出

channel = HeaderExchangeChannel{

         channel: NettyChannell{

                  channel :netty框架的channel

         }                         

}

Response={

         mStatus=ok

         mResult=服务调用结果

}

因此执行了HeaderExchangeChannel类的send方法

send(message, getUrl().getParameter(Constants.SENT_KEY, false));
Request request = new Request();

request.setVersion("2.0.0");

request.setTwoWay(false);

request.setData(message);

channel.send(request, sent);

此时 message = Request{

                  data: Response={

                            mStatus=ok

                            mResult=服务调用结果

                   }

         }

然后调用了 NettyChannel的send方法

ChannelFuture future = channel.write(message);

调用了netty框架的channel的写出发放 然后通过编码器编码最后传输到消费端

 

关于handler的调用过程请看:

NettyHandler {

         NettyServer{

                   AllChannelHandler{

                            MultiMessageHandler{

                                    HeartbeatHandler {

                                              DecodeHandler{

                                                       HeaderExchangeHandler {

                                                                  DubboProtocol 内部类实现

                                                        }

                                               }

                                      }

                            }

                   }

         }

}

这个结构的handler就是注册到netty框架的  会从外向里一层层调用

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值