发送大流到 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>
我有一个托管 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>