从结构外部使用Service Fabric CommunicationClient和servicePartitionCl



我希望能够从非结构应用程序或服务调用有状态的HTTP/WebApi服务。我可以将已发布的url用于有状态服务,但希望通过解析分区端点来利用故障转移到不同主服务器的优势。

我首先尝试在桌面控制台应用程序中进行测试,但它未能执行InvokeWithRetryAsync内部的通信Lambda函数。

这是一条死胡同(非结构应用程序无法解析有状态服务),还是有其他方法可以从非结构应用中解析端点。否则,我可能会将请求封装在"中间人"无状态服务(如Wordcount Web服务)中。

        var result = await servicePartitionClient.InvokeWithRetryAsync(
            client =>
            {
                //never reaches here. 
                Uri serviceAddress = new Uri(client.BaseAddress, "SetConfiguration");
                HttpWebRequest request = WebRequest.CreateHttp(serviceAddress);
                request.Method = "POST";
                //Add the content into the body
                byte[] byteArray = Encoding.UTF8.GetBytes(_datapacket);
                request.ContentType = "application/json";
                request.ContentLength = byteArray.Length;
                Stream dataStream = request.GetRequestStream();
                dataStream.Write(byteArray, 0, byteArray.Length);
                dataStream.Close();

                request.Timeout = (int)client.OperationTimeout.TotalMilliseconds;
                request.ReadWriteTimeout = (int)client.ReadWriteTimeout.TotalMilliseconds;
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                //for now, just return ok
                return Task.FromResult<string>("ok");
            });

我已经尝试了一段时间,但结果应该是一样的:构建一个无状态服务,作为有状态服务的网关。

我遇到的问题首先是连接到集群——如果它是一个安全的集群,那么你需要加载客户端证书,以便建立安全连接。

一旦解决了这个问题,您可能会遇到这样的问题:命名服务将分区解析为本地地址,而不是可以从集群外部解析的地址。

因此,最终的结果是,我们构建了一个无状态服务,可以作为典型的RESTneneneba API访问该服务,其好处是将分区的抽象移动到集群中的这一层。

是的,在Service Fabric集群之外运行的非Service Fabric应用程序绝对可以与Service Fabric程序对话。Service Fabric本身没有施加任何限制,因为是您的服务本身打开了通信端点(最终,您的服务只是在EXE中运行,它们可以像您以前编写的任何EXE一样侦听地址和端口)。当您使用通信客户端API(如ServicePartitionClient)时,您只是要求命名服务解析服务的地址和端口,然后您可以像往常一样连接到该地址和端口。

当您的客户端位于Service Fabric集群之外时,会出现两个潜在问题:

  1. 您的客户端是否可以访问集群,以便与命名服务进行通信?如果您的集群是用证书保护的,那么您需要在客户端中使用该证书来连接到命名服务
  2. 您的服务端点在群集中是否可见?通常,对于有状态服务,会从端口范围中为您分配一个端口。如果您的群集正在Azure中运行,则此端口范围仅为内部端口,不会通过Azure负载平衡器公开。如果你正在托管自己的集群,你可以设置它让客户端通过你的LB,但你应该考虑你是否真的希望客户端能够这样做

因此,正如Darran所提到的,最简单的解决方案通常是使用无状态服务作为客户端请求的入口点。一旦您"进入"集群,就不再有这些问题。

最新更新