在同一进程中的 AppDomain 之间发送大字节数组
我正在构建一个网络服务器,并在请求路由到的服务器上启动大量应用程序域。 将请求有效负载发送到应用程序域之一进行处理的最快方法是什么?
- 将有效负载从套接字读入字节数组并将其封送。
- 将网络流(继承自 MarshalByRef)编组到 AppDomain。
- 读取有效负载。 将其解码为对象。 编组解码的对象。
- 使用命名管道传输字节数组。
- 使用环回套接字。
- 也许有一种方法可以封送实际的套接字连接?
解码主要创建不可变对象,用于确定如何满足客户端请求,然后 AppDomain 创建响应并将其封送回主机 AppDomain,主机 AppDomain 通过套接字将其发送回。
该方法应该优先选择较少的内存而不是较少的 CPU。
WCF 不是一个选择。
I'm building a network server and starting a lot of AppDomains on the server to which requests are routed. What will be the fastest way to send off a request payload to one of the AppDomains for processing?
- Read in the payload from the socket into a byte array and marshal it.
- Marshal the network stream (inherits from MarshalByRef) to the AppDomain.
- Read the payload. Decode it into objects. Marshal the decoded objects.
- Use named pipes to transfer the byte array.
- Use loopback sockets.
- Maybe there is a way to marshal the actual socket connection?
The decoding mostly creates immutable objects that are used to determine how to fulfill the clients request and the AppDomain then creates a response and marshals it back to the host AppDomain which sends it back through the socket.
The method should prefer less memory over less CPU.
WCF is not an option.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
TCP 二进制远程处理当然很快,我不知道它比原始套接字快多少,原始套接字可能是最快的,但是是皇家 PIA。
我在生产环境中使用 HTTP 二进制远程处理在两个盒子之间每秒运行 1500 - 2000 个请求。 在同一台机器上,使用 TCP 或名称管道通道应该具有很高的性能,具体取决于处理数据所需的 CPU 周期。
TCP binary remoting is certainly fast, I do not how much faster it is than raw sockets which is probably the fastest, but a royal PIA.
I have run 1500 - 2000 req per second in production using HTTP binary remoting between two boxes. On the same box you should have much high performance using TCP or a name pipes channel, depending in the CPU cycles it takes to process the data.
如果我是你,我会看看 Cassini 是如何实现的。 它几乎完全符合您所说的功能。
实际上 Cassini 已经被 Webhost 取代了,Webhost 是 Visual Studio 现在附带的内置 Web 服务器。 请参阅 Phil Haack 博客上的这篇文章了解更多信息。
If I was you I would take a look at how Cassini is implemented. It does pretty much exactly what you are talking about doing.
Actually Cassini has been sort of superceded by Webhost which is the built-in webserver that ships with Visual Studio now. Take a look at this post on Phil Haack's blog for more.
非常好的问题。 如果我遇到这个问题,我可能会使用缓冲流/内存流,并将流编组到消耗对象的 AppDomain 中,以减少编组或序列化在不同 AppDomain 中创建的许多对象图。
但话又说回来,听起来你几乎完全复制了 IIS 的功能,所以我会查看/反射 System.Web.Hosting 命名空间,看看他们如何处理它以及他们的 WorkerThreadPool 等......
Very good question. If I were coming at this problem I would probably use a Buffered Stream / Memory Stream and marshal the stream into the AppDomain that consumes the object to reduce marshaling or serializing many object graphs that were created in a different AppDomain.
But then again, it sounds like you are almost completely duplicating the functionality of IIS, so I would look/reflector into the System.Web.Hosting namespace and see how they handle it and their WorkerThreadPool etc....
在我看来,第六是最好的选择。
Socket从进程的角度来看只是一个句柄。 AppDomain 驻留在单个进程中。 这意味着应用程序域可以交换套接字句柄。
如果套接字编组不起作用,您可以尝试在其他应用程序域中重新创建套接字。 您可以使用 DuplicateAndClose 来执行这。
如果这不起作用,您应该进行一些性能测试以选择最佳的数据传输方法。 (我会选择命名管道或内存映射文件)
6-th is IMO the best option.
Socket from process perspective is just a handle. AppDomains reside in single process. That means that appdomains can interchange socket handles.
If socket marshalling is not working, you can try recreating socket in other appdomain. You can use DuplicateAndClose to do this.
If that will not work, you should do some perfomance testing to choose the best data transfer method. (I would choose named pipes or memomry mapped files)