系列目錄html
按部就班學.Net Core Web Api開發系列目錄前端
本系列涉及到的源碼下載地址:https://github.com/seabluescn/Blog_WebApipython
1、概述nginx
本篇討論如何把項目發佈到Linux環境,主要包括如下內容:git
一、項目打包github
二、配置Nginx轉發web
三、配置守護服務Supervisorjson
在介紹實際內容前,有兩個疑問須要探討一下:centos
一、咱們的項目發佈後能夠自宿主運行,爲何要配置nginx轉發?api
答:nginx是專業的網絡服務器,功能強大,能夠幫忙處理靜態資源、SSL等。(簡單來講就是Kestrel沒有nginx、IIS等專業)
官方解釋:Kestrel is great for serving dynamic content from ASP.NET Core. However, the web serving capabilities aren't as feature rich as servers such as IIS, Apache, or Nginx. A reverse proxy server can offload work such as serving static content, caching requests, compressing requests, and SSL termination from the HTTP server. A reverse proxy server may reside on a dedicated machine or may be deployed alongside an HTTP server.
二、爲何要配置守護服務?
答:這個問題比較簡單,咱們的程序可能沒有那麼健壯,若是進程意外終止了,守護進程能夠自動從新啓動進程。
2、打包與發佈
CentOS環境下安裝 dotNet Core SDK的過程,請參考本系列第一篇:按部就班學.Net Core Web Api開發系列【1】:開發環境
利用VS 2017發佈項目很是簡單,執行發佈命令便可。須要注意的是saleservice.xml文件不會被髮布,須要手動拷貝到發佈目錄,有個簡單的辦法,我把發佈的路徑從PublishhOutput 改爲bin\Release\netcoreapp2.0\,Release模式編譯一下再發布就能夠,不過這不是什麼大問題。
將發佈目錄copy到目標服務器,運行如下代碼啓動程序:
# dotnet SaleService.dll
經過運行 # curl http://localhost:5000/api/products 能夠查看程序是否運行成功。
因爲系統默認監聽localhost:5000這個地址,因此即便防火牆開通了5000端口,外部也是沒法經過IP來訪問的。須要增長如下代碼來處理:
public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .UseUrls("http://*:5000") .Build();
固然,若是咱們要經過nginx代理訪問項目,並不會經過服務器IP來訪問,上面步驟就不須要。
在調試項目時,咱們在launchSettings.json中設置了啓動頁面,但項目部署後,這個配置不會有效果,若是但願輸入 http://localhost:5000 就跳轉到指定頁面,須要作以下處理:
修改app.UseMvcWithDefaultRoute()
//app.UseMvcWithDefaultRoute(); app.UseMvc(routes => routes.MapRoute(name: "default", template: "{controller=Account}/{action=Index}/{id?}"));
增長一個Controller
public class AccountController : Controller { public ActionResult Index() { return Redirect("/index.html"); } }
3、配置Nginx代理
一、安裝
# rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm # yum install nginx
二、配置
運行命令:
#vi /etc/nginx/conf.d/default.conf
修改文件內容以下:
server { listen 80; location / { proxy_pass http://localhost:5000; 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; } }
重啓nginx和項目。
此時應該能夠經過 http://192.168.0.110/api/product 來訪問項目,實際訪問時,頁面報錯:
這個問題是因爲SELinux保護機制所致使,須要將nginx添加至SELinux的白名單。
# yum install policycoreutils-python # sudo cat /var/log/audit/audit.log | grep nginx | grep denied | audit2allow -M mynginx # sudo semodule -i mynginx.pp
若是經過localhost能夠訪問,經過IP訪問報404錯誤,請注意確認防火牆是否打開。
4、跨域訪問的問題
跨域是指從一個域名的網頁去請求另外一個域名的資源,跨域的嚴格一點的定義是:只要 協議,域名,端口有任何一個的不一樣,就被看成是跨域。
在前端的Ajax代碼中咱們把localhost改爲了服務器的IP:
$("#query").click(function (event) { $.getJSON("http://192.168.109.131/api/products", function (result) { }); });
此時原來正常的程序會報錯:No 'Access-Control-Allow-Origin' header is present on the requested resource
處理辦法:
public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddCors(); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseCors(builder => builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader().AllowCredentials()); app.UseMvcWithDefaultRoute(); app.UseStaticFiles(); }
其中services.AddCors()能夠不用加,WebHost.CreateDefaultBuilder已經加了。
5、配置守護進程
一、 安裝Supervisor
# yum install python-setuptools # easy_install supervisor
二、 配置Supervisor
# mkdir /etc/supervisor # echo_supervisord_conf > /etc/supervisor/supervisord.conf # vi /etc/supervisor/supervisord.conf
在文件底部增長:
[include] files = conf.d/*.ini
在/etc/supervisor建一個conf.d的文件夾,在其下新建一個saleservice.ini文件,內容以下:
[program:SaleService] directory=/home/PublishOutput/ ; 命令執行的目錄 command=dotnet SaleService.dll ; 運行程序的命令 autorestart=true ; 程序意外退出是否自動重啓 stdout_logfile=/var/log/SaleService.out.log ; 輸出日誌文件 stderr_logfile=/var/log/SaleService.err.log ; 錯誤日誌文件 environment=ASPNETCORE_ENVIRONMENT=Production ; 進程環境變量 user=root ; 進程執行的用戶身份 stopsignal=INT
啓動supervisor
supervisord -c /etc/supervisor/supervisord.conf
關閉與重啓:
關閉:supervisorctl shutdown 重啓:supervisorctl reload
驗證咱們的項目是否啓動成功
ps -ef | grep SaleService
三、 配置supervisord爲服務
在/usr/lib/systemd/system文件夾下新建文件:supervisord.service
vi /usr/lib/systemd/system/supervisord.service
內容以下:
[Unit] Description=Supervisor daemon [Service] Type=forking ExecStart=/usr/bin/supervisord -c /etc/supervisor/supervisord.conf ExecStop=/usr/bin/supervisorctl shutdown ExecReload=/usr/bin/supervisorctl reload KillMode=process Restart=on-failure RestartSec=42s [Install] WantedBy=multi-user.target
這樣就能夠了。
服務管理的一些命令:
啓動/關閉服務 # systemctl start supervisord # systemctl stop supervisord 設置自動啓動supervisord # systemctl enable supervisord 驗證是否爲開機啓動: # systemctl is-enabled supervisord
把ngnix也設置爲開機自啓動,而後重啓系統看是否成功。