繼上一篇 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。
這個是為什麼?暫時我還不得而知,有沒知道的道友,後續我找到原因會更新在文章中。