Blazor部署在Nginx反向代理+负载均衡之后偶尔WebSocket 404偶尔能正常访问

本文详细描述了作者在部署Blazor Server应用到阿里云,通过Nginx做反向代理和负载均衡时遇到的WebSocket 404问题。通过排查、升级Nginx版本、配置重试机制,最终确定问题可能在于WebSocket握手期间的响应冲突,并提供了优化后的Nginx配置。
摘要由CSDN通过智能技术生成

最近遇到一个问题,应用程序是Blazor+Server的模式,部署在阿里云上,同时有开多个进程,然后用Nginx做反向代理和负载均衡,具体的部署配置在后面,这里先说遇到的问题和解决的经历。

首先说明一下,Blazor+Server是使用WebSocket保持长连接的方式来进行客户端与服务端之间的传输。
第一步,首先要保证应用程序本身是正常可用的,就在不使用Nginx之前,它是能运行正常的。
第二步, 按照微软文档的说明,将应用程序部署在Nginx上。Blazor Server部署

部署之后,开始访问应用程序。同时打开谷歌浏览器的控制台。
这时候会看到,偶尔的WebSocket的404,以及请求头上会有Provisional headers are shown。最令人抓狂的是这种情况只是偶尔的,
就是有时候它是正常的,有时候才会有这个提示。具体错误截图如下:
错误截图
最初看起来是404,所以以为是URL异常,或者包的参数不对,于是我尝试过抓包查看包里的信息,发现包里面的关键信息都是一样的。

这里我最开始用的是Nginx 1.17.3,我不知道版本不同是否会有影响,于是我改成使用Nginx 1.19.8,问题依旧。

然后我开始配置Nginx的日志,查看error.log,发现确实存在返回WebSocket的连接返回404记录,但是除了返回404之外并没有看到其他有用的信息。

然后我开始回到没有Nginx时候访问应用程序的方式,偶然在一个网络环境较差的地方,访问我的应用程序的时候,我发现也会有同样的问题。但是浏览器会自动做重新连接的尝试,最终表现出来的效果是连接的时间变长,但是最终客户端是可以连上的,只是在浏览器的控制台那里可以看到跟上面错误截图一样的错误。

于是我开始在Nginx上也添加配置,当Http返回404是进行重试,最终发现可以解决这个问题,而且就算有重试机制,它的访问速度不会比一次成功要慢多少,完全可以接受,而且没有再出现过偶尔404的情况。

猜测引起的原因是在Nginx和应用程序之间WebSocket的握手还未结束之时Nginx已经给客户端返回消息了,这时候因为WebSocket还未连上,所以返回的是404,偶尔能成功的原因是握手已经结束,WebSocket已经连上了,基于这个思路,添加重试之后,重试的时间其实是用来等待WebSocket握手成功的(这个原因纯属猜测,如有大佬知道真实原因欢迎指出,这个问题真的困扰我很久了,谢谢)。

最终Nginx.Conf主要配置如下(test.com,localhost改成自己的域名或者服务器IP,仅供参考,如有可以改进的配置欢迎各位大佬指出,蟹蟹):

	Http
	{
		#Nginx需要以下配置来识别以及将HTTP升级为WebSocket
		map $http_upgrade $connection_upgrade {
	        default Upgrade;
	        ''      close;
	    }
		upstream Web {
        	server localhost:10005 max_fails=3 fail_timeout=120s;
        	server localhost:10006 max_fails=3 fail_timeout=120s;
        	server localhost:10007 max_fails=3 fail_timeout=120s;
        	server localhost:10008 max_fails=3 fail_timeout=120s;
        	server localhost:10009 max_fails=3 fail_timeout=120s;
    	}
	    Server
	    {
			keepalive_requests 120; #单连接请求上限次数。
            listen 10000 ssl default http2;
            server_name test.com;
			#中间还有一些SSL的配置就不贴出来了,只贴重要的信息
			location / {
				#begin 最终就是添加了这两个配置,表示Nginx发现返回404时做一下重试,下面的10是重试次数,这个还可以添加配置 http_502等等,表示遇到那些情况也做一下重试。
                proxy_next_upstream error timeout http_404;
                proxy_next_upstream_tries 10;
                #end
                proxy_pass https://Web;
                #start 下面这几条是配合上面的Map,Nginx在识别下列信息会转成WebSocket
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "Upgrade";
                #end
                proxy_set_header Host $host;
                proxy_cache_bypass $http_upgrade;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_connect_timeout 4s; #配置点1
                proxy_read_timeout 600s; #配置点2,如果没效,可以考虑这个时间配置长一点Nginx发现该客户端在这个时间内如果没有心跳将断开连接
                proxy_send_timeout 120s; #配置点3
            }
		}
	}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值