循序漸進學.Net Core Web Api開發系列【7】:項目發布到CentOS7


系列目錄

循序漸進學.Net Core Web Api開發系列目錄

 本系列涉及到的源碼下載地址:https://github.com/seabluescn/Blog_WebApi

 

一、概述

本篇討論如何把項目發布到Linux環境,主要包括以下內容:

1、項目打包

2、配置Nginx轉發

3、配置守護服務Supervisor

在介紹實際內容前,有兩個疑問需要探討一下:

1、我們的項目發布后可以自宿主運行,為什么要配置nginx轉發?

答: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");
        }
 }

 

三、配置Nginx代理

1、安裝

# rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
# yum install nginx

 

2、配置

運行命令:

#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錯誤,請注意確認防火牆是否打開。

 

四、跨域訪問的問題

跨域是指從一個域名的網頁去請求另一個域名的資源,跨域的嚴格一點的定義是:只要 協議,域名,端口有任何一個的不同,就被當作是跨域。
在前端的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已經加了。

 

五、配置守護進程

1、 安裝Supervisor

# yum install python-setuptools
# easy_install supervisor

  

2、 配置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

  

3、 配置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也設置為開機自啟動,然后重啟系統看是否成功。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM