淺談express 連接在線數(shù)據(jù)庫踩坑
1. 前言
在學(xué)習(xí) Node.js 開發(fā)的過程中,Express 框架無疑是最受歡迎的選擇之一。
作為一名前端開發(fā)者,我決定深入學(xué)習(xí)后端技術(shù),搭建一個完整的博客系統(tǒng)。
第一步自然是連接數(shù)據(jù)庫,而我選擇了連接遠(yuǎn)程服務(wù)器上的 MySQL 數(shù)據(jù)庫,而不是在本地搭建環(huán)境。
這看似簡單的一步,卻讓我遇到了各種各樣的問題。
本文將記錄我在連接遠(yuǎn)程 MySQL 數(shù)據(jù)庫過程中遇到的各種坑,希望能幫助到同樣遇到困難的開發(fā)者。
2. 如何連接
2.1 環(huán)境準(zhǔn)備
首先,我們需要安裝必要的依賴:
npm install express mysql2 sequelize dotenv
2.2 配置文件
為了安全管理數(shù)據(jù)庫連接信息,我創(chuàng)建了 .env 文件來存儲敏感信息:
數(shù)據(jù)庫配置
DB_HOST=your_server_ip DB_PORT=3306 DB_NAME=your_database_name DB_USER=your_username DB_PASSWORD=your_password
服務(wù)器配置
PORT=3000 NODE_ENV=development
2.3 數(shù)據(jù)庫連接配置
然后創(chuàng)建 config/database.js 文件:
const { Sequelize } = require('sequelize');
require('dotenv').config();
// 從環(huán)境變量獲取數(shù)據(jù)庫配置
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 || '';
// 創(chuàng)建 Sequelize 實(shí)例,連接到遠(yuǎn)程數(shù)據(jù)庫
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
}
);
// 測試數(shù)據(jù)庫連接
const testConnection = async () => {
try {
await sequelize.authenticate();
console.log('數(shù)據(jù)庫連接成功!');
} catch (error) {
console.error('無法連接到數(shù)據(jù)庫:', error);
}
};
module.exports = {
sequelize,
testConnection
};
2.4 在應(yīng)用中使用
在主應(yīng)用文件 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 }));
// 測試數(shù)據(jù)庫連接
testConnection();
// 路由
app.get('/', function (req, res) {
res.send('hello, express');
});
// 啟動服務(wù)器
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`服務(wù)器運(yùn)行在端口 ${PORT}`);
});
3. 問題
在實(shí)際連接過程中,我遇到了各種各樣的問題,下面逐一解決。
3.1 MySQL 用戶權(quán)限問題
問題現(xiàn)象:
Access denied for user ''@'localhost' (using password: YES)
解決方案: 在 MySQL 服務(wù)器上創(chuàng)建允許遠(yuǎn)程連接的用戶:
# 登錄 MySQL mysql -u root -p # 查看用戶權(quán)限 SELECT user, host FROM mysql.user WHERE user = 'yel_test'; # 如果用戶不存在,創(chuàng)建新用戶 CREATE USER 'yel_test'@'%' IDENTIFIED BY '123456'; GRANT ALL PRIVILEGES ON yel_test.* TO 'yel_test'@'%'; # 如果用戶已存在但只允許本地連接,添加遠(yuǎn)程連接權(quán)限 GRANT ALL PRIVILEGES ON yel_test.* TO 'yel_test'@'%' IDENTIFIED BY '123456'; # 刷新權(quán)限 FLUSH PRIVILEGES;
3.2 MySQL 配置限制
問題現(xiàn)象:
ConnectionError [SequelizeConnectionError]: connect ETIMEDOUT
解決方案: 修改 MySQL 配置文件(通常是 /etc/my.cnf),添加或修改 bind-address 設(shè)置:
查找配置文件
# 查找主要配置文件 cat /etc/my.cnf | grep bind-address # 如果上面沒有結(jié)果,查看是否有包含的配置目錄 cat /etc/my.cnf | grep "!includedir" # 修改配置文件 vi /etc/my.cnf
如果使用 vi 但不熟悉:
- 按 i 進(jìn)入插入模式
- 移動到 [mysqld] 部分下方
- 添加 bind-address = 0.0.0.0
- 按 Esc 退出插入模式
- 輸入 :wq 保存并退出(或 :q! 不保存退出)
然后重啟 MySQL 服務(wù):
systemctl restart mysqld # 或 service mysqld restart
3.4 防火墻限制
問題現(xiàn)象:
無法連接到數(shù)據(jù)庫,但可以 ping 通服務(wù)器。
解決方案:
檢查并開放服務(wù)器防火墻的 MySQL 端口(默認(rèn) 3306):
# 查看防火墻規(guī)則 firewall-cmd --list-all | grep 3306 # 如果沒有開放,添加規(guī)則 firewall-cmd --zone=public --add-port=3306/tcp --permanent firewall-cmd --reload
3.5 云服務(wù)提供商安全組設(shè)置
問題現(xiàn)象:
即使服務(wù)器防火墻已經(jīng)開放端口,仍然無法連接。
解決方案:
在云服務(wù)提供商的控制面板中,確保安全組規(guī)則允許 3306 端口的入站流量:
允許 | MySQL 訪問 | TCP:3306/3306 | IPv4 | 任何位置 (0.0.0.0/0)
3.6 VPN 導(dǎo)致的連接問題
問題現(xiàn)象:
即使所有配置都正確,仍然出現(xiàn) ETIMEDOUT 錯誤。
解決方案:
關(guān)閉 VPN。VPN 可能會導(dǎo)致網(wǎng)絡(luò)路由沖突,使得到數(shù)據(jù)庫服務(wù)器的流量被錯誤地路由。
VPN 導(dǎo)致連接失敗的原因包括:
- 網(wǎng)絡(luò)路由沖突
- VPN 安全策略限制
- VPN 網(wǎng)絡(luò)延遲
- DNS 解析問題
4. 總結(jié)
連接遠(yuǎn)程 MySQL 數(shù)據(jù)庫看似簡單,實(shí)際上涉及多個層面的配置:
- 應(yīng)用層面:正確配置連接參數(shù)、環(huán)境變量和錯誤處理
- 數(shù)據(jù)庫層面:用戶權(quán)限、MySQL 配置
- 服務(wù)器層面:防火墻設(shè)置、端口開放
- 網(wǎng)絡(luò)層面:安全組規(guī)則、VPN 設(shè)置、網(wǎng)絡(luò)路由
到此這篇關(guān)于淺談express 連接在線數(shù)據(jù)庫踩坑的文章就介紹到這了,更多相關(guān)express 連接在線數(shù)據(jù)庫內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Nodejs高擴(kuò)展性的模板引擎 functmpl簡介
本文給大家分享的是一款nodejs高擴(kuò)展性的模板引擎functmpl的簡單介紹以及用法詳解,有需要的小伙伴可以參考下2017-02-02
Node.js中使用Log.io在瀏覽器中實(shí)時監(jiān)控日志(等同tail -f命令)
這篇文章主要介紹了Node.js中使用Log.io在瀏覽器中實(shí)時監(jiān)控日志,Log.io等同于tail -f命令,但更強(qiáng)大,需要的朋友可以參考下2014-09-09
node.js實(shí)現(xiàn)微信JS-API封裝接口的示例代碼
這篇文章主要介紹了node.js實(shí)現(xiàn)微信JS-API封裝接口的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-09-09
node.js連接mongoDB數(shù)據(jù)庫 快速搭建自己的web服務(wù)
這篇文章主要為大家詳細(xì)介紹了node.js連接mongoDB數(shù)據(jù)庫,如何快速搭建自己的web服務(wù),感興趣的小伙伴們可以參考一下2016-04-04
node.js使用net模塊創(chuàng)建服務(wù)器和客戶端示例【基于TCP協(xié)議】
這篇文章主要介紹了node.js使用net模塊創(chuàng)建服務(wù)器和客戶端,結(jié)合實(shí)例形式分析了node.js使用net模塊實(shí)現(xiàn)TCP客戶端與服務(wù)器端通信的相關(guān)操作技巧,需要的朋友可以參考下2020-02-02

