powered by simpleCommunicator - 2.0.36     © 2025 Programmizd 02
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / Скрипт умирает не отработав
33 сообщений из 33, показаны все 2 страниц
Скрипт умирает не отработав
    #40027998
Фотография БурыйТина
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изломал всю головушку, но в чем проблема даже предположить не могу.
Скрип работая, выполняя циклы, получая данные вдруг отмирает. Просто так, не объявляя войну и не крича о помощи, тихо мирно умирает.
Скрип находится на хостинге ТаймВеб, является приложением для битрикс 24. Превышений нагрузки на хостинге нет, в логах хостинга нет сведений о принудительном завершении скрипта.
В чем может быть причина и в какую сторону копать? подскажите пожалуйста


(''')0___0(''')
\ '( î_î )' / /
\ \_0_/ /
l . . l
/ /Y\ \
(„„„)_(„„„) Превед !
...
Рейтинг: 0 / 0
Скрипт умирает не отработав
    #40028005
Фотография БурыйТина
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот так выглядит лог
два цикл for один вложен в другой. Сначала узнаем количество страниц ответа, потом запускаем перебор по страницам
получаем количество экземпляров на странице и начинаем запрашивать каждый экземпляр. Как видите выполнение умирает неожиданно

Кусок лога:

НАЧАЛО НОВОГО ОТЧЕТА
Страниц в ответе: 10
i=1 page_cnt=10
Запрос к странице: ХХХХХХХХХХХХ
Экземпляров: (case_cnt) 25

Далее код:
Код: php
1.
for ($j=0; $j<$case_cnt; $j++){



Теперь лог выполнения кода
j=0 case_cnt=25
j=1 case_cnt=25
j=2 case_cnt=25
j=3 case_cnt=25
j=4 case_cnt=25
j=5 case_cnt=25
j=6 case_cnt=25
j=7 case_cnt=25
j=8 case_cnt=25
j=9 case_cnt=25
j=10 case_cnt=25
j=11 case_cnt=25
j=12 case_cnt=25
j=13 case_cnt=25
j=14 case_cnt=25
...
Рейтинг: 0 / 0
Скрипт умирает не отработав
    #40028096
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
БурыйТина
В чем может быть причина и в какую сторону копать?
Например, в превышении времени работы процесса или превышении нагрузки на проц. Возможно, есть какие-то еще ограничения на хостинге.
Начать можно с изучения ограничений хостинга и обращения в техподдержку. Чтобы убедиться в том, что срабатывают ограничения или нет.
Дальше уже по ситуации.
...
Рейтинг: 0 / 0
Скрипт умирает не отработав
    #40028121
Фотография БурыйТина
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vkle,

Спасибо за ответ, но нет
Во первых время работы на хостинге 800 секунд, а скрип умирает на 180-200 секунде как правило, проц не перегружается, это я уже проверил, логирую каждую строчку теперь чтобы понять где что умирает, непонятка полная пока
...
Рейтинг: 0 / 0
Скрипт умирает не отработав
    #40029338
Фотография БурыйТина
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Итак, новые вводные.
Умирает на curl_exec хотя далеко не всегда. Видимо что-то не получается с каким-то очередным запросом. Подскажите пожалуйста как отследить и отработать ошибку? curl_error пользы не приносит, ибо если скрип умирает, то он никуда больше не идет.
while(($data = curl_exec($ch)) === false or $data == '' ) такая конструкция у меня пытается заставить отработать запросы, но внутрь while не попадает обработчик.
...
Рейтинг: 0 / 0
Скрипт умирает не отработав
    #40029380
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
БурыйТина
Умирает на curl_exec хотя далеко не всегда.
Наверно, не сильно ошибусь, если предположу, что отработка курл занимает довольно заметную, а может даже и значительную долю времени в пределах шага цикла. В этом смысле вероятность попадания на курл момента прибития процесса со стороны ОС банально высока.

Кстати, что ответила техподдержка по существу проблемы?
...
Рейтинг: 0 / 0
Скрипт умирает не отработав
    #40029419
Фотография БурыйТина
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vkle,

поддержкаЗдравствуйте.

К сожалению, на текущий момент в логе не наблюдаем проблем которые могут привести превышению каких-либо лимитов и принудительному завершению скрипта.


поддержкаmax_execution_time, его значение равно 800 секунд.



отключение скрипта происходит гораздо раньше. Установка бесконечного времени на выполнение скрипта, тоже не дает эффекта.

Зато утром в логах я увидел что

Код: php
1.
while(($data = curl_exec($ch)) === false or $data == '' )



все же работает и повторяет запросы при пустом ответе и если возвращается ошибка.
Может на этом решится проблема? Буду смотреть. Я так понимаю что все события предусмотрены вышеприведенным кодом, за исключением того, что закончился лимит времени на выполнение
...
Рейтинг: 0 / 0
Скрипт умирает не отработав
    #40029427
Фотография БурыйТина
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот так выглядит кусок кода

Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
			$defaults = array(
				CURLOPT_URL => "URL",
				CURLOPT_HEADER => 0,
				CURLOPT_RETURNTRANSFER => TRUE,
				CURLOPT_TIMEOUT => 60
			); 	
			$ch = curl_init();
			curl_setopt_array($ch, $defaults);
			set_time_limit(130);
			$date = date('Y-m-d H:i:s');
			file_put_contents(dirname(__FILE__)."/logs/call_API.log", "$date делан запрос: http:\n", FILE_APPEND);			
			$data = curl_exec($ch);
			$date = date('Y-m-d H:i:s');
			file_put_contents(dirname(__FILE__)."/logs/call_API.log", "$date Запрос вернул: \n".$data, FILE_APPEND);			
			while($data === false or $data == '' ){
				set_time_limit(130);
				$date = date('Y-m-d H:i:s');
				file_put_contents(dirname(__FILE__)."/logs/call_API.log", "$date зашли в обработку ошибки или пустого значения\n". $data, FILE_APPEND);
					
					if($data === false){
						set_time_limit(130);
						$date = date('Y-m-d H:i:s');
						file_put_contents(dirname(__FILE__)."/logs/call_API.log", "$date Запрос вернул ошибку: $data \n".curl_error($ch), FILE_APPEND);
				}
				
			
			}



В логах последняя запись

лог2020-12-20 08:54:01 делан запрос: http:ХХХХХ


После этого тишина.
Всю голову уже сломал, что я не предусмотрел? Не отвечает curl_exec? Как это отловить и обработать?
...
Рейтинг: 0 / 0
Скрипт умирает не отработав
    #40029436
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
БурыйТина
Не отвечает curl_exec? Как это отловить и обработать?
По сути, curl_exec передает управление в какую-то функцию из lbcurl.so и ожидает ответ. Допустим, процесс php не дождалcя ответа от libcurl (положим, какая-то функция в libcurl зависла/зациклилась). А никак это из php не обработаете - не возвращено ему управление.

Какие я вижу возможные варианты:
- Процесс крашится с выпаданием в кору (что-то вроде файлика php.core образуется). Можно даже поковыряться в нем и обнаружить причину падения, вроде несоответствия какой-нить структуры данных (возможно после не слишком удачного обновления).
- То же самое, но сохранение коры либо запрещено на уровне системы, либо валится она в недоступное для пользователя место. Понятно, что в таком случае посмотреть вообще ничего не получится. Да и увидеть сам факт падения не представляется возможным.
- Процесс принудительно завершает (или убивает - от слова kill) ядро ОС (или другие "силовые структуры" сервера), обнаружив превышение норм потребления - по памяти, по ресурсам CPU или по каким-то еще признакам/свойствам/ограничениям.

Вот это навскидку и самое частое на мой взгляд. Раумеется в пхпшных логах будет полное отсутствие какой-либо информации, т.к. процесс php, который пишет лог, уже не существует и не может никуда и ничего записать. Однако, вполне возможно, что логгирование чего-то подобного имеется на уровне ОС, но рядовому пользователю недоступно. Потому в саппорт.


БурыйТина
поддержкаmax_execution_time, его значение равно 800 секунд.
Счет времени выполнения скрипта, которое сравнивается со значением max_execution_time останавливается (!) при вызове внешнего по отношению к php ПО. В этом смысле время выполнения скрипта так себе показатель - слишком частичный.
...
Рейтинг: 0 / 0
Скрипт умирает не отработав
    #40029437
Фотография БурыйТина
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИТОГО:
Отсутствие ответа обработать в данной ситуации невозможно, а исправлять ситуацию долго и дорого. Надо смириться. Так?

ЗЫ
автор- Процесс принудительно завершает (или убивает - от слова kill) ядро ОС (или другие "силовые структуры" сервера), обнаружив превышение норм потребления - по памяти, по ресурсам CPU или по каким-то еще признакам/свойствам/ограничениям.


Это тщательно и неоднократно проверялось. Нет превышений и "силовые структуры" тут не причем.
...
Рейтинг: 0 / 0
Скрипт умирает не отработав
    #40029446
Фотография БурыйТина
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Продолжение

ЛогФайл вернул ошибку:
Connection timed out after 60000 milliseconds2020-12-20 11:28:45 зашли в обработку ошибки или пустого значения
2020-12-20 11:28:45 Запрос: http://ХХХХ
вернул ошибку:
Connection timed out after 60000 milliseconds2020-12-20 11:28:45 зашли в обработку ошибки или пустого значения
2020-12-20 11:28:45 Запрос: http://ХХХХ
вернул ошибку:
Connection timed out after 60000 milliseconds2020-12-20 11:28:45 зашли в обработку ошибки или пустого значения
2020-12-20 11:28:45 Запрос: http://ХХХ
вернул ошибку:
Connection timed out after 60000 milliseconds2020-12-20 11:28:45 зашли в обработку ошибки или пустого значения
2020-12-20 11:28:45 Запрос: http://ХХХХ
вернул ошибку:
Connection timed out after 60000 milliseconds2020-12-20 11:28:45 зашли в обработку ошибки или пустого значения
2020-12-20 11:28:45 Запрос: http:ХХХХ
вернул ошибку:
Connection timed out after 60000 milliseconds2020-12-20 11:28:45 зашли в обработку ошибки или пустого значения
2020-12-20 11:28:45 Запрос: http://ХХХ
вернул ошибку:
Connection timed out after 60000 milliseconds2020-12-20 11:28:45 зашли в обработку ошибки или пустого значения
2020-12-20 11:28:45 Запрос: http://ХХХХ



И так 2 Гигабайта
По логу видно что он не ждет 60 секунд. Что это может значить?
...
Рейтинг: 0 / 0
Скрипт умирает не отработав
    #40029452
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не понятно, почему крашится на curl_exec один раз, а в логе множественные записи. Есть внешний цикл, которого тут не видно?

Назначение цикла while в примере не понял, $data внутри цикла не меняется же.

Сделайте, пожалуйста, небольшой, но достаточно полноценный тестовый пример, иллюстрирующий проблему. Чтобы можно было его скопипастить с форума и запустить на своей машинке.
...
Рейтинг: 0 / 0
Скрипт умирает не отработав
    #40029474
Фотография БурыйТина
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Крашится curl_exec из этого цикла и записи из этого цикла, более внешнего цикла нет. Дата меняется от выполнения curl_exec. Много раз все отрабатывается хорошо и дает нужный результат, но после 40-50 вызовов происходит краш.
Пока писал, возникла мысль, может тот кто дает мне API считает что я слишком часто запросы делаю и тупо блочит меня? При этом не говоря это?
Надо попробовать паузу поставить между запросами.
Только вот не понимаю почему он не ждет 60 секунд, как в опциях написано? Может сразу ошибку получает? Но какую? как ее поймать и отработать?
Проблема возникает когда не отвечает API
Код прописать не могу, так как для чистоты эксперимента придется открывать АПИ источник и ключ.
...
Рейтинг: 0 / 0
Скрипт умирает не отработав
    #40029509
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нафига открывать то? Насколько понимаю, проблема проявляется при connection timeout, когда не удалось установить TCP-соединение с вебсервером. Бан по айпи на стороне вебсервера вполне подходит. Или вебсервер перегружен и не имеет возможности принять подключение.

Как вариант, возможно, но не уверен, не удалось установить защищенное соединение, в том числе, по причине проблем с проверкой сертификата SSL.

В простейшем случае можно сделать обращение на свой же вебсервер, который то доступен, то недоступен (остановлен, порт не слушает). Включать/выключать можно хоть ручками.


БурыйТина
Крашится curl_exec из этого цикла
Дык в ЭТОМ цикле нет вызова курла. Как он крашится? И крашится ли с полным прекращением процесса php или как иначе. Потому и предлагаю не дергать кусками код, а сделать полноценный пример.


БурыйТина
Только вот не понимаю почему он не ждет 60 секунд, как в опциях написано? Может сразу ошибку получает? Но какую? как ее поймать и отработать?
Аналогично, не понятно. Можно попробовать запустить скрипт из консоли с трассировкой (strace или truss в зависимости от ОС) или под отладчиком. Может прольет какой-то свет, даст понимание последовательности вызовов хотя бы...., а может и нет.
...
Рейтинг: 0 / 0
Скрипт умирает не отработав
    #40031945
Фотография БурыйТина
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот код целиком

Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
$start = microtime(true);
	set_time_limit(600);
	
	$key = API_KEY;
	$host = TIME_WEB_HOST;
	$user = TIME_WEB_USER;
	$pass = TIME_WEB_PASS;
	$base = TIME_WEB_BASE;
	$date = date('Y-m-d H:i:s'); file_put_contents(dirname(__FILE__)."/logs/curl_info.log", "\n\n $date *****************ПОПЫТКА СКАЧАТЬ ФАЙЛ***************\n Адрес для скачивания https://?key=$key&pdfUrl=$arg \n", FILE_APPEND);	
	$link = new mysqli($host, $user, $pass, $base);
	$sql = "SELECT * FROM files WHERE URL = '$arg'";
	if(!$link->ping){$link = new mysqli($host, $user, $pass, $base);}
	$sql_result = $link->query($sql);
	$nr = $sql_result -> num_rows;//mysqli_num_rows($sql_result);
	if($nr == 0){//Не скачивали этот файл
		$date = date('Y-m-d H:i:s'); file_put_contents(dirname(__FILE__)."/logs/curl_info.log", "$date Файл не загружался ранее \n", FILE_APPEND );
		$ch = curl_init("https://?key=$key&pdfUrl=$arg");
		$fname = getRandomFileName(dirname(__FILE__)."/", "pdf");
		$tmp = dirname(__FILE__)."/!tmp";
		$fp = fopen($tmp, 'wb');
		curl_setopt($ch, CURLOPT_FILE, $fp);
		curl_setopt($ch, CURLOPT_HEADER, 0);
		curl_setopt($ch, CURLOPT_TIMEOUT, 60); //CURLOPT_TIMEOUT => 60
		do{
			$date = date('Y-m-d H:i:s'); file_put_contents(dirname(__FILE__)."/logs/curl_info.log", "$date *****************ПОПЫТКА СКАЧАТЬ ФАЙЛ***************\n", FILE_APPEND);	
			set_time_limit(600);
			//sleep(61);
			curl_exec($ch);
			if(curl_errno($ch)){
				$date = date('Y-m-d H:i:s'); file_put_contents(dirname(__FILE__)."/logs/curl_info.log", "$date curl_errno - ".curl_errno($ch), FILE_APPEND);
				
				//throw new Exception(curl_error($ch));
				
				
				}
			$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);	
			$content_length_download = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
			$curl_info_size_download =  curl_getinfo($ch, CURLINFO_SIZE_DOWNLOAD);
			$date = date('Y-m-d H:i:s'); file_put_contents(dirname(__FILE__)."/logs/curl_info.log", "$date http_code - $http_code  content_length_download - $content_length_download curl_info_size_download - $curl_info_size_download
			Время выполнения скрипта: ".round(microtime(true) - $start, 4)." сек.\n", FILE_APPEND);	
			}while($http_code!=200);	
		//$info = curl_getinfo($ch);	
		//print_r($info);
		curl_close($ch);
		fclose($fp);
		file_put_contents($fname, file_get_contents($tmp));	
		if(($file_size = filesize($fname))==0){
			unlink($fname);
			}else{
				$sql = "INSERT INTO files
				(URL, download_to)
				VALUES
				('$arg','$fname')";
				if(!$link->ping){$link = new mysqli($host, $user, $pass, $base);}
				$sql_result = $link->query($sql);	
				$file_id = $link->insert_id;

			}
			
		}else{//Есть кэшированные данные			
		$row = $sql_result -> fetch_assoc();
		$fname = $row['download_to'];
		$file_id = $row['pk'];
		$date = date('Y-m-d H:i:s'); file_put_contents(dirname(__FILE__)."/logs/curl_info.log", "$date Файл загружен из кэша $fname\n", FILE_APPEND );
		}
	

	//$date = date('Y-m-d H:i:s'); file_put_contents(dirname(__FILE__)."/logs/curl_info.log", "$date http_code - $http_code content_length_download - $content_length_download file_size - $file_size curl_info_size_download $curl_info_size_download, arg - $arg\n", FILE_APPEND );	
	$date = date('Y-m-d H:i:s'); file_put_contents(dirname(__FILE__)."/logs/curl_info.log", "$date fname - $fname\n", FILE_APPEND );	
	return $file_id;
	$date = date('Y-m-d H:i:s'); file_put_contents(dirname(__FILE__)."/logs/curl_info.log", "$date file_id - $file_id\n", FILE_APPEND );	
}




В логе всегда все заканчивается одинаково

curl_info.log

2020-12-28 19:29:52 *****************ПОПЫТКА СКАЧАТЬ ФАЙЛ***************
Адрес для скачивания https://pdf
2020-12-28 19:29:52 Файл не загружался ранее
2020-12-28 19:29:52 *****************ПОПЫТКА СКАЧАТЬ ФАЙЛ***************




И после этого тишина.

До этого может быть скачано несколько файлов успешно, а может и вообще ничего не скачать.
Как с этим бороться?

ЗЗы время отключки скрипта всегда разное, техподдержка таймвеба не видит ничего, что бы прибивало скрипт
...
Рейтинг: 0 / 0
Скрипт умирает не отработав
    #40032010
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
БурыйТина
Вот код целиком
Если это тестовый пример, который любой участник форума мог бы скопировать и запустить на своем компе, покрутить так и эдак и поискать проблему, то тут явно не хватает структуры таблицы и ее наполнения. Не понятно только, нафига нужна эта таблица (как дополнительая потенциальная проблема) для простейшего теста. А так же реально действующего адреса или скрипта, который мог бы сформировать внятный ответ. Нелишним было бы указать версии ПО и способ запуска скрипта. Функцию getRandomFileName, если без нее никак нельзя обойтись, тоже следует включить в файл.

Если же это некая рыба, которую следует обработать напильником по своему соображению... Не знаю, кому как, вот мне лень этим заниматься.

Ладно. Если предполагаете, что проблема где-то в курле, тогда есть вот какое предложение. Не упираться в курл, а реализовать запрос/получение контента с удаленного сервера на более низком уровне, на сокетах. Понятно, что код будет строк на десять длиннее. Однако, возможностей для логгирования чуточку больше.

БурыйТина
Как с этим бороться?
А какие способы Вы уже пробовали за более чем десять дней?
Задали вопрос техподдержке. Они не увидели проблему на реальном скрипте. Понятно.
И всё?
...
Рейтинг: 0 / 0
Скрипт умирает не отработав
    #40032019
Фотография БурыйТина
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vkle,

Спасибо за ответ!
Я не имею опыта программирования и не имею соответствующего образования. Решаю прикладную задачу под себя лично.

теперь по деталям начнем с простого

Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
function getRandomFileName($path, $extension='')
    {
        $extension = $extension ? '.' . $extension : '';
        do {
            $name = substr(md5(microtime() . rand(0, 9999)), 0, 20);			
            $file = $path . $name . $extension;		
        } while (file_exists($file));
        return $file;
    }



Что касаемо таблицы, то это кэш своеобразный, чтобы 2 раза не скачивать одно и тоже

По последнему
авторА какие способы Вы уже пробовали за более чем десять дней?
Задали вопрос техподдержке. Они не увидели проблему на реальном скрипте. Понятно.
И всё?


Сделал все что смог, на что хватает знаний и образования.
Всячески изучил курл, много нового узнал, поигрался с таймаутами, ожиданиями и т.д.
Понял что никак сам не справлюсь и пришел сюда, узнал новое слово "сокеты" пошел гуглить что это и говнокодить. Что умею ...
Спасибо что помогаете.
...
Рейтинг: 0 / 0
Скрипт умирает не отработав
    #40032051
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Отчасти странная функция. Есть же готовая https://www.php.net/manual/ru/function.tempnam для аналогичной цели.
Впрочем, и в том и в другом случае дерево для кэша не создается. А значит, по мере наполнения файлами (единицы тысяч) "плоской" директории появятся тормоза. Чем больше файлов - тем заметнее.
В ряде случаев кеш проще в базе хранить. Здесь как раз такой случай - им файла можно получить только лишь из базы, так почему бы сразу из базы не получить контент? Минус обращение к ФС получается. Впрочем, это вопрос другого толка, к данной теме отношения не имеет.

БурыйТина
пошел гуглить

По сокетам в документации есть, с примерами: https://www.php.net/manual/ru/function.fsockopen
...
Рейтинг: 0 / 0
Скрипт умирает не отработав
    #40032101
Фотография БурыйТина
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я наигрался с попыткой хранения JSON ответов в БД, целый день пытался понять что я делаю не так, а потом узнал что моя версия MYSQL не позволяет хранить JSON. И когда очередь дошла до хранения PDF я как то не думал даже о его хранении в БД, а сделал хранение в ФС сразу.
Тут у меня возникает еще одна проблема, иногда почему-то файл скачивается не полностью. В отчете отдан весь файл, судя по объему переданных данных, а по факту получаю "битый" pdf. Таких файлов около 10% получается.
Про хранение в базе услышал, а пока писал возникла мысль, может эти файлы разнести как-то по директориям? Получать общее количество файлов в директории и создавать следующую? Вы это имели ввиду когда писали дерево для кэша? Я только со второго прочтения понял.
Я бы не хотел базу файлами забивать или это совсем не страшно?
Про https://www.php.net/manual/ru/function.tempnam не знал, поэтому "слепил" странную функцию.
За сокеты спасибо, читаю, очень интересная тема оказалась.
...
Рейтинг: 0 / 0
Скрипт умирает не отработав
    #40032102
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
БурыйТина
а потом узнал что моя версия MYSQL не позволяет хранить JSON.
А вот не надо хранить JSON именно как JSON, если данные требуется только хранить , и не более того. Мускулячий тип данных JSON сильно для другого предназначен, чем просто для хранения.
По сути, JSON - это текст. Можете открыть в текстовом редакторе и убедиться. Для хранения же текста есть куча текстовых и бинарных (произвольные последовательности байтов) типов данных. Тынц . ENUM и SET не годятся, остальное вполне пригодно в зависимости от конкретной ситуации.

БурыйТина
В отчете отдан весь файл, судя по объему переданных данных, а по факту получаю "битый" pdf. Таких файлов около 10% получается.
PDF - бинарные данные. Возможно, с заголовками что-то не так. Не буду гадать, смотреть надо реально проблемный файл - как отдается, на чем срубается. Чудеса нынче бывают кране редко.

БурыйТина
может эти файлы разнести как-то по директориям? Получать общее количество файлов в директории и создавать следующую? Вы это имели ввиду когда писали дерево для кэша?
Да. Варианты реализации разные бывают. Довольно часто для имени файла используется фиксированное количество десятичных цифр или шестнадцатиричных цифр (например, хэш MD5 имеет 32 шестнадцатиричные цифры). Для именования директорий в дереве берутся первые три десятичные цифры от имени файла (получается не более 1000 вложенных объектов в директории) или две шестнадцатиричные (не более 256) на первом уровне вложенности. Так же две или три следующие на втором уровне и т.д.

БурыйТина
Я бы не хотел базу файлами забивать или это совсем не страшно?
СУБД по барабану, что вы в ней храните. Ограничения на объемы есть, конечно, и, гипотетически, в них можно впереться. Лучше сперва посмотреть, разумеется, лезут ли ваши гигабайты данных в максимально допустимые размеры текстовых или бинарных полей. ;-)
Однако, в большинстве случаев следует обращать внимание на структуру таблиц. Например чтобы при JOIN временные таблицы значительных размеров не создавались и/или не падали на диск в обязательном порядке.

Однако, это всё за рамками данного топика.
...
Рейтинг: 0 / 0
Скрипт умирает не отработав
    #40032120
Фотография peter64
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
БурыйТина,
б24 часом не под IIS работает?
...
Рейтинг: 0 / 0
Скрипт умирает не отработав
    #40032159
Фотография БурыйТина
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
peter64,
Не знаю, он облачный
...
Рейтинг: 0 / 0
Скрипт умирает не отработав
    #40032187
Фотография peter64
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
БурыйТина,
попробуйте в начало скрипта вставить error_reporting(E_ALL) и посмотрите результат;
Была похожая проблема с IIS. При обработке exсel файлов вылетал скрипт.
У IIS было ограничение по времени работы скрипта.
...
Рейтинг: 0 / 0
Скрипт умирает не отработав
    #40032199
Фотография peter64
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
БурыйТина,
https://stackoverflow.com/questions/31472800/connection-timed-out-after-10000-milliseconds-in-curl-and-php-geocoder
Рекомедуют : curl_setopt($curl, CURLOPT_TIMEOUT,0);

Ваша ошибка :
Connection timed out after 60000 milliseconds2020-12-20 11:28:45 зашли в обработку ошибки или пустого значения
2020-12-20 11:28:45 Запрос: http:ХХХХ
У Вас в скрипте : curl_setopt($ch, CURLOPT_TIMEOUT, 60); //CURLOPT_TIMEOUT => 60
Возможно поможет.
...
Рейтинг: 0 / 0
Скрипт умирает не отработав
    #40032357
Фотография БурыйТина
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
peter64,

авторпопробуйте в начало скрипта вставить error_reporting(E_ALL) и посмотрите результат;
Была похожая проблема с IIS. При обработке exсel файлов вылетал скрипт.
У IIS было ограничение по времени работы скрипта.

Спасибо, вставил

авторБурыйТина,
https://stackoverflow.com/questions/31472800/connection-timed-out-after-10000-milliseconds-in-curl-and-php-geocoder
Рекомедуют : curl_setopt($curl, CURLOPT_TIMEOUT,0);



Это не буду, так как после таймаута, должны делать запрос повторно, источник данных не всегда отвечает.
...
Рейтинг: 0 / 0
Скрипт умирает не отработав
    #40032368
Фотография БурыйТина
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vkle,

Очень интересно оказалось про сокеты.
Страницы открывать научился через SSL, но вот PDF скачивать не получается

Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
$port = 443;
$timeout = 30;
$host = "torta-torta.ru";
$path = "docs/pustoy-fayl-pdf-5-5d1eee323ff31-5d43c64a48619.pdf"; 
$opts = array(
    'ssl' => array(
        'verify_peer' => false,
        'verify_peer_name' => false
    ),
	'header'=>array(
		"Accept-language: ru\r\n" .
        "Cookie: foo=bar\r\n" .
		"charset: windows-1251"
			)
);
$context = stream_context_create($opts);
$fp = stream_socket_client('ssl://'.$host.':'.$port, $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $context);
if (!$fp) {
    echo "Ошибка создания сокета $errstr ($errno)
\n";
} else {
	//fwrite($fp, $out);
    $out = "GET /$path  HTTP/1.1\r\n";
    $out .= "Host: $host\r\n";
    $out .= "Connection: Close\r\n\r\n";
	echo "$out
\n";
    fwrite($fp, $out);
	
    while (!feof($fp)) {
        echo fgets($fp, 128);
    }
	
    fclose($fp);
}



Вот скрипт, дает вот такой ответ

авторGET /docs/pustoy-fayl-pdf-5-5d1eee323ff31-5d43c64a48619.pdf HTTP/1.1 Host: torta-torta.ru Connection: Close
HTTP/1.1 400 Bad Request Date: Tue, 29 Dec 2020 13:59:32 GMT Server: Apache/2.4.29 (Ubuntu) Content-Length: 312 Connection: close Content-Type: text/html; charset=iso-8859-1
Bad Request
Your browser sent a request that this server could not understand.
Apache/2.4.29 (Ubuntu) Server at www.codestudio.site Port 443



Что не так? Почему файл "забрать" не могу?
...
Рейтинг: 0 / 0
Скрипт умирает не отработав
    #40032410
Фотография БурыйТина
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Стоило задать вопрос, сразу пришел ответ
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
if (!$fp) {
    echo "Ошибка создания сокета $errstr ($errno)
\n";
} else {
	echo "Сокет успешно создан: $fp
\n";
	
    fwrite($fp, "GET /$path HTTP/1.0\r\nHost: $host\r\nAccept: */*\r\n\r\n");
	
    while (!feof($fp)) {
        echo fgets($fp, 128);
    }
	
    fclose($fp);



Все успешно выбрасывает в браузер. Теперь надо понять где начало и конец и как выделить именно PDF файл из ответа. Я думаю что действительно через сокеты будет надежнее качать чем курлом
...
Рейтинг: 0 / 0
Скрипт умирает не отработав
    #40032457
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
БурыйТина
Теперь надо понять где начало и конец и как выделить именно PDF файл из ответа.

Стандартная структура:
1. Заголовки HTTP.
2. Пустая строка (означает окончание заголовков).
3. Тело ответа (контент).

Начните с изучения заголовков ответа сервера. Там может быть отражено множество нюансов.
А лучше, до того, с изучения основ протокола HTTP. Сложного там нет ничего, а лишним оно вряд ли будет. Похожие структуры найдете в других местах, например, в SIP.
...
Рейтинг: 0 / 0
Скрипт умирает не отработав
    #40032490
Фотография БурыйТина
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vkle,

Да уже разобрался, спасибо
Код: php
1.
	list($header, $body) = explode("\r\n\r\n", $result, 2);


Вот так прекрасно разделяет и тело потом сохраняем в файл pdf
сейчас научусь разбирать заголовок. Мне по сути из него нужен ответ 200 или иной, и размер контента, чтобы сравнить с сохраненным файлом. Вы очень мне помогли дав правильное направление. По крайней мере в сокетах четко работает таймаут и процент удачных загрузок выше, чем у курла. Теперь смогу замыкать это в бесконечные циклы и запрещать выход без скачивания файла.
Останется только научиться еще сравнивать и сливать 2 JSON файла, чтобы в битрикс отдавать не всю "портянку" данных, а только новые данные и у меня одна часть будет сделана, можно будет в битриксе настроить бизнес процессы в зависимости от того, какие данные получены.
Спасибо большое за поддержку.
...
Рейтинг: 0 / 0
Скрипт умирает не отработав
    #40032493
Фотография БурыйТина
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дописал загрузку через сокеты.
Исходя из анализа логов, у источника API данных стоит какое-то ограничение, о котором мне не сказали, и после определенной частоты запросов сначала выдают 500, а если начинаю запрашивать далее то вообще перестают отвечать.
Сейчас попробую поиграть с ожиданиями типа sleep и подобрать оптимальную частоту запросов посмотрю что будет.
...
Рейтинг: 0 / 0
Скрипт умирает не отработав
    #40032514
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
БурыйТина
сравнивать и сливать 2 JSON файла
Получить из каждого JSON объект, а с ними уже выполнять сравнения, слияния и т.п. Не?


БурыйТина
сначала выдают 500, а если начинаю запрашивать далее то вообще перестают отвечать.
Гхм... Занятно. Не понятно, куда тут повод помирать скрипту затесался. Возможно, где-то на уровне библиотеки курла зашит. Выше, вроде, предлагал уже под отладчиком запустить срипт.

Ладно. Выходит, что торррррмоз, всё же, на удаленной стороне. И это надо как-то учесть.
Такая есть мысль. Таймауты сделать секунд пять. Может, семь... не более. Далее анализ всех ошибок. При тормозах или коде ответа не 200 сделать запись в лог и продолжить через минуту, полчаса, завтра... Если возможно, то продолжить со следующего за проблемным задания (гипотетически, удаленный сервер может на каких-то проблемных данных сваливаться в ошибку), чтобы исключить затык на каком-то одном проблемном. Тут есть, конечно, варианты.
...
Рейтинг: 0 / 0
Скрипт умирает не отработав
    #40032721
Фотография БурыйТина
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Написал источнику API данных, они признали проблему на их стороне, поправили. Теперь ошибки присутствуют иногда, но не в таком объеме.
...
Рейтинг: 0 / 0
Скрипт умирает не отработав
    #40034438
Фотография БурыйТина
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vkle
Отчасти странная функция. Есть же готовая https://www.php.net/manual/ru/function.tempnam для аналогичной цели.
Впрочем, и в том и в другом случае дерево для кэша не создается . А значит, по мере наполнения файлами (единицы тысяч) "плоской" директории появятся тормоза. Чем больше файлов - тем заметнее.
В ряде случаев кеш проще в базе хранить. Здесь как раз такой случай - им файла можно получить только лишь из базы, так почему бы сразу из базы не получить контент? Минус обращение к ФС получается. Впрочем, это вопрос другого толка, к данной теме отношения не имеет.


Дошли руки до этого замечания. Не поделитесь ли примером, как дерево для кэша создавать?
...
Рейтинг: 0 / 0
33 сообщений из 33, показаны все 2 страниц
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / Скрипт умирает не отработав
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]