zoukankan      html  css  js  c++  java
  • 循序渐进学.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 改成binRelease etcoreapp2.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也设置为开机自启动,然后重启系统看是否成功。

  • 相关阅读:
    Tips_of_JS 之 利用JS实现水仙花数的寻找与实现斐波那契数列
    我的天!居然可以这么“弹”!—— 弹性盒布局属性详述
    震惊,正儿八经的网页居然在手机上这样显示!
    这是假的JS——利用CSS Animation实现banner图非交互循环播放
    小K的H5之旅-HTML5与CSS3部分新属性浅见
    CSS小技巧-煎蛋的画法~
    小K的H5之旅-实战篇(一)
    SSM+Redis简介
    Hadoop HA(高可用搭建)
    hadoop完全分布式搭建(非高可用)
  • 原文地址:https://www.cnblogs.com/seabluescn/p/9252527.html
Copyright © 2011-2022 走看看