node.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > node.js > express 连接在线数据库

浅谈express 连接在线数据库踩坑

作者:实习生小黄

本文记录了连接远程MySQL数据库过程中遇到的常见问题及解决方案,包括用户权限、防火墙、安全组、VPN等,具有一定的参考价值,感兴趣的可以了解一下

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 但不熟悉:

然后重启 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 导致连接失败的原因包括:

4. 总结

连接远程 MySQL 数据库看似简单,实际上涉及多个层面的配置:

到此这篇关于浅谈express 连接在线数据库踩坑的文章就介绍到这了,更多相关express 连接在线数据库内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文