内容纲要
一、背景
开发连接的数据库,来自Amazon MySQL,无法直接连接,需要经过一个跳板机连接。
二、遇到问题
- MySQL无法直接连接云MySQL数据库
- IDEA中开发后端服务,也无法连接MySQL数据库
三、解决方案
当后端项目需要通过跳板机和私钥访问内网MySQL时,最佳实践是本地创建SSH隧道,让项目连接本地端口。
3.1 Navicat连接MySQL解决方案
方案1:配置SSH隧道
1、打开Navicat
2、创建MySQL数据源
3、填写数据库连接信息
4、点击SSH Tab页,填写预先获取的SSH隧道信息
预先获取的SSH隧道跳板机信息,来自:技术负责人/项目侧/自己配置的信息
5、测试连接成功
方案2:本地创建SSH隧道,让项目连接本地端口
1. 建立SSH隧道
在启动项目前,于本地终端执行此命令。它会在后台创建一个从本地3307
端口到远程数据库3306
端口的加密通道。
# -f: 后台运行
ssh -f -N -L 3307:数据库内网IP:3306 跳板机用户@跳板机地址 -i ~/.ssh/私钥文件
3307
: 本地映射端口,可自定义。数据库内网IP
: 从跳板机看到的实际要连接的数据库地址(如54.xx.xx.xx
)。
2. 配置 application.yml
修改项目配置,将数据库地址指向本地隧道端口。项目无需知道SSH的存在。
# application.yml
spring:
datasource:
# 连接到本地隧道入口
url: jdbc:mysql://localhost:3307/你的数据库名
username: 数据库用户
password: 数据库密码
3. 启动项目
直接运行你的Spring Boot应用。项目会通过本地隧道,安全地连接到远程数据库。
4. 关闭隧道
开发结束后,关闭后台SSH进程。
# macOS/Linux
pkill -f "ssh -f -N -L 3307"
总结
步骤 | 角色 | 任务 | 工具/配置 |
---|---|---|---|
步骤1 | 开发者 | 建立网络通道 | ssh 命令 |
步骤2 | 后端项目 | 连接数据库 | application.yml |
此方法将网络问题与应用配置解耦,是安全、简洁且通用的标准做法。
3.2 IDEA启动后端服务连接解决方案
同上方案2
为了方便,可以创建一个脚本,在开发前,直接双击运行,然后直接开发,后端连接本地127.0.0.1:3307的数据库即可。
windonws
创建一个文件,命名start_tunnel.bat
然后填写一下内容:
netstat -ano | findstr :3307
cd /d C:/Users/xxx/Desktop
ssh -i a -L 3307:54.xx.xx.xx:3306 ec2-user@ec2-xx.xx.xx.xx.ap-southeast-1.compute.amazonaws.com
a
文件是私钥文件,
内容开头为-----BEGIN RSA PRIVATE KEY-----
中间内容为几十行的秘钥字符串
结尾为-----END RSA PRIVATE KEY-----
mac
创建一个文件,命名start_tunnel.sh
然后填写一下内容:
#!/bin/bash
# --- 配置部分 ---
# 你的私钥文件名(假设和脚本在同一目录)
KEY_FILE="a"
# 本地映射端口
LOCAL_PORT="3307"
# 远程数据库的内网地址和端口
REMOTE_DB_HOST="54.xx.xx.xx"
REMOTE_DB_PORT="3306"
# 跳板机用户名和地址
JUMP_HOST_USER="ec2-user"
JUMP_HOST_ADDRESS="ec2-xx.xx.xx.xx.ap-southeast-1.compute.amazonaws.com"
# --- 配置结束 ---
echo "--- 1. 检查端口 ${LOCAL_PORT} 是否被占用 ---"
# lsof 是 macOS/Linux 下查看端口占用情况的常用工具
# -i: 查看网络文件, -P: 显示端口号, -n: 以数字形式显示地址
# grep -v grep 是为了排除掉 grep 进程本身
# 如果端口被占用,会显示进程信息 (PID 等)
PORT_CHECK=$(lsof -i :${LOCAL_PORT} -P -n | grep LISTEN | grep -v grep)
if [ -n "$PORT_CHECK" ]; then
echo "错误: 端口 ${LOCAL_PORT} 已被占用,请先关闭相关进程。"
echo "占用信息:"
echo "$PORT_CHECK"
exit 1 # 退出脚本,并返回错误码1
else
echo "端口 ${LOCAL_PORT} 空闲,可以继续。"
fi
echo "" # 打印空行,让输出更清晰
echo "--- 2. 切换到脚本所在目录 ---"
# dirname $0 获取脚本所在的目录
# cd "$(dirname "$0")" 切换到该目录,这是一种稳健的写法
cd "$(dirname "$0")"
echo "当前目录: $(pwd)"
echo "" # 打印空行
echo "--- 3. 启动 SSH 隧道 ---"
# 使用 -f 参数让隧道在后台运行
# -N 表示不执行远程命令,只做端口转发
# -L 进行本地端口映射
echo "正在连接 ${JUMP_HOST_USER}@${JUMP_HOST_ADDRESS}..."
echo "映射本地 :${LOCAL_PORT} 到远程 ${REMOTE_DB_HOST}:${REMOTE_DB_PORT}"
ssh -f -N \
-i "${KEY_FILE}" \
-L "${LOCAL_PORT}:${REMOTE_DB_HOST}:${REMOTE_DB_PORT}" \
"${JUMP_HOST_USER}@${JUMP_HOST_ADDRESS}"
# 检查 ssh 命令是否成功执行
if [ $? -eq 0 ]; then
echo ""
echo "✅ SSH 隧道已在后台成功建立!"
echo " 本地端口: localhost:${LOCAL_PORT}"
echo " 已连接到: ${REMOTE_DB_HOST}:${REMOTE_DB_PORT} (通过 ${JUMP_HOST_ADDRESS})"
echo ""
echo " 使用 'lsof -i :${LOCAL_PORT}' 查看隧道状态。"
echo " 使用 'pkill -f \"ssh -f -N -L ${LOCAL_PORT}\"' 关闭隧道。"
else
echo ""
echo "❌ SSH 隧道建立失败,请检查私钥路径、网络连接或服务器配置。"
exit 1
fi
保存后运行 chmod 命令添加执行权限
chmod +x start_tunnel.sh
现在,你就可以直接运行这个脚本了。
./start_tunnel.sh