Ignite 客户端与服务端消息交互分析

提取2个类, 一个是请求, 一个是结果

  1. GridJobExecuteRequest
  2. GridJobExecuteResponse

首先从请求出发
在类 org.apache.ignite.internal.processors.task.GridTaskWorker 中, 有方法 sendRequest
看到如下代码

                 //如果是本地,则直接执行
                  if (loc)
                        //这个虽然是本地调用, 猜测在远程服务器也是这个方法,后面开始寻找消息的流转
                        ctx.job().processJobExecuteRequest(ctx.discovery().localNode(), req);
                    else {
                        byte plc;

                        if (internal)
                            plc = MANAGEMENT_POOL;
                        else {
                            Byte ctxPlc = getThreadContext(TC_IO_POLICY);

                            if (ctxPlc != null)
                                plc = ctxPlc;
                            else
                                plc = PUBLIC_POOL;
                        }

                        // Send job execution request.
                        //如果是远程,发关到GridTopic, 这个topic名字叫  TOPIC_JOB
                        ctx.io().sendToGridTopic(node, TOPIC_JOB, req, plc);

                        if (log.isDebugEnabled())
                            log.debug("Sent job request [req=" + req + ", node=" + node + ']');
                    }

sendToGridTopic 这个方法位于 类 org.apache.ignite.internal.managers.communication.GridIoManager 中
看这个类的注释,主要是处理Grid通信

send方法

   /**
     * @param node Destination node.
     * @param topic Topic to send the message to.
     * @param topicOrd GridTopic enumeration ordinal.
     * @param msg Message to send.
     * @param plc Type of processing.
     * @param ordered Ordered flag.
     * @param timeout Timeout.
     * @param skipOnTimeout Whether message can be skipped on timeout.
     * @param ackC Ack closure.
     * @param async If {@code true} message for local node will be processed in pool, otherwise in current thread.
     * @throws IgniteCheckedException Thrown in case of any errors.
     */
    private void send(
        ClusterNode node,
        Object topic,
        int topicOrd,
        Message msg,
        byte plc,
        boolean ordered,
        long timeout,
        boolean skipOnTimeout,
        IgniteInClosure<IgniteException> ackC,
        boolean async
    ) throws IgniteCheckedException {
        assert node != null;
        assert topic != null;
        assert msg != null;
        assert !async || msg instanceof GridIoUserMessage : msg; // Async execution was added only for IgniteMessaging.
        assert topicOrd >= 0 || !(topic instanceof GridTopic) : msg;

         //封装成 GridIoMessage
        GridIoMessage ioMsg = new GridIoMessage(plc, topic, topicOrd, msg, ordered, timeout, skipOnTimeout);

//如果是本地节点,直接处理
        if (locNodeId.equals(node.id())) {
            assert plc != P2P_POOL;

            CommunicationListener commLsnr = this.commLsnr;

            if (commLsnr == null)
                throw new IgniteCheckedException("Trying to send message when grid is not fully started.");

            if (ordered)
                processOrderedMessage(locNodeId, ioMsg, plc, null);
            else if (async)
                processRegularMessage(locNodeId, ioMsg, plc, NOOP);
            else
                processRegularMessage0(ioMsg, locNodeId);

            if (ackC != null)
                ackC.apply(null);
        }
        else {
            if (topicOrd < 0)
                ioMsg.topicBytes(U.marshal(marsh, topic));

            try {
            //通过spi发送消息
                if ((CommunicationSpi)getSpi() instanceof TcpCommunicationSpi)
                    ((TcpCommunicationSpi)(CommunicationSpi)getSpi()).sendMessage(node, ioMsg, ackC);
                else
                    getSpi().sendMessage(node, ioMsg);
            }
            catch (IgniteSpiException e) {
                if (e.getCause() instanceof ClusterTopologyCheckedException)
                    throw (ClusterTopologyCheckedException)e.getCause();

                if (!ctx.discovery().alive(node))
                    throw new ClusterTopologyCheckedException("Failed to send message, node left: " + node.id(), e);

                throw new IgniteCheckedException("Failed to send message (node may have left the grid or " +
                    "TCP connection cannot be established due to firewall issues) " +
                    "[node=" + node + ", topic=" + topic +
                    ", msg=" + msg + ", policy=" + plc + ']', e);
            }
        }
    }

最终调用 GridTcpNioCommunicationClient 中的 sendMessage
之后调用 ses.sendNoFuture(msg, c);

ses是GridNioSession的实现类 GridNioSessionImpl 的实例

chain().onSessionWrite(this, msg, false, ackC);

tail.onSessionWrite(ses, msg, fut, ackC);

下面是各种filter write
GridNioServer.onSessionWrite
GridNioCodecFilter.onSessionWrite

GridConnectionBytesVerifyFilter

GridNioServer.send0

扫描二维码关注公众号,回复: 6435298 查看本文章

最终是把消息放进

DirectNioClientWorker.offer

未完成待续

猜你喜欢

转载自blog.csdn.net/gs80140/article/details/89400194