Skip to content

高可用模式下服务异常引起的bug #20

@juipengchang

Description

@juipengchang
  • 假设

我有3台ecs机器搭成的TuGraph集群,公网ip分别是A、B、C
测试代码:

public static void main(String[] args) throws Exception {
    List<String> urls = Lists.newArrayList(A, B, C);
    TuGraphDbRpcClient client = new TuGraphDbRpcClient(urls, username, password);
    System.out.println("client done");
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            String res = client.callCypher("match (n) return count(n);", "default", 100);
            System.out.println(res);
        }
        Thread.sleep(1000 * 30);  // 挂起30s方便去关停服务
        System.out.println("sleep done");
    }
}
  • 问题1:启动阶段机器挂掉(无需解决)

如果应用启动阶段就有一台机器挂掉,则报错:
github1
调用路径是
github2
github3
github4
到这里,由于url已经无效,所以抛出异常给refreshConnection,refreshConnection捕获异常但会继续抛出异常给构造方法TuGraphDbRpcClient,导致启动失败。
不过仔细想这样其实也不算问题,因为应用启动时,务必保证所有的TuGraph服务都可用,如果不可用则报错排查,符合逻辑。

  • 问题2:运行阶段机器挂掉(需要解决)

如果启动阶段机器都正常,第一次循环结束后挂起的30s内去关掉一台机器,则接下来的第二次循环将报错:
github5
调用路径是
github6
github7
github8
查询走到这里时,如果恰好轮询到的是关闭的机器,则会抛出异常,又试图通过refreshConnection去重新连接所有的url,自然又会和应用启动时一样再次抛出异常,并且这里同样也是捕获异常后再次向外抛出。
这里的预期行为应该是,即使挂掉一台ecs,client也能够在满足集群要求的情况下正常提供查询服务,而不是因为存在已经失效的url而抛出异常。建议在refreshClientPool函数中对url维度做异常处理。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions