Open ityongman opened 11 months ago
Motan的心跳是针对Endpoint(也就是Client)维度的,主要目的是为了解决因链路问题或者服务端压力(比如单节点连续失败10次)触发熔断后的恢复,服务正常的情况下是不会额外执行心跳操作的。
当client被熔断后,发送心跳会触发远程请求,只要请求成功就会恢复client的状态,所以心跳只需要检测client的状态就可以了。
至于单个channel维度的available,是由client内的连接池进行管理的,在获取或者交回链接时会进行单个链接的状态进行判断。
如果client所在的服务先启动,服务端后启动, 启动后EndPoint(Client)是OK的,但是检测到的服务端是存在问题的,如果这个检测放在channel中才检测,不管业务过多久进行rpc请求,第一次都会存在问题, motan应该提供机制在服务端后启动场景下, 客户端和服务端能重连
前面的回复提到了这个心跳机制是为了解决服务运行中,因链路问题导致熔断后,节点可以自动恢复,并不是用来解决启动时无效server节点的。
你提到的client启动时server节点未启动的问题是可以通过注册中心避免的,server端得先启动完成,并且打开提供服务的开关后,才会触发向注册中心注册server节点(一般server节点在启动后,还需要进行状态自检、预热等行为,保证服务可以正常工作后才会打开开关对外提供服务)。然后client端才能从注册中心发现这个server节点。
现在使用的是motan directUrl方式, 没使用注册中心, motan提供了directUrl能力,这种方式应该和有注册中心一样的能力,而不是配置方式不同,体现能力不同;针对注册中心方式,client也是和注册中心进行交互获取 server注册的信息, 如果是directUrl方式应该提供直接检查server是否可用的能力, 不然会存在 “不管业务过多久进行rpc请求,第一次都会提示server不可用的问题”
DirectRegistry是一个简单的注册中心实现,是为了方便直连调试等非线上场景,并没有做server节点可用性检测设计。如果direct注册中心要实现与其他注册中心等同的能力,需要在DirectRegistry中对serve节点的可用性进行周期性检测,在可用性发生变更时触发回调动态通知client当前可用的serve节点。这块我们会考虑在后续的版本中增强DirectRegistry。
一般线上业务不建议使用DirectRegistry这种服务发现方式,这种方式不太适合ip经常动态变动的云环境以及具有动态扩容能力的server。
server节点的不可用是可以发生在任何时刻的,client的熔断机制并不特别针对服务启动或者服务运行中,熔断机制是保证节点不可用后可以熔断,并在节点可用后可以恢复。链接可用性的管理是交给链接池负责的,如果请求时没有可用的链接,链接池会触发重新建连。
熔断机制是处理偶发server节点不可用的意外场景的,如果经常会出现server节点不可用的情况,建议使用动态注册中心方式(例如zk),或者优化服务的运维流程
public class HeartbeatClientEndpointManager implements EndpointManager {
}
// 如果节点是存活状态,那么没必要走心跳 if (endpoint.isAvailable()) { continue; } 着部分代码在检测节点存活状态, Endpoint检测的是当前终端是否可用, 应该检查 ((NettyClient)endpoint).channels 是不是都是avaliable, 如果存在不可用状态,调用 endpoint.heartbeat 进行心跳检查