繼上一篇 asp.net core 3.1多種身份驗證方案,cookie和jwt混合認證授權 的公司內部項目上線后發現文件上傳功能有問題。
上傳的文件超過50M以后前端就報錯了,沒有狀態返回,也沒有響應。只有瀏覽器 Console 里面能看到一條 net::ERR_CONNECTION_RESET
錯誤。
50M以內的都能傳輸,第一反應肯定是配置或者參數限制了。因為是部署的Linux,然后 nginx 做反向代理,檢查了代碼,運行程序的方面的大小限制是已經解除了的。
然后就是nginx限制,讓運維修改了大小限制,但是仍然不行。因為開發人員接觸不到部署環境,運維又說配置已經修改了,最后只得我自己在本地模擬線上環境調試找問題了(本地測試使用的IIS部署)。
由於我機器安裝了 wsl 2,所以准備用 wsl 2 來部署測試玩一玩,關於 wsl 2 的安裝可以看這個 Windows10上安裝Linux子系統(WSL2,Ubuntu),配合Windows Terminal使用
接口和服務修改上傳限制
對於程序需要修改兩個地方,一個是接口的請求大小限制,在方法上面打上 [DisableRequestSizeLimit]
另外一個是kestrel服務器 MultipartBodyLengthLimit
大小限制,Startup里面修改大小。
獨立方式部署
一般本地測試環境 .NET Core 會使用預先安裝運行時來部署,但是如果使用容器一般是自包含運行時的,所以使用獨立方式部署走一波。
可以使用命令方式發布,有vs就直接操作下就行了。
右鍵發布,設置獨立部署
模式,選擇目標運行時 Linux-x64。
wsl 安裝 unbuntu 后,本地幾個盤就已經掛載在了mnt下面。所以直接可以訪問windows上的目錄啟動程序,這也是wsl方便的地方。
我們進入到程序的目錄,然后執行主程序就行了。注意: 如果已經在程序所在目錄了,執行時要加 ./ 然后 ./xxx 的形式才能執行。
不需要安裝任何東西或者依賴,程序已經啟動了。接下來我們安裝 nginx
nginx 安裝和配置
使用 apt-get 安裝 Nginx。
sudo apt-get install nginx
安裝完成后啟動nginx
sudo service nginx start
nginx 默認使用的是80端口,但是我啟動后提示端口被占用。由於 wsl 與 Windows 是共用端口。
查看 iis 配置了80端口站點,停掉 iis 后再啟動還是占用,搜索是 SQL Server Reporting Services 服務停止后就可以了。
測試環境如果你不是非要用80端口,可以在配置里面將 nginx 端口改成其它的,以防常用端口沖突。
Nginx 配置為反向代理將請求轉接到 ASP.NET Core 應用,修改配置 /etc/nginx/sites-available/default。
sudo vim /etc/nginx/sites-available/default
使用vim修改配置為如下,我修改了 nginx 的端口為5000
server {
listen 5000;
location / {
proxy_pass http://localhost:5004;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
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;
}
}
完成配置 Nginx 后,運行 sudo nginx -t
來驗證配置文件的語法。 如果配置文件測試成功,通過運行 sudo nginx -s reload
重新加載。
測試與發現問題
上面的兩步走完后,直接在 Windows 瀏覽器里面訪問 http://localhost:5000 地址就行了,然后進行測試。
上傳文件報 413 requset entity too large,但是 kestrel 並沒有報錯,所以將 nginx 配置 client_max_body_size
設置成 3000m。
再次上傳幾百兆的文件都可以,當我上傳 1.5G 的文件時又報了一個錯誤。
504 超時,修改配置 設置 proxy_read_timeout
大小為 3600s,至於其它的一些 nginx 時間設置不用修改,比如網上有人修改鏈接超時時間什么的,其實沒什么關系。
配置修改后同上,需要運行 sudo nginx -s reload
最后測試了 2G 以內各種大小的上傳都能成功上傳了。
最后
我將本地的測試情況給運維說明了情況,起碼保證了程序是沒問題的,以及nginx會出問題的點。
當然線上環境比我這個測試環境復雜,還需要運維去排查(可能是配置沒生效或者配置不對),我這兒只是分享簡單的部署安裝和找問題過程。
另外還有一個注意點:
部署后啟動服務報 Microsoft.Data.SqlClient.dll 目標平台不支持。最后將運行時里面的復制替換到程序下面就沒問題了,而且運行時里面的文件是1M多,生成的只有幾百k。
這個是為什么?暫時我還不得而知,有沒知道的道友,后續我找到原因會更新在文章中。