zk的客户端发送请求

  • 客户端的发送数据核心代码如下
org.apache.zookeeper.ClientCnxn.SendThread.run()

while (state.isAlive()) {
                try {
                    if (!clientCnxnSocket.isConnected()) {
                       ...
                        if (rwServerAddress != null) {
                            serverAddress = rwServerAddress;
                            rwServerAddress = null;
                        } else {
                            serverAddress = hostProvider.next(1000);
                        }
                        startConnect(serverAddress);
                        clientCnxnSocket.updateLastSendAndHeard();
                    }

                  ...
                            sendPing();
                            clientCnxnSocket.updateLastSend();
                        } else {
                            if (timeToNextPing < to) {
                                to = timeToNextPing;
                            }
                        }
                    }

                   ...
                    clientCnxnSocket.doTransport(to, pendingQueue, outgoingQueue, ClientCnxn.this);
                }
                

这里是一个循环 只要是客户端没有被关闭 这个循环就会一直执行下去 主要的干的事情后有以下几件

  • 根据启动时指定的zk集群地址(使用逗号分隔)挨个进行连接直到连接成功
  • 连接成功后会修改一系列状态同时发布一些事件 然后触发心跳事件
 private void sendPing() {
           lastPingSentNs = System.nanoTime();
           RequestHeader h = new RequestHeader(-2, OpCode.ping);
           queuePacket(h, null, null, null, null, null, null, null, null);
       }

触发心跳也是往即将要发送和的消息队列中塞入一个请求 这里并没有单独开一个线程来进行维护

  • 最后一步就是具体的发送请求

这个流程解决了我的一些疑惑:
客户端连接zk集群的时候,指定了多个地址,具体应该去使用哪个地址,还有集群的leader挂了之后 如何去找其他可用的服务。通过上面的代码可知,这个循环在每次都会检查是否和服务端建立连接,如果没有建立 那么就一个一个地址挨个试,事实上zk集群的服务端,只有leader节点是可以和客户端建立连接的 因为只有leader会执行和startup方法,其他的都是节点都是被动跟着leader一起动的,leader挂了之后会选举出新的节点,新的主节点会执行startup方法接受客户端的连接

猜你喜欢

转载自blog.csdn.net/zhaoyu_nb/article/details/87088673