Servlet (Bilder aus Datenbank liefern) läuft nur einige Zeit

Status
Nicht offen für weitere Antworten.

mamue

Mitglied
Hallo,
ich habe zwei kleine Servlets, beide lesen Bilddaten aus einer MySQL-Datenbank. Nach einer Weile, ungefähr einem halben Tag, funktioniert eines der beiden oder auch beide nicht mehr. In den Logfiles sind keine Ausgaben zu erkennen, obwohl ich alle Exceptions (IOException/SQLException) mit out.println( ioe/sqle ) behandle.
Nebenbei läuft noch OpenCMS (basiert auch auf servlets), das davon scheinbar völlig unberührt bleibt.
Nach einem Neustart von Tomcat läuft der Dienst wieder.
Der Speicherverbrauch scheint sich nicht wesentlich zu verändern, über den Schalter "Xms" habe ich catalina ~700MB RAM gegönnt.
Zusammengefasst:
Die Datenbank läuft (OpenCMS zieht _alles_ aus der Datenbank), Tomcat läuft, aber eines meiner beiden Servlets "verweigert" seinen Dienst unabhängig von allen anderen.
Liegt das eher an der Ausgabe über den "BufferedOutputStream" oder an der Datenbankverbindung? Gibt es bei diesen beiden irgend etwas generelles zu beachten, dass ich vergessen habe?
Ich poste mal nur ein Servlet
Code:
public class ReadThumbnail extends HttpServlet {

    Connection connection = null;  //wird nur initialisiert, sofern null -> in getConnection()

    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        try {
            Class.forName( "com.mysql.jdbc.Driver" );
        }
        catch( ClassNotFoundException cnfe ) {
            //out.println( cnfe );  //schlechte Karten, in init habe ich noch kein "out"
        }
    }

    public void doGet(HttpServletRequest req, HttpServletResponse res)
                                throws ServletException, IOException {
        res.setContentType( "image/jpeg" );
        BufferedOutputStream bufferedOut =
                new BufferedOutputStream( res.getOutputStream() );
        PrintWriter out = new PrintWriter( bufferedOut );

        HttpSession session = req.getSession();
        String thumbnail_id =
                req.getParameter( "thumbnailID" );
        int thumbnailID = -1;
        if( thumbnail_id != null ) {
            thumbnailID = 8;
            try {
                thumbnailID = Integer.parseInt( thumbnail_id );
            }
            catch( NumberFormatException nfe ) {
                thumbnailID = 2;
            }
        }
        else {
            thumbnailID = 1;
        }
        try {
            readThumbnail( thumbnailID, bufferedOut );
        }
        catch( SQLException sqle ) {
            out.println( sqle );
        }
        catch( IOException ioe ) {
            out.println( ioe );
        }
    } //doGet

    protected Connection getConnection() throws SQLException {
        String dbUser = "dont-ask";
        String dbPass = "wont-tell-ya";
        String dbHost = "localhost";
        String dbURL = "jdbc:mysql://localhost:3306/not-even-this";
        return getConnection( dbUser, dbPass, dbHost, dbURL );
    }

    protected Connection getConnection( String dbUser,
                                        String dbPass,
                                        String dbHost,
                                        String dbURL ) throws SQLException {
        if( connection != null ) {
            return connection;
        }
        connection = DriverManager.getConnection( dbURL, dbUser, dbPass );
        return connection;
    }

    public void readThumbnail( int id,
                                            BufferedOutputStream outputStream ) throws SQLException, IOException {
        Connection con = getConnection();
        String query = "select thumbnail from some-table "
                     + "where photoID = ?";
        PreparedStatement pstmt =
                con.prepareStatement( query );
        pstmt.setInt( 1, id );
        ResultSet rs = pstmt.executeQuery();
        if( rs.next() ) {
            InputStream is = rs.getBinaryStream( 1 );
            if( is != null ) {
                BufferedInputStream in = new BufferedInputStream( is );
                byte b[] = new byte[ 8 ];
                int count;
                while( ( count=in.read( b ) ) != -1 ) {
                    outputStream.write( b, 0, count );
                }
                outputStream.flush();
                in.close();
            } //if is != null
        } //if rs.next()
    } //readThumbnail throws SQLException, IOException
} //class ReadThumbnail

Für Kommentare wäre ich dankbar,
mamue
 

KSG9|sebastian

Top Contributor
Schließe mal das ResultSet.
Aber mal ne andere Frage: Ändert sich das Bild eigentlich? Ich denk es wär sinnvoller das Bild bei Tomcatstart aus der Datenbank zu lesen. So hast du nur einmal nen Zugriff auf die Datenbank.
 
S

SlaterB

Gast
brutaler Tipp:
notfalls vor allen Einzelbefehlen eine Log-Ausgabe, zumindest aber zu Beginn jedes Requests und vor DB-Connections/ Dateizugriffen oder anderen gefährlichen Stellen,

und dann schau mal ob dort vielleicht eine Endlosschleife/ unendliches Warten droht
 

mamue

Mitglied
Ich danke beiden.
Ob das Schliessen des ResultSet etwas bringt, weiß ich natürlich erst morgen.
Ich muß, ich also doch noch mit der Logging API befassen? Mist, ich dachte, ich käme mit System.out durch Leben.

mamue
 
S

SlaterB

Gast
ich zumindest meinte mit loggen gerne auch System.out.println,
sofern sich das über Stunden hinweg verfolgen lässt..,
 

mamue

Mitglied
SlaterB hat gesagt.:
ich zumindest meinte mit loggen gerne auch System.out.println,
sofern sich das über Stunden hinweg verfolgen lässt..,
:wink: , zu spät. Ich protokolliere jetzt alle meiner Ansicht nach signifikanten Aktionen mit. Dabei ist mir ein, wie ich meine, blöder Fehler aufgefallen:
Code:
              byte b[] = new byte[ 8 ];
                int count;
                while( ( count=in.read( b ) ) != -1 ) {
                    outputStream.write( b, 0, count );
                }
Welchen Wert mag da "count" haben? Was habe ich mir damals bloß dabei gedacht (habe ich damals gedacht)? Ich meine, es müsste "count = b.length" heißen, oder? Andererseits hätte das doch dann eigentlich überhaupt nicht funktionieren dürfen, oder? :?

Danke,
mamue

P.S.: Die "8" in new byte[ 8 ] finde ich ohnehin schlichtweg geil - ich liebe magic numbers!
 
T

Toozie

Gast
hae?


Was meinste jetzt , erklär mal...


Meeinst du das man Count irgendwie wieder auf null setzen sollte ja?
 

mamue

Mitglied
Toozie hat gesagt.:
hae?


Was meinste jetzt , erklär mal...


Meeinst du das man Count irgendwie wieder auf null setzen sollte ja?

Re hae?
BufferedOutputStream.write( data:byte[], off:int, len:int ):void
Parameters:
b - the data.
off - the start offset in the data.
len - the number of bytes to write.

Das Servlet läuft immer noch nicht, bzw. nur eine Zeit lang.
Die Methode post läuft bis zum Ende durch, es steht nichts auffälliges in den Logfiles, nur die INFO-Level Nachrichten, die ich dort nach jedem Methodenaufruf reingesetzt habe.
Servletumgebung ist Apache Tomcat/5.0, Java-Version ist "1.5.0_07-b03, mixed mode, sharing".
Weiß jemand Rat?

Danke,
mamue
 
S

SlaterB

Gast
was heißt hier nix auffälliges..?,
werden am Ende noch Requests angenommen oder nicht, das ist doch die Frage,

geht der Server prinzipiell nicht mehr oder werden die Requests einfach unendlich lange bearbeitet
(ist natürlich nur ein kleine Info, die nicht unbedingt zu irgendwas weiterhilft ;) )

-------

versuche deine Funktionalität in Operationen auszulagern und rufe die bei jedem Request 100x auf,
kommt es dann schneller zu dem Fehler? (sofort statt nach halben Tag)
wieviele Request finden überhaupt in dem halben Tag statt, hängt es von der Anzahl ab?

wenn sich das ganze zeitraffern läßt, dann versuche, nur Teile 100x zu wiederholen,
z.B. 100x Connection erstellen,
--------

bei count musst du schon sagen was du damit meinst,
im Moment würde auch mir nur 'häh' einfallen,

wozu count am Anfang auf 8 setzen wenn das doch dann sofort in der Schleife überschrieben wird?,
warum sollte es nicht mehr funktionieren?
 

mamue

Mitglied
SlaterB hat gesagt.:
was heißt hier nix auffälliges..?,

wozu count am Anfang auf 8 setzen wenn das doch dann sofort in der Schleife überschrieben wird?,
warum sollte es nicht mehr funktionieren?

Nix auffälliges heißt, dass es nur Informationen gab - Statusmeldungen, die ich jetzt selber ins Logfile schreibe. So nach der Art:
Code:
<record>
  <date>2006-12-18T20:01:10</date>
  <millis>1166468470233</millis>
  <sequence>12</sequence>
  <logger>ReadThumbnail</logger>
  <level>INFO</level>
  <class>ReadThumbnail</class>
  <method>readThumbnail</method>
  <thread>11</thread>
  <message>writing.. </message>  //als nächstes wird in den Buffer geschrieben
</record>
<record>
  <date>2006-12-18T20:01:10</date>
  <millis>1166468470234</millis>
  <sequence>13</sequence>
  <logger>ReadThumbnail</logger>
  <level>INFO</level>
  <class>ReadThumbnail</class>
  <method>readThumbnail</method>
  <thread>11</thread>
  <message>..done writing</message>  //erfolgreich geschrieben
</record>
Ich überschreibe count in der Schleife nicht. Man kann IIRC write auch ohne "count" verwenden, dann nimmt java die Länge vom Buffer an. Ich nehme an, das Gleiche passiert, wenn count = 0 ist. Ansonsten müsst die Methode write genau 0 Bytes in den Ausgabestrom schreiben und würde dabei wohl nie fertig werden, nehme ich an. Wurde aber fertig, nahm also mehr "count" Bytes. Aber das scheint auch nicht die Ursache des Problems zu sein.
Wie gesagt, ich bekam nur diese "harmlosen" Standardmeldungen, bis jetzt eben, weiß der Geier, warum nicht eher:
Code:
com.mysql.jdbc.CommunicationsException: Communications link failure due to underlying exception:
java.io.EOFException
        at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1845)
..
        ReadThumbnail.java:117

ReadThumbnail.java:117 lautet
Code:
ResultSet rs = pstmt.executeQuery();
Ich sollte vielleicht mal schauen, wieviele Filehandles noch frei sind, vielleicht werden es ja weniger.

Ich habe es übrigens mit kleinen Lasttests versucht und von zwei PC parallel mit zwei verschiedenen Webbrowsern alle Bilder mehrfach in schneller Folge abgerufen. Das geht. Es scheint mehr ein zeitliches Problem zu sein.

Danke,
mamue
 
S

SlaterB

Gast
> Ich überschreibe count in der Schleife nicht.

> count=in.read( b )
 

mamue

Mitglied
SlaterB hat gesagt.:
> count=in.read( b )

Jaja, aber sonst nicht :oops:
Es ist schade, dass ich nie eine brauchbare Fehlermeldung/Exception bekam, so hat das Ganze sehr lange gedauert.
Es funktioniert jetzt. Ich habe zum einen vergessen, ein ResultSet zu schliessen (danke KSG9|sebastian), zum anderen hole ich mir jetzt jedesmal eine neue Datenbankverbindung. Vielleicht kann ich letzteres in zukünftigen Versionen vermeiden, mal sehen.

Danke an alle,
mamue
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
F Mehrere Bilder aus MySQL DB via Servlet darstellen. Allgemeines EE 1
G Jakarta Servlet API 5.0 Allgemeines EE 1
pkm Frage wegen AJAX-Zugriff auf ein Servlet Allgemeines EE 1
Dimax Servlet Servlet Kommunikation Allgemeines EE 18
K Unterschied zwischen JSP & Servlet gegenüber REST mittels JAX-RS Allgemeines EE 1
Dimax Servlet läuft in Eclipse, aber nicht im Browser Allgemeines EE 74
M URL Servlet Request getParameter Allgemeines EE 2
M Servlet Methoden Aufruf im Servlet Allgemeines EE 10
J 404 Not found (Servlet) Allgemeines EE 1
J Asynchrones Servlet löst NullPointerException aus Allgemeines EE 5
E Servlet Servlet das richtige? Allgemeines EE 11
B HTTP-Header-Inspektor-Servlet Allgemeines EE 1
N JSP Servlet mit JSP ansprechen Allgemeines EE 2
J FTP und Servlet Allgemeines EE 11
H Post an Servlet Allgemeines EE 2
A Binärdatei vom Servlet erzeugen lassen Allgemeines EE 3
S Servlet Authentication Filter Allgemeines EE 0
S LDAP JAAS oder Servlet Allgemeines EE 0
G Problem: Servlet in JSP einbinden mit <jsp:include> Allgemeines EE 3
F eigene Anwendung per Servlet Container starten Allgemeines EE 9
F Servlet Daten im Speicher ablegen Allgemeines EE 3
L Servlet ClassNotFoundException Servlet Allgemeines EE 3
G Allgemeine Frage zu Authentifizierung mittels Servlet API Allgemeines EE 2
J Servlet "package does not exist" Allgemeines EE 5
K Servlet-Mapping Allgemeines EE 9
0 Servlet mit ArrayList Allgemeines EE 3
E Servlet unter mehreren Adressen Allgemeines EE 16
S Pfad-Zugriff über Servlet-init() Allgemeines EE 2
E Servlet Wie kann ich ohne Hilfe von Eclipse in JBoss mein servlet aufrufen Allgemeines EE 2
S Servlet.service() threw exception Allgemeines EE 4
A Servlet erkennt request Objekt nicht Allgemeines EE 8
G Direkter Zugriff auf Servlet- doPost Allgemeines EE 15
G Servlet doGet, doPost Allgemeines EE 3
A Kodierungsproblem bei Parameterübergabe von Browser an Servlet (GET) Allgemeines EE 2
Antoras servlet-mapping auf dynamische URLs Allgemeines EE 17
0 Problem mit librarys javax.servlet.http.HttpServletRequest cannot be resolved Allgemeines EE 1
MQue Ajax - Servlet Allgemeines EE 2
MQue Servlet Allgemeines EE 9
S [Design] Dynamischer EJB Aufruf von Servlet Allgemeines EE 3
S Servlet auf JBoss 5? Allgemeines EE 11
B HttpSession bekommen wenn nicht in Servlet Allgemeines EE 8
MQue Servlet / Button Allgemeines EE 5
S In Eclipse werden die "Servlet-Klassen" nicht gefu Allgemeines EE 2
U javax.faces und javax.servlet cannot be resolved Allgemeines EE 2
W Potentielles Memory Leak bei Servlet Allgemeines EE 6
B unterschied servlet und bean Allgemeines EE 2
Escorter Servlet .sar und jede Menge .jar Archive Allgemeines EE 2
N Servlet und JSF (URL-Rewriting)? Allgemeines EE 3
A jsf: Servlet aufrufen, wie geht das? web.xml Fehler? Allgemeines EE 13
N Servlet zyklisch aktualisieren Allgemeines EE 2
zilti Verbindung Applet <-> Servlet Allgemeines EE 5
ARadauer Servlet Bild Rückgabe Allgemeines EE 2
I Über Formular Daten zu Servlet Allgemeines EE 36
H Servlet - Zwischenmeldung anzeigen bei längerer Berechnung Allgemeines EE 2
G Ordner mit Umlauten einlesen - Servlet Allgemeines EE 3
A web.xml für Servlet in Tomcat 5.5 erstellen Allgemeines EE 2
M Zwei Buttons in einem Servlet Allgemeines EE 2
M Servlet lässt sich nicht aufrufen Allgemeines EE 6
A web.xml für Servlet in Tomcat erstellen Allgemeines EE 6
B Servlet Allgemeines EE 3
G EJB - EJB wird nicht ins Servlet geladen Allgemeines EE 3
K load-on-startup -> in der Servlet Klasse Allgemeines EE 6
G Objekt an Servlet übergeben - oder Objekt global definieren? Allgemeines EE 4
W Was bei Servlet-Entwicklung alles beachten? Allgemeines EE 8
R Zugriff auf Filter Servlet Allgemeines EE 10
I JBOSS Jsp Files Pfad im Servlet? Allgemeines EE 4
N Servlet-Request abbrechen? Allgemeines EE 3
D Java Servlet mit Radio Buttons Allgemeines EE 2
G Servlet debugging Allgemeines EE 8
N Thread von Servlet aus starten Allgemeines EE 16
N JSP: Collection im Servlet überwachen (mit AJAX)? Allgemeines EE 5
J Socket daten darstellen per jsp,servlet Allgemeines EE 2
W servlet über https Allgemeines EE 2
L Servlet kann Funktion nicht aufrufen Allgemeines EE 3
B Parameterübergane von Servlet an JSP funktioniert nicht ? Allgemeines EE 2
M Aus einem Servlet auf ein anderes zugreifen ? Allgemeines EE 2
G Servlet Serializable Allgemeines EE 2
B Servlet-Api.jar auf JBoss? (Migration von Tomcat zu JBoss) Allgemeines EE 4
H Servlet - Importieren von Code Allgemeines EE 2
P Java Servlet - Umgang mit Verlinkungen Allgemeines EE 7
M Wert aus Servlet an normale Klasse übergeben Allgemeines EE 2
E Servlet soll JFRame öffnen. Jframe.setvisible schlägtfehl Allgemeines EE 2
M servlet --> jsp - problem beim umstrukturieren Allgemeines EE 5
D Servlet Problem über Server Allgemeines EE 26
K Servlet per Formular aufrufen Allgemeines EE 8
L sessions mit servlet oder jsp ? Allgemeines EE 9
B JSF - Servlet mit Parametern über einen Link öffnen Allgemeines EE 3
D Binärdaten im Servlet entgegen nehmen, aber wie? Allgemeines EE 5
T Servlet-Instanzen und ServletContext Allgemeines EE 2
L speichern von daten mittels servlet in xml Allgemeines EE 8
N Collection überwachen (Servlet + AJAX) Allgemeines EE 3
N Liste mit Checkboxen an Servlet übergeben? Allgemeines EE 3
T Wie Datenbank und Servlet koppeln? Allgemeines EE 3
G Ladeseite anzeigen lassen während das Servlet noch arbeitet? Allgemeines EE 6
P Tomcat Servlet POST Daten als Array Allgemeines EE 2
P PDF per Servlet übertragen, danach keinen Inhalt mehr Allgemeines EE 12
N JSP kann Servlet nicht aufrufen! :-( Allgemeines EE 2
J Servlet Parameter aus web.xml übergeben, wie zugreifen? Allgemeines EE 2
L servlet.jar ? Allgemeines EE 2
K Servlet: Respone.redirect mit POST-Parametern Allgemeines EE 5

Ähnliche Java Themen

Neue Themen


Oben