Karşılaştırma amacıyla TCP trafiği bir veya daha fazla uzak sunucuya nasıl kopyalanır?


30

Altyapı: Veri Merkezindeki Sunucular, İşletim Sistemi - Debian Squeeze, Webserver - Apache 2.2.16


Durum:

Canlı sunucu müşterilerimiz tarafından her gün kullanılıyor, bu da ayarlamalar ve iyileştirmelerin test edilmesini olanaksız kılıyor. Bu nedenle, canlı sunucudaki gelen HTTP trafiğini gerçek zamanlı olarak bir veya daha fazla uzak sunucuya kopyalamak istiyoruz. Trafik yerel Web sunucusuna (bu durumda Apache) VE uzak sunuculara iletilmelidir. Böylece konfigürasyonları ayarlayabilir ve mevcut canlı sunucu ile kıyaslama ve karşılaştırma yapmak için uzak sunucularda farklı / güncellenmiş kodlar kullanabiliriz. Şu anda web sunucusu yaklaşık olarak dinliyor. Müşteri yapısı nedeniyle 80 ve 443'ün yanı sıra 60 ilave port.


Soru: Bir veya daha fazla uzak sunucuya yapılan bu çoğaltma nasıl gerçekleştirilebilir?

Biz zaten denedik:

Buradaki seçeneklerimiz tükeniyor.

IPTABLES kullanırken TEE işlevinin "yerel ağdaki sunucunun" uygulanmasını devre dışı bırakmak için bir yöntem var mı?

Hedefimiz, IPTABLES veya Routes'un farklı kullanımıyla başarılabilir mi?

Bu amaç için test edilmiş ve bu özel durumlar için çalışan farklı bir araç biliyor musunuz?

Tee-proxy için farklı bir kaynak var mı (bunlar bizim gereksinimlerimize mükemmel şekilde uyuyordu, AFAIK)?


Cevaplarınız için şimdiden teşekkür ederiz.

----------

düzenleme: 05.02.2014

işte ihtiyaç duyduğumuz şekilde çalışacak python betiği

import socket  
import SimpleHTTPServer  
import SocketServer  
import sys, thread, time  

def main(config, errorlog):
    sys.stderr = file(errorlog, 'a')

    for settings in parse(config):
        thread.start_new_thread(server, settings)

    while True:
        time.sleep(60)

def parse(configline):
    settings = list()
    for line in file(configline):
        parts = line.split()
        settings.append((int(parts[0]), int(parts[1]), parts[2], int(parts[3])))
    return settings

def server(*settings):
    try:
        dock_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        dock_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

        dock_socket.bind(('', settings[0]))

        dock_socket.listen(5)

        while True:
            client_socket = dock_socket.accept()[0]

            client_data = client_socket.recv(1024)
            sys.stderr.write("[OK] Data received:\n %s \n" % client_data)

            print "Forward data to local port: %s" % (settings[1])
            local_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            local_socket.connect(('', settings[1]))
            local_socket.sendall(client_data)

            print "Get response from local socket"
            client_response = local_socket.recv(1024)
            local_socket.close()

            print "Send response to client"
            client_socket.sendall(client_response)
            print "Close client socket"
            client_socket.close()

            print "Forward data to remote server: %s:%s" % (settings[2],settings[3])
            remote_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            remote_socket.connect((settings[2], settings[3]))
            remote_socket.sendall(client_data)       

            print "Close remote sockets"
            remote_socket.close()
    except:
        print "[ERROR]: ",
        print sys.exc_info()
        raise

if __name__ == '__main__':
    main('multiforwarder.config', 'error.log')

Bu betiği kullanacak yorumlar:
Bu betiği, bir dizi yapılandırılmış yerel bağlantı noktasını başka bir yerel ve uzak soket sunucusuna iletir.

Yapılandırma:
Aşağıdaki gibi içerikleri içeren port-forward.config satırları config dosyasına ekleyin:

Hata mesajları 'error.log' dosyasında saklanır.

Betik, config dosyasının parametrelerini böler:
Her config-line'i
0: lokal portu
1: yerel port
2'ye iletmek için : spacer uzak ip adresi
: 3: hedef sunucunun uzak portu
ve dönüş ayarları


Trafik trafiğinin tümü HTTP mi?
longneck,

evet, trafiğin tümü HTTP.
Sise

1
Btw. teeproxy burada bulabilirsiniz: github.com/chrislusf/teeproxy
Tombart

1
Başka bir olasılık: github.com/ebowman/splitter Scala / Netty tabanlı.
Rich K.,

Yanıtlar:


11

Bu imkansız. TCP durum protokolüdür. Kullanıcı son bilgisayarı, bağlantının her aşamasında yer alır ve iletişim kurmaya çalışan iki ayrı sunucuya asla cevap vermez. Yapabileceğiniz tek şey, web sunucusu veya bazı proxy'lerde tüm http isteklerini toplamak ve bunları tekrar etmektir. Ancak bu, canlı bir sunucunun eşzamanlılık veya trafik koşullarını vermeyecektir.


TCP'yi çoğaltmak imkansız-- Buna katılıyorum. Katman 7 trafiğini çoğaltmak değildir. İstekleri istemciden alabilir ve diğer sunuculara geri oynayabilirsiniz. TCP oturumu çalma başına basit 1 isteği oldukça kolay olmalıdır. Kalıcı bağlantılar, müşterinin ek isteklerini nasıl zamanlayacağınız kadarıyla bazı düşünceler gerektirecektir.
Evan Anderson,

@Kazimieras Aliulis: İki ayrı sunucu ile iletişim kurmak gerekli değildir. istemci birincil sunucuyla iletişim kuruyor = canlı sunucu. canlı sunucu, istemci isteklerini işliyor ve müşteriyi yanıtlıyor. işleme koyma ve müşteriye cevap vermenin yanı sıra, birincil sunucu talepleri ikinci sunucuya kopyalar = test sunucusu. ikinci sunucudan birincil sunucuya verilen yanıtlar birincil sunucuda atılacak / yoksayılacak ve müşteriye iletilmeyecektir.
Sise

@Evan Anderson: HTTP düzeyinde çoğaltma bizim ilk fikrimizdi, ancak örneğin apache proxy veya benzeri araçlar veya modüller istekleri yerel olarak eşzamanlı olarak işlemeye izin vermiyor ve uzak bir ana bilgisayara çoğaltıyor. Başka bir fikriniz varsa, lütfen tavsiye! :) biz anında karşılaştırma sonuçları almak için kayıt ve tekrar oynatırken çoğaltmayı tercih ediyoruz.
Sise

1
@Sise: trafiği iki sunucuya ileten kendi http proxy'nizi yazmayı deneyebilirsiniz. Python Twisted framework twistedmatrix.com ile yapmak oldukça kolay olmalı .
Kazimieras Aliulis,

@Kazimieras Aliulis: Bu kesinlikle bir alternatif! hiç duymadım. ancak bunu kontrol etmek amacımıza mükemmel şekilde uyacağını göstermektedir. Daha önce python'u düşünmüyorduk ama şu anda Twisted çerçevesine ve genel python ile olasılıklara bakıyoruz. Başarılı olursak rapor edeceğim!
Sise


7

Teeproxy trafiği çoğaltmak için kullanılabilir. Kullanımı gerçekten basittir:

./teeproxy -l :80 -a localhost:9000 -b localhost:9001
  • a üretim sunucusu
  • b test sunucusu

Web roundrobinsunucunuzdan önce bir HAproxy (with ) koyduğunuzda , trafiğinizin% 50'sini test sitenize kolayca yeniden yönlendirebilirsiniz:

         /------------------> production
HAproxy /                 ^
        \                /
         \---- teeproxy -.....> test (responses ignored)

4

Durum bilgisi olan bir protokol olan TCP, @KazimierasAliulis'in işaret ettiği gibi, paketlerin kopyalarını başka bir ana bilgisayarda patlatmak için uygun değildir.

Paketleri TCP sonlandırma katmanından almak ve bunları yeni bir TCP akışı olarak aktarmak mantıklıdır. Teksir aracı Eğer görünüşünü bağlantılı en iyi bahis gibi. TCP durum makinesinin düzgün çalışmasına izin veren bir TCP proxy'si olarak çalışır. Test makinelerinizden gelen yanıtlar atılacak. Tam olarak istediğin şeyin faturasına uyuyor gibi geliyor.

Çoğalıcı aracını neden kabul edilemez olarak yazdığın açık değil. Yalnızca tek bir bağlantı noktasında dinlediğinden, ancak aracın birden çok örneğini çalıştırmanız gerekir; ancak, muhtemelen, bu farklı dinleme bağlantı noktalarının her birini arka uç sistemindeki farklı bağlantı noktalarına aktarmak istersiniz. Değilse, tüm dinleme portlarını teksir aletinin tek bir dinleme kopyasına yönlendirmek için iptables DNAT kullanabilirsiniz.

Test ettiğiniz uygulamalar basit değilse, zamanlama ve dahili uygulama durumuyla ilgili bu test metodolojisinde sorun yaşayacağınızı umuyorum. Yapmak istediğin aldatıcı bir şekilde basit geliyor. Çok fazla ileri vaka bulacağını umuyorum.


evet, tamamen haklısınız, agnoster teksir aracı çok portlu durum dışındaki gereksinimlerimize uyacak. Ayrıca test makinesinin cevaplarının atılması da tamamlandı. Gerçek / canlı durumu mümkün olduğunca doğru bir şekilde simüle etme hedefimize ulaşmak için, canlı sunucudaki tüm bağlantı noktalarını test makinesindeki tek bir bağlantı noktasına birleştiremeyiz. İstemci cihazlarını farklı müşterilere bölmek için farklı portlar kullanılır. Bu nedenle, bu çoğaltıcı aracın 60-70 seansını açmak zorundayız. Tahmin edebileceğiniz gibi bu çok pratik değil.
Sise

@Sise - Bilgisayarlar sıkıcı şeyler yapmakta iyidir. Apache yapılandırmalarınızı ayrıştırmak için bir komut dosyası yazabileceğinizi ve çoğaltma aracının 60 - 70 örneklerini çalıştırmak için gerekli komut satırlarını tükürebileceğinizi düşünmüştüm. Çoğaltıcı aracının çok yoğun bir kaynak olduğunu hayal bile edemiyorum, ancak olsa bile, bu 60-70 örneklerini başka bir makinede çalıştırabilir ve oradaki trafiği elde etmek için bir ağ hilesi yapabilirdiniz. Bana göre, en azından, bu tamamen pratik görünüyor ve bununla başa çıkmak için oldukça basit bir yol.
Evan Anderson,

1

Benzer bir şey yapmaya çalışıyorum, ancak sadece bir sunucudaki yükü simüle etmeye çalışıyorsanız, yük testi çerçevesi gibi bir şeye bakardım. Daha önce locust.io dosyasını kullandım ve sunucudaki yükü simüle etmek için gerçekten iyi çalıştı. Bu, çok sayıda müşteriyi taklit etmenize ve trafiği ağrılı bir şekilde başka bir sunucuya iletmek zorunda kalmadan sunucunun yapılandırmasıyla oynamanıza izin vermelidir.


0

"Canlı sunucudaki gelen HTTP trafiğini gerçek zamanlı olarak bir veya birden fazla uzak sunucuya kopyalamak istiyoruz" a kadar, yukarıda değinildiği, bağlı olduğu anahtardaki bir ayna bağlantı noktasını yapılandıran bir yol vardır.

Cisco Catalyst anahtarları söz konusu olduğunda, buna SPAN denir (daha fazla bilgi burada ). Cisco ortamında, yansıtılmış bağlantı noktasını bile farklı bir anahtarda kullanabilirsiniz.

Ancak bunun amacı trafik analizi içindir, bu nedenle tek yönlü olacaktır - yukarıdaki birinci paragrafta belirtilen metinde anahtar kelime: gelen . O limanın herhangi bir dönüş trafiğine izin vereceğini sanmıyorum ve eğer öyleyse, yinelenen dönüş trafiğini nasıl ele alırsınız? Bu muhtemelen sadece ağınıza zarar verecek.

Yani ... sadece listenize bir olasılık eklemek istedim, ama bunun tek yönlü trafik için gerçekten olacağına dikkat edin. Belki o ayna portuna bir hub koyabilir ve başlatılan oturumları alıp yanıtlayabilecek bazı yerel istemci simülatörünün elindeki çift sunucu cevaplarına sahip olabilirsiniz, ancak sonra gelen sunucunuza gelen trafiği kopyalayacaksınız ... büyük olasılıkla siz değil istemek.


Bunu düşündük, SPAN kullanmanın alternatifini okudum. Ancak, sunucular üçüncü taraf bir sağlayıcının veri merkezinde bulunduğundan, donanım değişiklikleri söz konusu olduğunda sınırlı imkanlarımız vardır. Zaten doğrudan bir ikinci nic üzerinde 2 sunucuları bağlamak istedi. Yalnızca bu 2 sunucu için yerel bir ağla birleştirilen bu işlem, IPTABLES'i TEE ile kullanmama izin verecek. Ancak bu alternatife gitmek için, NoGo olan sunucuların harici IP'lerini değiştirmemiz gerekir, çünkü istemci cihazlar ayarlanmış IP'ye bağlanacak şekilde yapılandırılmıştır.
Sise

0

Ayrıca Node.js ile benzer bir amaç için bir ters proxy / yük dengeleyici yazdım (şu anda hazır değil, yalnızca eğlence amaçlıdır).

https://github.com/losnir/ampel

Bu çok fikirli ve şu anda destekler:

  • GET Round-robin seçimini kullanarak (1: 1)
  • POSTİstek bölmesini kullanma. "Usta" ve "gölge" kavramı yoktur - yanıt veren ilk arka uç, müşteri isteğine hizmet edecek olandır ve diğer tüm yanıtlar atılır.

Birisi yararlı bulursa daha esnek olması için geliştirebilirim.


Node.js, böyle bir uygulama için çok yüksek performans gerektiren çok garip bir dil seçimidir. Bunun üretime hazır olacağından emin değilim.
Michael Hampton

Kesinlikle haklısın. Bu yüksek performanslı olması değildi - yazması kolay (benim için). Gerekli yüke bağlı olduğunu düşünüyorum. Yine de (2 çekirdekli) düşük uçlu bir makinede 1.000 rps'nin biraz üzerinde bir miktar elde edebildim.
losnir

0

şirketimin benzer bir ihtiyacı vardı, bir paketi klonlamak ve başka bir ana bilgisayara göndermek (piyasa veri simülatörleri kullanıyoruz ve bir piyasa verisi TCP beslemesini dinleyen, her paketi kesip aynı zamanda başka bir simülatöre bir paket klonu gönderen geçici bir çözüme ihtiyaç duyduk) sunucusu)

bu ikili çok iyi çalışıyor, TCP Duplicator sürümü ancak jscript yerine golang yazıyor, bu yüzden daha hızlı ve reklamı yapıldığı gibi çalışıyor,

https://github.com/mkevac/goduplicator


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.