Çoğullama aslında yeni bir teknoloji değildir.İşlevi, bir iletişim bağlantısına dayalı olarak aynı anda birden fazla istek ve yanıtı işlemektir. Ağ iletişimi için böyle bir söz yoktur, çünkü ağ katmanı yalnızca veri aktarımından sorumludur; üst katman uygulama protokollerinin formülasyonu nedeniyle, birçok geleneksel hizmet çoğullamayı destekleyemez; örneğin: http1.1, sqlserver, redis, vb. Vb, bazı hizmetler toplu işlem sağlasa da, bu işlemlerin tümü bir RPS'ye dayalıdır. Aşağıdaki, tek kanallı ve çoklanmış kanallar arasındaki farkı göstermektedir.
Her istek yanıtının özel bir bağlantısı ve okuma ve yazma için ağa özel bir bağlantısı vardır; bu, bağlantının uzun süre boşta kalmasına neden olur ve ağ kaynaklarını daha iyi kullanamaz. IO okuma ve yazma özel olduğu için, bu RPS işlem hacminin IO tarafından taşınmasına neden olur ve IO işlemi performansı tüketir, bu nedenle yüksek RPS işlemede performans sorunları ortaya çıkar. IO'yu etkin bir şekilde birleştirememe, özellikle nispeten küçük istek paketleri için iletişimde bant genişliği israfına da yol açacaktır. İletişim gecikmesi çok sayıda RPS'yi desteklemek olduğunda, daha fazla bağlantı desteklenmelidir Bağlantı sayısındaki artış, kaynak maliyetini de artırır.
Çoklama, aynı anda tek bir bağlantıda birden çok istek yanıtını işleyebilir, bu da bağlantı sayısını büyük ölçüde azaltabilir ve ağın işlem kapasitesini artırabilir. Paylaşılan bir bağlantı olduğu için, farklı istek yanıt veri paketleri işleme için tek bir GÇ'de birleştirilebilir, bu da GÇ işlem hacmini büyük ölçüde azaltabilir ve performansı daha iyi hale getirebilir.
Aşağıdakiler, tek bir hizmet milyon RPS verimi elde etmek için .net çekirdeğinde çoğullamayı kullanır ve nispeten düşük gecikme süresi sağlayabilir. Aşağıdaki test sürecidir:
Temel iletişim, mesaj paketi birleştirme işlevine sahip olmadığından, entegrasyon testi BeetleX temelinde yapılır.Ana BeetleX, mesajları otomatik olarak bir Tamponda birleştirir, böylece IO'nun okuma ve yazma oranını azaltır.
Bu test Protobuf'u temel etkileşimli mesaj olarak kullanır Sonuçta, Protobuf zaten bir ikili serileştirme standardıdır.
Mesaj iste
public int ID {get; set;} public Double RequestTime {get; set;}Cevap mesajı
public int EmployeeID {get; set;} public string LastName {get; set;} public string FirstName {get; set;} public string Adres {get; set;} public string Şehir {get; set;} public string Bölge {get ; set;} public string Ülke {get; set;} public Double RequestTime {get; set;}* Sunucu tarafı işleme kodu *
public static void Response (Tuple < IServer, ISession, SearchEmployee > değer) {Employee emp = Employee.GetEmployee (); emp.RequestTime = value.Item3.RequestTime; value.Item1.Send (emp, value.Item2); System.Threading.Interlocked.Increment (ref Count);} genel geçersiz kılma void SessionPacketDecodeCompleted (IServer sunucusu, PacketDecodeCompletedEventArgs e) {SearchEmployee emp = (SearchEmployee) e.Message; multiThreadDispatcher.Enqueue (yeni Tuple < IServer, ISession, SearchEmployee > (sunucu, e.Session, emp));}Servis yanıt nesnesi içeriği
Çalışan sonucu = yeni Çalışan (); result.EmployeeID = 1; result.LastName = "Davolio"; result.FirstName = "Nancy"; result.Address = "ja"; result.City = "Seattle"; result.Region = "WA"; result.Country = "ABD";Mesajı aldıktan sonra kuyruğa koyun ve ardından kuyruk yanıtı işleyecek, istek zamanına karşılık gelen isteği ayarlayacak ve toplam işlenen mesaj sayısını kaydedecektir.
Müşteri istek kodu
özel statik boşluk Yanıtı (Tuple < AsyncTcpClient, Çalışan > veri) {System.Threading.Interlocked.Increment (ref mCount); if (mCount > 100) {if (data.Item2.RequestTime > 0) {double tick = mWatch.Elapsed.TotalMilliseconds-data.Item2.RequestTime; AddToLevel (tick);}} var s = new SearchEmployee (); s.RequestTime = mWatch.Elapsed.TotalMilliseconds; data.Item1.Send (s );}İstemci testi başlatma kodu
for (int i = 0; i < mConnections; i ++) {var client = SocketFactory.CreateClient < BeetleX.Clients.AsyncTcpClient, TestMessages.ProtobufClientPacket > (mIPAddress, 9090); client.ReceivePacket = (o, e) = > {Employee emp = (Employee) e; multiThreadDispatcher.Enqueue (yeni Tuple < AsyncTcpClient, Çalışan > ((AsyncTcpClient) o, emp));}; client.ClientError = (o, e) = > {Console.WriteLine (e.Message);}; mClients.Add (istemci);} for (int i = 0; i < 200; i ++) {foreach (mClients'taki var öğesi) {SearchEmployee search = new SearchEmployee (); Task.Run (() = > {item.Send (search);});}}Testin tamamında 10 bağlantı açılmış ve bu 10 bağlantı bazında istek yanıt çoklama gerçekleştirilmiştir.
Test ortamı iki sunucudur ve yapılandırma Alibaba Cloud üzerinde 12 çekirdekli bir sunucudur (karşılık gelen fiziksel makine 6 çekirdek ve 12 iş parçacığı olmalıdır)
Hem hizmet hem de istemci sistemleri şunlardır: Ubuntu 16.04
Dotnet çekirdek sürümü: 2.14
Müşteri istatistikleri
Sunucu istatistikleri
Bant genişliği istatistikleri