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

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

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

1.先决条件

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

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

2.应用发布

我们将应用的"目标运行时"发布为"可移植",提高我们应用程序的"可移植性",确保在部署时如果发生失败和错误,不是应用程序发布的问题。

3.部署方式的选择

可选择的部署方式:

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

第一种方式和第二种方式其实没有本质上的区别,只是二者在功能上各有侧重:

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

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

bash 复制代码
root@xxxx:~# /usr/bin/dotnet /root/HuaWei/DotNetPublish/Test2/HuaWeiProject.dll --urls=http://192.168.1.xxx:监听端口
  • /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文件,可能会导致有些配置文件无法生效,笔者在使用这种方式时,就碰到了数据库配置失效的问题

bash 复制代码
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

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

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

4.部署步骤

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

(1)编写服务单元

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

bash 复制代码
vim /etc/systemd/system/webapi.service

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

bash 复制代码
[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

上述内容可以作为模板,需要修改的只有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应当如下:

bash 复制代码
[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

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

(2)重新加载配置文件

bash 复制代码
systemctl daemon-reload

(3)开启服务

bash 复制代码
systemctl start webapi.service 

(4)查看服务状态

bash 复制代码
systemctl status webapi.service

看到active则表示已经运行成功,可以远程访问

5.ip地址的选择

bash 复制代码
ExecStart=/usr/bin/dotnet /root/mypublishapi/mydll.dll --urls=http:172.168.1.101:8080

在编写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 官方文档

相关推荐
疯狂飙车的蜗牛1 小时前
从零玩转CanMV-K230(4)-小核Linux驱动开发参考
linux·运维·驱动开发
远游客07133 小时前
centos stream 8下载安装遇到的坑
linux·服务器·centos
马甲是掉不了一点的<.<3 小时前
本地电脑使用命令行上传文件至远程服务器
linux·scp·cmd·远程文件上传
jingyu飞鸟3 小时前
centos-stream9系统安装docker
linux·docker·centos
超爱吃士力架4 小时前
邀请逻辑
java·linux·后端
LIKEYYLL5 小时前
GNU Octave:特性、使用案例、工具箱、环境与界面
服务器·gnu
云云3216 小时前
搭建云手机平台的技术要求?
服务器·线性代数·安全·智能手机·矩阵
云云3216 小时前
云手机有哪些用途?云手机选择推荐
服务器·线性代数·安全·智能手机·矩阵
cominglately6 小时前
centos单机部署seata
linux·运维·centos
魏 无羡6 小时前
linux CentOS系统上卸载docker
linux·kubernetes·centos