java - 谷歌 Spanner 单例重新连接故障

标签 java google-cloud-platform google-cloud-spanner

我正在创建一个 SpannerSingleton,以便在应用程序的生命周期内保持连接。 我对连接持久性感兴趣...如果存在 session /连接问题,如何重新创建 session ?

一个想法是,如果超过 90% 的池已耗尽,则生成一个新连接,将 setMaxSessions 增加到更高的数字。就像指数退避的反面一样?但是我在哪里/如何才能做到这一点?我在客户端库中找不到任何可以让我监视池状态或客户端计数的内容。

我选择了bill-pugh-singleton因为这似乎是一个不错的选择...

这是我所拥有的:

public class SpannerSingleton {

    private static Spanner spanner;
    private static SpannerOptions options;

    private static SessionPoolOptions sessionPoolOps = SessionPoolOptions
            .newBuilder()
            .setMaxSessions(1000)  // 1000 concurrent queries
            .setMinSessions(100)  // keep 100 alive
            .setMaxIdleSessions(100)  // how many to keep from being idle and closed
            .build(); 

    private SpannerSingleton() {
        try {
            options = SpannerOptions
                    .newBuilder()
                    .setSessionPoolOption(sessionPoolOps)
                    .build();

            spanner = options.getService();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static class SingletonHelper{
        private static final Spanner CONNECTION = new SpannerSingleton().spanner;
    } 

    public static synchronized Spanner getSpanner() {
        return SingletonHelper.CONNECTION;
    }

}

我使用工厂模式来制作 dbClient

public SpannerFactory {

    private static Spanner spanner = SpannerSingleton.getSpanner();
    private static DatabaseId dbId;

    public static DatabaseClient getConnection(String instance) {
        if (Util.isEmpty(instance)) return null;

        if ("mickey".equalsIgnoreCase(instance)) {
            dbId = DatabaseId.of(spanner.getOptions().getProjectId(), "instance1", "mickey");
        }

        if ("mouse".equalsIgnoreCase(instance)) {
            dbId = DatabaseId.of(spanner.getOptions().getProjectId(), "instance1", "mouse");
        }

        return spanner.getDatabaseClient(dbId);

    }
}

我想添加的是检查连接池以查看我们距离饥饿有多近,然后重新创建它自己......我可能想太多了,但是如果连接中断会发生什么?

最佳答案

客户端库应该负责维护健康的 session 池,用户不必明确担心 session /连接

如 java 客户端中所述,如果您正确设置 MaxSessions - 客户端将负责维护这么多 session 。

在较高层次上,流程如下:

If currentSessions < MaxSessions {
   if !idleSessions.empty()
        use an idle session.
   else
        CreateNewSession.
} else {
   Block/Fail based on action chosen in : ActionOnExhaustion.
}

如果您想避免在请求处理过程中 CreateSession 产生少量开销,建议的一个选项是保持 minSessionsmaxSessions 与您的并发 TPS 要求,以便一开始我们就有那么多 session 可供使用。

有关 session 监控、保持空闲 session Activity 等其他详细信息:请参阅文档:https://cloud.google.com/spanner/docs/sessions

关于java - 谷歌 Spanner 单例重新连接故障,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54602065/

相关文章:

django - 在提供 secret 媒体文件时,Web 应用程序应如何确保安全?

google-cloud-platform - Cloud Spanner - WHERE 子句中大量项目的读取性能

java - 在数据流2.3.0中使用谷歌 Spanner

database - 在 Google Cloud Spanner 中,我可以通过非主键字段进行更新或删除吗?

java - log4j的配置

java - 我正在使用 Actions 类移动到某个元素,但无法单击下拉列表中的元素

docker - 谷歌CP : GCE: COS: Docker: Change which container is automatically started?

linux - 如何在我的 Google Cloud Ubuntu 实例上设置我的用户密码?

java - Jersey 2 中的自定义 MOXyJsonProvider 不起作用?

java - 字符串的高级正则表达式处理