Linux 服务器 CPU 架构主要可分为:X86_64/AMD64ARM64/AARCH64 两大类,大多情况使用的都是基于 AMD64 CPU 架构的服务器。但随着国产操作系统、CPU 等自主生态打造的应用产品得到越来越多的用户认可和应用,如:华为鲲鹏、统信 UOS 这类服务器不断被采购使用,而它们均有采用 ARM64 CPU 架构,所以 .NET 程序如果需要在更多的国产服务器中运行,适配 ARM64 CPU 架构将是开始的第一步。

本文的介绍并不是一个简单的 Demo 示例,而是基于一个较大项目适配 ARM64 架构改造的经验分享。

该项目的大概背景如下:

  • 基于多个 .NET Core 服务构成的微服务架构系统

  • 基于 gRPC 实现的微服务应用

  • 基于主流中间件,如:MongodbRedisKafkaZookeeper

当时提出整个项目需要支持在 ARM64 CPU 架构的服务器中进行部署时,其实并没有太多担忧,因为 .NET Core 的跨平台能力与生俱来,所以随便找了个服务来测试,结果马上被打脸了,跑不起来。接着一度怀疑是运行环境的问题,尝试多次重装 .NET Core SDK,并测试了多个版本,结果还是失败。经过一番研究与确认,主要是以下3个问题:

  1. 服务启动时加载 Confluent.Kafka(Kafka 操作的封装库)会出现如下错误:

    Unhandled exception. System.DllNotFoundException: Failed to load the librdkafka native library.at Confluent.Kafka.Impl.Librdkafka.Initialize(String userSpecifiedPath)at Confluent.Kafka.Consumer`2..ctor(ConsumerBuilder`2 builder)at Confluent.Kafka.ConsumerBuilder`2.Build()
    

    该问题的原因是在发布代码中并不包含在 linux-arm64 运行所需的 librdkafka.so,解决方法其实比较简单,因为我们的项目引用的 Confluent.Kafka NuGet 包版本相对较低,在高版本中已包含对 linux-arm64 的支持,所以只需要对引用了 Confluent.Kafka 的项目基础包进行升级,然后相关服务升级基础包即可。

  2. 服务启动时加载 Grpc.Core(gRPC 核心实现)会出现如下错误:

    Unhandled exception. System.IO.IOException: Error loading native library "/usr/local/temp/program/publish/runtimes/linux/native/libgrpc_csharp_ext.x64.so". at Grpc.Core.Internal.UnmanagedLibrary..ctor(String[] libraryPathAlternatives)at Grpc.Core.Internal.NativeExtension.LoadUnmanagedLibrary()at Grpc.Core.Internal.NativeExtension.LoadNativeMethods()at Grpc.Core.Internal.NativeExtension..ctor()at Grpc.Core.Internal.NativeExtension.Get()at Grpc.Core.Internal.NativeMethods.Get()at Grpc.Core.GrpcEnvironment.GrpcNativeInit()at Grpc.Core.GrpcEnvironment..ctor()at Grpc.Core.GrpcEnvironment.AddRef()at Grpc.Core.Channel..ctor(String target, ChannelCredentials credentials, IEnumerable`1 options)at Grpc.Core.Channel..ctor(String target, ChannelCredentials credentials)
    

    该问题相对复杂很多,引用 Grpc.Core 后,程序在发布时也会生成对应运行平台的 runtime 文件 libgrpc_csharp_ext.x86.solibgrpc_csharp_ext.x64.so,很显然也是没有对应 linux-arm64 的版本。与 Confluent.Kafka 不同,官方并没有打算默认支持的意思,只是提到如果需要可自行基于源代码编译。在 Github 的 Issue 讨论中也看到另外一种解决方案,可是将 Grpc.Core 替换成 dotnet-grpcdotnet-grpc 是官方随 .NET Core 3.0 一起发布的一个 gRPC 扩展组件,没有额外的 runtime 文件的依赖,但是替换成  dotnet-grpc 的时间成本相对较高(虽然这条路看上去之后还是得走,gRPC 在 C# 中的未来属于grpc-dotnet ),所以当前选择了自编译的方式。

    以下是基于 Debian ARM64 CPU 架构服务器上编译操作。

    安装基础依赖组件

    sudo apt-get install build-essential autoconf libtool pkg-config
    sudo apt-get install libgflags-dev libgtest-dev
    sudo apt-get install clang libc++-dev
    sudo apt-get install cmake
    

    拉取 grpc 源码(项目当前使用是 v1.22.1)

    git clone -b v1.22.1 https://github.com/grpc/grpc
    cd grpc# 获取依赖的子模块
    git submodule update --init
    

    编译

    mkdir -p cmake/build
    cd cmake/build
    cmake -DgRPC_BUILD_TESTS=OFF -DCMAKE_BUILD_TYPE="${MSBUILD_CONFIG}" ../..
    make -j4 grpc_csharp_ext
    

    获取 libgrpc_csharp_ext.so

    cp libgrpc_csharp_ext.so ../../../libgrpc_csharp_ext.x86.so
    cp libgrpc_csharp_ext.so ../../../libgrpc_csharp_ext.x64.so
    

    得到 libgrpc_csharp_ext.x86.solibgrpc_csharp_ext.x64.so 之后,在 CI 工具中对发布的程序文件进行二次替换即可解决报错问题。

  3. ASP.NET Core Runtime 版本问题,官方并没有提供 ASP.NET Core Runtime 2.2.x 对应的 ARM64 版本

    针对此问题的处理方式还是比较果断的,那就是全面升级到 3.1,首先 3.1 是 LTS 版本,且提供了 ARM64 对应的 runtime,另外因为之前已经升级过一波,目前基于 2.2 的服务残留的并不多,当然整个升级改造过程还是需要谨慎,可参考:从 ASP.NET Core 2.2 迁移到 3.0 [1] 和 从 ASP.NET Core 3.0 迁移到 3.1[2]

以上主要是 .NET Core 服务本身适配 ARM64 服务器部署遇到的一些问题,不过不同的项目还是会面对不一样的情况,解决后目前来看一切正常。当然这还不包含其他配套组件的改造,比如:MySQL 替换成 MariaDB 等。

参考资料

[1]

从 ASP.NET Core 2.2 迁移到 3.0 : https://docs.microsoft.com/zh-cn/aspnet/core/migration/22-to-30?view=aspnetcore-5.0&tabs=visual-studio

[2]

从 ASP.NET Core 3.0 迁移到 3.1: https://docs.microsoft.com/zh-cn/aspnet/core/migration/30-to-31?view=aspnetcore-5.0&tabs=visual-studio

- END -

分享、点赞再看,三连走一波

.NET Core 服务在 ARM64 服务器中的部署相关推荐

  1. 定位服务在iOS 8中不起作用

    本文翻译自:Location Services not working in iOS 8 My app that worked fine on iOS 7 doesn't work with the ...

  2. WCF技术剖析之二十: 服务在WCF体系中是如何被描述的?

    任何一个程序都需要运行于一个确定的进程中,进程是一个容器,其中包含程序实例运行所需的资源.同理,一个WCF服务的监听与执行同样需要通过一个进程来承载.我们将为WCF服务创建或指定一个进程的方式称为服务 ...

  3. [原创]WCF技术剖析之二十: 服务在WCF体系中是如何被描述的?

    任何一个程序都需要运行于一个确定的进程中,进程是一个容器,其中包含程序实例运行所需的资源.同理,一个WCF服务的监听与执行同样需要通过一个进程来承载.我们将为WCF服务创建或指定一个进程的方式称为服务 ...

  4. 免费开源的客服系统 Linux 服务器环境安装部署过程

    最近因为项目需要,要找一款在线客服系统集成在 APP 中使用,而且涉及到生意开单,客服系统必须稳定可靠.另外甲方要求,必须支持 Linux 服务器环境. 我们以 Ubuntu 18.04 为例把安装部 ...

  5. 关于webservice服务在springboot项目中的开发的介绍

    在springboot项目中搭建webservice服务端及使用客户端进行请求的介绍 一.引包 二.搭建webservice服务 (一)使用CXF搭建webservice服务 (二)webservic ...

  6. ASP.NET Core在Azure Kubernetes Service中的部署和管理

    目标 部署:掌握将aspnetcore程序成功发布到Azure Kubernetes Service(AKS)上 管理:掌握将AKS上的aspnetcore程序扩容.更新版本 准备工作 注册 Azur ...

  7. nodejs应用在linux服务器中的部署

    1.(可选)添加用户: addgroup wmui添加用户组 useradd -d /home/wmui -s /bin/bash -m wmui创建wmui用户 passwd wmui设置密码,如果 ...

  8. 苹果手机如何显示定位服务器地址,iOS8定位服务在哪?苹果iPhone6/Plus开启或关闭定位方法图文介绍...

    以下是具体的iPhone6/Plus开启或关闭定位方法,适合所有iOS8系统的iPhone设备. iOS8定位服务在哪? 定位服务关系用户隐私方面的东西,因此iOS8定位服务在iOS8设置中的&quo ...

  9. 打开服务器数据库文件,如何打开服务器中的数据库文件

    如何打开服务器中的数据库文件 内容精选 换一换 云服务器新增磁盘,开机自动执行磁盘初始化脚本后,Oralce.MySQL和SQL Server等数据库系统日志Msg 823错误 .磁盘初始化脚本Win ...

最新文章

  1. 学习UI设计的一些小技巧你会了吗
  2. UVA1342 That Nice Euler Circuit(ACM - ICPC 2004 Asia - Shanghai)(计算几何、欧拉定理)
  3. 科技城|从专利布局看人工智能领域全球竞争与中国面临的挑战
  4. Reduce Join介绍及案例
  5. 第一次来,试发一帖!--ASP.NET 2.0 中的SqlCacheDependency特性
  6. rem布局在部分手机上显示不正常问题
  7. JPQL设置自增长、只读、文本类型等的注解
  8. 如何将文件加添加成webapp
  9. 客户端服务端防止用户重复提交表单
  10. ajax工作中使用模板
  11. 电脑上玩和平精英_《和平精英》怎么投屏到电脑上?手把手教你电脑键鼠玩手游...
  12. 贝叶斯数据分析_科研进阶项目 | 剑桥大学 | 心理学、社会学、生物医学:统计数据分析(6.13开课)...
  13. python字符串常用函数-Python字符串常用函数详解
  14. c语言程序设计爱心图片,c语言爱心图片表白程序源代码
  15. html5响应式的插件,Chocolat-jQuery响应式LightBox插件 -HTML5功能
  16. 作文素材:看完这23种蔬菜描写,恨不得穿过屏幕吃掉它们!
  17. oracle10g迁移到11g配置,Windows下Oracle10g32位迁移到11g64位
  18. RK3328启动失败解决记录
  19. 六个办公常用的网站,让你大开眼界的网站
  20. 985毕业,半路出家28岁进军Java,坚持了三年现如今年薪36W+,也不算辜负自己!

热门文章

  1. 关于Session的使用和优化
  2. nginx限流健康检查
  3. su: user tomcat does not exist
  4. Java研发方向如何准备BAT技术面试答案(上)
  5. JNI中的内存管理(转)
  6. 在线自动下载最新版本jquery
  7. keil之编辑环境配置
  8. 基于MapWinGis的开发探索(三)--改善缩放、渲染、显示文本
  9. 设置Windows 10时如何创建本地帐户
  10. php xxtea加密,php - esp32和php XXTEA字符串加密 - SO中文参考 - www.soinside.com