spring integration leader 选举 jdbc 无法断开连接

标签 spring spring-integration

我正在尝试使用 JDBC 在 spring-integration 中使用领导者选举。只要连接了数据库,它就可以工作。一旦数据库连接断开,领导者选举就会停止,该节点上的领导者信息将保持不变。

据我对代码的理解,连接丢失时会抛出一个异常。 leader 选举然后尝试解除数据库中的锁(当然这是不可能的)并且抛出另一个异常并且 executor 服务停止运行。 (最后阻塞在 LockRegistryLeaderInitiator call() 方法中)

我必须对数据库断开使用react吗?我需要配置什么吗?

重现步骤:

  • 启动第一个服务
  • 检查它是否是领导者
  • 停止数据库
  • 实例仍然是领导者
  • 再次启动数据库
  • 启动第二个实例
  • 现在都是领导者

依赖关系:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.10.RELEASE</version>
</parent>
<dependency>
  <groupId>org.springframework.integration</groupId>
  <artifactId>spring-integration-core</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.integration</groupId>
  <artifactId>spring-integration-jdbc</artifactId>
</dependency>

LeaderElectionConfiguration

@Configuration
public class LeaderElectionConfiguration {

@Bean
public LockRegistry lockRegistry(LockRepository lockRepository) {
    return new JdbcLockRegistry(lockRepository);
}

@Bean
public DefaultLockRepository lockRepository(DataSource dataSource) {
    return new DefaultLockRepository(dataSource);
}

@Bean
public LockRegistryLeaderInitiator leaderInitiator(LockRegistry lockRegistry) {
    LockRegistryLeaderInitiator lockRegistryLeaderInitiator = new LockRegistryLeaderInitiator(lockRegistry);
    lockRegistryLeaderInitiator.start();
    return lockRegistryLeaderInitiator;
}

jdbc配置:

spring:
  datasource:
    initialize: false
    url: jdbc:mysql://localhost:3306/whatever
    username: admin
    password: adminpw
    driver-class-name: com.mysql.cj.jdbc.Driver

最佳答案

我确认这是一个错误:https://jira.spring.io/browse/INT-4447 .

我们确实在 LockRegistryLeaderInitiator 中有一段代码,例如:

catch (Exception e) {
                    if (this.locked) {
                        this.lock.unlock();
                        this.locked = false;
                        // The lock was broken and we are no longer leader
                        handleRevoked();
                        if (isRunning()) {
                            // Give it a chance to elect some other leader.
                            Thread.sleep(LockRegistryLeaderInitiator.this.busyWaitMillis);
                        }
                    }

我们确实必须处理来自 unlock() 的异常并独立于结果撤销领导者。

作为解决方法,我建议实现您自己的(只需扩展现有的 DefaultLockRepository 就足够了)和 中的 try...catch() 异常delete()LockRegistryLeaderInitiator 中的 unlock 逻辑正常进行。

关于spring integration leader 选举 jdbc 无法断开连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49706410/

相关文章:

java - Spring 组件扫描不工作

java - Apache Tomcat 执行具有相同启动时加载的 Servlet

java - Spring MVC - 严重 : Exception starting filter Spring OpenEntityManagerInViewFilter

java - Tomcat 在使用 Spring Integration Java DSL 时挂起关闭

java - 卡夫卡 : what is the point of using "acknowledgment.nack" if I can simply "not acknowledgment.acknowledge"

spring - 运行 spring mvc web 应用程序时 Tomcat 错误

java - 在 spring 中从 ResourceBundleMessageSource 按模式获取属性键

servlet spring 的 javax.servlet.ServletException : Servlet. init() 抛出异常

java - Spring-Integration-Kafka outbound-channel-adapter 发送消息

spring-integration - 延迟器 JDBCMessageStore