• 在linux上不依赖于Nignx等服务器部署ASP.NET Core 7.0 WebAPI


    笔者近期需要部署一款基于B/S架构的后端程序在linux的Debian发行版上,本文章以本次部署遇到的问题为线索,总结如何在Debian上部署ASP.NET Core7.0WebAPI应用程序。

    1.先决条件

    • 使用具有 sudo 特权的标准用户帐户访问linux
    • 在linux服务器上安装好支持将要部署的应用程序的.NET运行时

    如果还没有安装.NET运行时,可以参考这篇文章在Linux上安装.NET

    2.应用发布

    我们将应用的“目标运行时”发布为“可移植”,提高我们应用程序的“可移植性”,确保在部署时如果发生失败和错误,不是应用程序发布的问题。
    在这里插入图片描述

    3.部署方式的选择

    可选择的部署方式:

    • 基于Nignx等反向代理服务器部署
    • 基于Linux服务管理器部署(如systemd)
    • 直接运行应用程序

    第一种方式和第二种方式其实没有本质上的区别,只是二者在功能上各有侧重:
    在这里插入图片描述

    • 如果更关注 ASP.NET Core 应用的系统管理、监控和自动启停,使用 Systemd Service 更为合适。
    • 如果需要反向代理、负载均衡等功能,或者希望将多个应用整合到同一域名或 IP 地址下,可以选择使用 Nginx 反向代理
    • 通常情况下,这两者结合使用能够充分发挥各自的优势。 Systemd Service 负责应用的启动和监控,Nginx 负责外部请求的处理和分发。

    至于第三种方式,最为快捷和简单,直接启用应用程序:

    root@xxxx:~# /usr/bin/dotnet /root/HuaWei/DotNetPublish/Test2/HuaWeiProject.dll --urls=http://192.168.1.xxx:监听端口
    
    • 1
    • /usr/bin/dotnet是.NET运行时的根目录
    • /root/HuaWei/DotNetPublish/Test2/是应用程序发布后的目标目录根目录
    • HuaWeiProject.dll是应用程序发布根目录下与exe文件同名的dll文件

    在这里插入图片描述

    • --urls=http://192.168.1.xxx:监听端口是我们指定监听的ip和端口,通过访问这个地址,我们可以进入调用我们WebAPI的其实页面

    我这里开启了swagger,通过在远程或者本地的浏览器访问http://192.168.1.xxx:监听端口/swagger可以进入swagger调试页面
    在这里插入图片描述

    使用这第三种方式,在命令行键入命令后回车,我们可以成功运行应用程序,但是这个时候问题来了:
    在这里插入图片描述

    虽然我们可以运行成功,并且监听我们指定的地址和端口,但是我们只是运行了dll文件,可能会导致有些配置文件无法生效,笔者在使用这种方式时,就碰到了数据库配置失效的问题

    fail: Microsoft.AspNetCore.Server.Kestrel[13]
          Connection id "0HN1MKK48QQ2H", Request id "0HN1MKK48QQ2H:00000001": An unhandled exception was thrown by the application.
          Autofac.Core.DependencyResolutionException: An exception was thrown while activating Service.BusinessService.ProductInfoService -> DBModels.AgiletyDbContext -> λ:Microsoft.EntityFrameworkCore.DbContextOptions`1[[DBModels.AgiletyDbContext, DBModels, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].
           ---> MySqlConnector.MySqlException (0x80004005): Access denied for user ''@'localhost' (using password: NO)
             at MySqlConnector.Core.ServerSession.ReceiveReplyAsync(IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/ServerSession.cs:line 894
             at MySqlConnector.Core.ServerSession.SendClearPasswordAsync(String password, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/ServerSession.cs:line 743
             at MySqlConnector.Core.ServerSession.SwitchAuthenticationAsync(ConnectionSettings cs, String password, PayloadData payload, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/ServerSession.cs:line 712
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    MySqlConnector.MySqlException (0x80004005): Access denied for user ''@'localhost' (using password: NO)表名我的user和password都是空的。

    综上所述,第三种方式可以运行一些简单的配置少的程序,但并不适合我们的WebAPI,因为我们的API一般都是要访问数据库的。解决这个问题的方法是采用第一种或第二种方式。

    4.部署步骤

    笔者选择的是第二种方式基于Linux服务管理器部署,一方面是因为笔者不熟悉Nignx,另一方面,这是一个Linux系统集成的最佳实践,也被ASP.NET Core官方文档作为推荐之一。

    (1)编写服务单元

    在终端中,我们新建一个服务单元

    vim /etc/systemd/system/webapi.service
    
    • 1

    文件将会建立在 /etc/systemd/system/目录下,服务单元的名称可以自定义,我这里取的是webapi,带有一些语义信息,webapi.service中的内容如下

    [Unit]
    Description=ASP.NET Core WebAPI Service
    
    [Service]
    User=root
    Group=root
    WorkingDirectory=/root/HuaWei/DotNetPublish/Test
    Restart=always
    RestartSec=10
    Environment=ASPNETCORE_ENVIRONMENT=Production
    ExecStart=/usr/bin/dotnet /root/HuaWei/DotNetPublish/Test/HuaWeiProject.dll --urls=http://192.168.1.xxx:xx64
    
    [Install]
    WantedBy=multi-user.target
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    上述内容可以作为模板,需要修改的只有4个地方:

    • WorkingDirectory=/root/HuaWei/DotNetPublish/Test替换为程序发布的目标目录在linux文件系统中的绝对位置
    • /root/HuaWei/DotNetPublish/Test/HuaWeiProject.dll替换为程序发布出的dll文件及文件路径
    • urls=http://192.168.1.xxx:xx64替换为你想要监听的ip和端口(如果需要远程访问,要确保此端口已经开启了防火墙规则)

    举一个例子,你的应用程序发布后,与可执行文件(exe)同名的文件为“mydll.dll”,整个目标文件夹为mypublishapi,放在了linux服务器的root目录下,现在你要监听http:172.168.1.101:8080,那么你的webapi.service应当如下:

    [Unit]
    Description=ASP.NET Core WebAPI Service
    
    [Service]
    User=root
    Group=root
    WorkingDirectory=/root/mysqlpublishapi
    Restart=always
    RestartSec=10
    Environment=ASPNETCORE_ENVIRONMENT=Production
    ExecStart=/usr/bin/dotnet /root/mypublishapi/mydll.dll --urls=http:172.168.1.101:8080
    
    [Install]
    WantedBy=multi-user.target
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在vim中编辑完上述内容后,保存退出

    (2)重新加载配置文件

    systemctl daemon-reload
    
    • 1

    (3)开启服务

    systemctl start webapi.service 
    
    • 1

    (4)查看服务状态

    systemctl status webapi.service
    
    • 1

    在这里插入图片描述

    看到active则表示已经运行成功,可以远程访问
    在这里插入图片描述

    5.ip地址的选择

    ExecStart=/usr/bin/dotnet /root/mypublishapi/mydll.dll --urls=http:172.168.1.101:8080
    
    • 1

    在编写webapi.service的配置代码时,除了端口,ip地址的选择也是值得考究的。

    我们有3个选择:

    • linux服务器的公网ip
    • localhost
    • ifconfig命令查询出的ip地址

    笔者因为购买的服务器对ip的限制而在很长一段时间内没有部署成功,下面给出选择方案:

    • 如果远程主机ping得通linux服务器的公网ip,linux服务器自己也ping得通公网ip,那么我们可以选择直接使用公网ip,这种方法允许我们远程访问

    • 如果远程主机ping得通linux服务器的公网ip,linux服务器自己ping不通公网ip,那我们可以选择使用ifconfigfig查询出来的ip,这种方式一般也允许我们远程访问
      在这里插入图片描述

    • 选择localhost,这种方式只能在本机访问

    如果linux服务器配置了公网地址,服务器的网络配置包括公网IP地址,自己ping得通公网ip,就可以远程访问,这是最直接最简单的。

    使用ifconfig命令提供了服务器操作系统能够识别的本机IPv4地址,该地址可用于在本地主机上运行应用程序,并且可能会通过反向NAT技术在互联网上映射到服务器。这样,即使是通过ifconfig查看的地址也可用于本地部署和远程访问。

    而localhost(127.0.0.1)是一个回环地址,用于在本地主机上访问自身服务。因此,虽然应用程序在本地主机上运行成功,但由于localhost不会通过物理网络接口发送或接收数据包,因此无法从外部网络访问。

    6.参考文档

    ASP.NET Core 官方文档

  • 相关阅读:
    一文搞懂 NULL 和 nullptr 的区别【CC++面试必备】
    【DL with Pytorch】第 6 章 : 用循环神经网络分析数据序列
    IO多路转接
    电路仿真设计软件集锦
    【C++笔记】C++ list类模拟实现
    缓存同步之 RabbitMQ 和 Canal
    Android Binder 跨进程通信的优势是什么
    如何降低复杂度,用数据库做消息队列的存储?
    关于电脑功耗与电费消耗的问题,你了解多少?
    sort内部实现原理
  • 原文地址:https://blog.csdn.net/liukuande/article/details/136313110