ASP.NET Core之部署应用程序到Linux环境(非Docker模式)

一、前言

  在.NET Core中实现跨平台的特性,我们创建一个ASP.NET Core的应用程序,然后通过非Docker方式部署到Linux环境中(Centos),通过一步步实践来体验跨平台的特性,及其在部署过程中要注意的事项,当前实践只是一个Demo实例,在实际生产环境下要考虑各种性能问题,所以要复杂的多。主要包括如下几个,在Linux环境中搭建运行程序的运行时;VS编译工具发布应用程序,上传到Liunx;然后启动应用程序;将应用程序设置系统后台服务运行。

二、Liunx中搭建NET Core运行环境

  在Windows环境不管运行.NET Framework或者运行.NET Core都必须安装相关的SDK和运行时,比如在.NET Framework中的.NET 4.5、.NET 4.7、.NET4.8等版本,如果安装的应用程序没有相关的.NET版本会提示错误信息,安装该版本,或者在打包应用程序时一起将SDK、运行时打包到程序中安装。在WIN+R中运行%systemroot%\Microsoft.NET\Framework,可以查看当前Windows环境安装的版本,或者通过下述.bat文件在cmd中运行获取全部版本信息!

@echo off
reg query "HKLM\SOFTWARE\Microsoft\NET Framework Setup\NDP" /s > "%temp%\net_versions.txt"
for /f "tokens=1,2,3 delims= " %%a in ('findstr /C:"Version" "%temp%\net_versions.txt"') do (
    set "key=%%a"
    set "value=%%c"
    echo .NET Framework Version: %%~c
)
del "%temp%\net_versions.txt"
pause

  .NET Core一样通过在cmd中dotnet --info命令获取全部系统已经安装的SDK与运行时的全部版本信息。通过dotnet -version获取当前最终版本号。

   上述的安装通过在官网的.NET Core的下载页面https://dotnet.microsoft.com/zh-cn/download/dotnet/8.0,下载不同版本,包括Windows、Liunx、OS环境离线安装包。

  主要包括SDK、ASP.NET Core的运行时、.NET桌面运行时、.NET运行时(NET 运行时仅包含运行控制台应用所需的组件),涉及到运行.NET Core中创建Web应用程序、桌面应用程序WPF、控制台应用程序Console。

  上述都是安装Windows环境的,接下来安装Linux的运行环境,主要①在下载页下载离线安装包注意(版本号、操作系统、二进制文件区分),②直接在Liunx中在线下载SDK、运行时,③使用Docker容器,创建dockerfile文件包含相关的SDK、运行时信息。通过输入如下命令在线下载安装。

  第一步、运行以下命令,将 Microsoft 包签名密钥添加到受信任密钥列表,并添加 Microsoft 包存储库,注意/8版本号。

sudo rpm -Uvh https://packages.microsoft.com/config/centos/8/packages-microsoft-prod.rpm

  第二步、选择SDK版本与ASP.NET Core版本执行安装命令,如下命令(其中使用dotnet-runtime-7.0运行时可以替代asp.netcore-runtime-7.0包含该运行时)。

sudo yum install dotnet-sdk-7.0 dotnet-runtime-7.0
或者
sudo yum install dotnet-sdk-7.0 aspnetcore-runtime-7.0

   通过dotnet --list-sdks 查看当前系统安装的.NET Core全部版本,及其文件位置,在安装dotnet-sdk-7.0的同时,依赖安装了asp.netcore-runtiime-7.0、dotnet-runtiime-7.0等包。

注意:1、通过命令sudo yum install dotnet-sdk-7.0下载了SDK并且一起依赖安装了asp.netcore-runtiime-7.0、dotnet-runtiime-7.0运行时,在.net core3.1中无法依赖同时安装SDK和运行时,需两个都安装。2、通过在线下载安装.NET Core,如果离线下载.tag包安装时必须确认krb5-libs、libicu、openssl-libs、zlib库是否在系统已经安装了。

三、Liunx中发布ASP.NET Core应用

  在VS中创建一个框架为.NET 7.0的ASP.NET Core WebApi应用程序,然后基于简单的测试,直接编译、发布项目,获取\net7.0\publish下的文件内容,上传至Liunx中/home/netcore/WebApplication7。

   完成上述的创建项目->编译项目->发布项目,则在Liunx中启动webApi应用,通过运行命令dotnet WebApplication7.dll --urls="http://localhost:5002",注意这个端口被占用,如果不加--urls参数则默认是5000,其运行与在Windows环境一致;不关闭当前的命令窗口,新开一个命令窗口,运行命令curl http://127.0.0.1:5002/weatherforecast,如下图返回接口请求结构,说明WebApi已经部署成功。

四、创建ASP.NET Core系统服务

  上述的.NET Core运行在命令窗口中,如果关闭这个窗口会导致程序关闭。可以通过将这个.NET Core应用程序设置成系统服务、后台服务。使用守护进程方式设置程序,可以使用systemd模块或者supervisor为程序创建守护进程,其中systemd在上一个文章中记录了,我们使用supervisor来实现。

  第一步、在系统中安装supervisor,当前环境为centos,主要执行下述命令实现安装

1. 使用epel-release仓库来安装Supervisor,先安装epel-release包
sudo yum install -y epel-release

2.安装Supervisor
sudo yum install -y supervisor

3.启动Supervisor服务,并设置开机自启
sudo systemctl start supervisord
sudo systemctl enable supervisord

   上述提示启动失败,通过查看状态找到原因,是要先配置config文件相关参数,然后在启动程序,默认的配置文件位于/etc/supervisord.conf,编辑如下参数项

[unix_http_server]
file=/tmp/supervisor.sock   ;UNIX socket 文件,supervisorctl 会使用
;chmod=0700                 ;socket文件的mode,默认是0700
;chown=nobody:nogroup       ;socket文件的owner,格式:uid:gid

;[inet_http_server]         ;HTTP服务器,提供web管理界面
;port=127.0.0.1:9001        ;Web管理后台运行的IP和端口,如果开放到公网,需要注意安全性
;username=user              ;登录管理后台的用户名
;password=123               ;登录管理后台的密码

[supervisord]
logfile=/tmp/supervisord.log ;日志文件,默认是 $CWD/supervisord.log
logfile_maxbytes=50MB        ;日志文件大小,超出会rotate,默认 50MB,如果设成0,表示不限制大小
logfile_backups=10           ;日志文件保留备份数量默认10,设为0表示不备份
loglevel=info                ;日志级别,默认info,其它: debug,warn,trace
pidfile=/tmp/supervisord.pid ;pid 文件
nodaemon=false               ;是否在前台启动,默认是false,即以 daemon 的方式启动
minfds=1024                  ;可以打开的文件描述符的最小值,默认 1024
minprocs=200                 ;可以打开的进程数的最小值,默认 200

[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ;通过UNIX socket连接supervisord,路径与unix_http_server部分的file一致
;serverurl=http://127.0.0.1:9001 ; 通过HTTP的方式连接supervisord



;包含其它配置文件
[include]
files =/etc/supervisord.d/*.ini    ;可以指定一个或多个以.ini结束的配置文件

  其中files =/etc/supervisord.d/*.ini表示可以加载相关进程,使用.结尾的ini文件,然后重新运行sudo systemctl start supervisord命令,查看是否启动成功,如下所示。

   第二步、在/etc/supervisord.d/目录下新建要守护进程的配置文件,使用上述.NET Core应用程序为例,主要参数如下

[program:WebApplication7]
command=dotnet WebApplication7.dll --urls="http://localhost:5002"    #运行命令
directory=/home/netcore/WebApplication7 #程序路径
environment=ASPNETCORE__ENVIRONMENT=Production
user=root
stopsignal=INT
autostart=true #自动启动
autorestart=true #3秒自动重启
startsecs=3
stderr_logfile=/var/log/ossoffical.err.log
stdout_logfile=/var/log/ossoffical.out.log

  第三步、重新启动supervisord,加载这个ini文件,然后使用命令sudo systemctl start supervisord查看是否已经加入成功!

   通过上述命令应用程序已经启动,并且可以访问获取接口数据,说明成功加入。还可以通过使用supervisord的其他命令操作进程!

  第四步、通过在.ini文件中配置的应用程序日志路径,可以查看应用程序的执行日志,如下所示

 

五、使用nignx代理服务

  通过上述的操作,已经在Linux环境下运行ASP.NET Core应用,通过ASP.NET Core的内置服务器Kestrel启动服务,但是对外提供web服务,可以使用ngnix代理服务器的方式转发至这个服务中(ngnix作为web服务提供更好的性能、Kestrel则更多是应用服务),主要的操作如下所示

  第一步,在Linux环境中安装nginx应用,可以通过docker或者非docker方式。

  第二步、在nginx应用的配置文件中nginx.conf中配置代理参数,如下所示。

# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;
      location / {
            root   html;
            index  index.html index.htm;
        }
        
        location /dotnet/ {
            proxy_pass http://127.0.0.1:5002/weatherforecast;
        }
        error_page 404 /404.html;
            location = /40x.html {
        }
        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }

# Settings for a TLS enabled server.
#
#    server {
#        listen       443 ssl http2 default_server;
#        listen       [::]:443 ssl http2 default_server;
#        server_name  _;
#        root         /usr/share/nginx/html;
#
#        ssl_certificate "/etc/pki/nginx/server.crt";
#        ssl_certificate_key "/etc/pki/nginx/private/server.key";
#        ssl_session_cache shared:SSL:1m;
#        ssl_session_timeout  10m;
#        ssl_ciphers PROFILE=SYSTEM;
#        ssl_prefer_server_ciphers on;
#
#        # Load configuration files for the default server block.
#        include /etc/nginx/default.d/*.conf;
#
#        location / {
#        }
#
#        error_page 404 /404.html;
#            location = /40x.html {
#        }
#
#        error_page 500 502 503 504 /50x.html;
#            location = /50x.html {
#        }
#    }
}

  第三步、然后重启nginx加载修改后的配置文件,在浏览器访问服务器IP/dotnet/获取默认接口数据

六、总结

  使用非docker的方式在centos环境下安装.net core的SDK,并且安装asp.net core的运行时,创建ASP.NET Core WebApi应用,部署在系统中。使用supervisord完成了守护进程(.dotnet)的设置,然后通过nignx的代理服务器对外提供这个应用程序的接口服务,至此一个完整的asp.net core应用跨平台部署就完成。这个是简单的Demo,在实际的生产环境要考虑应用的安全性、并发性能、扩展性能、分布式、CI/CD等复杂的内容。

参考:https://learn.microsoft.com/zh-cn/dotnet/core/install/linux-centos#install-preview-versions,https://blog.csdn.net/u014597198/article/details/85158056,https://www.cnblogs.com/leoxuan/p/11108231.html

posted @ 2024-05-11 00:25  tuqunfu  阅读(113)  评论(0)    收藏  举报