Multi Tasks

dakata__92

Super Moderator
Използвате ли код за изпращане на мулти заявки? Какъв код бихте използвали по темата?
 
eLite каза:
Какво ще рече "мулти заявки"?
Имах предвид curl_multi_init, като говоря за обработване на множество заявки пратени към сървър едновременно.
 
Тука ме хвана неподготвен. :?
Такива задачи обикновено изпълявам на заден план и някакво MQ.

Виж дали това ще ти помогне: https://www.onlineaspect.com/2009/01/26/how-to-use-curl_multi-without-blocking/
 
eLite каза:
Тука ме хвана неподготвен. :?
Такива задачи обикновено изпълявам на заден план и някакво MQ.

Виж дали това ще ти помогне: https://www.onlineaspect.com/2009/01/26/how-to-use-curl_multi-without-blocking/

Аз си използвам вариация на тази система, но ми изниква един въпрос. Как така се изпълняват едновременно и защо е по-бързо от обикновенният кърл? Кода е в пъти по-голям и се използват повече цикли а в един момент нещата са много по-бързи. Защо?
 
Имам ето този метод и се чудя как да ускоря кода. Драснах функция в метода за да няма повтаряне на кода и да има преизползваемост но направо много цикли много нещо....
Кода работи но някак си нещо бъркам логически и не намирам начин да го ускоря. Използвам прекалено много цикли и незнам кой е неправилно използван от мен.
PHP:
public function getMultiResponse(Array $urlArray, $threadWidth = Null) 
	{
		$threads = 0;
		$running = 0;
		$response = array();
		
		if ($threadWidth == null) {
			$threadWidth = count($urlArray);
		}
		
		$curlMultiExec = function ($threads,$threadWidth,$running,$response) 
		{
			while (curl_multi_exec($this->mch, $running) == CURLM_CALL_MULTI_PERFORM);
			curl_multi_select($this->mch);
			while ($done = curl_multi_info_read($this->mch)) {
				foreach ($response as &$res) {
					if ($res['handle'] == $done['handle']) {
						$res['response'] = curl_multi_getcontent($done['handle']);
					}
				}
				curl_multi_remove_handle($this->mch, $done['handle']);
				curl_close($done['handle']);
				$threads--;
			}
			return array($threads,$threadWidth,$running,$response);
		};
		
		foreach ($urlArray as $url => $responseArray) {
			switch (true) {
				case is_numeric($url) :
					$url = $responseArray;
					break;
				case is_array($responseArray) :
					$this->setResponseArray($responseArray);
					break;					
			}
			
			$options = array( 
				CURLOPT_URL => $url, 
				CURLOPT_USERAGENT => $this->responseArray["useragent"],
				CURLOPT_REFERER => $this->responseArray["referer"],
				CURLOPT_ENCODING => $this->responseArray["encoding"],
				CURLOPT_HTTPPROXYTUNNEL => true,
				CURLOPT_FOLLOWLOCATION => true,
				CURLOPT_RETURNTRANSFER => true,
				CURLOPT_SSL_VERIFYPEER => false,
				CURLOPT_SSL_VERIFYHOST => false
			);
			
			$ch = curl_init();
			curl_setopt_array($ch, $options);
			curl_multi_add_handle($this->mch, $ch); //push URL for single rec send into curl stack
			$response[] = array("url" => $url, "handle" => $ch);
			$threads++;	
			if ($threads >= $threadWidth) {
				// print '<br>'.$threads.'-'.$running;
				list($threads,$threadWidth,$running,$response) = $curlMultiExec($threads,$threadWidth,$running,$response);
			}
		}
		
		while ($threads > 0) { 
			list($threads,$threadWidth,$running,$response) = $curlMultiExec($threads,$threadWidth,$running,$response);
			// print '<br>'.$threads.'-'.$running;
			// $threads--;
		} 
		$this->multiCurlOpt = $options;
		return $response;
	}
 
heytar каза:
dakata__92 каза:
lam3r4370 каза:
/off Използвай node или go :D
В смисъл? Дай пример за какво става на въпрос.
Тия неща дето ги правиш не се правят на РНР.

Ееее C и производни не са ми сила. В случая, се получи доста добре кода ми, като наистина свалям доста от обработването на данните.
 
Не C... Java или C#. Макар че мултитрединг в уеб се ползва в много редки ситуации, като пращане на SMS-и например.
 
pix3l каза:
Не C... Java или C#.
C (под производни по име имах предвид) C++, C# а относно Java пак казвам не са ми сила тези езици, че да драскам на тях сложна система.
 
dakata__92 каза:
pix3l каза:
Не C... Java или C#.
C (под производни по име имах предвид) C++, C# а относно Java пак казвам не са ми сила тези езици, че да драскам на тях сложна система.
Че той Java като синтаксис е по-беден от PHP... :D
Нямаш предаване по референция, нямаш traits, имаш силно типизиране (което намалява грешките) и т.н... Java не е по-труден от PHP, ако това си мислиш.
 
Можеш да погледнеш pthreads. Покрай темата се зачетох и ми стана интересно. Има и други алтернативи, например pcntl_fork.
pthreads is an object-orientated API that provides all of the tools needed for multi-threading in PHP. PHP applications can create, read, write, execute and synchronize with Threads, Workers and Threaded objects.
 
Въпроса е, че търся бързодействие, поради което си пиша и собствен код, който доста ускорих, но вече идва ограниченията, които езика ми задава. Не мога да използвам нещо различно от curl понеже това е единствената алтернатива за създаване на подобна система.
 
Защо cURL multi не връща резултат при огромен брой заявки? При по-малък няма проблем но при по-голям (1000)примерно не връща респонд от сървъра?

PHP:
public function getMultiResponse(Array $urlArray, $threadWidth = Null) 
	{
		$threads = 0;
		$running = 0;
		$response = array();
		
		if ($threadWidth == null) {
			$threadWidth = count($urlArray);
		}
		
		$curlMultiExec = function ($threads,$threadWidth,$running,$response) 
		{
			while (curl_multi_exec($this->mch, $running) == CURLM_CALL_MULTI_PERFORM);
			curl_multi_select($this->mch);
			while ($done = curl_multi_info_read($this->mch)) {
				foreach ($response as &$res) {
					if ($res['handle'] == $done['handle']) {
						$res['response'] = curl_multi_getcontent($done['handle']);
					}
				}
				curl_multi_remove_handle($this->mch, $done['handle']);
				curl_close($done['handle']);
				$threads--;
			}
			return array($threads,$threadWidth,$running,$response);
		};
		
		foreach ($urlArray as $url => $responseArray) {
			switch (true) {
				case is_numeric($url) :
					$url = $responseArray;
					break;
				case is_array($responseArray) :
					$this->setResponseArray($responseArray);
					break;					
			}
			
			$options = array( 
				CURLOPT_URL => $url, 
				CURLOPT_USERAGENT => $this->responseArray["useragent"],
				CURLOPT_REFERER => $this->responseArray["referer"],
				CURLOPT_ENCODING => $this->responseArray["encoding"],
				CURLOPT_HTTPPROXYTUNNEL => true,
				CURLOPT_FOLLOWLOCATION => true,
				CURLOPT_RETURNTRANSFER => true,
				CURLOPT_SSL_VERIFYPEER => false,
				CURLOPT_SSL_VERIFYHOST => false
			);
			
			$ch = curl_init();
			curl_setopt_array($ch, $options);
			curl_multi_add_handle($this->mch, $ch); //push URL for single rec send into curl stack
			$response[] = array("url" => $url, "handle" => $ch);
			$threads++;	
			if ($threads >= $threadWidth) {
				// print '<br>'.$threads.'-'.$running;
				list($threads,$threadWidth,$running,$response) = $curlMultiExec($threads,$threadWidth,$running,$response);
			}
		}
		
		while ($threads > 0) { 
			list($threads,$threadWidth,$running,$response) = $curlMultiExec($threads,$threadWidth,$running,$response);
			// print '<br>'.$threads.'-'.$running;
			// $threads--;
		} 
		$this->multiCurlOpt = $options;
		return $response;
	}
 
Явно никой не е крашвал PHP cURL, както аз в момента. :eek: Направо незнам какво да правя и къде се корени проблема.
 
възможно е да е има outbound лимитация на сървъра и тотал конекции
 
vinsbg каза:
възможно е да е има outbound лимитация на сървъра и тотал конекции
По-скоро е поради пренатоварване. Голям масив го подаваш, чрез стъпков цикъл на системата и делиш ресурсите, като използваш по-малко памет и не крашва системата връщайки отговора.
 

Горе