V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
NGINX
NGINX Trac
3rd Party Modules
Security Advisories
CHANGES
OpenResty
ngx_lua
Tengine
在线学习资源
NGINX 开发从入门到精通
NGINX Modules
ngx_echo
ericgui
V2EX  ›  NGINX

一个 Node.js 部署的常见错误,但我就是搜不到解决方案,搞不定,求高人指点

  •  1
     
  •   ericgui · 2017-12-12 01:45:24 +08:00 · 5411 次点击
    这是一个创建于 2543 天前的主题,其中的信息可能已经有所发展或是发生改变。
    ## 我把 log 在 google 上搜了一下,很多人描述这个问题,我也尝试了 2 天了,都搞不定,特来求助

    ## 环境:
    - Node.js v8.9.1
    - ExpressJS
    - Ubuntu 16.04 LTS
    - pm2

    ## 错误
    - 描述 1:如果短时间内多次刷新首页,出现 502 Bad Gateway 错误
    - 描述 2:代码里,用户注册或登陆成功后会自动跳转到首页,在本机 OK,但部署到服务器之后,跳转出现 502 Bad Gateway

    ## 配置:
    ### Nginx 配置文件:

    1 upstream helloworld {
    2 server <server-ip-address>:3000 max_fails=0 fail_timeout=10s weight=1;
    3 ip_hash;
    4 keepalive 512;
    5 }
    6
    7 server {
    8 listen 80;
    9 server_name helloworld.com www.helloworld.com;
    10
    11 #charset koi8-r;
    12 access_log /app/archives/logs/nginx/helloworld .host.access.log main;
    13 error_log /app/archives/logs/nginx/helloworld .host.error.log debug;
    14
    15 root /app/helloworld ;
    16
    17 location / {
    18 proxy_pass http://helloworld;
    19 proxy_set_header X-Real-IP $remote_addr;
    20 proxy_set_header X-Forwarded-Proto $scheme;
    21 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    22 proxy_set_header Host $host;
    23 proxy_set_header X-NginX-Proxy true;
    24 proxy_http_version 1.1;
    25 proxy_set_header Upgrade $http_upgrade;
    26 proxy_set_header Connection 'upgrade';
    27 proxy_set_header Host $host;
    28 proxy_cache_bypass $http_upgrade;
    29
    30 }
    31 }

    ## error log
    2017/12/11 09:22:23 [error] 29952#29952: *81 connect() failed (111: Connection refused) while connecting to upstream, client: 169.228.200.160, server: helloworld.com, request: "GET / HTTP/1.1", upstream: "http://<server-ip-address>:3000/", host: "www.helloworld.com", referrer: "http://www.helloworld.com/user/signin"
    第 1 条附言  ·  2017-12-13 02:46:35 +08:00
    操,我解决了,我看了 youtube 上的一个视频,发现了一行代码,和我的 error log 有关,因为老是 hostname 不匹配

    所以就加了这么一句,定义 hostname, 然后 app.listen 加了一个参数,成了这样:

    const hostname = process.argv[2] || null;
    app.listen(3000, hostname);

    就好了,跳转就没有 502 了

    我也不知道为啥好了。
    第 2 条附言  ·  2017-12-13 02:47:26 +08:00
    这句是加在 app.js 里了
    第 3 条附言  ·  2017-12-13 02:54:31 +08:00
    哪位高人能解释一下这句 到底啥意思?为啥加了这句就好了?
    22 条回复    2017-12-13 01:46:02 +08:00
    lucas56
        1
    lucas56  
       2017-12-12 04:46:28 +08:00 via iPhone
    之前遇到过,修改下 proxy_set
    lucas56
        2
    lucas56  
       2017-12-12 04:47:07 +08:00 via iPhone
    proxy_set_header
    qfdk
        3
    qfdk  
       2017-12-12 05:49:27 +08:00 via iPhone
    其实可以考虑用我的方案 http://blog.qfdk.me/post/2017-10-23
    ericgui
        4
    ericgui  
    OP
       2017-12-12 06:39:16 +08:00
    @lucas56 请问能具体说一下吗?谢谢
    ericgui
        5
    ericgui  
    OP
       2017-12-12 06:46:13 +08:00
    @qfdk 我是部署一个 expressjs,您的代码我有点看不懂
    marknote
        6
    marknote  
       2017-12-12 06:57:48 +08:00 via iPhone
    location / {
    18 proxy_pass http://helloworld;


    这里有问题吧 自己 proxy 自己 死循环了
    ericgui
        7
    ericgui  
    OP
       2017-12-12 07:01:42 +08:00
    @marknote 这一段是我抄网上的,因为 log 里有个 upstream,我搜了一下, 说是这样写。

    其实这样写没问题,我的网站可以工作,就是登陆成功后跳转就出 502

    当然,22 和 27 行是重复的,已经去掉了一行了。
    tlday
        8
    tlday  
       2017-12-12 08:18:15 +08:00 via Android
    建议先定位问题出在 Node 代码层面还是 nginx。
    不要反向代理,打开浏览器 Network 里面的 preserve log 再尝试重现问题。
    mcfog
        9
    mcfog  
       2017-12-12 08:28:25 +08:00 via Android
    看看 node 的日志吧,感觉是 node 有问题 crash 了然后瞬间被 pm 又拉起来了
    ericgui
        10
    ericgui  
    OP
       2017-12-12 08:32:27 +08:00
    @tlday 应该是 nginx 的问题,我在本地没任何问题,跳转都 OK,部署之后,也能正常打开网站。

    刚才按照您的建议,打开了 preserve log,显示进入登陆页,GET 200,提交用户名和密码,POST 302 (因为登陆成功就跳转),然后立刻就 502 了。
    ericgui
        11
    ericgui  
    OP
       2017-12-12 08:41:59 +08:00
    @mcfog 是的,就是这个原因。google 上好几个人都这么说。但我就是不知道怎么修。
    yimity
        12
    yimity  
       2017-12-12 09:29:45 +08:00
    把 12345 去掉。
    yimity
        13
    yimity  
       2017-12-12 09:32:44 +08:00   ❤️ 1
    把 12345 删掉
    proxy_pass http://helloworld; 这个直接给你本地的 ip 和端口。

    server {
    listen 80;
    server_name abc.com;

    location / {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $http_host;
    proxy_pass http://172.18.0.5:3000;
    }
    }
    crz
        14
    crz  
       2017-12-12 09:44:38 +08:00
    @ericgui 如 @mcfog 所说的,先看看 node 的日志吧
    KuroNekoFan
        15
    KuroNekoFan  
       2017-12-12 09:56:16 +08:00
    @qfdk nodejs 做反代对比 nginx 有什么优势吗
    whypool
        16
    whypool  
       2017-12-12 09:58:42 +08:00
    nginx 配置不对吧;
    tlday
        17
    tlday  
       2017-12-12 12:46:52 +08:00 via Android
    302 跳转有多种情况,可以看下 303 或者 307。我个人倾向于认为是你的 302,POST 请求发给 node 端导致 express 那里崩溃了,然后被 pm2 直接瞬间拉起来了。nginx 出问题的几率不大。刷新速度过快 502 应该也是你 express 那里程序写的问题,但两个问题可能没有关联。建议你看看 express 的日志,考虑把所有的详细日志打出来。你的情况下,默认日志的位置应该在~/.pm2/log 之类的地方,有几个 worker 就有几个日志,挨个检查一下。
    tlday
        18
    tlday  
       2017-12-12 12:51:51 +08:00 via Android
    另外,nginx 和 pm2 合用似乎是重复的。因为 pm2 起多个 worker,但是只代理一个端口,pm2 也是会作为负载均衡转发请求给各个 worker 的。不过它的自动重启对于 express 这种没有最外层 ExceptionHandler,崩溃就 GG 的程序还是很有必要的。
    qfdk
        19
    qfdk  
       2017-12-12 14:53:13 +08:00 via iPhone
    @KuroNekoFan 简单:) 不用搞 nginx 复杂肥肉编译 几行代码搞定 加个 forever 美滋滋
    defunct9
        20
    defunct9  
       2017-12-12 18:28:49 +08:00 via iPhone
    开 ssh,上去帮你看看
    ericgui
        21
    ericgui  
    OP
       2017-12-13 01:41:41 +08:00
    @tlday 是的,我把 pm2 一停,就用 npm start,一切都 OK 了。
    ericgui
        22
    ericgui  
    OP
       2017-12-13 01:46:02 +08:00
    @tlday 但只用 npm start 也很原始,而且 log 都输出到 console 来了。最好还是用 pm2 的吧?否则怎么自动重启呢?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3458 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 11:02 · PVG 19:02 · LAX 03:02 · JFK 06:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.