2014-04-23 4 views
5

Ho uno stack Hibernate, Spring, Debian, Tomcat, MySql su un server Linode in produzione con alcuni client. È un'applicazione Spring-Multitenant che ospita pagine Web per circa 30 client.java.net.SocketException: Troppi file aperti Spring Hibernate Tomcat

Le applicazioni inizia bene, poi dopo un po ', Im ottenendo questo errore:

java.net.SocketException: Too many open files 
at java.net.PlainSocketImpl.socketAccept(Native Method) 
at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:390) 
at java.net.ServerSocket.implAccept(ServerSocket.java:453) 
at java.net.ServerSocket.accept(ServerSocket.java:421) 
at org.apache.tomcat.util.net.DefaultServerSocketFactory.acceptSocket(DefaultServerSocketFactory.java:60) 
at org.apache.tomcat.util.net.JIoEndpoint$Acceptor.run(JIoEndpoint.java:216) 
at java.lang.Thread.run(Thread.java:662) 

Prima di questo errore viene generato tuttavia, Nagios mi avvisa che i ping al server di arresto rispondere.

precedenza ho avuto nginx come un proxy, e stavo ottenendo questo nginx errori per richiesta invece, e ha dovuto riavviare Tomcat in ogni caso:

2014/04/21 12:31:28 [error] 2259#0: *2441630 no live upstreams while connecting to upstream, client: 66.249.64.115, server: abril, request: "GET /catalog.do?op=requestPage&selectedPage=-195&category=2&offSet=-197&page=-193&searchBox= HTTP/1.1", upstream: "http://appcluster/catalog.do?op=requestPage&selectedPage=-195&category=2&offSet=-197&page=-193&searchBox=", host: "www.anabocafe.com" 
2014/04/21 12:31:40 [error] 2259#0: *2441641 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 200.74.195.61, server: abril, request: "GET/HTTP/1.1", upstream: "http://127.0.0.1:8080/", host: "www.oli-med.com" 

Questa è la mia configurazione server.xml Connettore:

<Connector port="80" protocol="HTTP/1.1" 
       maxHttpHeaderSize="8192" 
       maxThreads="500" minSpareThreads="250" 
       enableLookups="false" redirectPort="8443" acceptCount="100" 
       connectionTimeout="20000" disableUploadTimeout="true" 
       acceptorThreadCount="2" /> 

Ho provato a cambiare l'ulimit usando this tutorial Sono stato in grado di modificare il limite rigido per i descrittori di file aperti per l'utente che esegue tomcat, ma non ha risolto il problema, l'applicazione si blocca ancora.

L 'ultima volta che ho dovuto riavviare il server, ha funzionato per circa 3 ore, ho avuto questi valori per le connessioni aperte colpito con forza:

lsof -p TOMCAT_PID | wc -l 
632 (more or less!! i did not write the exact number) 

Questi numeri improvvisamente inizia a crescere.

Ho alcune applicazioni molto simili a questa su altri server, la differenza è che sono una versione Stand Alone e questa è un'architettura Multitenant, ho notato che in questa app mi sto procurando questo tipo di connessioni socket, che don 't si verificano nella versione stand Alone di una qualsiasi delle altre installazioni:

java 11506 root 646u IPv6 136862  0t0  TCP lixxx-xxx.members.linode.com:www->180.76.6.16:49545 (ESTABLISHED) 
java 11506 root 647u IPv6 136873  0t0  TCP lixxx-xxx.members.linode.com:www->50.31.164.139:37734 (CLOSE_WAIT) 
java 11506 root 648u IPv6 135889  0t0  TCP lixxx-xxx.members.linode.com:www->ec2-54-247-188-179.eu-west-1.compute.amazonaws.com:28335 (CLOSE_WAIT) 
java 11506 root 649u IPv6 136882  0t0  TCP lixxx-xxx.members.linode.com:www->ec2-54-251-34-67.ap-southeast-1.compute.amazonaws.com:19023 (CLOSE_WAIT) 
java 11506 root 650u IPv6 136884  0t0  TCP lixxx-xxx.members.linode.com:www->crawl-66-249-75-113.googlebot.com:39665 (ESTABLISHED) 
java 11506 root 651u IPv6 136886  0t0  TCP lixxx-xxx.members.linode.com:www->190.97.240.116.viginet.com.ve:1391 (ESTABLISHED) 
java 11506 root 652u IPv6 136887  0t0  TCP lixxx-xxx.members.linode.com:www->ec2-50-112-95-211.us-west-2.compute.amazonaws.com:19345 (ESTABLISHED) 
java 11506 root 653u IPv6 136889  0t0  TCP lixxx-xxx.members.linode.com:www->ec2-54-248-250-232.ap-northeast-1.compute.amazonaws.com:51153 (ESTABLISHED) 
java 11506 root 654u IPv6 136897  0t0  TCP lixxx-xxx.members.linode.com:www->baiduspider-180-76-5-149.crawl.baidu.com:31768 (ESTABLISHED) 
java 11506 root 655u IPv6 136898  0t0  TCP lixxx-xxx.members.linode.com:www->msnbot-157-55-32-60.search.msn.com:35100 (ESTABLISHED) 
java 11506 root 656u IPv6 136900  0t0  TCP lixxx-xxx.members.linode.com:www->50.31.164.139:47511 (ESTABLISHED) 
java 11506 root 657u IPv6 135924  0t0  TCP lixxx-xxx.members.linode.com:www->ec2-184-73-237-85.compute-1.amazonaws.com:28206 (ESTABLISHED) 

sono un qualche tipo di connessioni automatiche credo.

Quindi la mia domanda è:

Come posso determinare se il problema è a causa del mio codice, server o un qualche tipo di attacco e quale approccio sarebbe Consiglieresti a capirlo?

Grazie in anticipo :)

+0

maxThreads = "10000" è davvero ottimistico;) – Stefan

+1

jaja! hai ragione, probabilmente hai dimenticato di reimpostarlo dopo un test o qualcosa del genere. Grazie per averlo precisato. – Ernest

+0

Modificato in maxThreads = "500" e aggiornato il post. :) – Ernest

risposta

4

Ok, si è scoperto che il problema era le impostazioni di connessione jdbc, ha maxActive impostato su 20 connessioni, ho cambiato il limite a 200 e il problema si è fermato.

Il modo in cui ho pensato che questo fosse il problema era grazie all'appdynamics.Il meraviglioso strumento di com, che ti consente di controllare una grande quantità di metriche nelle metriche ApplicationInfraestructurePerformance.

Inoltre, ha trovato questo bellissimo articolo su questo argomento, che mi ha aiutato a mettere a punto la mia app:

http://www.tomcatexpert.com/blog/2010/04/01/configuring-jdbc-pool-high-concurrency

la documentazione oficial anche aiutato:

https://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html.

Immagino che le connessioni in arrivo abbiano iniziato una query che ha prima bloccato la capacità di risposta del server, e dopo aver riempito i limiti del socket del SO, in linux, i socket aperti sono file aperti. Spero che questo aiuti qualcuno!

EDIT

Ciao! Questa soluzione ha risolto il problema a breve termine, ma è apparso un altro errore relativo alla connessione JDBC, l'applicazione non chiudeva le connessioni, ho aperto e risolto un ticket relativo a tale numero here

1

Avete controllato il vostro ulimit per l'utente che esegue gatto? Linux ha un limite di 1024 file aperti per impostazione predefinita. Altro su How do I change the number of open files limit in Linux?

C'è la possibilità di avere troppe connessioni nei file di configurazione o per qualche motivo non sta chiudendo correttamente alcuni flussi IO (altamente improbabile).

Mi avvicinerei aumentando lo ulimit e quindi eseguo alcuni test di caricamento per vedere cosa sta causando l'utilizzo del file.

+0

Ciao Mite, grazie per la risposta ... Ho cambiato l'ulimit, l'ho scritto nel post originale, dopo la descrizione del connettore server.xml. L'ho aumentato a 65535. Non ho ricevuto quell'errore, ma Tomcat ha smesso di rispondere e i file aperti erano in aumento. Probabilmente avrei avuto quell'errore se l'avessi lasciato da solo, ma dovevo riavviare. Ho provato a caricare i test con jmeter, se metto un sacco di richieste al secondo rallenta, ma non sono sicuro di come rilevare che cosa lo causa. – Ernest

+0

quando si esegue lsof -p TOMCAT_PID quali sono i file aperti, le connessioni o qualcos'altro? –

+0

Ciao Mite, per lo più connessioni, come da robot e webcrawlers, penso. Ho appena creato uno script che guarderà quando succede e registra l'output di -p TOMCAT_PID, così posso darti una risposta precisa. Grazie ancora per la risposta. Aggiornerò presto con maggiori informazioni – Ernest

0

un po 'in ritardo, ma forse un aiuto/suggerimento per chiunque abbia difficoltà con questo problema. abbiamo avuto lo stesso strano problema ogni tanto (il nostro servizio tomcat viene riavviato ogni giorno di notte (che pulisce le maniglie aperte), quindi l'errore non si verificava così spesso).
Utilizziamo un proxy apache con protocollo ajp. Il problema era un'implementazione del protocollo errata.
nostro config connettore è ora la seguente:

<Connector 
     port="8009" 
     protocol="org.apache.coyote.ajp.AjpNioProtocol" 
     connectionTimeout="1800000" 

     acceptorThreadCount="2" 
     maxThreads="400" 
     maxConnections="8192" 
     asyncTimeout="20000" 
     acceptCount="200" 
     minSpareThreads="40" 
     compression="on" 
     compressableMimeType="text/html,text/xml,text/plain" 

     enableLookups="false" 
     URIEncoding="UTF-8" 
     redirectPort="8443" /> 

Si prega di mente questo: protocollo = "org.apache.coyote.ajp.AjpNioProtocol"
Questa implementazione ha fatto il trucco per noi - nessun file più aperta maniglie. Ulteriori informazioni possono essere trovate qui: https://itellity.wordpress.com/2013/07/12/getting-rid-of-close_waits-in-tomcat-67-with-mod_proxy/
Spero che questo aiuti qualcuno. Buona giornata!