diff --git a/packages/dubbo/src/registry/zookeeper.ts b/packages/dubbo/src/registry/zookeeper.ts index 4554c4e6..94651cfe 100644 --- a/packages/dubbo/src/registry/zookeeper.ts +++ b/packages/dubbo/src/registry/zookeeper.ts @@ -17,7 +17,7 @@ import debug from 'debug'; import ip from 'ip'; -import zookeeper from 'node-zookeeper-client'; +import zookeeper, {State} from 'node-zookeeper-client'; import qs from 'querystring'; import DubboUrl from '../dubbo-url'; import { @@ -36,6 +36,7 @@ import Registry from './registry'; const log = debug('dubbo:zookeeper'); const ipAddress = ip.address(); +const CHECK_TIME = 30 * 1000; export class ZkRegistry extends Registry { constructor(props: IZkClientProps & IDubboRegistryProps) { @@ -49,6 +50,7 @@ export class ZkRegistry extends Registry { this._connect(this._init); } + private _checkTimer: NodeJS.Timer; private _client: zookeeper.Client; private _agentAddrSet: Set; @@ -105,6 +107,35 @@ export class ZkRegistry extends Registry { this._subscriber.onData(this._allAgentAddrSet); }; + /** + * 重连 + */ + private _reconnect() { + if (this._client) { + this._client.close(); + } + this._connect(this._init); + } + + /** + * 由于zk自己的监测机制不明确, 改为自主检测 + */ + private _monitor() { + clearInterval(this._checkTimer); + this._checkTimer = setInterval(() => { + const state = this._client.getState(); + switch (state) { + case State.EXPIRED: + case State.DISCONNECTED: + log(`checker is error, state is ${state}, need reconnect`); + this._reconnect(); + break; + default: + log(`checker is ok, state is ${state}`); + } + }, CHECK_TIME); + } + /** * 获取所有的负载列表,通过agentAddrMap聚合出来 * 这样有点Reactive的感觉,不需要考虑当中增加删除的动作 @@ -171,6 +202,7 @@ export class ZkRegistry extends Registry { clearTimeout(timeId); callback(null); msg.emit('sys:ready'); + this._monitor(); }); //the connection between client and server is dropped. diff --git a/packages/dubbo/src/scheduler.ts b/packages/dubbo/src/scheduler.ts index 72571bba..3c9e9ee4 100644 --- a/packages/dubbo/src/scheduler.ts +++ b/packages/dubbo/src/scheduler.ts @@ -131,7 +131,13 @@ export default class Scheduler { log(err); //说明zookeeper连接不上 if (err instanceof ZookeeperTimeoutError) { - this._status = STATUS.FAILED; + switch (this._status) { + // 当zk已经初始化完成后, 相应的provider已经找到了, 如果zk这时出现问题, 不应该让provider不允许调用 + case STATUS.READY: + break; + default: + this._status = STATUS.FAILED; + } } };