所以,让它正常工作真的很痛苦。但它有效。嗯,有点。
首先,Reliable Services 在 Linux 上仍处于预览阶段: https ://github.com/Microsoft/service-fabric/issues/71
完整的 Linux 支持应该很快就会到来(实际上它应该已经根据之前的链接可用......)。
现在有关如何进行的详细信息,这里有一些信息可以帮助其他人,因为在 Microsoft 文档中没有任何内容,我实际上浪费了 3 天的时间试图让它工作。
1. 为您的项目使用 .NET Core 2.0。
它在 Linux 上受支持。目前处于预览状态,但它可以工作。
2. 为您的项目使用正确的 RID。
截至今天(2018 年 4 月),要使用的正确 RID 是ubuntu.16.04-x64
. 编辑csproj
Reliable Service 项目的文件并像这样设置 RID:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
<IsServiceFabricServiceProject>True</IsServiceFabricServiceProject>
<RuntimeIdentifier>ubuntu.16.04-x64</RuntimeIdentifier>
<Platforms>AnyCPU;x64</Platforms>
</PropertyGroup>
有趣的是,您应该能够使用参数(末尾RuntimeIdentifiers
带有S )提供多个 RID,如下所示:
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
<IsServiceFabricServiceProject>True</IsServiceFabricServiceProject>
<RuntimeIdentifiers>win7x64;ubuntu.16.04-x64</RuntimeIdentifiers>
<Platforms>AnyCPU;x64</Platforms>
</PropertyGroup>
因此,您可以同时构建 Windows 二进制文件和 Linux 二进制文件。但它根本行不通。从 Visual Studio 构建项目时,我最终只得到以下目录:
bin/Debug/netcoreapp2.0/
只有 DLL,没有有效的入口点。没有win7-x64
文件夹,没有ubuntu.16.04-x64
,什么都没有。这是一个应该修复的错误,但事实并非如此(我使用的 Visual Studio 15.6.2 都是最新的)。见https://github.com/dotnet/core/issues/1039
3. 您的服务需要一个有效的入口点。
在 Windows 上,它是一个可执行文件 (*.exe)。在 Linux 上不是。我最终得到了 Linux C# 示例并复制/粘贴了入口点。https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-create-your-first-linux-application-with-csharp
所以基本上我现在在ServiceManifest.xml
每个可靠服务的文件中都有以下内容EntryPoint
:
<?xml version="1.0" encoding="utf-8"?>
<ServiceManifest Name="XXXX"
Version="1.0.0"
xmlns="http://schemas.microsoft.com/2011/01/fabric"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ServiceTypes>
<!-- This is the name of your ServiceType.
This name must match the string used in RegisterServiceType call in Program.cs. -->
<StatefulServiceType ServiceTypeName="YYY" HasPersistedState="true" />
</ServiceTypes>
<!-- Code package is your service executable. -->
<CodePackage Name="Code" Version="1.0.0">
<EntryPoint>
<ExeHost>
<Program>entryPoint.sh</Program>
</ExeHost>
</EntryPoint>
</CodePackage>
entryPoint.sh
如下:
#!/usr/bin/env bash
check_errs()
{
# Function. Parameter 1 is the return code
if [ "${1}" -ne "0" ]; then
# make our script exit with the right error code.
exit ${1}
fi
}
DIR=`dirname $0`
echo 0x3f > /proc/self/coredump_filter
source $DIR/dotnet-include.sh
dotnet $DIR/NAME_OF_YOUR_SERVICE_DLL.dll $@
check_errs $?
dotnet-include.sh
如下:
#!/bin/bash
. /etc/os-release
linuxDistrib=$ID
if [ $linuxDistrib = "rhel" ]; then
source scl_source enable rh-dotnet20
exitCode=$?
if [ $exitCode != 0 ]; then
echo "Failed: source scl_source enable rh-dotnet20 : ExitCode: $exitCode"
exit $exitCode
fi
fi
两者都在PackageRoot
文件夹内。我为它们的两个属性指定了Build Action
is " Content
" 和Copy to Output Directory
is " Copy always
"。

4. 不要使用 MSBuild 构建!
是的,它也应该构建 Linux 包,或者至少看起来如此,因为当您右键单击项目并单击“构建”时,MSBuild 能够生成以下文件:

不要相信操作的表面上的成功,它会在部署时无法正确执行。一些*.so
文件丢失和其他问题。MSBuild 是错误的,并且在依赖项方面行为不端。
例如,请参阅此错误报告:https ://github.com/dotnet/sdk/issues/1502
近一年后仍未修复...
或https://github.com/dotnet/core/issues/977(也有这个)。
5. 自己编写一些 PowerShell 脚本来构建这些东西。
我最终使用以下脚本重新发明了轮子来构建我的包:
# Creating binaries for service 1
cd DIRECTORY_OF_MY_SERVICE_1
dotnet publish -c Release -r ubuntu.16.04-x64
# Creating binaries for service 2
cd ..\DIRECTORY_OF_MY_SERVICE_2
dotnet publish -c Release -r ubuntu.16.04-x64
# Creating binaries for service 3
cd ..\DIRECTORY_OF_MY_SERVICE_3
dotnet publish -c Release -r ubuntu.16.04-x64
# Copying ApplicationManifest.xml
cd ..
mkdir PKG\ServiceFabricApplication
echo F|xcopy "ServiceFabricApplication\ApplicationPackageRoot\ApplicationManifest.xml" "PKG\ServiceFabricApplication\ApplicationManifest.xml" /sy
# Copying Service1 files
mkdir "PKG\ServiceFabricApplication\Service1Pkg"
mkdir "PKG\ServiceFabricApplication\Service1Pkg\Code"
xcopy "Service1\PackageRoot\*" "PKG\ServiceFabricApplication\Service1Pkg" /sy /D
xcopy "Service1\bin\Release\netcoreapp2.0\ubuntu.16.04-x64\publish\*" "PKG\ServiceFabricApplication\Service1Pkg\Code" /sy
# Copying Service2 files
mkdir "PKG\ServiceFabricApplication\Service2Pkg"
mkdir "PKG\ServiceFabricApplication\Service2Pkg\Code"
xcopy "Service2\PackageRoot\*" "PKG\ServiceFabricApplication\Service2Pkg" /sy /D
xcopy "Service2\bin\Release\netcoreapp2.0\ubuntu.16.04-x64\publish\*" "PKG\ServiceFabricApplication\Service2Pkg\Code" /sy
# Copying Service3 files
mkdir "PKG\ServiceFabricApplication\Service3Pkg"
mkdir "PKG\ServiceFabricApplication\Service3Pkg\Code"
xcopy "Service3\PackageRoot\*" "PKG\ServiceFabricApplication\Service3Pkg" /sy /D
xcopy "Service3\bin\Release\netcoreapp2.0\ubuntu.16.04-x64\publish\*" "PKG\ServiceFabricApplication\Service3Pkg\Code" /sy
# Compresses the package
Write-host "Compressing package..."
Copy-ServiceFabricApplicationPackage -ApplicationPackagePath .\PKG\ServiceFabricApplication -CompressPackage -SkipCopy
sfproj
文件是 Visual Studio / MSBuild 相关的项目,所以您需要自己构建所有内容。上面的脚本生成的内容与使用 Visual Studiopkg
构建时由 MSBuild 创建的文件夹相同。sfproj
它将所有内容复制PKG
到解决方案根目录的文件夹中。
此处详细介绍了包结构:https ://github.com/MicrosoftDocs/azure-docs/blob/master/articles/service-fabric/service-fabric-package-apps.md
6. 现在是部署的时候了!
此时我不再信任 Visual Studio,因此我构建了自己的 PowerShell 脚本:
. .\ServiceFabricApplication\Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath '.\PKG\ServiceFabricApplication' -PublishProfileFile '.\ServiceFabricApplication\PublishProfiles\Cloud.xml' -DeployOnly:$false -ApplicationParameter:@{} -UnregisterUnusedApplicationVersionsAfterUpgrade $false -OverrideUpgradeBehavior 'None' -OverwriteBehavior 'SameAppTypeAndVersion' -SkipPackageValidation:$false -ErrorAction Stop
它在项目内重用Deploy-FabricApplication.ps1
Service Fabric 项目模板提供的脚本sfproj
。此脚本解析Cloud.xml
PublishProfile
并部署到您的服务结构集群。
因此,您指定两者的权限值PublishProfiles/Cloud.xml
,ApplicationParameters/Cloud.xml
然后执行脚本。
当然,只有在您的机器上安装了用于保护集群的证书时,它才有效。
请注意第一个点“。” 很重要,因为如果您不使用它,您将遇到以下错误:
Get-ServiceFabricClusterManifest:集群连接实例为空
见https://stackoverflow.com/a/38104087/870604
哦,由于 Service Fabric SDK 也存在错误,您可能也想关闭本地 SF 集群...
https://github.com/Azure/service-fabric-issues/issues/821
7. 现在是另一个欺骗的时候了。
它根本不起作用,服务在启动时崩溃。在LinuxsyslogVer2v0
Azure 存储表(Linux 的日志表,位于使用 SF 集群自动创建的两个 Azure 存储帐户之一)中搜索了几个小时后,我发现微软自己的 Nuget 包也有问题。
具体来说,Nuget 包Microsoft.Azure.Devices
不适用于 1.6.0 版。未找到 dll 的引用或其他问题。我回滚到以前的版本,即 1.5.1,它已被修复。
在这一点上,我没有精力再为此创建另一个 Github 问题。对不起 MS,我不是你的 QA 团队,我累了。
8. 使用第一个 PowerShell 脚本再次构建,使用第二个 PowerShell 脚本进行部署,就完成了。
您终于使用 .NET Core 2.0 从 Windows 上的 Visual Studio(有点,因为它有问题,我使用了 PowerShell)将 C# Reliable Services 部署到 Linux SF 集群。
现在我的 ASP.NET Core 服务仍然存在问题,但这将是另一天的故事。
结论:TL;DR
整个事情是一团糟。到处都是虫子。在 SDK 中,在工具中,在一些 Microsoft Nuget 包中。糟糕的经历。但它受支持(目前处于预览状态),您可以使其工作。希望这篇文章会有所帮助...