浅谈express 连接在线数据库踩坑
作者:实习生小黄
1. 前言
在学习 Node.js 开发的过程中,Express 框架无疑是最受欢迎的选择之一。
作为一名前端开发者,我决定深入学习后端技术,搭建一个完整的博客系统。
第一步自然是连接数据库,而我选择了连接远程服务器上的 MySQL 数据库,而不是在本地搭建环境。
这看似简单的一步,却让我遇到了各种各样的问题。
本文将记录我在连接远程 MySQL 数据库过程中遇到的各种坑,希望能帮助到同样遇到困难的开发者。
2. 如何连接
2.1 环境准备
首先,我们需要安装必要的依赖:
npm install express mysql2 sequelize dotenv
2.2 配置文件
为了安全管理数据库连接信息,我创建了 .env
文件来存储敏感信息:
数据库配置
DB_HOST=your_server_ip DB_PORT=3306 DB_NAME=your_database_name DB_USER=your_username DB_PASSWORD=your_password
服务器配置
PORT=3000 NODE_ENV=development
2.3 数据库连接配置
然后创建 config/database.js
文件:
const { Sequelize } = require('sequelize'); require('dotenv').config(); // 从环境变量获取数据库配置 const DB_HOST = process.env.DB_HOST || 'localhost'; const DB_PORT = process.env.DB_PORT || 3306; const DB_NAME = process.env.DB_NAME || 'test_db'; const DB_USER = process.env.DB_USER || 'root'; const DB_PASSWORD = process.env.DB_PASSWORD || ''; // 创建 Sequelize 实例,连接到远程数据库 const sequelize = new Sequelize( DB_NAME, DB_USER, DB_PASSWORD, { host: DB_HOST, port: DB_PORT, dialect: 'mysql', pool: { max: 5, min: 0, acquire: 30000, idle: 10000 }, dialectOptions: { timezone: '+08:00' }, logging: process.env.NODE_ENV !== 'production' ? console.log : false } ); // 测试数据库连接 const testConnection = async () => { try { await sequelize.authenticate(); console.log('数据库连接成功!'); } catch (error) { console.error('无法连接到数据库:', error); } }; module.exports = { sequelize, testConnection };
2.4 在应用中使用
在主应用文件 app.js
中:
require('dotenv').config(); const express = require('express'); const bodyParser = require('body-parser'); const cors = require('cors'); const { sequelize, testConnection } = require('./config/database'); const app = express(); // 中间件 app.use(cors()); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); // 测试数据库连接 testConnection(); // 路由 app.get('/', function (req, res) { res.send('hello, express'); }); // 启动服务器 const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(`服务器运行在端口 ${PORT}`); });
3. 问题
在实际连接过程中,我遇到了各种各样的问题,下面逐一解决。
3.1 MySQL 用户权限问题
问题现象:
Access denied for user ''@'localhost' (using password: YES)
解决方案: 在 MySQL 服务器上创建允许远程连接的用户:
# 登录 MySQL mysql -u root -p # 查看用户权限 SELECT user, host FROM mysql.user WHERE user = 'yel_test'; # 如果用户不存在,创建新用户 CREATE USER 'yel_test'@'%' IDENTIFIED BY '123456'; GRANT ALL PRIVILEGES ON yel_test.* TO 'yel_test'@'%'; # 如果用户已存在但只允许本地连接,添加远程连接权限 GRANT ALL PRIVILEGES ON yel_test.* TO 'yel_test'@'%' IDENTIFIED BY '123456'; # 刷新权限 FLUSH PRIVILEGES;
3.2 MySQL 配置限制
问题现象:
ConnectionError [SequelizeConnectionError]: connect ETIMEDOUT
解决方案: 修改 MySQL 配置文件(通常是 /etc/my.cnf
),添加或修改 bind-address
设置:
查找配置文件
# 查找主要配置文件 cat /etc/my.cnf | grep bind-address # 如果上面没有结果,查看是否有包含的配置目录 cat /etc/my.cnf | grep "!includedir" # 修改配置文件 vi /etc/my.cnf
如果使用 vi 但不熟悉:
- 按 i 进入插入模式
- 移动到 [mysqld] 部分下方
- 添加 bind-address = 0.0.0.0
- 按 Esc 退出插入模式
- 输入 :wq 保存并退出(或 :q! 不保存退出)
然后重启 MySQL 服务:
systemctl restart mysqld # 或 service mysqld restart
3.4 防火墙限制
问题现象:
无法连接到数据库,但可以 ping 通服务器。
解决方案:
检查并开放服务器防火墙的 MySQL 端口(默认 3306):
# 查看防火墙规则 firewall-cmd --list-all | grep 3306 # 如果没有开放,添加规则 firewall-cmd --zone=public --add-port=3306/tcp --permanent firewall-cmd --reload
3.5 云服务提供商安全组设置
问题现象:
即使服务器防火墙已经开放端口,仍然无法连接。
解决方案:
在云服务提供商的控制面板中,确保安全组规则允许 3306 端口的入站流量:
允许 | MySQL 访问 | TCP:3306/3306 | IPv4 | 任何位置 (0.0.0.0/0)
3.6 VPN 导致的连接问题
问题现象:
即使所有配置都正确,仍然出现 ETIMEDOUT
错误。
解决方案:
关闭 VPN。VPN 可能会导致网络路由冲突,使得到数据库服务器的流量被错误地路由。
VPN 导致连接失败的原因包括:
- 网络路由冲突
- VPN 安全策略限制
- VPN 网络延迟
- DNS 解析问题
4. 总结
连接远程 MySQL 数据库看似简单,实际上涉及多个层面的配置:
- 应用层面:正确配置连接参数、环境变量和错误处理
- 数据库层面:用户权限、MySQL 配置
- 服务器层面:防火墙设置、端口开放
- 网络层面:安全组规则、VPN 设置、网络路由
到此这篇关于浅谈express 连接在线数据库踩坑的文章就介绍到这了,更多相关express 连接在线数据库内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!