registrieren registriertes Mitglied


Anzeige

Anzeige

Sind hier PHP'ler unterwegs?

Stell hier Deine Frage zu: HTML, CSS, PHP, MySQL, htaccess, robots.txt, Javascript usw
Hanzo2012
Community-Manager
Community-Manager
Beiträge: 2155
Registriert: 26.09.2011, 23:31

Beitrag Hanzo2012 » 25.11.2020, 09:14 Sind hier PHP'ler unterwegs?

Danke für's Ausprobieren! Dass es (gefühlt) nicht schneller ist, wundert mich. Welchen Wert nutzt du denn für $nThreads? Auch nur 3? Das kannst du locker hochschrauben. Probier einfach mal verschiedene Werte wie 10, 20, ... - nur nicht übertreiben, weil jeder Thread auch RAM braucht.

Dass du damit deine eigenen Seiten aufrufst - wahrscheinlich um deinen Cache zu füllen - hatte ich mir schon gedacht.

Zu deinem Anliegen: Ich würde die Funktion so ändern, dass sie ein Array aus Paaren von URLs und dazugehörigen Optionen erwartet. Außerdem wäre es praktisch "Basis-Optionen" angeben zu können, die für jeden Request gleich sind, und pro Request nur die individuellen Optionen hinzufügen/ändern zu können. Hier ist mein erster Entwurf:

Code: Alles auswählen

function multi_thread_curl($urlsAndOptions, $numThreads, $baseOptions = array()) {
	$curlArray = array_chunk($urlsAndOptions, $numThreads, $preserve_keys = true);
	$results = array();
	
	foreach ($curlArray as $threads) {
		
		$curlHandles = array();
		foreach ($threads as $index => $urlAndOptions) {
			$curlHandle = curl_init();
			$curlHandles[$index] = $curlHandle;
			curl_setopt_array($curlHandle, $baseOptions + $urlAndOptions["options"]);
			curl_setopt($curlHandle, CURLOPT_URL, $urlAndOptions["url"]); 
		}
		
		$mh = curl_multi_init();
		foreach ($threads as $index => $urlAndOptions) {
			curl_multi_add_handle($mh, $curlHandles[$index]);
		}
		
		do {
			$status = curl_multi_exec($mh, $active);
			if ($active) {
				curl_multi_select($mh);
			}
		} while ($active && $status == CURLM_OK);
		
		foreach ($threads as $index => $urlAndOptions) {
			$curlHandle = $curlHandles[$index];
			$results[$index] = curl_multi_getcontent($curlHandle);
			curl_multi_remove_handle($mh, $curlHandle);
		}
		
		curl_multi_close($mh);
	}
	
	return $results;
}
Wie du siehst, habe ich den Code generell etwas aufgeräumt und schöner gemacht.

Nun, wie würdest du das nutzen? Ein Beispiel:

Code: Alles auswählen

// Optionen, die für alle Requests gleich sein sollen:
$baseOptions = array(
	CURLOPT_RETURNTRANSFER => 1,
	CURLOPT_HEADER => true,
	CURLOPT_CUSTOMREQUEST => 'GET',
	CURLOPT_FOLLOWLOCATION => false,
	CURLOPT_ENCODING => 'gzip',
	CURLOPT_CONNECTTIMEOUT => 10,
	CURLOPT_TIMEOUT => 10,
	CURLOPT_SSL_VERIFYHOST => 0,
	CURLOPT_SSL_VERIFYPEER => false,
	CURLOPT_NOBODY => false,
	CURLOPT_HTTPHEADER => array('Cache-Control: max-age=0,no-store,no-cache'),
	CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1
);

// Individuelle Optionen:
$individualOptions = array(
	array(
		CURLOPT_USERAGENT => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.47 Safari/537.36"
	),
	array(
		CURLOPT_USERAGENT => "Wurstbrowser/7.4 FAKE"
	)
);

// ... SQL-Code weggelassen ...

$crawlURLsAndOptions = array();
while ($row = $crawler_query_result->fetch_array()) {
	// Jede URL mit jedem individuellen Set an Optionen separat abfragen.
	$url = $row["url"];
	foreach ($individualOptions as $options) {
		$crawlURLsAndOptions[] = array("url" => $url, "options" => $options);
	}
}

$results = multi_thread_curl($crawlURLsAndOptions, $nThreads, $baseOptions);

Anzeige von:


Content Erstellung von ABAKUS Internet Marketing
Ihre Vorteile:
  • einzigartige Texte
  • suchmaschinenoptimierte Inhalte
  • eine sinnvolle Content-Strategie
  • Beratung und Umsetzung
Jetzt anfragen: 0511 / 300325-0

supervisior
PostRank 9
PostRank 9
Beiträge: 2718
Registriert: 26.06.2006, 09:11

Beitrag supervisior » 25.11.2020, 09:30 Sind hier PHP'ler unterwegs?

Also für den ersten (parallelen) Probelauf hab ich zunächst mal nur 3 gleichzeitige Threads eingestellt, wobei es zwischen jedem Thread nochmal einen Delay von 300 Microseconds gibt. Ich muss mich da erst noch rantasten, wobei Speicher das kleinere Poblem zu sein scheint. Die CPU Load geht nach oben, wobei das noch harmlos ist. Ich hab' aber trotzdem einen Begrenzer drin, der den Prozess bei 0.8 stoppt.

Deine Änderungen teste ich gleich mal aus, wobei in Sachen Optimierung vielleicht noch mehr ginge. CURLOPT_RETURNTRANSFER => 1 brauche ich eigentlich nicht, was sich ohnehin auf den Speicher auswirkt. Ich muss mich noch genauer einlesen, aber es könnte sein, dass wenn ich CURLOPT_RETURNTRANSFER mit CURLOPT_WRITEFUNCTION+CURLOPT_HEADERFUNCTION ersetze, könnte ich den Ressourcen Verbrauch noch weiter senken.

Das mit den Basis Optionen hatte ich die ganze Zeit schon im Sinn, allerdings gescheitert bei der Umsetzung....
Zuletzt geändert von supervisior am 25.11.2020, 09:37, insgesamt 1-mal geändert.

Hanzo2012
Community-Manager
Community-Manager
Beiträge: 2155
Registriert: 26.09.2011, 23:31

Beitrag Hanzo2012 » 25.11.2020, 09:33 Sind hier PHP'ler unterwegs?

Da ist noch ein Bug in meinem Code, weil array_merge komische Sachen macht bei numerischen Schlüsseln. Warte noch einen Augenblick bitte ...

Hanzo2012
Community-Manager
Community-Manager
Beiträge: 2155
Registriert: 26.09.2011, 23:31

Beitrag Hanzo2012 » 25.11.2020, 09:35 Sind hier PHP'ler unterwegs?

So, müsste jetzt korrigiert sein. Ich habe meinen Post oben angepasst, bitte nochmal neu rauskopieren (nur die Funktion). PHP ist schon sehr seltsam manchmal.

supervisior
PostRank 9
PostRank 9
Beiträge: 2718
Registriert: 26.06.2006, 09:11

Beitrag supervisior » 25.11.2020, 09:41 Sind hier PHP'ler unterwegs?

Da ist noch ein Fehler drin mit dem vereinsamten "$" nach:
curl_setopt_array($curlHandle, $baseOptions + $urlAndOptions["options"]);

Anzeige von: