A
Apraxus
Gast
Hi,
ich hab mich gefragt, ob man Threads nicht auch dazu nutzen kann die Latenzzeit bei Webanwendungen zu umgehen.
Das heißt konkret, dass ich wenn eine Seite geladen wird ein anderer Thread die nächste Seite vorlädt und dann bereitstellt.
Ich habe versucht das ganze Thread Prinzip in den letzten zwei Tagen soweit in meine Anwendung zu integrieren, dass diese damit umgehen und das ganze auch verarbeiten kann. Hier im Forum gab es ja auch schon ein paar Hinweise und Fragen zu diesem Thema. :?:
Da meine Anwendung zuerst ein Login benötigt, finde ich es ein wenig komplizierter wie die ganzen restlichen Anwendungen die hier so herumgeistern. Ich bin auch dazu übergegangen nicht die einzelnen Seiten ansich in Threads wie in einer Warteschleife zu laden, sondern das Abarbeiten einer ganzen Sequenz von Anweisungen.
Die Threads sind hierbei nur irgendwie so schnell, dass das durchführen der gesamten Anweisungen aus der run() Methode nicht mehr durchgeführt wird. Die Ausgabe des System.out.println() wird noch vollbracht
Das hier sind die Fehler die ich erhalte:
... und danach wird das laden der Seite schon mit einigen Exceptions abgebrochen. ...
Weiterhin gibt es dann noch ein paar NullPointerExceptions, sowie IllegalState und ProtocolExceptions. Diese bauen meiner Meinung nach aber auf den oben geposteten Fehlern auf...
Na ja und wenn ich das ganze mit noch mehr als 2 Threads laufen lassen würde gibt es noch mehr und noch schneller Fehler.
Wenn ich das ganze ohne Threads ausführe komme ich wunderbar zu dem gewünschten Ergebnis.
Kann mir von euch vielleicht jemand Helfen.
Schon mal danke im Vorraus.
Ah... vielleicht sollte ich noch dazusagen, dass das DTO Objekt im Moment ca. 40 ids an die while Schleife liefert, welche letztendlich den Thread bzw. das Runnable aufruft.
ich hab mich gefragt, ob man Threads nicht auch dazu nutzen kann die Latenzzeit bei Webanwendungen zu umgehen.
Das heißt konkret, dass ich wenn eine Seite geladen wird ein anderer Thread die nächste Seite vorlädt und dann bereitstellt.
Ich habe versucht das ganze Thread Prinzip in den letzten zwei Tagen soweit in meine Anwendung zu integrieren, dass diese damit umgehen und das ganze auch verarbeiten kann. Hier im Forum gab es ja auch schon ein paar Hinweise und Fragen zu diesem Thema. :?:
Da meine Anwendung zuerst ein Login benötigt, finde ich es ein wenig komplizierter wie die ganzen restlichen Anwendungen die hier so herumgeistern. Ich bin auch dazu übergegangen nicht die einzelnen Seiten ansich in Threads wie in einer Warteschleife zu laden, sondern das Abarbeiten einer ganzen Sequenz von Anweisungen.
Code:
package com.vit.crawler.launch;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.SocketException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Collection;
import java.util.EmptyStackException;
import java.util.Iterator;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.vit.crawler.CClient;
import com.vit.crawler.CLogin;
import com.vit.db.DB_Object;
import com.vit.db.DB_UIDS;
import com.vit.dto.DTO_UIDS;
import com.vit.util.CRead;
import com.vit.util.CTimer;
/**
* CCrawler.class
*
* The Crawler Class is the main starting JAVA class file for the Visualize.It
* crawler. So do your settings and have fun!
*/
public class CCrawlerProfileThread
{
private static final Log LOG = LogFactory.getLog(CCrawlerProfileThread.class);
private static String MAIN_PROPERTIES = "src/properties/main.properties";
private static String USER_PROPERTIES = "src/properties/user.properties";
//Thread implements Runnable
//shows the available processors installed at the System
int processorsNum = Runtime.getRuntime().availableProcessors();
//starts two threads, for each processor
ExecutorService executor = Executors.newFixedThreadPool(processorsNum);
/**
* The Main Method
* @param args
*/
public static void main(String[] args)
{
CTimer tt = new CTimer();
long time_start = tt.getTime();
Properties props_main = new Properties();
try {
props_main.load(new FileInputStream(MAIN_PROPERTIES));
} catch (FileNotFoundException e) {
if(LOG.isErrorEnabled())
LOG.error("com.vit.crawler.CClient\n --> propertiesfiles not found:\n --> " + e.toString());
} catch (IOException e) {
if(LOG.isErrorEnabled())
LOG.error("com.vit.crawler.CClient\n --> proplems while loading the propertiesfiles:\n --> " + e.toString());
}
int reconnect = Integer.parseInt(props_main.getProperty("reconnect"));
while(reconnect >= 0)
{
try {
CCrawlerProfileThread cpt = new CCrawlerProfileThread();
boolean t = false;
t = cpt.start();
System.out.println("\n\n ---\nDurchgang erfolgreich?: " + t + " \n---\n\n");
}catch (SocketException e) {
LOG.fatal("SOCKETEXCEPTION: " + e.toString());
System.out.println("\n---\nSocketExceptionHandling\n---\n");
main(null);
}catch (NullPointerException e) {
LOG.fatal("NULLPOINTEREXCEPTION: " + e.toString());
System.out.println("\n---\nNullPointerExceptionHandling\n---\n");
main(null);
}catch (EmptyStackException e){
long time_end = tt.getTime();
tt.calculateTime(time_start, time_end);
System.out.println("JOB CRASHED ");
e.printStackTrace();
System.exit(1);
}catch (RuntimeException e){
long time_end = tt.getTime();
tt.calculateTime(time_start, time_end);
System.out.println("JOB CRASHED ");
e.printStackTrace();
System.exit(1);
}
reconnect--;
System.out.println("\n\n --- ---- --- \n Reconnects: " + reconnect + " \n --- --- --- \n\n");
}
long time_end = tt.getTime();
tt.calculateTime(time_start, time_end);
System.out.println("JOB COMPLETED");
System.exit(0);
}//main()
/**
* Start the Profile-Crawler
*/
public boolean start() throws SocketException, NullPointerException
{
LOG.info("com.vit.crawler.launch.CCrawler");
HttpClient httpClient = null;
CLogin login = new CLogin();
// get the needed information out of the properties file
Properties props_main = new Properties();
Properties props_user = new Properties();
try {
props_main.load(new FileInputStream(MAIN_PROPERTIES));
props_user.load(new FileInputStream(USER_PROPERTIES));
} catch (FileNotFoundException e) {
if(LOG.isErrorEnabled())
LOG.error("com.vit.crawler.CClient\n --> propertiesfiles not found:\n --> " + e.toString());
} catch (IOException e) {
if(LOG.isErrorEnabled())
LOG.error("com.vit.crawler.CClient\n --> proplems while loading the propertiesfiles:\n --> " + e.toString());
}
// prepare the variables
int selectedUser = Integer.parseInt(props_user.getProperty("selecteduser"));
String id = "";
String nid = "";
switch(selectedUser)
{
case 0: id = props_user.getProperty("id");
nid = props_user.getProperty("nid");
System.out.println("User 0");
break;
case 1: id = props_user.getProperty("id1");
nid = props_user.getProperty("nid1");
System.out.println("User 1");
break;
default:
id = props_user.getProperty("defaultid");
nid = props_user.getProperty("defaultnid");
System.out.println("User Default");
break;
}
String loggedin_uid = id;
// do the login at the community site
String cookieValue = login.doLogin(selectedUser);
// get a normal HTTPVItClient
httpClient = CClient.getHttpVItClient();
// crawl profiles
Connection cn = null;
int crawls = Integer.parseInt(props_main.getProperty("crawls"));
int schleife = 0;
try {
cn = new DB_Object().get_Connection();
// get crawlable profiles from database
DB_UIDS dbuid = new DB_UIDS();
Collection col = null;
// number of crawls
for(int i = 0; i < crawls; i++)
{
col = dbuid.getUserArrayToCrawlThread(cn, loggedin_uid);
Iterator itr = col.iterator();
// profiles to crawl.
while(itr.hasNext())
{
DTO_UIDS dto = (DTO_UIDS) itr.next();
// allocation
id = String.valueOf(dto.getUser_UID());
CCrawlerThreadFriends ctf = new CCrawlerThreadFriends(id, httpClient, cookieValue, cn, loggedin_uid, dbuid);
this.executor.execute(ctf);
schleife++;
System.out.println("\n\n --- ---- --- \n Anzahl Schleife: " + schleife + " \n --- --- --- \n\n");
}//while
schleife = 0;
System.out.println("\n\n --- ---- --- \n Anzahl: " + i + " \n --- --- --- \n\n");
}//for
new DB_Object().close_Connection(cn);
} catch (SQLException e) {
LOG.error("" + e.toString());
}
return true;
}//start()
}//class
/**
* Thread class for the ProfileCrawler of Visualize.it
* The class implements Runnable and is controlled by the
* Java ExecutorService ...
*/
class CCrawlerThreadFriends implements Runnable
{
private static final Log LOG = LogFactory.getLog(CCrawlerThreadFriends.class);
private static boolean status = false;
private String id;
private HttpClient httpClient;
private String cookieValue;
private Connection cn;
private String loggedin_uid;
private DB_UIDS dbuid;
public CCrawlerThreadFriends(String id, HttpClient httpClient, String cookieValue,
Connection cn, String loggedin_uid, DB_UIDS dbuid)
{
this.id = id;
this.httpClient = httpClient;
this.cookieValue = cookieValue;
this.cn = cn;
this.loggedin_uid = loggedin_uid;
this.dbuid = dbuid;
}
public void run()
{
try
{
// prepare profile site
String nextProfile = "/profile.php?id=" + id;
// prepare friends site
String friendsURL = "/friends.php?id=" + id + "&nk=0";
System.out.println("ID: " + id +" AND URLS: " + nextProfile + " " + friendsURL);
// write result to database - id specifies the current user
StringBuffer sbprofile = CClient.httpGetSiteProfile(httpClient, nextProfile, cookieValue, id);
// parse profile personal information
CRead.parsePersonalInfoFromProfile(cn, sbprofile.toString(), id);
// parse network information
CRead.parsePersonalNetwork(cn, sbprofile.toString(), id);
// parse profile groups
CRead.parseGIDsFromProfile(cn, sbprofile.toString(), id);
// parse education info
CRead.parseEducationInfoFromProfile(cn, sbprofile.toString(), id);
// parse work info
CRead.parseWorkInfoFromProfile(cn, sbprofile.toString(), id);
// parse friends from profiles and write result to database
// -> loggedin_uid specifies the current logged in user
// -> id specifies the user id of the profile that is crawled at the moment
StringBuffer sbfriends = CClient.httpGetSiteFriends(httpClient, friendsURL, cookieValue);
CRead.parseUserFriendsFromProfile(cn, sbfriends.toString(), id, loggedin_uid, 1, httpClient, cookieValue);
// update crawled profile entries
boolean b = dbuid.updateUserArrayToCrawl(cn, id, loggedin_uid);
System.out.println("SET USER TO 1: " + b);
if(LOG.isDebugEnabled())
LOG.debug("STATUS PROFILE: " + status);
} catch (Exception e){
System.err.println ("Exception Fehler");
e.printStackTrace();
}
}
}//class
Die Threads sind hierbei nur irgendwie so schnell, dass das durchführen der gesamten Anweisungen aus der run() Methode nicht mehr durchgeführt wird. Die Ausgabe des System.out.println() wird noch vollbracht
Das hier sind die Fehler die ich erhalte:
Code:
8345 [pool-1-thread-1] INFO com.vit.crawler.CClient - com.vit.crawler.CClient.httpGetSiteProfile()
8346 [pool-1-thread-2] INFO com.vit.crawler.CClient - com.vit.crawler.CClient.httpGetSiteProfile()
8349 [pool-1-thread-2] WARN org.apache.commons.httpclient.SimpleHttpConnectionManager - SimpleHttpConnectionManager being used incorrectly. Be sure that HttpMethod.releaseConnection() is always called and that only one thread and/or method is using this connection manager at a time.
8938 [pool-1-thread-1] FATAL com.vit.crawler.CClient - IOEXCEPTION: org.apache.commons.httpclient.ProtocolException: Unable to parse header: hre=t-8
8939 [pool-1-thread-2] FATAL com.vit.crawler.CClient - IOEXCEPTION: java.net.SocketException: socket closed
... und danach wird das laden der Seite schon mit einigen Exceptions abgebrochen. ...
Weiterhin gibt es dann noch ein paar NullPointerExceptions, sowie IllegalState und ProtocolExceptions. Diese bauen meiner Meinung nach aber auf den oben geposteten Fehlern auf...
Na ja und wenn ich das ganze mit noch mehr als 2 Threads laufen lassen würde gibt es noch mehr und noch schneller Fehler.
Wenn ich das ganze ohne Threads ausführe komme ich wunderbar zu dem gewünschten Ergebnis.
Kann mir von euch vielleicht jemand Helfen.
Schon mal danke im Vorraus.
Ah... vielleicht sollte ich noch dazusagen, dass das DTO Objekt im Moment ca. 40 ids an die while Schleife liefert, welche letztendlich den Thread bzw. das Runnable aufruft.