Design pattern per un fetcher URL multi-thread in java

1

Sto cercando suggerimenti e suggerimenti su un progetto per un fetcher URL multi-thread in Java. I requisiti specifici sono:

  • Per recuperare periodicamente ciascuno di circa 1000 URL
  • L'intervallo tra ogni recupero sarà specifico per l'URL
  • Gli intervalli possono essere compresi tra 2 minuti e 1 ora

Sto immaginando che avrò bisogno di un gruppo di fetcher ognuno in esecuzione nel proprio thread che ottenga il prossimo URL da recuperare quando è in uno stato "pronto".

Dovrò gestire gli errori, ad esempio, per uscire dall'interrogazione di un URL specifico se è scaduto più volte o 404 secondi.

Qualche idea molto apprezzata.

Grazie

    
posta Richard H 05.07.2011 - 13:53
fonte

3 risposte

5

1000 thread (alcuni dei quali attivi una volta in 2 ore) è un grande no-no. Così sta iniziando una nuova discussione per ogni lavoro che potrebbe finire qualche secondo dopo. Crea un thread "scheduler" che seleziona gli URL per il recupero e un numero di thread worker che riportano il loro stato allo scheduler. Schedulatore in sequenza:

  • esegue la gestione del pool di thread di lavoro: - se nessun thread è libero, genera alcuni nuovi. - se più di X thread (ad esempio 3) sono inattivi, termina i thread aggiuntivi.
  • seleziona il nuovo URL da recuperare al momento (o salta il passaggio),
  • trova il primo thread libero, gli assegna il lavoro,
  • raccoglie i risultati dei thread terminati (se presenti)

Quindi dormi e ripeti il ciclo. In sostanza, si dispone di un thread padre semi-in tempo reale che esegue tutti i lavori "veloci" e i thread di lavoro con stati di attesa-occupato.

Ovviamente la distribuzione dell'URL può essere effettuata tramite il pattern Observer, modificato per "consumare" il messaggio se un "client" lo accetta (distribuire l'URL da recuperare). L'elenco di thread può essere un elenco collegato da attraversare in modo ricorsivo.

    
risposta data 05.07.2011 - 14:13
fonte
3

Controlla ScheduledExecutorService . Dovrebbe avere tutto ciò di cui hai bisogno.

Se vuoi un maggiore controllo, considera l'utilizzo di un DelayQueue e programmare la logica intorno a te stesso.

    
risposta data 05.07.2011 - 14:52
fonte
1

Sembra che tu voglia una coda con priorità thread-safe. La priorità sarà basata sul momento in cui ogni URL deve essere recuperato. Quando hai un'attività per recuperare un URL, lo metti in coda. Avrai un pool di thread per gestire le attività in coda. Probabilmente vorrai regolare il numero esatto su alcune statistiche a proposito di 1) per quanto tempo ogni URL impiega a recuperare in media, e 2) quanti URL devi recuperare in un dato momento.

Ad esempio, se mediamente 3 secondi per recuperare i dati per un URL e un URL per recuperare ogni secondo, ovviamente hai bisogno di almeno tre thread per arrivare ragionevolmente vicino al tuo mantenimento. Meno ovviamente, probabilmente vorrai calcolare la varianza (o deviazione standard) del traffico, per avere un'idea di quanti thread hai bisogno per gestire i burst. In alternativa, puoi regolare il numero in modo dinamico, in base alla domanda nei prossimi secondi.

Probabilmente vorrai includere un intervallo di ripetizione nella definizione di un'attività, insieme al numero di (consecutivi?) volte in cui l'attività è fallita. Dopo N ripetizioni, semplicemente non rimetterai l'attività nella coda di esecuzione (o, in alternativa, potresti pianificarne l'esecuzione a intervalli più lunghi, e probabilmente solo quando il sistema è inattivo altrimenti).

Inutile, mi sembra che tu probabilmente stimi il numero di thread coinvolti a meno che la maggior parte di quegli URL finisca molto più vicino ai 2 minuti intervallo rispetto all'intervallo di 1 ora. Se assumiamo una distribuzione approssimativamente casuale, otteniamo qualcosa come un URL per recuperare ogni ~ 1,8 secondi. A quel ritmo, una discussione potrebbe facilmente essere adeguata.

    
risposta data 05.07.2011 - 14:13
fonte

Leggi altre domande sui tag