所以,要让它正常工作真是一件痛苦的事。但它有效。嗯,有点。
首先,Reliable Services 在 Linux 上仍处于预览状态: https://github.com/Microsoft/service-fabric/issues/71 https://github.com/Microsoft/service-fabric/issues/71
完整的 Linux 支持应该很快就会到来(实际上它应该可用already根据前面的链接...)。
现在,关于如何进行的详细信息,这里有一些可以帮助其他人的信息,因为 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>
有趣的是,你should能够使用提供多个 RIDRuntimeIdentifiers
参数(带有S在最后)就像这样:
<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 https://github.com/dotnet/core/issues/1039
3. 您的服务需要一个有效的入口点。
在 Windows 上,它是一个可执行文件 (*.exe)。在 Linux 上则不然。我最终获得了 Linux C# 示例并复制/粘贴了入口点。https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-create-your-first-linux-application-with-csharp https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-create-your-first-linux-application-with-csharp
所以基本上我现在有ServiceManifest.xml
每个 Reliable Service 的文件如下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/sdk/issues/1502快一年了还没修好...
Or https://github.com/dotnet/core/issues/977 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 相关项目,因此您需要自己构建所有内容。
上面的脚本生成的内容与pkg
构建时由 MSBuild 创建的文件夹sfproj
使用 Visual Studio。它将所有内容复制到PKG
解决方案根目录下的文件夹。
包结构详细说明如下:https://github.com/MicrosoftDocs/azure-docs/blob/master/articles/service-fabric/service-fabric-package-apps.md 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
并部署到您的 Service Fabric 集群。
所以你指定了两者的权限值PublishProfiles/Cloud.xml
and ApplicationParameters/Cloud.xml
然后执行脚本。
当然,只有当您拥有用于保护计算机上安装的集群的证书时,它才有效。请注意第一个点“.”很重要,因为如果不使用它,将会出现以下错误:
Get-ServiceFabricClusterManifest:集群连接实例为空
See https://stackoverflow.com/a/38104087/870604 https://stackoverflow.com/a/38104087/870604
哦,由于 Service Fabric SDK 上也存在错误,您可能也想关闭本地 SF 集群...https://github.com/Azure/service-fabric-issues/issues/821 https://github.com/Azure/service-fabric-issues/issues/821
7. 现在是时候进行另一次欺骗了。
它根本不起作用,服务在启动时崩溃。在里面搜索了几个小时后LinuxsyslogVer2v0
Azure 存储表(Linux 的日志表,位于使用 SF 集群自动创建的两个 Azure 存储帐户之一),我发现 Microsoft 自己的 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 包中。糟糕的经历。但它是受支持的(目前处于预览版)并且您可以使其工作。希望这篇文章能有所帮助...