Skip to content

Commit

Permalink
chore[doc]: update doc
Browse files Browse the repository at this point in the history
  • Loading branch information
jaysunxiao committed Mar 23, 2024
1 parent 5c1bc4d commit 0e6fb0a
Show file tree
Hide file tree
Showing 3 changed files with 6 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) {
}


// 把客户端信息包装为一个GatewayAttachment,因此通过这个网关附加包可以得到玩家的uid、sid之类的信息
// 把客户端信息包装为一个GatewayAttachment,因此通过这个网关附加包可以得到用户或玩家的uid、sid之类的信息
var gatewayAttachment = new GatewayAttachment(session);
var signalAttachment = (SignalAttachment) decodedPacketInfo.getAttachment();
if (signalAttachment != null) {
Expand All @@ -87,7 +87,7 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) {
}

// 网关优先使用IGatewayLoadBalancer作为一致性hash的计算参数,然后才会使用客户端的session做参数
// 例子:以聊天服务来说,玩家知道自己在哪个群组groupId中,那往这个群发送消息时,会在Packet中带上这个groupId做为一致性hash就可以了。
// 例子:以聊天服务来说,用户或玩家知道自己在哪个群组groupId中,那往这个群发送消息时,会在Packet中带上这个groupId做为一致性hash就可以了。
if (packet instanceof IGatewayLoadBalancer) {
var loadBalancerConsistentHashObject = ((IGatewayLoadBalancer) packet).loadBalancerConsistentHashObject();
gatewayAttachment.setTaskExecutorHash(loadBalancerConsistentHashObject.hashCode());
Expand All @@ -103,7 +103,7 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) {
}
// 再使用session的sid做一致性hash,因为每次客户端连接过来sid都会改变,所以客户端重新建立连接的话可能会被路由到其它的服务器
// 如果有特殊需求的话,可以考虑去重写网关的转发策略
// 拿着玩家的sid做一致性hash,那肯定是:一旦重连sid就会一直变化。所以:一般情况下除非自己创建TcpClient,否则逻辑不应该走到这里。 而是走上面的通过UID做一致性hash
// 拿着用户或玩家的sid做一致性hash,那肯定是:一旦重连sid就会一直变化。所以:一般情况下除非自己创建TcpClient,否则逻辑不应该走到这里。 而是走上面的通过UID做一致性hash
var sid = session.getSid();
forwardingPacket(packet, gatewayAttachment, sid);
}
Expand Down
4 changes: 2 additions & 2 deletions net/src/main/java/com/zfoo/net/router/Router.java
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ public void receive(Session session, Object packet, @Nullable Object attachment)
gatewayAttachment.setClient(false);
dispatchByTaskExecutorHash(gatewayAttachment.taskExecutorHash(), task);
} else {
// 这里是:别的服务提供者提供授权给网关,比如:在玩家登录后,home服查到了玩家uid,然后发给Gateway服
// 这里是:别的服务提供者提供授权给网关,比如:在用户或玩家登录后,home服查到了玩家uid,然后发给Gateway服
var gatewaySession = NetContext.getSessionManager().getServerSession(gatewayAttachment.getSid());
if (gatewaySession == null) {
logger.error("gateway receives packet:[{}] and attachment:[{}] from server" + ", but serverSessionMap has no session[id:{}], perhaps client disconnected from gateway.", JsonUtils.object2String(packet), JsonUtils.object2String(attachment), gatewayAttachment.getSid());
Expand Down Expand Up @@ -159,7 +159,7 @@ public void receive(Session session, Object packet, @Nullable Object attachment)
* 在zfoo这套线程模型中,保证了服务器所接收到的Packet(最终被包装成PacketReceiverTask任务),永远只会在同一条线程处理,
* TaskBus通过AbstractTaskDispatch去派发PacketReceiverTask任务,具体在哪个线程处理通过IAttachment的taskExecutorHash计算。
* <p>
* 这种流水线做法对cpu缓存非常友好,java线程能大部分时间跑在一个cpu核心,而玩家又和线程一一对应,这样就可以最大限度提高cpu缓存命中率。
* 这种流水线做法对cpu缓存非常友好,java线程能大部分时间跑在一个cpu核心,而用户逻辑又和线程一一对应,这样就可以最大限度提高cpu缓存命中率。
* cpu的cache越大命中率就越高,性能提高就越明显。
* <p>
* 单线程热点问题,在负载足够大的情况下,比如5000人同时在线的8核服务器,因为样本足够大每个核心分配的人数差距并不会太大。
Expand Down
2 changes: 1 addition & 1 deletion orm/src/main/java/com/zfoo/orm/model/IEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public interface IEntity<PK extends Comparable<PK>> {
* <p>
* 写入一条数据到数据库的时候会对比当前entity的vs和数据库的vs是不是一样,不是一样的话无法写入,一致的话就写入数据并且让vs自增+1.
* 主要是为了防止多个服务器去操作同一条数据,保证在分布式环境的数据一致性;简单的说就是一个数据版本号的简单实现,版本号一致才能写入数据。
* 在分布式环境中,会存在有状态服务器,比如网关路由一个玩家的数据到a服务器,这个时候你加了一个b服务器,有可能下一条数据就被路由到b。
* 在分布式环境中,会存在有状态服务器,比如网关路由一个用户或玩家的数据到a服务器,这个时候你加了一个b服务器,有可能下一条数据就被路由到b。
* 虽然用了一致性hash的负载均衡算法,但是一样有概率会让某些消息路由到不同服务器。
* 这个时候版本号就可以保证只有一台服务器可以对数据库做操作,不用担心多个服务器去操作数据。
* 这是一个容错的操作,真实环境下很少发生。为了高性能必须要把服务器做成有状态的,这个容错操作就是最后一道保证数据一致的方案。
Expand Down

0 comments on commit 0e6fb0a

Please sign in to comment.