java - Spring Data JPA 与远程 MySQL 服务器的 ssh 隧道

标签 java hibernate ssh spring-data jsch

我使用 Spring Data JPA 和 Hibernate 作为持久性提供程序,并结合远程 MySQL5 服务器来执行定期复制内部数据子集的作业。该作业(即 quartz 调度的 Java 应用程序)每天运行一次,大约需要30秒完成同步)。出于安全原因,我们不想打开远程服务器以进行来自外部的直接连接(即本地主机以外的连接)。

我见过使用 Jsch 以编程方式设置 ssh 隧道的示例,但找不到任何有关如何将 Jsch 与 spring 数据集成的资源。我看到的一个问题是我的某些 spring bean(即 org.apache.commons.configuration.DatabaseConfiguration)是在应用程序启动时创建的,并且已经需要访问数据源。

我可以在应用程序外部打开 ssh 隧道,但它会一直打开,但我想避免这种情况,因为我只需要每天打开它 30 秒。

编辑:

经过一番研究,我发现了几种获得 ssh 隧道的方法

A)实现我自己的数据源(我扩展了 org.springframework.jdbc.datasource.DriverManagerDataSource),然后使用 PostContruct 和 Predestroy 通过 Jsch 设置/关闭 ssh 隧道

--> 问题:ssh 隧道在应用程序的生命周期内保持开放,这不是我想要的

B)实现我自己的驱动程序(我扩展了 com.mysql.jdbc.Driver)并覆盖“connect”以在连接之前创建 ssh 隧道

--> 问题:我无法关闭 ssh 隧道连接

欢迎提出更多建议

最佳答案

如果您的 Spring 配置中有一个 DataSource bean,您可以创建自己的 DataSource 实现,该实现在尝试使用提供的 JDBC 建立连接之前打开 SSH 隧道网址。作为示例,请考虑以下使用 HikariDataSource 的配置:

<bean id="entityManagerFactory"
  class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  <property name="dataSource">
    <bean class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">...</bean>
  </property>
</bean>

您可以扩展类 HikariDataSource 以提供您自己的实现。下面是一个例子:

class TunneledHikariDataSource extends HikariDataSource implements InitializingBean {
  private boolean createTunnel = true;
  private int tunnelPort = 3306;

  public void afterPropertiesSet() {
    if(createTunnel) {
      // 1. Extract remote host name from the JDBC URL.
      // 2. Extract/infer remote tunnel port (e.g. 3306)
      // from the JDBC URL.
      // 3. Create a tunnel using Jsch and sample code
      // at http://www.jcraft.com/jsch/examples/PortForwardingL.java.html
      ...
    }
  }
}

然后,为自定义类实例化一个 bean 实例,而不是 HikariDataSource

关于java - Spring Data JPA 与远程 MySQL 服务器的 ssh 隧道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33547147/

相关文章:

java - EntityManager 不坚持合并,当刷新时我得到一个无法初始化代理 - 没有抛出 session

linux - Windows 和 Linux 之间的文件层次结构差异

python - 如何提高paramiko的性能

java - 使用java/JMF的开源网络 session 系统

java - 如何记录 hibernate 中插入和更新查询的响应时间

mysql - 将 java.time 作为 tinyblob 持久化到 Date

hibernate - 具有该名称 [userName] 的参数不存在

java - 存储、检索、编辑和删除数据

java - 如何使 JFileChooser 在断开网络驱动器时正常运行?

ruby - 在 Net::SSH session 中执行 Ruby 方法