Spring Boot-当程序失去与数据库的连接时如何执行方法?

时间:2019-09-06 19:40:40

标签: java spring oracle spring-boot cassandra

在这里是春季靴子的新手。我一直在研究一种连接到两个数据库的微服务,一个是Cassandra,另一个是Oracle。它们包含相同的信息,因为Cassandra数据库正在代替Oracle数据库作为该项目的主数据库,但是,如果Cassandra数据库出现故障,我们将保留oracle数据库作为后备。

我不确定在遇到连接断开时如何告诉我的应用程序“执行某些操作”。当失去与Cassandra的连接时,我的控制台输出以下内容-

2019-09-06 14:23:15.127 ERROR 2836 --- [-reconnection-0] c.d.driver.core.ControlConnection        : [Control connection] Cannot connect to any host, scheduling retry in 1000 milliseconds
2019-09-06 14:23:15.147 ERROR 2836 --- [-reconnection-0] c.d.driver.core.ControlConnection        : [Control connection] Cannot connect to any host, scheduling retry in 1000 milliseconds
2019-09-06 14:23:16.134 ERROR 2836 --- [-reconnection-0] c.d.driver.core.ControlConnection        : [Control connection] Cannot connect to any host, scheduling retry in 2000 milliseconds
2019-09-06 14:23:16.149 ERROR 2836 --- [-reconnection-0] c.d.driver.core.ControlConnection        : [Control connection] Cannot connect to any host, scheduling retry in 2000 milliseconds
2019-09-06 14:23:23.137 ERROR 2836 --- [-reconnection-1] c.d.driver.core.ControlConnection        : [Control connection] Cannot connect to any host, scheduling retry in 4000 milliseconds

它一直这样,超时时间加倍,直到可以重新连接为止。

这种情况发生时是否可以触发方法?如果我可以在失去连接时在控制器中更改变量的值,那么一切都会很好,但是我似乎找不到有关该主题的任何信息。有没有其他方法可以解决我什至没有想到的问题,例如根据连接而变化的布尔值?抱歉,如果这听起来有些误导,我真的在这里抓稻草。

此外,重新建立连接时是否可以触发事件?

感谢您的帮助。我真的很感谢任何建议。

作为PS,我不确定该代码将对您有多大帮助,但是我觉得我至少应该对自己的情况有所了解。

这是我的cassandra配置

@ConfigurationProperties(prefix = "cassandra")
@Getter
@Setter
@Component
public class CassandraConfiguration {

    private String clusterName;
    private String hostNames;
    private String username;
    private String password;
    private String keyspace;
    private boolean sslEnabled;
    private int port;
    private int fetchSize;
    private String localDC;

    private static final Logger LOGGER = LoggerFactory.getLogger(CassandraConfiguration.class);

    @Bean
    public Session cassandraSession() {
        String[] hostname = hostNames.split(",");
        Cluster cluster = null;

        LoadBalancingPolicy loadBalancingPolicy = new TokenAwarePolicy(
                DCAwareRoundRobinPolicy.builder()
                        .withLocalDc(localDC)
                        .build()
        );

        PoolingOptions poolingOptions = new PoolingOptions();
        poolingOptions
                .setConnectionsPerHost(HostDistance.LOCAL,  4, 10)
                .setConnectionsPerHost(HostDistance.REMOTE, 2, 4)
                .setMaxRequestsPerConnection(HostDistance.LOCAL, 32768)
                .setMaxRequestsPerConnection(HostDistance.REMOTE, 2000);

        if (isSslEnabled()) {

            cluster = Cluster.builder().addContactPoints(hostname)
                    .withClusterName(clusterName)
                    .withCredentials(username, password)
                    .withPort(port)
                    .withoutJMXReporting()
                    .withSSL()
                    .withQueryOptions(new QueryOptions().setConsistencyLevel(ConsistencyLevel.LOCAL_QUORUM))
                    .withLoadBalancingPolicy(loadBalancingPolicy)
                    .withPoolingOptions(poolingOptions)
                    .build();

        } else {
            cluster = Cluster.builder().addContactPoints(hostname)
                    .withClusterName(clusterName)
                    .withCredentials(username, password)
                    .withPort(port)
                    .withoutJMXReporting()
                    .withQueryOptions(new QueryOptions().setConsistencyLevel(ConsistencyLevel.LOCAL_QUORUM))
                    .withLoadBalancingPolicy(loadBalancingPolicy)
                    .withPoolingOptions(poolingOptions)
                    .build();
        }

        cluster.getConfiguration().getCodecRegistry()
                .register(LocalDateCodec.instance)
                .register(InstantCodec.instance);
        Session session = cluster.connect(keyspace);

        return session;
    }

    @Bean
    public MappingManager mappingManager() {
        return new MappingManager(cassandraSession());
    }

}

这是我针对oracle的jdbc配置

@ConfigurationProperties("jdbc")
@Configuration
@Getter
@Setter
@ConditionalOnProperty(name = "jdbc.accessService", havingValue = "enabled")
public class JDBCConfig {
    @Autowired
    SshTunnel sshTunnel;

    private String driver;
    private String url;
    private String user;
    private String password;

    @PostConstruct
    private void init() {
        try {
            Class.forName(driver);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Bean
    public Connection jdbcConnection() {
        Connection jdbcConnection = null;

        try {
            jdbcConnection = DriverManager.getConnection (url, user, password);
            System.out.println("Connection Established");
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return jdbcConnection;
    }
}

1 个答案:

答案 0 :(得分:2)

听起来您需要一个断路器,它是一个软件组件,可以监视某些打包服务的故障,尝试检测何时再次可用,并且可以重定向到其他一些实现或让异常在失败情况下转义。

当前明显的默认设置(和我的建议)是resilience4j