我已經實現了一個連接到後端服務器的簡單TCP轉發器。此服務器設置爲http://localhost:5000
,並且此TCP轉發器正在偵聽http://localhost:5001
。使用另一臺機器使用wrk
which is a HTTP benchmarking tool to generator load生成負載,我有2個不同的結果。當我直接發送負載到基於asp.net core web api
的asp.net core web api
上的服務時,會處理超過230K個請求/秒,但是當我將負載發送到此TCP轉發器時,可以處理83Krequest /秒。這裏是代碼:使用C#中的Socket改進TCP轉發器#
using System;
using System.Net;
using System.Net.Sockets;
namespace BrunoGarcia.Net
{
static void Main(string[] args)
{
new TcpForwarderSlim().Start(
new IPEndPoint(IPAddress.Parse(args[0]), int.Parse(args[1])),
new IPEndPoint(IPAddress.Parse(args[2]), int.Parse(args[3])));
}
public class TcpForwarderSlim
{
private readonly Socket _mainSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
public void Start(IPEndPoint local, IPEndPoint remote)
{
_mainSocket.Bind(local);
_mainSocket.Listen(10);
while (true)
{
var source = _mainSocket.Accept();
var destination = new TcpForwarderSlim();
var state = new State(source, destination._mainSocket);
destination.Connect(remote, source);
source.BeginReceive(state.Buffer, 0, state.Buffer.Length, 0, OnDataReceive, state);
}
}
private void Connect(EndPoint remoteEndpoint, Socket destination)
{
var state = new State(_mainSocket, destination);
_mainSocket.Connect(remoteEndpoint);
_mainSocket.BeginReceive(state.Buffer, 0, state.Buffer.Length, SocketFlags.None, OnDataReceive, state);
}
private static void OnDataReceive(IAsyncResult result)
{
var state = (State)result.AsyncState;
try
{
var bytesRead = state.SourceSocket.EndReceive(result);
if (bytesRead > 0)
{
state.DestinationSocket.Send(state.Buffer, bytesRead, SocketFlags.None);
state.SourceSocket.BeginReceive(state.Buffer, 0, state.Buffer.Length, 0, OnDataReceive, state);
}
}
catch
{
state.DestinationSocket.Close();
state.SourceSocket.Close();
}
}
private class State
{
public Socket SourceSocket { get; private set; }
public Socket DestinationSocket { get; private set; }
public byte[] Buffer { get; private set; }
public State(Socket source, Socket destination)
{
SourceSocket = source;
DestinationSocket = destination;
Buffer = new byte[8192];
}
}
}
}
你認爲什麼問題?!當我使用TCP轉發器時,如何改進結果?還是有更好的方法讓隧道或轉發器監聽端口並將TCP請求發送到2個或更多後端服務之一?
謝謝,但是這個解決方案完全降低了rps到10K! :| – Alex
這值得一試。有可能有更好的方法來優化這種解決方案。我會在這兩個版本中使用一個分析器,並查看兩個熱鍵的位置。也可以嘗試使用更大或更小緩衝區大小的解決方案我認爲我的'Math.Min(SourceSocket.ReceiveBufferSize,DestinationSocket.SendBufferSize);'會有所幫助,但也許會傷害到性能。 –