الخطأخطأ: استمع EADDRINUSE: العنوان قيد الاستخدام بالفعل :::3000 يعني أن هناك عملية أخرى تستخدم بالفعل المنفذ الذي يريده تطبيق Node.js. إنه أحد الأخطاء الأكثر شيوعًا أثناء التطوير. إليك كل الطرق لإصلاحها.
📋 Table of Contents
- ما الذي يسبب هذا الخطأ
- الإصلاح 1: البحث عن العملية وإيقافها (نظام التشغيل MacOS/Linux)
- الإصلاح 2: البحث عن العملية وإيقافها (Windows)
- الإصلاح 3: استخدام منفذ مختلف
- الإصلاح 4: التعامل مع الخطأ بلطف
- الإصلاح 5: تنفيذ إيقاف التشغيل اللطيف (يمنع المشكلة)
- الإصلاح 6: استخدم Nodemon لإعادة التشغيل النظيف
- برنامج Kill-Port النصي القابل لإعادة الاستخدام
- الأسئلة المتداولة
- الخلاصة
ما الذي يسبب هذا الخطأ
- لم يتم إغلاق مثيل الخادم السابق بشكل نظيف ولا يزال يحتفظ بالمنفذ
- يستخدم تطبيق آخر نفس المنفذ (خادم تطوير آخر، قاعدة بيانات)
- أدت العملية المتعطلة إلى ترك زومبي ممسكًا بالمنفذ
- لقد قمت بتشغيل الخادم الخاص بك مرتين
الإصلاح 1: البحث عن العملية وإيقافها (نظام التشغيل MacOS/Linux)
# Find the process using port 3000
lsof -i :3000
# COMMAND PID USER FD TYPE DEVICE NODE NAME
# node 12345 you 20u IPv6 ... TCP *:3000 (LISTEN)
# Kill it by PID
kill -9 12345
# Or do it in one command
kill -9 $(lsof -ti :3000)
# Kill all node processes (nuclear option)
killall -9 node
الإصلاح 2: البحث عن العملية وإيقافها (Windows)
# Find the process using port 3000
netstat -ano | findstr :3000
# TCP 0.0.0.0:3000 0.0.0.0:0 LISTENING 12345
# Kill it by PID
taskkill /PID 12345 /F
# PowerShell one-liner
Stop-Process -Id (Get-NetTCPConnection -LocalPort 3000).OwningProcess -Force
الإصلاح 3: استخدام منفذ مختلف
// Make the port configurable via environment variable
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log("Server running on port " + PORT);
});
// Then run with a different port:
// PORT=3001 node server.js
الإصلاح 4: التعامل مع الخطأ بلطف
const server = app.listen(PORT);
server.on('error', (err) => {
if (err.code === 'EADDRINUSE') {
console.error("Port " + PORT + " busy. Trying " + (PORT + 1));
server.listen(PORT + 1); // fall back to next port
} else {
throw err;
}
});
الإصلاح 5: تنفيذ إيقاف التشغيل اللطيف (يمنع المشكلة)
غالبًا ما يكون السبب الجذري هو عدم قيام الخادم بتحرير المنفذ عند الخروج. إضافة معالجات إيقاف التشغيل الرشيقة:
const server = app.listen(PORT, () => {
console.log("Server running on port " + PORT);
});
function shutdown(signal) {
console.log(signal + " received. Closing server...");
server.close(() => {
console.log("Server closed. Port released.");
process.exit(0);
});
setTimeout(() => {
console.error("Forced shutdown");
process.exit(1);
}, 10000);
}
process.on('SIGTERM', () => shutdown('SIGTERM'));
process.on('SIGINT', () => shutdown('SIGINT')); // Ctrl+C
الإصلاح 6: استخدم Nodemon لإعادة التشغيل النظيف
npm install --save-dev nodemon
# package.json
{
"scripts": {
"dev": "nodemon server.js"
}
}
# nodemon cleanly restarts and releases ports between reloads
npm run dev
برنامج Kill-Port النصي القابل لإعادة الاستخدام
# kill-port.sh
#!/bin/bash
PORT=${1:-3000}
PID=$(lsof -ti :$PORT)
if [ -n "$PID" ]; then
echo "Killing process $PID on port $PORT"
kill -9 $PID
else
echo "No process on port $PORT"
fi
# Usage: ./kill-port.sh 3000
الأسئلة المتداولة
س: لماذا يظل المنفذ قيد الاستخدام بعد أن أوقف تطبيقي؟
ج: عادة بسبب توقف العملية فجأة دون تحرير المقبس، أو أن العملية الفرعية لا تزال تحتفظ بها. تمنع معالجات إيقاف التشغيل الرشيقة ذلك.
س: ماذا يعني ::: في ‘:::3000’؟
ج: تدوين IPv6 لـ “جميع الواجهات” (مثل 0.0.0.0 في IPv4). يرتبط الخادم الخاص بك بجميع واجهات الشبكة على المنفذ 3000.
س: هل يمكن لتطبيقين مشاركة نفس المنفذ؟
ج: لا – يمكن ربط عملية واحدة فقط بمنفذ على الواجهة في المرة الواحدة. استخدم منافذ مختلفة أو وكيلًا عكسيًا (nginx) للتوجيه حسب المسار/المجال.
س: كيف يمكنني تجنب ذلك في Docker؟
ج: تحتوي كل حاوية على مساحة اسم الشبكة الخاصة بها، لذلك تحدث التعارضات فقط عند تعيين المضيف. تعيين منافذ مضيفة مختلفة:-p 3001:3000.
س: هل عقدة killall آمنة؟
ج: إنه يقتل جميع عمليات Node.js – جيد في التطوير، ولكن كن حذرًا إذا كان لديك تطبيقات Node أخرى لا تريد إيقافها.
الخلاصة
EADDRINUSE يعني أن المنفذ مأخوذ بالفعل. حل سريع:ابحث عن العملية باستخدامlsof -ti :PORT واقتله. الإصلاح الدائم:إضافة معالجات إيقاف التشغيل الرشيقة لذلك يقوم خادمك دائمًا بتحرير المنفذ عند الخروج واستخدامnodemon قيد التطوير لإعادة التشغيل النظيف. جعل المنفذ قابلاً للتكوين عبرprocess.env.PORT كما يتجنب الصراعات على الفور.
🔗 Share this article
✍️ Leave a Comment