将大量流发送到ServiceFabric服务 [英] Send large stream to ServiceFabric Service
问题描述
我有一个托管WebAPI的ServiceFabric服务.在控制器上,我在请求中收到FileStream
.我在那里读FileStream
没问题.
I have a ServiceFabric service hosting WebAPI. On a controller, I receive, in my Request, a FileStream
. I have no problem reading the FileStream
there.
然后,我希望此WebAPI服务调用另一个SF服务(有状态)-让我们将其称为Service2,并在参数中提供MemoryStream
.
Then, I want this WebAPI service to call another SF service (stateful) - let's call it Service2, giving a MemoryStream
in parameter.
try
{
await _service2Proxy.MyService2Method(myMemoryStream, otherParameters);
// Line after
}
catch
{
// Error handling
}
在Service2中
public Task MyService2Method(MemoryStream ms, string otherParam)
{
// Log line
// Do something
}
它与File< 3 MB.但是,文件大于5 MB时,该呼叫将无法正常工作.我们从不进行// Line after
,// Error handling
或// Log line
.
It works perfectly well with a File < 3 MB. Yet, with a file > 5 MB, the call doesn't work. We never go on // Line after
, // Error handling
or // Log line
.
我确实在控制器程序集,WebAPI服务程序集和Service2程序集上添加了[assembly: FabricTransportServiceRemotingProvider(MaxMessageSize = int.MaxValue)]
.
Service2接口具有[OperationContract]
和[ServiceContract]
属性.
I did add [assembly: FabricTransportServiceRemotingProvider(MaxMessageSize = int.MaxValue)]
on the controller assembly, the WebAPI service assembly and the Service2 assembly.
The Service2 interface has the [OperationContract]
and [ServiceContract]
attributes.
我还尝试发送byte[]
而不是MemoryStream
.问题还是一样.
I also tried sending a byte[]
instead of a MemoryStream
. The problem is still the same.
推荐答案
如果这是一个StatefulService,并且您使用了带有大量数据的ReliableDictionary,则在SF复制字典数据时可能会导致类似的问题.
If it's a StatefulService and you use some ReliableDictionary with huge data, it could lead to similar issues when SF replicates your dictionary data.
您可以设置两个以上的设置来防止这种情况:
You can set two more settings to prevent this:
- 在创建服务实例时设置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中设置这些设置.
A highly better way to do this: In case you have authentication between replica, you should set these settings in 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>
这篇关于将大量流发送到ServiceFabric服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!