ASP.NET5 RC1 在 Nginx for windows 下的部署问题记录

momo314相同方式共享非商业用途署名转载

最近.NET的势头越来越好,突然感觉自己要out的感觉,压力产生动力,咱也折腾起了 ASP.NET5。

不过果然还是rc1版本啊,感觉还在完善中(听说Core50也已经支持MEF2了呢),但是还是有点不太靠谱的样子,小坑不断(听说EF还不支持延迟加载?),不过,体验下来感觉还是不错的。

废话不多说,进入正题,咱们还是掰扯掰扯 ASP.NET5 RC1 在 Nginx for windows 下的部署问题 吧:

俩问题,可折腾死我了,搞了我好几天( ̄^ ̄)

1. 配置好 Nginx 之后始终无法访问到 ASP.NET5 MVC6 站点

什么叫“无法访问到”呢? 就是,在chrome里直接输入URL,打开之后是空白页,查看开发者工具,请求如下:

chrome开发这工具中的请求状态chrome开发这工具中的请求状态

但其实,这个请求的 Status Code 却是 200 OK 。感觉就是请求到了nginx,但是nginx向Kestrel转发请求的时候出了什么幺蛾子。要不是我在nginx里配置的nodejs站点能够正常访问,我一定会怀疑是不是我把nginx的配置文件写错了。。。

要不是我英文好,看得懂stackoverflow,还真搞不定呢(●′ω`●)

stackoverflow:asp-net-5-behind-nginx

总之就是一个 RC1 版本的bug,将会在 RC2 中修复,原因如下:

For some reason nginx sends a Connection: close header to Kestrel. The nginx-proxy template actually erases any Connection headers in the request, but that's not really the issue because for HTTP/1.1 no Connection == Connection: keep-alive.

所以呢,我们只需要在 nginx.conf 中加一句 proxy_set_header Connection keep-alive;就哦啦。

server {
    listen       80;
    server_name  demo.com;
    location / {
        proxy_pass   http://localhost:81;
        proxy_http_version 1.1;
        proxy_set_header Connection keep-alive;
    }
}

2. 通过 Nginx 访问 ASP.NET5 MVC6 站点时,有时正常,有时又特别慢

是的,经过上面的配置之后,我又出现了这个问题,具体表现如下:

  1. 通过Nginx访问时,有时会特别慢,有时又是正常的,当特别慢时,多刷新几次页面,有几率刷到正常的请求
  2. 直接通过Kestrel访问,不经过Nginx时,访问速度很正常
  3. 通过Nginx访问时,当出现很慢的情况时,并没有执行到程序中的断点或日志
  4. 通过Nginx访问时,当出现很慢的情况时,时间基本与nginx中配置的 http/keepalive_timeout 值相同

通过上面的分析,我不得不说,这果然是nginx的问题啊(Nginx小白就是我),虽然我是小白,但是看日志的道理还是懂的:

2016/04/05 19:42:04 [error] 14148#10624: *9 upstream timed out (10060: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond) while connecting to upstream, client: 127.0.0.1, server: demo.com, request: "GET / HTTP/1.1", upstream: "http://[::1]:81/", host: "demo.com"

具体问Google的经过就不写了,总之,还是那句话,学好英语很重要,最后我就找到了这个:

Nginx-ticket/496 摘要如下:

Apparently, your backend doesn't respond on IPv6 localhost address (::1), while "localhost" name you use resolves to both IPv4 and IPv6 addresses. The 1.2.9 version works for you as names written in the configuration file are resolved to IPv6 addresses as well as IPv4 ones only starting with this change in nginx 1.3.10:

Changes with nginx 1.3.10

25 Dec 2012

Change:

  • domain names specified in configuration file are now resolved to IPv6 addresses as well as IPv4 ones.

...

Using IPv4 address you want nginx to connect to should be a proper solution, that is

proxy_pass http://127.0.0.1:3000;

should do the trick. Alternatively, configure your OS to map "localhost" name to only IPv4 address.

所以呢,按照这位大神所说的,我们只需要将上面配置文件中的 proxy_pass http://localhost:81; 替换为 proxy_pass http://127.0.0.1:81;,明确指明我们使用的是IPV4就可以啦 (ˉ▽ ̄~)

server {
    listen       80;
    server_name  demo.com;
    location / {
        proxy_pass   http://127.0.0.1:81;
        proxy_http_version 1.1;
        proxy_set_header Connection keep-alive;
    }
}
✎﹏ 本文来自于 momo314和他们家的猫,文章原创,转载请注明作者并保留原文链接。