NextJS部署CentOS7时服务端fetch报ETIMEDOUT超时错误
服务端请求超时问题排查
部署环境说明
项目部署在配置了8080端口转发的CentOS 7服务器上,站点可通过「服务器IP:8080」的形式访问,前后端反向代理通过NGINX实现。
站点NGINX配置
server { listen 80; listen [::]:80; server_name myapp.com etc.com; #my api location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Auth-Request-Redirect "http://api.myapp.com"; proxy_cache_bypass $http_upgrade; proxy_pass http://127.0.0.1:3333; proxy_http_version 1.1; proxy_buffer_size 128k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; proxy_redirect off; #proxy_cookie_path / "/; SameSite=lax; HTTPOnly; Secure"; } #my app location /myapp { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Auth-Request-Redirect "http://ipaddress:8080/adminpage"; proxy_cache_bypass $http_upgrade; proxy_pass http://127.0.0.1:3000; proxy_http_version 1.1; proxy_buffer_size 128k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; #proxy_cookie_path / "/; SameSite=lax; HTTPOnly; Secure"; } }
运行时错误日志
FetchError: request to http://ipaddress:8080/auth/checkauth failed, reason: connect ETIMEDOUT ipaddress:8080 at ClientRequest.<anonymous> (/root/web/myapp/node_modules/next/dist/compiled/node-fetch/index.js:1:64142) at ClientRequest.emit (node:events:527:28) at Socket.socketErrorListener (node:_http_client:454:9) at Socket.emit (node:events:527:28) at emitErrorNT (node:internal/streams/destroy:157:8) at emitErrorCloseNT (node:internal/streams/destroy:122:3) at processTicksAndRejections (node:internal/process/task_queues:83:21) { type: 'system', errno: 'ETIMEDOUT', code: 'ETIMEDOUT' }
关联业务代码
_middleware.ts 中间件代码
import type { NextRequest } from 'next/server'; import { NextResponse } from 'next/server'; export async function middleware(req: NextRequest) { const token = req.cookies; const urlClone = req.nextUrl.clone(); urlClone.pathname = `/404`; const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/auth/checkauth`, { method: 'GET', headers: { Authorization: `Bearer ${token.app_token}`, }, }); if (res.status === 200) { return NextResponse.next(); } return NextResponse.rewrite(urlClone); }
当前应用运行状态
生产环境下应用基础功能正常,客户端侧Axios接口请求可正常响应,可通过Axios请求完成登录操作,但middleware中、getServerSideProps中编写的服务端fetch请求持续触发connect ETIMEDOUT连接超时错误。
已尝试排查方案(均未解决问题)
- 配置proxy agent
- 将fetch请求替换为适配后的axios请求
- 调整测试不同的请求URL配置
- 将API服务的CORS规则设置为全放行
额外验证结果
- 服务器内部可通过curl正常调用对应API接口
- 本地开发机通过Postman可正常调用该接口
- 另一套按照相同流程部署在Linux服务器的NextJS应用,middleware和
getServerSideProps中的fetch请求可正常运行,唯一区别是该服务器未配置端口转发,初步怀疑端口转发是问题诱因 - 当前使用的NextJS版本为v12.1.6,需要定位问题根因。
内容的提问来源于stack exchange,提问作者ßiansor Å. Ålmerol
相关产品推荐
相关产品推荐

