Azure service fabric 从群集中的其他应用程序调用服务

Azure service fabric 从群集中的其他应用程序调用服务,azure-service-fabric,Azure Service Fabric,在服务结构集群中,是否可以从一个应用程序向另一个应用程序调用服务或参与者?当我尝试(使用具有适当Uri的ActorProxy.Create)时,我得到一个“找不到接口的MethodDispatcher”是的,这是可能的。只要您对服务(或ActorService)具有正确的Uri,并且您可以通过定义服务或参与者的接口访问程序集,那么它应该与从同一应用程序中调用服务/参与者没有太大区别。如果有,那么您还必须为exchange设置证书 如果我有一个简单的服务定义为: 公共接口iCalOutServi

在服务结构集群中,是否可以从一个应用程序向另一个应用程序调用服务或参与者?当我尝试(使用具有适当Uri的ActorProxy.Create)时,我得到一个“找不到接口的MethodDispatcher”

是的,这是可能的。只要您对服务(或ActorService)具有正确的Uri,并且您可以通过定义服务或参与者的接口访问程序集,那么它应该与从同一应用程序中调用服务/参与者没有太大区别。如果有,那么您还必须为exchange设置证书

如果我有一个简单的服务定义为:

公共接口iCalOutService:iSeries设备
{
任务SayHelloAsync();
}
内部密封类Callout服务:无状态服务、iCalOutService
{
公共调用服务(无状态ServiceContext上下文)
:base(context){}
受保护的重写IEnumerable CreateServiceInstanceListeners()
{
返回新的ServiceInstanceListener(this.CreateServiceRemotingListener);
}
公共任务SayHelloAsync()
{
返回Task.FromResult(“hello”);
}
}
一个简单的演员:

public interface ICalloutActor : IActor
{
    Task<string> SayHelloAsync();
}

[StatePersistence(StatePersistence.None)]
internal class CalloutActor : Actor, ICalloutActor
{
    public CalloutActor(ActorService actorService, ActorId actorId)
        : base(actorService, actorId) {}

    public Task<string> SayHelloAsync()
    {
        return Task.FromResult("hello");
    }
}
公共接口ICAlloutator:IActor
{
任务SayHelloAsync();
}
[StatePersistence(StatePersistence.None)]
内部类CalloutActor:Actor、iCalOutActor
{
公共调用参与者(ActorService ActorService,ActorId ActorId)
:base(actorService,actorId){}
公共任务SayHelloAsync()
{
返回Task.FromResult(“hello”);
}
}
在这样的应用程序中运行:

然后,您可以从同一集群中的另一个应用程序调用它:

        // Call the service
        var calloutServiceUri = new Uri(@"fabric:/ServiceFabric.SO.Answer._41655575/CalloutService");
        var calloutService = ServiceProxy.Create<ICalloutService>(calloutServiceUri);
        var serviceHello = await calloutService.SayHelloAsync();

        // Call the actor
        var calloutActorServiceUri = new Uri(@"fabric:/ServiceFabric.SO.Answer._41655575/CalloutActorService");
        var calloutActor = ActorProxy.Create<ICalloutActor>(new ActorId(DateTime.Now.Millisecond), calloutActorServiceUri);
        var actorHello = await calloutActor.SayHelloAsync();
//调用服务
var calloutServiceUri=新Uri(@“fabric:/servicefrick.SO.Answer._41655575/CalloutService”);
var calloutService=ServiceProxy.Create(calloutServiceUri);
var servicehollo=wait calloutService.SayHelloAsync();
//给演员打电话
var calloutActorServiceUri=新Uri(@“fabric:/servicefrick.SO.Answer._41655575/CalloutActorService”);
var calloutActor=ActorProxy.Create(新ActorId(DateTime.Now.毫秒),calloutActorServiceUri);
var actorHello=await callout actor.SayHelloAsync();
如果单击服务并查看名称,您可以在服务结构资源管理器中找到正确的Uri。默认情况下,服务的Uri为:
fabric:/{applicationName}/{serviceName}

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

如果不这样做,而只是在VisualStudio解决方案之间共享代码,那么服务结构会认为这是两个不同的接口,即使它们共享完全相同的签名。如果您为服务执行此操作,则会得到一个
NotImplementedException
说明“接口id{xxxxxxxx}”不是由对象“{Service}”实现的,如果您为参与者执行此操作,则会得到一个
KeyNotfoundException
说明“没有为接口id'-{xxxxxxxxxxxxx}'找到MethodDispatcher”


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

这是可能的,但不是一种好的做法。我认为这是一种设计的味道。为了获得最佳实践,这些SF应用程序应该通过API进行通信。通过已知的Tcp/fabric协议和已知接口(公开的服务接口)与服务进行通信的方式就是与API进行通信。如果您知道您的客户机是集群中的其他应用程序,那么我认为通过HTTP公开API没有什么不同,比如说端点的夸张文档。我想说,这取决于您的体系结构,这些服务可能是内部“核心”服务,提供其他应用程序服务使用的各种通用功能。在这种情况下,我不会说使用织物传输是一个设计问题。
        // Call the service
        var calloutServiceUri = new Uri(@"fabric:/ServiceFabric.SO.Answer._41655575/CalloutService");
        var calloutService = ServiceProxy.Create<ICalloutService>(calloutServiceUri);
        var serviceHello = await calloutService.SayHelloAsync();

        // Call the actor
        var calloutActorServiceUri = new Uri(@"fabric:/ServiceFabric.SO.Answer._41655575/CalloutActorService");
        var calloutActor = ActorProxy.Create<ICalloutActor>(new ActorId(DateTime.Now.Millisecond), calloutActorServiceUri);
        var actorHello = await calloutActor.SayHelloAsync();