当我们项目和数据库在不同服务器上且服务器不在同一局域网下。需要远程连接数据库,通过ssh通道的方式。下面我们就来解决这个问题:
一:首先 我们需要设置数据库可以被远程访问:
- 在命令窗口登录mysql: mysql> mysql -u root -p
- 登陆成功以后切换到mysql数据库: mysql> use mysql;
- 修改root的host字段: mysql> update user set host = '%' where user = 'root';
- 刷新: mysql> flush privileges;
- 检查host值是否修改成功:mysql> select host,user from user;
进行到这一步数据库的远程连接权限已经开通,当然使用navicat测试一下更好。
- 新建MySQL连接,点击SSH,选中使用SSH通道;主机填写的为公网IP、端口默认为22、用户名和密码是Linux登录的用户名和密码。
2.到常规界面,正常填写就行,其中用户名和密码为服务器上数据库的用户名和密码。
3. 操作完成以后点击测试连接,出现连接成功。证明以上操作全部正确完成,现在开始进行SpringBoot代码部分;
如果出现错误,请注意下图navicat和ssh服务器以及数据库中的连线。由此可以看出来错误出现在那次连接中,然后再去排查错误,这样就方便的多了。
二:创建SpringBoot项目(这里不再介绍SpringBoot的创建),顺便写一套连接本地数据库的代码,进行本地数据库连接。这样做的目的是,保证你数据库连接以及数据处理都写正确了。将来报错的时候,不用考虑代码的问题。集中心思解决ssh通道问题。
SSH通道:
创建连接类:SSHConnectionw
package com.hz.utils;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
/**
* @author NZL
* @version 1.0
* @date 2019/12/11 9:47
*/
public class SSHConnection {
String user = "root";
// 服务器登录名
String password = "******";
// 登陆密码
String host = "公网IP";
//服务器公网IP
int port = 22;
// 跳板机ssh开放的接口 默认端口 22
int local_port = 3307;
// 这个是本地的端口,很重要!!!选取一个没有占用的port即可
String remote_host = "172.19.185.112";
// 要访问的mysql所在的host 服务器局域网IP(127.0.0.1也行)
int remote_port = 3306;
// 服务器上数据库端口号
Session session = null;
/**
* 建立SSH连接
*/
public void SSHConnection() throws Exception{
try {
JSch jsch = new JSch();
session = jsch.getSession(user, host, port);
session.setPassword(password);
session.setConfig("StrictHostKeyChecking", "no");
// 日志打印自己脑补
session.connect();
session.setPortForwardingL(local_port, remote_host, remote_port);
} catch (Exception e) {
// do something
}
}
/**
* 断开SSH连接
*/
public void closeSSH () throws Exception
{
this.session.disconnect();
}
}
建立 MyContextListener 监听类
package com.hz.utils;
import org.springframework.stereotype.Component;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
/**
* @author NZL
* @version 1.0
* @date 2019/12/11 9:53
*/
@WebListener
@Component
public class MyContextListener implements ServletContextListener {
private SSHConnection conexionssh;
public MyContextListener() {
super();
}
/**
* @see ServletContextListener#contextInitialized(ServletContextEvent)
*/
@Override
public void contextInitialized(ServletContextEvent arg0) {
// 建立连接
System.out.println("Context initialized ... !\n\n\n");
try {
conexionssh = new SSHConnection();
conexionssh.SSHConnection();
System.out.println("\n\n\n成功建立SSH连接!\n\n\n");
} catch (Throwable e) {
System.out.println("\n\n\nSSH连接失败!\n\n\n");
e.printStackTrace(); // error connecting SSH server
}
}
/**
* @see ServletContextListener#contextDestroyed(ServletContextEvent)
*/
@Override
public void contextDestroyed(ServletContextEvent arg0) {
// 断开连接
System.out.println("Context destroyed ... !\n\n\n");
try {
conexionssh.closeSSH(); // disconnect
System.out.println("\n\n\n成功断开SSH连接!\n\n\n");
} catch (Exception e) {
e.printStackTrace();
System.out.println("\n\n\n断开SSH连接出错!\n\n\n");
}
}
}
当这两个类建好以后,也就基本完成了。剩余的就是配置application.properties文件了
配置application.properties:在这里要注意,url上的port是本机的,在连接SSH的类中配置的,而非服务器上的数据库端口号。username和password为服务器上的数据库账号密码。
spring.datasource.url=jdbc:mysql://localhost:3307/student?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.druid.test-on-borrow=true
spring.datasource.druid.test-while-idle=true
这样基本上就成了。今天写着文档,处理这接口联调的问题。思绪有点乱了,我把源码放出来看看吧。