前言
目前ASP.NET Core RC2已經正式發布了,可以參考如下鏈接:
https://blogs.msdn.microsoft.com/dotnet/2016/05/06/net-core-rc2-improvements-schedule-and-roadmap/
https://blogs.msdn.microsoft.com/dotnet/2016/05/16/announcing-net-core-rc2/
雖然提供了關於publish的文檔(見參考資料部分),但是目前的文檔有幾個問題:
- 針對Ubuntu的,我們公司服務器都是Centos,所以文檔里的安裝方式對於我們來說不合適,所以這里詳細說明在Centos 7.x版本上如何發布.NET Core RC2應用程序。
- 這個文檔明顯過時了,沒有及時更新,目前還是基於RC1的,而不是RC2的。(比如需要配置commands,這明顯過時了,因為RC2中已經移除了commands設置)
- 這個文檔有錯誤,清理socket資源部分,應該用 -S 而不是 -f 來判斷socket文件是否存在。
環境搭建
操作系統
要求是Centos 7.1以上版本即可,這里使用Centos 7.2
安裝.NET Core
可以參考.NET Core的官方安裝說明,https://www.microsoft.com/net/core#centos。 實際安裝時發現.NET Core的安裝包在公司虛機上無法下載。解決方案:
- 可以先下載到本地(這也比較慢),然后上傳到服務器root家目錄下
- 將文件解壓到 /root/dotnet 目錄下
- 在/usr/local/bin目錄下創建 /root/dotnet/dotnet 文件的連接檔:ln -s /root/dotnet/dotnet /usr/local/bin/dotnet
- 創建新目錄,在這個目錄下可以運行 dotnet new、dotnet restore、dotnet run,來驗證dotnet運行環境是否安裝成功
安裝Nginx
主要參考Nginx官方文檔:https://nginx.org/en/linux_packages.html
- 創建/etc/yum.repos.d/nginx.repo,內容如下:
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1 - yum install nginx,就可以安裝了
安裝Supervisor
- 先安裝setuptools,https://pypi.python.org/pypi/setuptools
- 然后運行easy_install supervisor,即可完成Supervisor的安裝了
- 配置supervisor,在/etc/supervisor目錄下添加supervisord.conf,內容如下:
[supervisord]
logfile = /tmp/supervisord.log
logfile_maxbytes = 50MB
logfile_backups=10
loglevel = info
pidfile = /tmp/supervisord.pid
nodaemon = false
minfds = 1024
minprocs = 200
umask = 022
user = root
identifier = supervisor
directory = /tmp
nocleanup = true
childlogdir = /tmp
strip_ansi = false - 在bash下運行supervisord,如果沒有錯誤的話就說明supervisor可以運行了
- 配置為Service。在/usr/lib/systemd/system目錄下添加supervisord.service文件,內容如下:
[Unit]
Description=Supervisor daemon[Service]
Type=forking
ExecStart=/usr/bin/supervisord
ExecStop=/usr/bin/supervisorctl $OPTIONS shutdown
ExecReload=/usr/bin/supervisorctl $OPTIONS reload
KillMode=process
Restart=on-failure
RestartSec=42s [Install]
WantedBy=multi-user.target - 啟動服務,service supervisord start
網站發布
-
將網站監聽的URL修改為可配置的,這樣方便修改,示例代碼如下
IConfiguration configuration = new ConfigurationBuilder().AddJsonFile("config.json").Build(); var host = new WebHostBuilder() .UseConfiguration(configuration) .UseKestrel() .UseContentRoot(Directory.GetCurrentDirectory()) .UseIISIntegration() .UseStartup<Startup>() .Build(); host.Run();
{ "server.urls": "http://+:5000" //注意這里用+,而不是localhost,用localhost的話只能在本機訪問,其他機器不能訪問 }
-
先運行dotnet publish命令發布網站,將網站上傳到Linux服務器。然后進入網站目錄,運行dotnet app.dll,啟動網站。在瀏覽器查看 http://serverip:5000/ 是否可以正常響應。如果這步成功的話,說明.NET Core相關的已經發布成功了。接下來開始配置Nginx。
配置Nginx作為反向代理服務器
- 修改Nginx的運行帳號為root。編輯/etc/nginx/nginx.conf文件,將其中user配置改為root
- 將網站監聽的URL修改為監聽unix socket,這里修改為:http://unix:/var/aspnet/WebApplication1/kestrel.sock
- 修改Nginx的配置,添加.NET Core的WebServer配置,注意修改proxy_pass配置,如下:
server{
listen 8080;
server_name localhost;
location / {
proxy_pass http://unix:/var/aspnet/WebApplication1/kestrel.sock;
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;
}
} - 訪問 http://serverip:8080 驗證是否可以正常響應
需要注意的幾點
- Nginx是通過unix socket將請求轉發給.NET Core的網站,這里是向一個socket文件寫入請求來實現的。所以運行Nginx的帳號需要有向socket文件的寫權限,我這里簡單配置為root帳號
- 如果遇到dotnet進程以外關閉的情況,.sock文件可能不會自動清理,導致.sock資源泄漏。此時需要清理下.sock。否則啟動網站的話會遇到下面的錯誤:
Unhandled Exception: System.AggregateException: One or more errors occurred. (Error -98 EADDRINUSE address already in use) ---> Microsoft.AspNetCore.Server.Kestrel.Networking.UvException: Error -98 EADDRINUSE address already in use - 監聽socket時,.sock文件所在目錄必須首先存在,不存在的話需要先創建,否則報下面的錯誤:
Unhandled Exception: System.AggregateException: One or more errors occurred. (Error -13 EACCES permission denied) ---> Microsoft.AspNetCore.Server.Kestrel.Networking.UvException: Error -13 EACCES permission denied - 如果有問題的話,可以看下Nginx的error.log和access.log來排查問題。路徑為:/var/log/nginx
監控網站應用
- 在網站根目錄下添加web.sh的bash腳本,內容如下,這個腳本的主要目的是每次啟動網站前都先清理socket資源,避免因為socket沒有清理導致網站無法啟動:
if [ -S "/var/aspnet/WebApplication1/kestrel.sock" ]; then
rm "/var/aspnet/WebApplication1/kestrel.sock"
fi
dotnet /root/WebApp2/WebApplication1.dll - 在上面的supervisord.conf文件中追加如下配置:
[program:WebApplication1]
command=bash /root/WebApp2/web.sh
autostart=true
autorestart=true
stderr_logfile=/root/WebApp2/WebApplication1.err.log
stdout_logfile=/root/WebApp2/WebApplication1.out.log
environment=Hosting__Environment=Production
user=root
stopsignal=INT - 重啟Supervisor service
service supervisor stop
service supervisor start
參考資料