[英]Deploy a C# Stateful Service Fabric application from Visual Studio to Linux
编辑04/06/18 =>更新了上次状态的问题
所以我有这个工作.Net 4.6状态服务,目前在我部署在Azure上的Windows Service Fabric集群上运行。
从2017年9月开始,我应该可以转到Linux: https ://blogs.msdn.microsoft.com/azureservicefabric/2017/09/25/service-fabric-6-0-release/
所以我试图在Linux上部署它,这样我就可以节省成本。
首先,我将所有代码从.Net 4.6迁移到.Net Core 2.0。 现在我可以毫无问题地编译我的二进制文件。 我基本上创建了新的.Net Core项目,然后将我的所有源代码从.Net 4.6项目移动到新的.Net Core项目。
然后我更新了我的Service Fabric应用程序。 我从我的sfproj中删除了以前的SF服务,然后我添加了新的.Net Core服务。
看起来有一个警告(虽然输出窗口上没有任何内容),但无论如何,如果我尝试通过Service Fabric Tools 2.0(beta)提供的模板使用.Net core 2.0创建一个新的空Statful服务,它就在这里:
所以我会忍受它。
runtimeIdentifier
。 在我的Windows机器上本地运行我的SF群集很好。
runtimeIdentifier
。 我还更改了ServiceManifest.xml文件以定位与linux兼容的二进制文件:
<!-- Code package is your service executable. -->
<CodePackage Name="Code" Version="1.9.6">
<EntryPoint>
<ExeHost>
<Program>entryPoint.sh</Program>
</ExeHost>
</EntryPoint>
</CodePackage>
entryPoint.sh
是最终执行的基本脚本:
dotnet $DIR/MyService.dll
错误事件:SourceId ='System.Hosting',Property ='CodePackageActivation:Code:EntryPoint'。 CodePackage激活期间出错。服务主机以退出代码终止:134
看起来我的二进制文件在启动时崩溃了。 所以这是我的问题:
编辑 :查看LinuxsyslogVer2v0表,我收到以下错误:
starthost.sh [100041]:未处理的异常:System.IO.FileLoadException:无法加载文件或程序集'System.Threading.Thread,Version = 4.1.0.0,Culture = neutral,PublicKeyToken = b03f5f7f11d50a3a'。 定位的程序集的清单定义与程序集引用不匹配。 (HRESULT异常:0x80131040)
我发现了以下错误报告: https : //github.com/dotnet/sdk/issues/1502不幸的是,我仍然在不使用MSBuild(使用dotnet deploy
)的情况下得到错误。
编辑 :进一步澄清:
所以,为了让它正常工作,这是一个真正的痛苦。 但它的确有效。 好吧,有点儿。
首先,Reliable Services仍然在Linux上进行预览: https : //github.com/Microsoft/service-fabric/issues/71
完整的Linux支持应该很快就会到来(实际上它应该已经根据之前的链接提供了......)。
现在有关如何处理的详细信息,这里有一些信息可以帮助其他人,因为在Microsoft文档上没有任何关于它的信息,而且我确实在3天内试图让它工作。
它在Linux上受支持。 现在预览,但它的工作原理。
截至今天(2018年4月),使用的正确RID是ubuntu.16.04-x64
。 编辑Reliable Service项目的csproj
文件,并将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
在Windows上,它是一个可执行文件(* .exe)。 在Linux上它不是。 我最终获得了Linux C#示例并复制/粘贴了入口点。 https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-create-your-first-linux-application-with-csharp
所以基本上我现在在每个Reliable Service的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
是“ Content
”, Copy to Output Directory
是“ Copy always
”。
是的,它也应该构建Linux软件包,或者至少看起来如此,因为当您右键单击项目并单击“构建”时,MSBuild能够生成以下文件:
不要相信操作的明显成功,在部署时将很难正确执行。 一些*.so
文件丢失和其他问题。 MSBuild是关于依赖关系的地狱和行为不端的错误。
例如,请参阅此错误报告: https : //github.com/dotnet/sdk/issues/1502近一年后仍未修复...
或者https://github.com/dotnet/core/issues/977 (也有这个)。
我最后使用以下脚本重新发明轮子来构建我的包:
# 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相关的项目,因此您需要自己构建所有内容。 上面的脚本生成的内容与MSBuild在使用Visual Studio构建sfproj
时创建的pkg
文件夹相同。 它将所有内容复制到解决方案根目录下的PKG
文件夹中。
包结构详见: https : //github.com/MicrosoftDocs/azure-docs/blob/master/articles/service-fabric/service-fabric-package-apps.md
此时我不再信任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
它重用sfproj
项目中Service Fabric项目模板提供的Deploy-FabricApplication.ps1
脚本。 此脚本解析Cloud.xml
PublishProfile
并部署到服务结构集群。
因此,您在PublishProfiles/Cloud.xml
和ApplicationParameters/Cloud.xml
上指定权限值,然后执行该脚本。
只有当您拥有用于保护计算机上安装的群集的证书时,它才有效。 请注意第一个点'。' 很重要,因为如果你不使用它,你将有以下错误:
Get-ServiceFabricClusterManifest:群集连接实例为空
请参阅https://stackoverflow.com/a/38104087/870604
哦,因为Service Fabric SDK上也有bug,你可能也想关闭你的本地SF集群... https://github.com/Azure/service-fabric-issues/issues/821
它根本不起作用,服务在启动时崩溃。 在LinuxsyslogVer2v0
Azure存储表(Linux的日志表,位于使用SF集群自动创建的两个Azure存储帐户之一)中搜索数小时后,我发现微软自己的Nuget软件包也有错误。
具体来说,Nuget包Microsoft.Azure.Devices
在1.6.0版本上不起作用。 引用未找到的DLL或其他问题。 我回滚到以前的版本,即1.5.1,它已修复。
在这一点上,我没有更多的精力来创建另一个Github问题。 对不起MS,我不是你的QA团队,我累了。
您最终使用Visual Studio中的.NET Core 2.0(因为它有问题而我使用PowerShell)在Windows上部署了C#Reliable Services到Linux SF Cluster。
现在我的ASP.NET核心服务仍然存在问题,但它将成为另一天的故事。
整件事情一团糟。 到处都是虫子。 在SDK中,在工具中,在一些Microsoft Nuget包中。 糟糕的经历。 但它支持(现在预览),你可以使它工作。 希望这篇文章能有所帮助......
我有类似的问题,但我相信这是问题所在:
在此版本中,仅在Service Fabric for Windows上支持.NET Core 2.0服务。 Windows和Linux上对.NET Core 2.0服务的完全跨平台支持即将推出。
从Service Fabric 6.1发行说明 ,只要您的目标是.net core 2.0,就没有Linux。
通过此帮助,我已成功部署到Linux服务结构
打开所有服务.csproj文件并更新RuntimeIdentifier,如下所示
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
<IsServiceFabricServiceProject>True</IsServiceFabricServiceProject>
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
</PropertyGroup>
更新ServiceManifest.xml以删除.exe扩展名,如下所示
<CodePackage Name="Code" Version="1.0.0">
<EntryPoint>
<ExeHost>
<Program>Web1</Program>
</ExeHost>
</EntryPoint>
</CodePackage>
* Visual Studio 15.7.3
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.