当你使用 PM2 来启动 Node.js 应用时,可能会遇到一个常见的错误:“Error: listen EINVAL”。该错误通常意味着 Node.js 应用试图在不允许的端口上侦听连接,这可能是由于一些常见的问题引起的。
在本文中,我们将深入研究这个错误的原因,并提供一些解决方案,使你能够快速解决这个问题。
问题原因
该错误通常是由于以下原因之一引起的:
- 端口已被占用
- 操作系统不允许占用某些端口
- Node.js 应用试图同时监听 IPV4 和 IPV6 地址,但其中一个地址无效
解决方案
检查端口是否被占用
我们可以从最简单的开始,查看应用程序使用的端口是否被其他进程占用。可以使用以下命令在 Windows 和 Linux 中查看端口使用情况:
# 找到已经在占用的端口号 sudo lsof -i -P -n | grep LISTEN
或者
# 找到占用某个特定端口的进程 sudo netstat -tulpn | grep <port_number>
如果输出以上任何一个命令都返回占用某个特定端口或者带有 LISTEN 状态的进程,则可以先杀死占用该端口的进程,然后再次启动你的应用程序。
选择合适的端口
如果你确定端口未被占用,则需要确保你的应用程序运行在正确的端口上,并且操作系统允许进程在该端口上侦听连接。尝试使用操作系统允许的不受限制的端口范围(例如 3000 至 5000),可以避免该问题。
如果你的应用程序在云计算环境中运行,则需要检查云提供商是否已禁用某些端口。例如,Google Cloud Platform(GCP)中禁用了 80 和 443 端口,因此如果你在 GCP 上运行应用程序,则需要选择其他端口。
禁用 IPV6
如果你的应用程序提交的是 IPV6 地址,但是该地址在你的机器上无效,则会出现此问题。可以尝试禁用 IPV6 以解决问题。可以使用以下命令禁用 IPV6:
# Disable IPV6 sudo sysctl -w net.ipv6.conf.all.disable_ipv6=1
更改应用程序的代码
在一些特定情况下,可能需要更改你应用程序的代码以解决此问题:
如果是使用 Express.js,则可以通过以下方式仅侦听 IPV4 连接:
const express = require('express'); const app = express(); const port = 3000; app.listen(port, '0.0.0.0', () => { console.log(`Server started on port ${port}`); });
如果你正在使用 Node.js 0.12 或更早版本,还可以尝试删除 BACKLOG 选项:
const net = require('net'); const server = net.createServer(); server.listen(5000); // This line will cause EINVAL error
更改为:
const net = require('net'); const server = net.createServer(); server.listen({ port: 5000, backlog: 0, }); // This line will not cause EINVAL error
结论
“Error: listen EINVAL” 是 Node.js 应用程序启动时可能遇到的常见错误之一。通过确定端口是否被占用,选择正确的端口范围,禁用 IPV6 或更改应用程序代码,可以快速解决此问题。这篇文章将帮助开发人员深入了解此错误,并提供了一些解决方案以解决此问题。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6721e7bd2e7021665e094cb3