Linux server CPU architecture can be divided into X86_64/AMD64 and ARM64/AARCH64. Most servers are based on the AMD64 CPU architecture. However, with the domestic operating system, CPU and other self-developed application products gaining more and more user recognition and application, such as: Servers like Huawei Kunpeng and TONGxin UOS are constantly purchased and used, and they all use ARM64 CPU architecture. Therefore, if.net programs need to run in more domestic servers, adapting ARM64 CPU architecture will be the first step.

This article is not intended to be a simple Demo, but rather a share of experience based on a larger project adapting the ARM64 architecture.

The general background of the project is as follows:

  • Microservices architecture system based on multiple.net Core services
  • Based on thegRPCImplementation of microservice applications
  • Based on mainstream middleware, such as:Mongodb,Redis,Kafka,Zookeeper

When I proposed that the whole project should support the deployment in ARM64 CPU architecture server, I didn’t have too much concern, because.NET Core is inherent in cross-platform ability, so I found a random service to test, but it was immediately rejected and couldn’t run. Then I suspected that there was something wrong with the runtime environment. I tried to reinstall the.NET Core SDK for several times and tested several versions, but still failed. After some research and confirmation, there are mainly the following three problems:

  1. Confluent.Kafka: Confluent.Kafka: Confluent.Kafka: Confluent.

    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()Copy the code

    The problem is that librdkafka.so, which is required to run in linux-arm64, is not included in the distribution code. The solution is actually relatively simple because the Confluent.Kafka NuGet package version referenced in our project is relatively low. Linux-arm64 support is included in older versions, so simply upgrade the project base package that references Confluent.kafka and then upgrade the base package for the related services.

  2. Grpc.Core (Grpc Core implementation) is loaded when the service is started.

    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)Copy the code

    Libgrpc_csharp_ext.x64. So libgrpc_csharp_ext.x64. So libgrpc_csharp_ext.x64. There is obviously no linux-arm64 equivalent either. Unlike Confluent.Kafka, there is no intention to support it by default, only that it can be compiled from source code if needed. Grpc.Core is replaced by dotnet-grpc. Dotnet-grpc is a Grpc extension officially released with.net Core 3.0. There is no dependency on additional runtime files, but the time cost of switching to dotnet-grpc is relatively high (although this path seems to come later, GRPC’s future in C# belongs to grpc-dotnet), so self-compilation is the current option.

    The following is compiled on a server based on the Debian ARM64 CPU architecture.

    Install base dependency components

    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
    Copy the code

    Pull GRPC source code (project currently using V1.22.1)

    Git clone - b v1.22.1 CD GRPC # https://github.com/grpc/grpc for dependent child module git submodule update - initCopy the code

    compile

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

    Get libgrpc_csharp_ext. So

    cp libgrpc_csharp_ext.so .. /.. /.. /libgrpc_csharp_ext.x86.so cp libgrpc_csharp_ext.so .. /.. /.. /libgrpc_csharp_ext.x64.soCopy the code

    Libgrpc_csharp_ext.x64. So, libgrpc_csharp_ext.x64. So, libgrpc_csharp_ext.x64.

  3. ASP.NET Core Runtime 2.2.x ARM64 is not available

    First of all, 3.1 is the LTS version, and provides the runtime corresponding to ARM64. In addition, there are not many residual services based on 2.2 because of the previous upgrade. Of course, the whole upgrade process still needs to be cautious. See: Migration from ASP.NET Core 2.2 to 3.0 and from ASP.NET Core 3.0 to 3.1.

The above are mainly.net Core service ADAPTS ARM64 server deployment encountered some problems, but different projects still face different situations, after solving the problem, so far everything is ok. Of course, this does not include other ancillary components, such as MySQL to MariaDB, etc.