2011-12-09 15 views
16

Chcę, aby niezwykle wydajny klient TCP wysyłał wiadomości z protokołu protokołu google. Korzystam z biblioteki Netty w celu opracowania serwera/klienta.Jak napisać wysokiej wydajności klient sieciowy

W testach serwer wydaje się być w stanie obsłużyć do 500 tys transakcji na sekundę, bez wielu problemów, ale klient ma tendencję do osiągania szczytowych wartości około 180 tys. Transakcji na sekundę.

Oparłem mojego klienta na przykładach podanych w dokumentacji Netty, ale różnica polega na tym, że chcę tylko wysłać wiadomość i zapomnieć, że nie chcę odpowiedzi (którą dostaje większość przykładów). Czy mimo to optymalizuję mojego klienta, aby uzyskać wyższy TPS?

Czy mój klient powinien obsługiwać wiele kanałów, czy też powinienem być w stanie osiągnąć wyższą przepustowość niż przy pojedynczym kanale?

+2

wyczucie czasu rzeczywiście * brzmi * tak, jak klient czeka na odpowiedź ... tylko myśl - ponieważ brzmi to jak dość prosta usługa, czy próbowałeś po prostu użyć surowego gniazda? –

+1

czy ktoś rozwiązał problem dla tego rodzaju klienta, czy możesz podzielić się kodem klienta, na przykład z jaką wersją netty? obecnie utknąłem ze zmianami wersji –

Odpowiedz

17

1) Jeśli klient jest zainteresowany tylko wysyłanie, nie odbiera, zawsze możesz wyłączyć odczyt z kanału jak poniżej

channel.setReadable(false); 

2) Można zwiększyć przepustowość bardzo łatwo poprzez wiele kanałów klienta za klienta, a także może skalować.

3) i można zrobić następujących poprawek w celu poprawy wydajności w ogóle (dla odczytu/zapisu)

  • Lepiej mieć Seda jak PipLine dodając EXecutionHandler z OrderdMemoryAwareThreadPoolExecutor, (z min, max pamięć kanał o optymalnej wartości)

    bootstrap.setPipelineFactory(new ChannelPipelineFactory() { 
        @Override 
        public ChannelPipeline getPipeline() throws Exception { 
         return Channels.pipeline(
           executionHandler1,//sharable 
           new MessageDecoderHandler(), 
           new MessageEncoderHandler(), 
           executionHandler2,//sharable 
           new BusinessLogicHandler1(), 
           new BusinessLogicHandler2()); 
        } 
    }); 
    
  • Ustawianie writeBufferHighWaterMark kanału do wartości optymalnej (upewnij się, że ustawienie dużą wartość nie będzie tworzyć zatory)

    bootstrap.setOption("writeBufferHighWaterMark", 10 * 64 * 1024);

  • Ustawianie rozmiaru bufora SO_READ, SO_WRITE

    bootstrap.setOption("sendBufferSize", 1048576); bootstrap.setOption("receiveBufferSize", 1048576);

  • Włączenie TCP Bez opóźnienia

    bootstrap.setOption("tcpNoDelay", true);

+0

Dzięki, Jedno pytanie w punkcie 2). Jaki jest najlepszy sposób, aby to zrobić, czy powinienem utworzyć wiele kanałów i umieścić ich programy obsługi w kolejce procesów roboczych, aby przetwarzać żądania? – Dave

+0

@Zapytaj tę odpowiedź, aby zobaczyć, jak klient może korzystać z wielu połączeń http://stackoverflow.com/a/7905761/596720 – Abe

+0

Znalazłem, że 'setReadable (false)' prawdopodobnie nie jest dobrym pomysłem, chyba że masz sposób na stwierdzenie, że zdalny koniec został odłączony bez próby odczytania kanału. –

3

Nie jestem pewien, czy „TcpNoDelay "pomaga poprawić przepustowość. Opóźnienie ma poprawić wydajność. Niemniej jednak spróbowałem i zobaczyłem, że przepustowość faktycznie spadła o ponad 90%.

Powiązane problemy