Service Fabric 服务远程处理

Service Fabric Service Remoting

过去几周我一直在从云服务迁移到 Service Fabric,并且 运行 在两个服务之间使用远程处理遇到了一些绊脚石。

我一直在使用有关服务远程处理的官方文档和示例代码,特别是我正在尝试让此处概述的示例正常工作:

https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-reliable-services-communication-remoting

我有 2 项服务。一个名为 "RemoteService",另一个名为 "CallerService"。两者都派生自默认的无状态服务项目。

"RemoteService""CallerService" 项目中,我添加了以下接口来描述服务他们之间的合同:

public interface IMyService : IService
{
    Task<string> HelloNameAsync(string name);
}

"RemoteService" 中,我在 RemoteService class

中创建了关联方法
public Task<string> HelloNameAsync(string name)
{
    return Task.FromResult("Hello " + name + "!");
}

我还用以下

覆盖了CreateServiceInstanceListeners
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
    return new[] { new ServiceInstanceListener(context => this.CreateServiceRemotingListener(context)) };
}

在我的 "CallerService" 中,当我尝试连接时,使用以下内容调用 "RemoteService":

IMyService helloNameClient = ServiceProxy.Create<IMyService>(new Uri("fabric:/Application/RemoteService"));
string message = await helloNameClient.HelloNameAsync("Luke");

我得到这个异常

InnerException = {"Interface id '1994370306' is not implemented by object 'RemoteService.RemoteService'"}

我已经用细齿梳仔细检查了这个样本,并确信我已经把所有东西都准备好了。我已经阅读了有关设置端点并将您的服务注册到服务目录的信息,但据我了解,这些是针对外部服务的,远程处理文档没有提到需要这样做。

更新:

RemoteService class 的声明方式如下:

internal sealed class RemoteService : StatelessService, IMyService

更新 2

以下是两种服务的 Settings.xml 外观。这些是项目开箱即用的默认设置。我没有添加或删除任何东西。我还想指出,我 运行 所有这些都在我的本地服务结构上。

<?xml version="1.0" encoding="utf-8" ?>
<Settings xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2011/01/fabric">
  <!-- Add your custom configuration sections and parameters here -->
  <!--
  <Section Name="MyConfigSection">
    <Parameter Name="MyParameter" Value="Value1" />
  </Section>
  -->
</Settings>

声明服务接口的程序集需要与客户端共享,您不能在客户端重新创建相同的接口。当 Service Fabric 设置通信时,它会构建接口的映射以及服务使用的实际程序集中的方法。

根据您的描述,您似乎在服务项目和客户端项目中声明了相同的接口?如果是这样,那么这就是解决方法。

来自: 唯一棘手的部分是如何获得从外部服务到调用服务的接口?您可以简单地为您希望调用的服务引用内置的 .exe,或者您可以将包含接口的程序集打包为 NuGet 包并放在私有源上。

如果您不这样做,而只是在 Visual Studio 解决方案之间共享代码,Service Fabric 会认为这是两个不同的接口,即使它们共享完全相同的签名。如果你为一个服务做它,你会得到一个 NotImplementedException 说 "Interface id '{xxxxxxxx}' is not implemented by object '{service}'" 如果你为一个 Actor 做它你会得到一个 KeyNotfoundException 说 "No MethodDispatcher is found for interface id '-{xxxxxxxxxx}'".

因此,要解决您的问题,请确保您在调用的外部应用程序中引用了您要调用的应用程序中的同一程序集。