高性能C#服务器套接字的技巧/技术 [英] Tips / techniques for high-performance C# server sockets

查看:68
本文介绍了高性能C#服务器套接字的技巧/技术的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一台.NET 2.0服务器似乎正在遇到扩展问题,这可能是由于套接字处理代码的设计不良所致,我正在寻找有关如何重新设计它以提高性能的指南.

I have a .NET 2.0 server that seems to be running into scaling problems, probably due to poor design of the socket-handling code, and I am looking for guidance on how I might redesign it to improve performance.

使用场景:50-150个客户端,以高速率(高达100s/秒)的小消息(每个10s字节)发往/来自每个客户端.客户端连接寿命长-通常为数小时.(服务器是交易系统的一部分.客户端消息被聚合为组,以通过较少数量的出站"套接字连接发送到交易所,并且确认消息被发送回客户端,因为每个组都由交易所处理.)操作系统是Windows Server 2003,硬件是2 x 4核X5355.

Usage scenario: 50 - 150 clients, high rate (up to 100s / second) of small messages (10s of bytes each) to / from each client. Client connections are long-lived - typically hours. (The server is part of a trading system. The client messages are aggregated into groups to send to an exchange over a smaller number of 'outbound' socket connections, and acknowledgment messages are sent back to the clients as each group is processed by the exchange.) OS is Windows Server 2003, hardware is 2 x 4-core X5355.

当前客户端套接字设计: TcpListener 生成一个线程,以在客户端连接时读取每个客户端套接字.线程在 Socket.Receive 上阻塞,解析传入的消息,并将它们插入一组队列中,以供核心服务器逻辑处理.确认消息是使用异步 Socket.BeginSend 从与交换端进行通信的线程中的调用通过客户端套接字发回的.

Current client socket design: A TcpListener spawns a thread to read each client socket as clients connect. The threads block on Socket.Receive, parsing incoming messages and inserting them into a set of queues for processing by the core server logic. Acknowledgment messages are sent back out over the client sockets using async Socket.BeginSend calls from the threads that talk to the exchange side.

已观察到的问题:随着客户端数量的增加(现在为60-70),我们开始看到在向客户端发送数据或从客户端接收数据时出现的间歇性延迟高达100毫秒.(我们记录每个确认消息的时间戳,并且可以看到时间戳序列中偶尔出现的间隔较长的间隙,这些间隙通常来自同一组,通常在几毫秒内就消失了.)

Observed problems: As the client count has grown (now 60-70), we have started to see intermittent delays of up to 100s of milliseconds while sending and receiving data to/from the clients. (We log timestamps for each acknowledgment message, and we can see occasional long gaps in the timestamp sequence for bunches of acks from the same group that normally go out in a few ms total.)

整个系统的CPU使用率很低(<10%),有大量的可用RAM,并且核心逻辑和出站(面向交换)方面运行良好,因此问题似乎对客户端是孤立的套接字代码.服务器和客户端(千兆位局域网)之间有足够的网络带宽,我们已经排除了网络或硬件层的问题.

Overall system CPU usage is low (< 10%), there is plenty of free RAM, and the core logic and the outbound (exchange-facing) side are performing fine, so the problem seems to be isolated to the client-facing socket code. There is ample network bandwidth between the server and clients (gigabit LAN), and we have ruled out network or hardware-layer problems.

任何建议或指向有用资源的指针将不胜感激.如果有人有任何诊断或调试技巧来准确找出问题所在,那么这些技巧也将很好.

Any suggestions or pointers to useful resources would be greatly appreciated. If anyone has any diagnostic or debugging tips for figuring out exactly what is going wrong, those would be great as well.

注意:我有《 MSDN杂志》上的文章 Winsock:请密切注意.NET 中的带有高性能套接字的电线,我瞥了一眼Kodart的"XF.Server"组件-看起来最好还是粗略的.

Note: I have the MSDN Magazine article Winsock: Get Closer to the Wire with High-Performance Sockets in .NET, and I have glanced at the Kodart "XF.Server" component - it looks sketchy at best.

推荐答案

其中很多与系统上运行的多个线程以及内核给每个线程一个时间片有关.设计简单,但扩展性不佳.

A lot of this has to do with many threads running on your system and the kernel giving each of them a time slice. The design is simple, but does not scale well.

您可能应该考虑使用Socket.BeginReceive,它将在.net线程池上执行(您可以以某种方式指定其使用的线程数),然后从异步回调(可以在其中运行)中将其放入队列.NET线程中的任何一个).这应该给您更高的性能.

You probably should look at using Socket.BeginReceive which will execute on the .net thread pools (you can specify somehow the number of threads it uses), and then pushing onto a queue from the asynchronous callback ( which can be running in any of the .NET threads ). This should give you much higher performance.

这篇关于高性能C#服务器套接字的技巧/技术的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆