发送大流到 ServiceFabric 服务

Send large stream to ServiceFabric Service

我有一个托管 WebAPI 的 ServiceFabric 服务。在控制器上,我在请求中收到 FileStream。我在那里阅读 FileStream 没问题。

然后,我希望此 WebAPI 服务调用另一个 SF 服务(有状态)- 我们称它为 Service2,在参数中提供 MemoryStream

try
{
    await _service2Proxy.MyService2Method(myMemoryStream, otherParameters);
    // Line after
}
catch
{
    // Error handling
}

而在 Service2

public Task MyService2Method(MemoryStream ms, string otherParam)
{
    // Log line
    // Do something
}

它适用于小于 3 MB 的文件。然而,对于大于 5 MB 的文件,调用不起作用。我们永远不会继续 // Line after// Error handling// Log line

我确实在控制器程序集、WebAPI 服务程序集和 Service2 程序集上添加了 [assembly: FabricTransportServiceRemotingProvider(MaxMessageSize = int.MaxValue)]。 Service2 接口具有 [OperationContract][ServiceContract] 属性。

我还尝试发送 byte[] 而不是 MemoryStream。问题依旧。

对我们来说效果很好。

确保正确设置程序集属性。 https://msdn.microsoft.com/en-us/library/4w8c1y2s(v=vs.110).aspx

这就是我们正在做的事情。

使用Microsoft.ServiceFabric.Services.Remoting.FabricTransport; [程序集:FabricTransportServiceRemotingProvider(MaxMessageSize = 134217728)]

再次确保它在创建服务远程侦听器的程序集和使用 ServiceProxy 调用它的程序集中可用。

或者,您可以在创建侦听器时或在 settings.xml 配置文件中以编程方式设置最大消息大小。有关详细信息,请参见此处:https://azure.microsoft.com/en-us/documentation/articles/service-fabric-reliable-services-secure-communication/

如果它是一个 StatefulService 并且您使用一些具有大量数据的 ReliableDictionary,则当 SF 复制您的字典数据时可能会导致类似的问题。

您可以再设置两个设置来防止这种情况发生:

  • 创建服务实例时设置 MaxReplicationMessageSize。
  • 使用自定义 FabricTransportListenerSettings 初始化您的 ServiceReplicaListener:MaxMessageSize

代码:

public MyStateFulService(StatefulServiceContext context) 
    : base(context, new ReliableStateManager(context, new ReliableStateManagerConfiguration(new ReliableStateManagerReplicatorSettings
    {
        MaxReplicationMessageSize = 1073741824
    }))){ }

protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
{
    var setting = new FabricTransportListenerSettings();
    setting.MaxMessageSize = 1073741824;
    return new[] { new ServiceReplicaListener(initParams => new FabricTransportServiceRemotingListener(initParams, this, setting), "RpcListener")};
}

编辑:

一种更好的方法:如果您在副本之间进行身份验证,则应在 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">
  <!-- This is used by the StateManager's replicator. -->
  <Section Name="ReplicatorConfig">
    <Parameter Name="ReplicatorEndpoint" Value="ReplicatorEndpoint" />
    <Parameter Name="MaxReplicationMessageSize" Value="1073741824" />
  </Section>
  <!-- This is used for securing StateManager's replication traffic. -->
  <Section Name="ReplicatorSecurityConfig">
    <Parameter Name="CredentialType" Value="Windows" />
    <Parameter Name="ProtectionLevel" Value="None" />
  </Section>

  <!-- Add your custom configuration sections and parameters here. -->
  <!--
  <Section Name="MyConfigSection">
    <Parameter Name="MyParameter" Value="Value1" />
  </Section>
  -->
</Settings>