谷歌扳手单例故障重新连接

时间:2019-02-09 00:38:57

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

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

一个想法是,如果超过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;
    }

}

我使用Factory模式制作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);

    }
}

我想添加的内容是检查连接池以了解我们有多饥饿,然后重新创建自己……我可能会想得太多,但是如果连接中断,会发生什么?

1 个答案:

答案 0 :(得分:2)

客户端库应注意保持健康的会话池,用户不必担心会话/连接

如Java客户端中所述,如果您正确设置MaxSessions-客户端将负责维护许多会话。

从高层次看,流程如下:

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

如果要避免在 CreateSession 中作为请求处理的一部分,建议的一种方法是使minSessionsmaxSessions与并发的 TPS保持相同要求,这样一开始我们就可以使用很多会话。

有关会话监视等其他详细信息,可以保持空闲会话活动:请参阅文档:https://cloud.google.com/spanner/docs/sessions