Chiude brevemente una presa di ascolto e poi riapre la sua orribile idea?

3

Sto scrivendo un'applicazione su x86_64 CentOS 7 che funziona come un server, gestendo potenzialmente migliaia di dispositivi. Perché la mia applicazione non funziona bene quando si esegue il processo di connessione (vari handshaking a livello di applicazione, operazioni DB, ecc.) Ed è concepibile che migliaia di dispositivi potrebbero venire online contemporaneamente, voglio prova la connessione che limita la frequenza accetta (come possibile approccio "cura alla fonte" ai miei problemi di scala).

In breve, le connessioni in entrata verrebbero "rifiutate" in qualche modo mentre il processo di handshaking delle applicazioni per i dispositivi n è già in corso (si tratti di un n per T limite di tempo, o un limite di handshake simultaneo n .

Purtroppo:

Ho sentito che il sovraccarico di accept() / connect() non è elevato (in particolare se confrontato con l'effettivo I / O), quindi sono propenso a spegnere semplicemente il mio socket di ascolto quando sto già gestendo (diciamo) 100 riconnessioni, quindi riaprilo / re accept() quando la costa è libera.

Ma questo in qualche modo sembra la strada sbagliata per le cose.

Come affronteresti questo problema, dati i vincoli di cui sopra?

    
posta Lightness Races in Orbit 06.06.2017 - 20:09
fonte

2 risposte

0

leave incoming connections in the backlog, pending an artificially delayed accept()

Ritardare artificialmente il rilevamento effettivo ha più senso, rimuovendo temporaneamente il descrittore dal set di epoll.

andy mango suggerito nei commenti , ed è ciò che alla fine ho fatto ( che era architettonicamente più semplice del previsto).

Questo non risponde alla domanda se chiudere e riaprire un socket in rapida successione sia "un'idea orribile", ma significa che non devo più chiedermi.

    
risposta data 07.07.2017 - 15:43
fonte
-1

Se ho capito correttamente hai creato un server personalizzato e su ogni accetta hai creato un thread. Quindi quando troppe connessioni sono aperte contemporaneamente il server viene sovraccaricato.

Se è il caso, dovresti usare un ThreadPool. L'accettazione non sarà più nella discussione principale. È qualcosa del genere;

class Server 
{
     ServerSocket serverSocket;

     class Worker implements Runnable 
     {
         public void run() 
         {
            while(true) 
            {
                 try
                {
                       Socket s = serverSocket.accept();
                       // your code
                 } catch (Exception e) {
                       e.printStackTrace()
                 }
            }
      }

      public void run()
      {
           serverSocket = new ServerSocket(8081,5000);

           new Thread( new Worker() );
           new Thread( new Worker() );
           new Thread( new Worker() );
           new Thread( new Worker() );
      }
}

In questo modo, il server verrà aperto sulla porta 8081 consentirà 5000 connessioni in attesa di accettare prima di rifiutare la connessione e funzionerà al massimo su 4 connessioni contemporaneamente.

Esiste un'implementazione che apre e chiude dinamicamente i thread worker su Java.util.concurrent chiamato ThreadPool.

La maggior parte dei server web lo fa già. Se implementi il tuo servizio come servlet, devi solo configurare il tuo webserver in base alle dimensioni del pool che desideri.

    
risposta data 07.07.2017 - 14:52
fonte

Leggi altre domande sui tag