返回
ZooKeeper 单机服务端与客户端连接交互流程分析
后端
2024-01-19 07:01:11
ZooKeeper 连接交互流程
ZooKeeper 是一个分布式协调服务,它为分布式应用提供统一的命名服务、配置管理、集群管理等功能。ZooKeeper 采用的是主从复制架构,由一个主节点和多个从节点组成。主节点负责处理客户端的请求,而从节点则负责复制主节点的数据。
1. 客户端发起连接
当客户端需要使用 ZooKeeper 服务时,它首先会向 ZooKeeper 服务端发起连接请求。连接请求中包含客户端的 IP 地址、端口号等信息。
2. 服务端响应
ZooKeeper 服务端收到客户端的连接请求后,会进行验证和授权。如果验证和授权通过,服务端会向客户端发送一个连接响应。连接响应中包含服务端的 IP 地址、端口号等信息。
3. 客户端接收响应
客户端收到服务端的连接响应后,会解析响应中的信息,并建立与服务端的连接。
源码分析
1. 服务端响应
public void processConnectRequest(Request request) {
ZooKeeperServer zkServer = server;
if (!zkServer.authManager.authenticate(request.authInfo,
"digest",
request.sessionId)) {
return;
}
long sessionId = request.sessionId;
// If it is a session reconnect request (new client connecting with a
// session id)
if (request.sessionId != 0) {
// Verify if this is a valid session
Session session = zkServer.sessionTracker.getSession(sessionId);
if (session != null) {
session.updateJMXNode();
} else {
zkServer.sessionTracker.killSession(sessionId);
}
}
try {
if (request.sessionId == 0) {
long id = zkServer.sessionTracker.createSession(zkServer);
outBuffer.writeSessionMessage(id, request.timeOut);
} else {
// session reconnect
zkServer.sessionTracker.touchSession(sessionId, zkServer);
outBuffer.writeSessionMessage(0, request.timeOut);
}
} catch (KeeperException e) {
outBuffer.writeExceptionMessage(e);
}
}
在上面的代码中,processConnectRequest()
方法是处理客户端连接请求的入口函数。它首先验证客户端的授权信息,如果授权通过,则继续处理。然后,它检查客户端的连接类型,如果是新客户端连接,则创建一个新的会话,否则更新现有会话的超时时间。最后,它向客户端发送连接响应消息。
2. 客户端接收响应
protected void processConnectResponse(ByteBuffer request) {
if (request.getInt() != 0) {
// the server will not set the session Id to 0
throw new IOException("Session establish error, HResultCode: " + request.getInt());
}
long sessionId = request.getLong();
this.sessionId = sessionId;
}
在上面的代码中,processConnectResponse()
方法是处理客户端连接响应消息的入口函数。它首先检查响应消息中的错误码,如果错误码不为 0,则抛出异常。然后,它从响应消息中提取会话 ID,并将其存储在客户端的会话对象中。最后,它通知客户端连接已建立。
总结
ZooKeeper 的连接交互流程是一个复杂的过程,涉及到客户端和服务端之间的多次交互。通过分析源码,我们可以更好地理解这个流程的底层机制。