[英]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.