2016-03-22 4 views
5

Microsoft Azureサービスファブリックを初めて使用しました。私の修士号のために、私はサービスファブリックでマイクロサービスアプローチプロトタイプを開発しなければなりません。調査の時間がたっても、私はまだ私の問題を解決していません。ServiceProxy経由でステートレスサービスにアクセスできません+ ASP.NET 5 Web APIプロジェクトによって正常性状態エラーが発生します

https://azure.microsoft.com/en-us/documentation/articles/service-fabric-add-a-web-frontend/のように、Webフロントエンドで(展開されたローカルファブリッククラスタの)ステートレスサービスにアクセスしたいとします。そのための最も簡単な方法は、Service FabricアプリケーションにASP .NET 5 Web Apiプロジェクトを追加し、ValuesControllerServiceProxyメソッド呼び出しを行うことです。だから、私は解決策にこのコードを追加:

ValuesController.cs:

[Route("api/[controller]")] 
public class ValuesController : Controller 
{ 
    // GET api/values/IObject 
    [HttpGet("{interfaceName}")] 
    public async Task<string> Get(string interfaceName) 
    { 
    var serviceName = "fabric:/DataServiceFabric/MasterDataMService"; 
    var masterDataService = ServiceProxy.Create<IMasterDataMService>(new Uri(serviceName)); 
    var result = await masterDataService.GetMasterDataByName(interfaceName); 
    return result.Content; 
    } 
} 

を私のブラウザが自動的に自分のWebフロントエンドに移動していないF5は、配置した後。私のASP .NET 5アプリケーションは、健康状態のエラーをスローサービスファブリックExplorerに見ることによって:

Kind  Health State Description 
============================================================================= 
Partitions Error   Unhealthy partitions: 100% (1/1), MaxPercentUnhealthyPartitionsPerService=0%. 
Partition Error   Unhealthy partition: PartitionId='413...', AggregatedHealthState='Error'. 
Event  Error   Error event: SourceId='System.FM', Property='State'. Partition is below target replica or instance count. 

このthis質問の後「パーティションがターゲットレプリカまたはインスタンス数を下回っている」は、私の中にその未処理の例外を示し、サービスが起動しないようにしています。しかし、私はService Fabric Explorerでこの障害をデバッグするためにスタックstraceを見つけることができません。

ServiceManifest.xml(WEB1):

<?xml version="1.0" encoding="utf-8"?> 
<ServiceManifest xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="Web1" Version="1.0.0" xmlns="http://schemas.microsoft.com/2011/01/fabric"> 
    <ServiceTypes> 
     <StatelessServiceType ServiceTypeName="Web1Type"> 
     <Extensions> 
      <Extension Name="__GeneratedServiceType__"> 
       <GeneratedNames xmlns="http://schemas.microsoft.com/2015/03/fabact-no-schema"> 
        <DefaultService Name="Web1Service" /> 
        <ServiceEndpoint Name="Web1TypeEndpoint" /> 
       </GeneratedNames> 
      </Extension> 
     </Extensions> 
     </StatelessServiceType> 
    </ServiceTypes> 
    <CodePackage Name="C" Version="1.0.0"> 
     <EntryPoint> 
     <ExeHost> 
      <Program>approot\runtimes\dnx-clr-win-x64.1.0.0-rc1-update1\bin\dnx.exe</Program> 
      <Arguments>--appbase approot\src\Web1 Microsoft.Dnx.ApplicationHost Microsoft.ServiceFabric.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener</Arguments> 
      <WorkingFolder>CodePackage</WorkingFolder> 
      <ConsoleRedirection FileRetentionCount="5" FileMaxSizeInKb="2048" /> 
     </ExeHost> 
     </EntryPoint> 
    </CodePackage> 
    <Resources> 
     <Endpoints> 
     <Endpoint Name="Web1TypeEndpoint" Protocol="http" Type="Input" Port="80" /> 
     </Endpoints> 
    </Resources> 
</ServiceManifest> 

そして、ここに私の私のサービス・ファブリック・ソリューションのApplicationManifest.xml

ApplicationManifest.xmlこれは私のASP .NET Webサービスの私のServiceManifest.xmlです:

<?xml version="1.0" encoding="utf-8"?> 
<ApplicationManifest xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ApplicationTypeName="DataServiceFabricType" ApplicationTypeVersion="1.0.0" xmlns="http://schemas.microsoft.com/2011/01/fabric"> 
    <Parameters> 
     <Parameter Name="ActorTestServiceActorService_PartitionCount" DefaultValue="10" /> 
     <Parameter Name="MasterDataMService_InstanceCount" DefaultValue="-1" /> 
    </Parameters> 
    <ServiceManifestImport> 
    <ServiceManifestRef ServiceManifestName="Web2Pkg" ServiceManifestVersion="1.0.0" /> 
    <ConfigOverrides /> 
    </ServiceManifestImport> 
    <ServiceManifestImport> 
     <ServiceManifestRef ServiceManifestName="Web1" ServiceManifestVersion="1.0.0" /> 
    </ServiceManifestImport> 
    <ServiceManifestImport> 
     <ServiceManifestRef ServiceManifestName="ActorTestServicePkg" ServiceManifestVersion="1.0.0" /> 
    </ServiceManifestImport> 
    <ServiceManifestImport> 
     <ServiceManifestRef ServiceManifestName="MasterDataMServicePkg" ServiceManifestVersion="1.0.0" /> 
     <ConfigOverrides /> 
    </ServiceManifestImport> 
    <DefaultServices> 
     <Service Name="Web1Service"> 
     <StatelessService ServiceTypeName="Web1Type"> 
      <SingletonPartition /> 
     </StatelessService> 
     </Service> 
     <Service Name="ActorTestServiceActorService" GeneratedIdRef="761ee3cf-5a3a-49d8-9c57-aa3480d1acf1"> 
     <StatelessService ServiceTypeName="ActorTestServiceActorServiceType"> 
      <UniformInt64Partition PartitionCount="[ActorTestServiceActorService_PartitionCount]" LowKey="-9223372036854775808" HighKey="9223372036854775807" /> 
     </StatelessService> 
     </Service> 
     <Service Name="MasterDataMService"> 
     <StatelessService ServiceTypeName="MasterDataMServiceType" InstanceCount="[MasterDataMService_InstanceCount]"> 
      <SingletonPartition /> 
     </StatelessService> 
     </Service> 
    </DefaultServices> 
</ApplicationManifest> 

ASP.NET 5 Webアプリケーションと同じValuesController.csで新しいソリューションを作成しました。ステートレスサービスがローカルクラスタ上で実行されていることを保証し、私は新しいWebアプリケーションを開始しました。私のコントローラでGET-メソッドを呼び出した後、私は次の例外を得た:

Exception thrown: 'System.Fabric.FabricException' in mscorlib.dll 
Microsoft.AspNet.Hosting.Internal.HostingEngine: Information: Request finished in 0,2593ms 500 
Microsoft.AspNet.Server.Kestrel: Error: An unhandled exception was thrown by the application. 
System.Fabric.FabricException: Invalid partition key/ID '{0}' for selector {1} 

は私のステートレスサービスはSingletonPartitionあるので、私はここでは、パーティション・キーが必要なのでしょうか?はいの場合は、どうすれば鍵を入手できますか?サービスファブリックエクスプローラは、私のステートレスサービスに関するこの情報を私に提供しません。ここに私のステートレスサービスのServiceManifest.xmlです:

ServiceManifest.xml(MasterDataMService):

MasterDataMService:私はOWINとサービスの通信を設定することを決めた後

<?xml version="1.0" encoding="utf-8"?> 
<ServiceManifest Name="MasterDataMServicePkg" 
       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. --> 
    <StatelessServiceType ServiceTypeName="MasterDataMServiceType" /> 
    </ServiceTypes> 

    <!-- Code package is your service executable. --> 
    <CodePackage Name="Code" Version="1.0.0"> 
    <EntryPoint> 
     <ExeHost> 
     <Program>MasterDataMService.exe</Program> 
     </ExeHost> 
    </EntryPoint> 
    </CodePackage> 

    <!-- Config package is the contents of the Config directoy under PackageRoot that contains an 
     independently-updateable and versioned set of custom configuration settings for your service. --> 
    <ConfigPackage Name="Config" Version="1.0.0" /> 

    <Resources> 
    <Endpoints> 
     <!-- This endpoint is used by the communication listener to obtain the port on which to 
      listen. Please note that if your service is partitioned, this port is shared with 
      replicas of different partitions that are placed in your code. --> 
     <Endpoint Name="ServiceEndpoint" Type="Input" Protocol="http" Port="80"/> 
    </Endpoints> 
    </Resources> 
</ServiceManifest> 

。CS:

var client = new HttpClient(); 
var request = "http://localhost:80/MasterDataMService/api/values/query"; 
var result = string.Empty; 
HttpResponseMessage response = await client.GetAsync(request); 
if (response.IsSuccessStatusCode) 
{ 
    result = await response.Content.ReadAsStringAsync(); 
} 

しかし、私は元々望んでいないthatsの:

internal sealed class MasterDataMService : StatelessService, IMasterDataMService 
{ 
    [...]  

    protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners() 
    { 
    return new[] 
    { 
     new ServiceInstanceListener(initParams => new OwinCommunicationListener("MasterDataMService", new StartUp(), initParams)) 
    }; 
    } 
} 

今、私は私のDefaultControllerHttpClientを使用して、私のmicroserviceをアセスすることができます。私は私の要求でサービスエンドポイントを特定したくありません。代わりに、ServiceProxyで私の無国籍サービスと連絡したいと思います。ここではどのように達成するのですか?何が間違っていたのですか?また、サービスファブリッククラスタに展開されているASP .NET 5アプリケーションでこの正常性状態のエラーを解決するにはどうすればよいですか。

お時間をいただきありがとうございます。

編集:無効なパーティションキー例外の

拡張スタックトレース:

Exception thrown: 'System.Fabric.FabricException' in mscorlib.dll 
Microsoft.AspNet.Hosting.Internal.HostingEngine: Information: Request finished in 1,35ms 500 
Microsoft.AspNet.Server.WebListener.MessagePump: Error: ProcessRequestAsync 
System.Fabric.FabricException: Invalid partition key/ID '{0}' for selector {1} ---> System.Runtime.InteropServices.COMException: exception of HRESULT: 0x80071BBF 
    at System.Fabric.Interop.NativeClient.IFabricServiceManagementClient4.EndResolveServicePartition(IFabricAsyncOperationContext context) 
    at System.Fabric.FabricClient.ServiceManagementClient.ResolveServicePartitionEndWrapper(IFabricAsyncOperationContext context) 
    at System.Fabric.Interop.AsyncCallOutAdapter2`1.Finish(IFabricAsyncOperationContext context, Boolean expectedCompletedSynchronously) 
    --- End of inner exception stack trace --- 
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at Microsoft.ServiceFabric.Services.Client.ServicePartitionResolver.<ResolveAsyncHelper>d__2a.MoveNext() 
--- End of stack trace from the previous location where the exception was thrown --- 
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at Microsoft.ServiceFabric.Services.Communication.Client.CommunicationClientFactoryBase`1.<GetClientAsync>d__a.MoveNext() 

あなたがより多くを必要とする場合は、私にフィードバックをお願いします。

無効スキーム例外スタックトレース(フルスタックトレースは82行の長さである):

Exception thrown: 'System.ArgumentException' in mscorlib.dll 
Microsoft.AspNet.Hosting.Internal.HostingEngine: Information: Request finished in 1,45ms 500 
Microsoft.AspNet.Server.WebListener.MessagePump: Error: ProcessRequestAsync 
System.ArgumentException: the provided uri scheme 'http' is invalid; expected 'net.tcp'. 
Parametername: via 
    at System.ServiceModel.Channels.TransportChannelFactory`1.ValidateScheme(Uri via) 
    at System.ServiceModel.Channels.ConnectionOrientedTransportChannelFactory`1.OnCreateChannel(EndpointAddress address, Uri via) 
    at System.ServiceModel.Channels.ChannelFactoryBase`1.InternalCreateChannel(EndpointAddress address, Uri via) 
    at System.ServiceModel.Channels.ServiceChannelFactory.ServiceChannelFactoryOverDuplexSession.CreateInnerChannelBinder(EndpointAddress to, Uri via) 
    at System.ServiceModel.Channels.ServiceChannelFactory.CreateServiceChannel(EndpointAddress address, Uri via) 
    at System.ServiceModel.Channels.ServiceChannelFactory.CreateChannel(Type channelType, EndpointAddress address, Uri via) 
    at System.ServiceModel.DuplexChannelFactory`1.CreateChannel(InstanceContext callbackInstance, EndpointAddress address, Uri via) 
    at System.ServiceModel.DuplexChannelFactory`1.CreateChannel(InstanceContext callbackInstance, Binding binding, EndpointAddress endpointAddress) 
    at Microsoft.ServiceFabric.Services.Communication.Wcf.Client.WcfCommunicationClientFactory`1.<CreateClientAsync>d__2.MoveNext() 
--- End of stack trace from the previous location where the exception was thrown --- 
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at Microsoft.ServiceFabric.Services.Communication.Client.CommunicationClientFactoryBase`1.<CreateClientWithRetriesAsync>d__1e.MoveNext() 
+0

に役立ちます願っていますが、1つのパーティションを持っている場合、それは問題ではないはずです。 – Mikhail

+0

無効なパーティションキー例外のスタックトレースには他のものがありますか?シングルトンパーティションスキームを使用するサービスのパーティションキーを指定する必要はありません。ステートレスサービスのように、エラーが奇妙に見えることがあります。 –

+0

@Mikhail私の 'ActorTestServiceActorService'のようなを指定し、 'ServiceProxy'を使って私のマイクロサービスに話をすると、** System.ArgumentExceptionが発生します:**提供されたURIスキーム 'http'は無効です。期待されるネット。tcp'_ – MegaMax

答えて

0

私は、これらの同じイライラの問題の中に自分自身を実行し、それらを解決しました。

物事のカップル

1をチェックするためには)あなたのASP.NET 5ウェブAPIプロジェクトは、任意のX64ライブラリを参照していないことを確認します。

2)ポートクラッシュASPNET 5 Web APIをクラスタに展開する場合、同じポートを使用している2つのWebサイトがないことを確認してください。あなたは[ASP.NET 5プロジェクト] /PackageRoot/ServiceManifest.xml内のポートを下に向かって変更することができます

** 3) "wrap" folder madness!ラップフォルダ(ルートソリューションフォルダの)には、.net 4.5.1クラスライブラリのみが含まれていることを確認します。 wrapフォルダ内の "Newtonsoft.Json"フォルダを削除すると、私の問題は解決しました。これで、project.lock.jsonファイルを再作成するようにdnu restoreを実行する必要があります。

4)startup.csクラス内に何も吹き飛ばされていないことを確認してください。ウェブAPIをローカルで実行するだけで、ロードが確実に行われます。通常はサービスプロキシクラスがロードに失敗することがあります。あなたはHTTPエンドポイントでリッスンしているサービスに接続するためにServiceProxyを使用しようとしているように見えます

System.ArgumentException: the provided uri scheme 'http' is invalid; expected 'net.tcp'. 

:2番目のスタックトレースから判断

+0

ご迷惑をおかけいたします...あなたのサービスが準備完了状態(緑色)であると仮定してこのコメントを書きました...あなたのサービスはこれを表示していますか? InBuildを表示していますか? –

+0

はい、私のステートレスサービスは準備完了状態です。ご回答有難うございます。 ** 1)**私のweb apiプロジェクトの特定ランタイムをx64からx86に変更しました。しかし、どのリファレンスがx64ライブラリを必要としているかを正しく調べる方法を見つけることができませんでした。 ** 2)**私は特定のポートを削除しました** 3)**これは私のために働いた。正常性状態のエラーはなくなり、Web APIにナビゲートできます。 ** 4)**私はstartup.csをF5-deployでデバッグしたところ、すべて正しいと思われます。それとも私は何かが恋しい? – MegaMax

0

。 ServiceProxyは、HTTPではなくバイナリプロトコルを使用するService Remoting Listenerを必要とします。

最初の例外は、まだ謎のビットです:

System.Fabric.FabricException: Invalid partition key/ID '{0}' for selector {1} 

パーティションキーを設けることなく、均一なint64型または名前付きパーティションサービスを解決しようとした場合にのみ発生します。あなたの設定では、ターゲットサービスがシングルトンパーティションとして設定されているように見えます。この場合、このエラーは表示されません。したがって、接続しようとしているサービスが実際にシングルトンパーティションとして作成されたことを再確認できますサービス?

+0

これは、ServiceProxyがバイナリプロトコルを予期していることを知っていることです。しかし、なぜServiceManifestのエンドポイントのプロトコルがhttpに指定されているのですか? (申し訳ありませんが、これは間違った質問です)はい、サービスはシングルトンパーティションサービスです。私のソースコードの編集中にpartion 0を呼び出すまでに終了しました。私はそれを正しいオーバーロードに変更しました。私も自分のOWIN-Listenerを削除しなければならず、代わりに 'ServiceRemotingListener'を返しました(誤ったプロトコルのため)。 OWIN-Listenerを持って、同時にServiceProxy経由でサービスにアクセスすることはできないと思いますか? – MegaMax

3

はじめの例では、ServiceUriBuilderクラスがあります。このクラスを初期化するには、コンストラクタにサービス名を渡します。あなたのMasterDataMService CreateServiceInstanceListeners方法でも

var proxyLocation = new ServiceUriBuilder("MasterDataMService"); 
var masterDataService = ServiceProxy.Create<IMasterDataMService>(proxyLocation.ToUri()); 

var result = await masterDataService.GetMasterDataByName(interfaceName); 

、それはこのようなものに見えることを確認してください:私はステートレスサービスとServiceProxyを使用して、正確に同じ問題に走った

protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners() 
    { 
     return new[] { new ServiceInstanceListener(context => new FabricTransportServiceRemotingListener(context, this)) }; 
    } 
+0

独自の 'ServiceRemotingListener'実装の代わりに' return new [] {新しいServiceInstanceListener(context =>新しいServiceRemotingListener (コンテキスト、this))};を使用するのと同じですか?私はここで自分で何が実現できるのか分かりません。 – MegaMax

2

を。私はうまく機能ステートフル・サービスを持っていますが、ステートレスは、受信した

の代わりに:

System.Fabric.FabricException: Invalid partition key/ID '{0}' for selector {1} 

アランTは、上記に言及したように、あなたもServiceProxy.Create()のための第三のコンストラクタのオーバーロードを使用する必要があります:

ServiceProxy.Create<IMasterDataMService>(0, new Uri("fabric:/DataServiceFabric/MasterDataMService")); 

使用:

ServiceProxy.Create<IMasterDataMService>(new Uri("fabric:/DataServiceFabric/MasterDataMService")); 

...単純に、指定しないでくださいパーティション。それはエラーが私のために消えた。

https://msdn.microsoft.com/en-us/library/mt628402.aspx

+0

私は自分のソースコードで行った編集全体を通して、パーティション0で 'Create()'を呼び出そうとしていました。パーティションを指定せずに適切なオーバーロードに変更しました。私はOWIN-Listenerを削除して、それを 'return new [] {new ServiceInstanceListener(context =>新しいServiceRemotingListener )}}に置き換えなければなりませんでした}' – MegaMax

+1

私の問題はまったく反対でした。私はパーティション番号を1と指定するまで動作しません。なぜ誰かがアイデアを持っていますか? – kamilk

4

サービスファブリックについて学びながら、私は同じ問題に遭遇しました。ちょうどURIを提供することが十分ではなかったことが判明 - 私はまた1の魔法の値として、パーティションキーを指定する必要がありました:

IHelloService service = ServiceProxy.Create<IHelloService>(new Uri("fabric:/Application1/HelloService"), new ServicePartitionKey(1)); 

賛辞をthis thread on disq.usに。

Diogo, take a look at this article that explains partitioning: link Specifically, look at ranged partitioning (otherwise known as UniformInt64Partition): "This is used to specify an integer range (identified by a low key and high key) and a number of partitions (n). It creates n partitions, each responsible for a non-overlapping subrange of the overall partition key range. For example, a ranged partitioning scheme with a low key of 0, a high key of 99, and a count of 4 would create four partitions, as shown below." Then look at your service manifest and figure out how it is configured - how many partitions and what is the range (low key - high key). If you have one partition, any key in that range goes to the (one) partition, so it doesn't matter which key you specify. If you have more than one partition, you need to figure out with which one your client needs to talk to. Specify a partition key in the range that partition is serving.

私は私自身がこの説明を理解することがより深くパーティショニングを勉強しなければならないことを認めなければならない:1つの作品の値は理由として、MicrosoftのエンジニアのOanaプラトンが提供するより深い説明もあります。

0

私の場合、上記のどれもうまくいきませんでした。まず、確認してください私は私のサービスを登録しています:

protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners() 
    { 
     return new[] { new ServiceReplicaListener(context => this.CreateServiceRemotingListener(context)) };} 

そして第二に、非常に参照するか、より正確には、私の解決策は、私は2つのことを行うために必要な上記の解決策

の組み合わせ/バリエーションました最初のサービス(0の「魔法」の値)

 ServiceProxy.Create<IMasterDataMService>(new Uri("fabric:/DataServiceFabric/MasterDataMService"), new ServicePartitionKey(0)); 

私はあなたが任意のパーティション・キーを指定することができ、これは

関連する問題