1. Получаю xml
2. Достаю все заголовки
3. Достаю ссылки на полные новости в массив
4. Перебираю через foreach, и там же работаю preg_match_all - чтобы вытащить в цикле все тексты новостей из общего контента.
По отдельности бегает, а вот когда п.4 ес-но
Fatal error: Maximum execution time of 60 seconds exceeded
Вроде логичный алгоритм, но такая беда.
Или есть вариант по оптимальней?
Спустя 25 минут, 52 секунды (20.09.2011 - 18:18) caballero написал(а):
установи тайм аут в php побольше
а что иначче можно посоветовать не видя файла
или покури в сторону xpath может можно выгрести все сразу
а что иначче можно посоветовать не видя файла
или покури в сторону xpath может можно выгрести все сразу
Спустя 2 минуты, 52 секунды (20.09.2011 - 18:21) Игорь_Vasinsky написал(а):
да не xml парсится шустро, а вот в цикле по линкам бегать и регуляркой шарить - вот тут таймаут.
Спустя 12 минут, 27 секунд (20.09.2011 - 18:33) Игорь_Vasinsky написал(а):
таймаут не дадут на хосте менять.
Спустя 3 минуты, 15 секунд (20.09.2011 - 18:36) Игорь_Vasinsky написал(а):
так.. а если в буфер получить страницу ?? это повлияет на скорость?
Спустя 6 минут, 41 секунда (20.09.2011 - 18:43) Winston написал(а):
Цитата (Игорь_Vasinsky @ 20.09.2011 - 18:36) |
так.. а если в буфер получить страницу ?? это повлияет на скорость? |
Должно немного быстрее быть. Но лучше покажи код.
Спустя 6 минут, 17 секунд (20.09.2011 - 18:49) Игорь_Vasinsky написал(а):
в коде много всего лишнего, объяснять долго - меня сам алгоритм волнует.
1.foreach
После того как я получаю ссылки на полные новости - я забиваю новый массив (страницами через file_get_contents())
2. foreach
Прохожу по массиву preg_match_all - забиваю новый массив "чистыми новостями"
Так вот 1й foreach - проходит, а дальше не успевает... новостей то шт 30
Думал while, попробую - по статистике foreach вроде быстрее
Так же смотрел - sleep() установить после первого foreach - да чё то не логично - время работы скрипта увеличу только.
С буфером..... сомнительно.
Может кто писал такой граббер?
1.foreach
После того как я получаю ссылки на полные новости - я забиваю новый массив (страницами через file_get_contents())
2. foreach
Прохожу по массиву preg_match_all - забиваю новый массив "чистыми новостями"
Так вот 1й foreach - проходит, а дальше не успевает... новостей то шт 30
Думал while, попробую - по статистике foreach вроде быстрее
Так же смотрел - sleep() установить после первого foreach - да чё то не логично - время работы скрипта увеличу только.
С буфером..... сомнительно.
Может кто писал такой граббер?
Спустя 3 минуты, 18 секунд (20.09.2011 - 18:53) Winston написал(а):
Цитата (Игорь_Vasinsky @ 20.09.2011 - 18:49) |
Так вот 1й foreach - проходит |
Можно вместо foreach попробовать сделать array_map + create_function();
Возможно будет какой-то выигрыш.
Спустя 2 минуты, 17 секунд (20.09.2011 - 18:55) neadekvat написал(а):
Цитата (Игорь_Vasinsky @ 20.09.2011 - 19:33) |
таймаут не дадут на хосте менять. |
Ошибка разве не к директиве time_limit (ф-я устаовки set_time_limit) относится? Ставишь в 0 и усе.
Спустя 2 минуты, 31 секунда (20.09.2011 - 18:57) alex12060 написал(а):
neadekvat
На многих хостингах эта функция заблокирована
На многих хостингах эта функция заблокирована
Спустя 6 минут, 53 секунды (20.09.2011 - 19:04) Игорь_Vasinsky написал(а):
Буфер не помог.
php_value set_time_limit 0 в htaccess
не реагирует
ini_set("max_execution_time", "0"); в начале кода - пока жду... шуршит...
php_value set_time_limit 0 в htaccess
не реагирует
ini_set("max_execution_time", "0"); в начале кода - пока жду... шуршит...
Спустя 6 минут, 38 секунд (20.09.2011 - 19:11) Игорь_Vasinsky написал(а):
ща ещё хочу попробовать разделить парсер xml и дальнейший парсинг ссылок из него на 2 скрипта..
Спустя 1 минута, 31 секунда (20.09.2011 - 19:13) Winston написал(а):
Вверху скрипта напиши
set_time_limit(0);
Спустя 31 секунда (20.09.2011 - 19:13) Игорь_Vasinsky написал(а):
))))) 3 минуты шуршал.... а я забыл вывод включить... и не знаю забился массив или нет дубль 2
Спустя 8 минут, 38 секунд (20.09.2011 - 19:22) neadekvat написал(а):
Цитата (alex12060 @ 20.09.2011 - 19:57) |
На многих хостингах эта функция заблокирована |
Порой у меня возникает чувство, что люди выбирают хостинг по списку заблокированных функций (чем больше - тем лучше), а не по количеству разрешенных действий и доступных дополнительных (не php) функций.
Это закрыто, то закрыто... Да найдите один, где все это можно - это _базис_, создаете сами себе проблемы и потом улюлюкаете - ой, а у нас так нельзя, давайте другой вариант мне. Ичо?
PS Алекс, это не к тебе лично. Так. В космос.
Игорь_Vasinsky, перепробовал все варианты, а прочитать то, что я написла в скобках - это уже сложно оказалось?
Спустя 4 минуты, 30 секунд (20.09.2011 - 19:26) Игорь_Vasinsky написал(а):
таймаут я снял, спасиб... я щас пробую найти решение как сократить время работы скрипта.
Спустя 10 минут, 39 секунд (20.09.2011 - 19:37) Winston написал(а):
Цитата (Игорь_Vasinsky @ 20.09.2011 - 17:52) |
Вообщем вместо cUrl я использую file_get_contents |
А вместо file_get_contents попробуй
simplexml_load_file('http://адрес');
Он уж точно быстрее будет чем file_get_contents + preg_match_all
Спустя 13 минут, 14 секунд (20.09.2011 - 19:50) Игорь_Vasinsky написал(а):
XML - я один раз прошу и быстро его получаю, у меня затраты времени на получение страниц с полными новостями в foreach + preg_match_all
Спустя 3 минуты, 37 секунд (20.09.2011 - 19:54) twin написал(а):
sleep() помоему не учитывается во времени на таймоут.
Спустя 43 секунды (20.09.2011 - 19:54) Игорь_Vasinsky написал(а):
Да.. я уже уточнил.
вот другой вопрос:
этот пример сделает $page подмассивов $content_found в $all ? т.е. слишком мудрёно вложженые массивы у меня будут?
как обойти этот момент?
вот другой вопрос:
//$pages - массив с сырым контентом страниц
$content_found = array();
$all = array();
foreach($pages as $page)
{
preg_match_all($pattern, $page, $content_found[], PREG_PATTERN_ORDER);
}
этот пример сделает $page подмассивов $content_found в $all ? т.е. слишком мудрёно вложженые массивы у меня будут?
как обойти этот момент?
Спустя 7 минут, 56 секунд (20.09.2011 - 20:02) twin написал(а):
Я не понял, новости в формате XML? Если так, зачем мудрить, есть же штатные средства для его разбора...
Спустя 6 минут, 35 секунд (20.09.2011 - 20:09) Игорь_Vasinsky написал(а):
в том то и дело в xml - тока ссылки на полные новости, а они в контексте самого сайта.
Спустя 3 минуты, 6 секунд (20.09.2011 - 20:12) Игорь_Vasinsky написал(а):
да блин.. а где мои согруппники то?
Спустя 19 минут, 18 секунд (20.09.2011 - 20:31) Winston написал(а):
Игорь_Vasinsky
Дай адрес XML с ссылками.
Дай адрес XML с ссылками.
Спустя 1 минута, 23 секунды (20.09.2011 - 20:33) Игорь_Vasinsky написал(а):
Спустя 3 минуты, 28 секунд (20.09.2011 - 20:36) Игорь_Vasinsky написал(а):
что то мне кажется что провайдер - по головке не погладит за такой скрипт
30 новостных страниц - 3,5-4 минуты.
30 новостных страниц - 3,5-4 минуты.
Спустя 13 минут, 15 секунд (20.09.2011 - 20:49) Winston написал(а):
Игорь_Vasinsky
Сейчас, пойду перекушу, и попробую оптимизировать, чтобы быстрее работало..
Сейчас, пойду перекушу, и попробую оптимизировать, чтобы быстрее работало..
Спустя 1 минута, 1 секунда (20.09.2011 - 20:50) Игорь_Vasinsky написал(а):
ну если время есть - то спасиб, приятного.
Спустя 26 минут, 36 секунд (20.09.2011 - 21:17) killer8080 написал(а):
Игорь_Vasinsky
а как тебе такой вариант, разбиваешь задачу на два скрипта.
script1.php
script2.php
Таким способом ты не только обойдёшь ограничение по времени, но и ускоришь процесс распараллеливанием, эмуляцией многопоточности.
а как тебе такой вариант, разбиваешь задачу на два скрипта.
script1.php
// парсим xml, получаем все ссылки в массив $links
...
// перебираем ссылки и формируем пост запросы ко второму скрипту.
foreach($links as $link){
$post = 'job='.urlencode($link);
$req = 'POST /script2.php HTTP/1.0'."\r\n".
'Host:'.$_SERVER['HTTP_HOST']."\r\n".
'Content-Length:'.strlen($post)."\r\n".
"\r\n".
$post;
$f = fsockopen('127.0.0.1', 80);
if($f){
fwrite($f, $req);
fclose($f);
}
}
script2.php
// получаем контент одной страницы запрошенной из первого скрипта
$content = file_get_contents($_POST['job']);
preg_match('regexp', $content, $match);
// парсим и сохраняем результат
Таким способом ты не только обойдёшь ограничение по времени, но и ускоришь процесс распараллеливанием, эмуляцией многопоточности.
Спустя 7 минут, 5 секунд (20.09.2011 - 21:24) Игорь_Vasinsky написал(а):
ну я планировал распределить на 2 скрипта, а твой пример вообще не понял
Цитата |
foreach($links as $link){ $post = 'job='.urlencode($link); $req = 'POST /script2.php HTTP/1.0'."\r\n". 'Host:'.$_SERVER['HTTP_HOST']."\r\n". 'Content-Length:'.strlen($post)."\r\n". "\r\n". $post; $f = fsockopen('127.0.0.1', 80); if($f){ fwrite($f, $req); fclose($f); } } |
Спустя 5 минут, 6 секунд (20.09.2011 - 21:29) killer8080 написал(а):
Цитата (Игорь_Vasinsky @ 20.09.2011 - 21:24) |
ну я планировал распределить на 2 скрипта, а твой пример вообще не понял |
В моём примере первый скрипт просто раздаёт задания другим экземплярам script2.php параллельно, не тратя время на ожидание результата их работы. То есть асинхронно.
Спустя 3 минуты, 19 секунд (20.09.2011 - 21:33) killer8080 написал(а):
Возможно в цикле через n-ное число итераций нужно поставить задержку, чтоб не перегружать сервак.
Спустя 40 секунд (20.09.2011 - 21:33) Игорь_Vasinsky написал(а):
я даже и не думал о такой реализации, ща попробую разобраться.
Спустя 1 минута, 27 секунд (20.09.2011 - 21:35) killer8080 написал(а):
в принципе второй скрипт можно было бы запускать не через http, а командной строкой, но не на всех хостингах оно позволено.
Спустя 31 секунда (20.09.2011 - 21:35) Winston написал(а):
Вот мой, так нужно? Посмотри.
PS: исполняется за 12-13 с.
Спустя 6 минут, 29 секунд Winston написал(а):
UDP
Подправил, уже 3-5 с
Свернутый текст
$start = microtime(true);
$xml = simplexml_load_file('http://www.liga.net/lenta/export/RSS/all.xml');
ob_start();
$links = '';
foreach($xml -> channel -> item AS $item)
$links .= '|' . $item -> link;
$links = array_diff(explode('|', $links), Array(''));
$page = array_map(create_function('$item', 'return file_get_contents($item);'), $links);
$content = array_map(create_function('$item', 'preg_match("#<span class=\"content\">(.*)</span>#isuU", $item, $matches); return $matches[1];'), $page);
$content = array_map(create_function('$item', 'return strip_tags($item);'), $content);
echo '<pre>'.htmlspecialchars(print_r($content, 1)).'</pre>';
$html = ob_get_contents();
ob_end_clean();
$end = microtime(true);
echo $html;
echo '<br/>' . ($end - $start);
PS: исполняется за 12-13 с.
Спустя 6 минут, 29 секунд Winston написал(а):
UDP
Подправил, уже 3-5 с
Спустя 11 минут, 14 секунд (20.09.2011 - 21:46) Игорь_Vasinsky написал(а):
Winston
ты где тестил? на денвере нехватка времени.
ты где тестил? на денвере нехватка времени.
Спустя 53 секунды (20.09.2011 - 21:47) killer8080 написал(а):
Цитата (Winston @ 20.09.2011 - 21:35) |
PS: исполняется за 12-13 с. |
у меня он отработал за 52 секунды.
Цитата (Winston @ 20.09.2011 - 21:35) |
UDP Подправил, уже 3-5 с |
а это за 41 с
Каков будет результат на хостинге трудно предугадать, к тому же он во многом зависит от сторонних сайтов.
Спустя 20 секунд (20.09.2011 - 21:48) Winston написал(а):
Игорь_Vasinsky
Цитата (Игорь_Vasinsky @ 20.09.2011 - 21:46) |
ты где тестил? на денвере нехватка времени |
Хм... У меня denwer на win7, браузер хром, за 3-5 с отрабатывается....
Спустя 1 минута, 31 секунда (20.09.2011 - 21:49) killer8080 написал(а):
Winston
Думаю от браузера тут мало что зависит
Думаю от браузера тут мало что зависит
Спустя 1 минута, 7 секунд (20.09.2011 - 21:50) Игорь_Vasinsky написал(а):
Winston
аналогичная сборка, прям 1 в 1
результат 104.334271193с
но выдача есть
спасиб.
это всё array_map() ?
аналогичная сборка, прям 1 в 1
результат 104.334271193с
но выдача есть
спасиб.
это всё array_map() ?
Спустя 1 минута, 59 секунд (20.09.2011 - 21:52) Winston написал(а):
Цитата (Игорь_Vasinsky @ 20.09.2011 - 21:50) |
результат 104.334271193с |
Ого
Спустя 1 минута, 26 секунд (20.09.2011 - 21:54) Игорь_Vasinsky написал(а):
счас 85.3663239479 - это поход от сайта зависит.
Спустя 1 минута, 3 секунды (20.09.2011 - 21:55) Winston написал(а):
Цитата (Игорь_Vasinsky @ 20.09.2011 - 21:54) |
это поход от сайта зависит |
Мне тоже так кажется, уже у меня 10с
Спустя 1 минута, 30 секунд (20.09.2011 - 21:56) Игорь_Vasinsky написал(а):
Лан. огромное спасибо. открыл для себя новую схему.
Спустя 39 минут, 45 секунд (20.09.2011 - 22:36) killer8080 написал(а):
Вот рабочий вариант
script1.php
script2.php
там каждая новость сохраняется в отдельный файл, для наглядности (file1.html ... file30.html)
script1.php
Свернутый текст
$t = microtime(1);
$path = substr(str_replace("\\", '/', dirname(__FILE__)).'/', strlen($_SERVER['DOCUMENT_ROOT']));
$xml = simplexml_load_file('http://www.liga.net/lenta/export/RSS/all.xml');
$links = array();
foreach($xml -> channel -> item AS $item)
$links[] = $item -> link;
$links = array_filter($links);
$i = 0;
foreach($links as $link){
$post = 'job='.urlencode($link).'&n='.++$i;
$req = 'POST '.$path.'script2.php HTTP/1.0'."\r\n".
'Host:'.$_SERVER['HTTP_HOST']."\r\n".
'Content-Length:'.strlen($post)."\r\n".
'Content-Type:application/x-www-form-urlencoded'."\r\n".
"\r\n".
$post;
$f = fsockopen('127.0.0.1', 80);
if($f){
fputs($f, $req, strlen($req));
fclose($f);
}
}
$t = microtime(1) - $t;
echo 'done for '.$t.' seconds <br>with '.$i.' iterations';
script2.php
Свернутый текст
if(empty($_POST['job'])) die();
$content = file_get_contents($_POST['job']);
preg_match("#<span class=\"content\">(.*)</span>#isuU", $content, $matches);
file_put_contents('file'.$_POST['n'].'.html', $content);
там каждая новость сохраняется в отдельный файл, для наглядности (file1.html ... file30.html)
Спустя 3 минуты, 46 секунд (20.09.2011 - 22:40) Игорь_Vasinsky написал(а):
ни чё себе.
Спустя 3 минуты, 18 секунд (20.09.2011 - 22:43) killer8080 написал(а):
так о тож
Спустя 1 минута, 23 секунды (20.09.2011 - 22:44) Игорь_Vasinsky написал(а):
Я без сарказма. Просто я с такими методами не сталкивался.
Спустя 7 секунд (20.09.2011 - 22:45) Winston написал(а):
Спустя 2 минуты, 26 секунд (20.09.2011 - 22:47) killer8080 написал(а):
я то же
просто вспомнился хак с виртуальной многопоточностью в php.
просто вспомнился хак с виртуальной многопоточностью в php.
Спустя 2 минуты, 21 секунда (20.09.2011 - 22:49) killer8080 написал(а):
только учти, что если ссылок будет слишком много, можно перегрузить сервак, выйти за лимиты памяти. На этот случай можно ввести слипы в цикл, через пару десятков итераций.
Спустя 2 дня, 23 часа, 24 минуты, 37 секунд (23.09.2011 - 22:14) Хиросим написал(а):
Вклинюсь в тему чтоб клоны не плодить.
У меня задача похожая, но проблема другая.
Я пытаюсь парсить страницу выдачи яндекса с целью определить проиндексированность УРЛа.
(Размещаю СЕО статьи на других сайтах и хочу придумать машинку для определения проиндексированности оных).
Ставлю задержку аж в 10 сек, но яндекс всеравно определяет меня как бота и выдает ругню.
Может ктонибудь знает как правильно задачу решить???
Если нужно, код такой:
У меня задача похожая, но проблема другая.
Я пытаюсь парсить страницу выдачи яндекса с целью определить проиндексированность УРЛа.
(Размещаю СЕО статьи на других сайтах и хочу придумать машинку для определения проиндексированности оных).
Ставлю задержку аж в 10 сек, но яндекс всеравно определяет меня как бота и выдает ругню.
Может ктонибудь знает как правильно задачу решить???
Если нужно, код такой:
//$result['link'] - УРЛ из базы
while ($result = mysql_fetch_assoc($query))
{
if ($result['link'] != '' && $result['link'] !== NULL)
{
$url = 'http://yandex.ru/yandsearch?text='.htmlentities(urlencode($result['link'])).'&lr=213';
if (file_get_contents($url) !== FALSE)
{
$yandex_string = file_get_contents($url);
if (strpos($yandex_string, ' href="'.$result['link'].'" ') !== FALSE)
{
$indexation = '<a href="'.$url.'">ok>></a>';
}
else
{$indexation = 'noInd';}
}
else
{$indexation = 'noUrl';}
sleep(10);
}
else
{$indexation = 'noLink';}
}
Спустя 12 минут, 17 секунд (23.09.2011 - 22:26) Игорь_Vasinsky написал(а):
Сдаётся мне тебе cURL поможет, он тебя замаскирует
Спустя 8 минут, 16 секунд (23.09.2011 - 22:34) Хиросим написал(а):
Нуда, я попытался вкурить cURL , но туговато для меня пока...
только что решил... правда через задний проход... вывел последний file_get_contents из цикла в браузер, отобразилась капча, я ее заполнил и яндекс поверил в мои благие намерения...
Прошу прощений за поспешный пост, буду штурмовать CURL
только что решил... правда через задний проход... вывел последний file_get_contents из цикла в браузер, отобразилась капча, я ее заполнил и яндекс поверил в мои благие намерения...
Прошу прощений за поспешный пост, буду штурмовать CURL
Спустя 16 секунд (23.09.2011 - 22:35) Winston написал(а):
Цитата (Игорь_Vasinsky @ 23.09.2011 - 22:26) |
Сдаётся мне тебе cURL поможет |
Поможет
Цитата (Игорь_Vasinsky @ 23.09.2011 - 22:26) |
он тебя замаскирует |
Ну если у него динамический IP то поможет, еще можно прокси заюзать через curl
Спустя 3 минуты, 39 секунд (23.09.2011 - 22:38) Игорь_Vasinsky написал(а):
А чё лин не выложил??? я знаю - у тя большой сундучёк...
Спустя 2 минуты, 38 секунд (23.09.2011 - 22:41) Winston написал(а):
Цитата (Игорь_Vasinsky @ 23.09.2011 - 22:38) |
А чё лин не выложил??? я знаю - у тя большой сундучёк |
Ну раз уж вас поисковики забанили, то сочувствую...
А я с ними дружу, потому можете здесь посмотреть, там все просто описано:)
Спустя 5 дней, 19 часов, 33 минуты, 4 секунды (29.09.2011 - 18:14) Winston написал(а):
Еще актуально или уже нет ?
Решил познакомится с multi-curl. Однако это весчь !!! :)
И немного переписал свой предыдущий пример с помощью multi-curl и добился фантастических результатов (у себя на локалке) 30 страниц обрабатывает за 0.5 - 1.5 сек (!!!!!)
Потому, если кому не впадло, то потестите плиз скрип :rolleyes:
Решил познакомится с multi-curl. Однако это весчь !!! :)
И немного переписал свой предыдущий пример с помощью multi-curl и добился фантастических результатов (у себя на локалке) 30 страниц обрабатывает за 0.5 - 1.5 сек (!!!!!)
Потому, если кому не впадло, то потестите плиз скрип :rolleyes:
Свернутый текст
<?php
header("Content-Type: text/html; charset=utf-8");
set_time_limit(0);
$start = microtime(true);
$xml = simplexml_load_file('http://www.liga.net/lenta/export/RSS/all.xml'); // Получаем список URL'ов
ob_start();
$links = '';
foreach($xml -> channel -> item AS $item)
$links .= '|' . $item -> link; // Соединяем URL'ы
$links = preg_split('#\|#', $links, null, PREG_SPLIT_NO_EMPTY); // Возвращаем массив URL'ов
$countLinks = sizeof($links); // Количество URL'ов
$cmi = curl_multi_init(); // Инициализация сеанса мультикурл
for($i = 0; $i < $countLinks; $i++)
{
$cis[] = curl_init($links[$i]); // Создаем отдельный сеанс для каждой страницы
curl_setopt($cis[$i], CURLOPT_RETURNTRANSFER, true); // Возвращаем страницу
curl_multi_add_handle($cmi, $cis[$i]); // Добавляем дескрипторы каждой страницы в общую корзину (набор)
}
$run = null;
do
$cme = curl_multi_exec($cmi, $run); // Выполняем запросы пока в наборе есть еще ссылки
while($run > 0);
for($i = 0; $i < $countLinks; $i++)
{
$pages[] = curl_multi_getcontent($cis[$i]); // Получаем страницу в массив
curl_multi_remove_handle($cmi, $cis[$i]); // Удаляем дескриптор для только что выполненого сеанса
}
curl_multi_close($cmi); // Завершаем мультисеанс
// Возвращаем обработанную новость
$content = array_map(function($item) {preg_match("#<span class=\"content\">(.*)</span>#isuU", $item, $matches); return strip_tags($matches[1]);}, $pages);
echo '<pre>'.htmlspecialchars(print_r($content, 1)).'</pre>';
$html = ob_get_contents();
ob_end_clean();
$end = microtime(true);
echo $html;
echo '<br/>TIME: ' . ($end - $start);
Спустя 2 месяца, 21 день, 4 часа, 16 минут, 44 секунды (20.12.2011 - 22:31) NestoR написал(а):
Мне препод скинул класс динамической очереди и пример его применения, сейчас пытаюсь прикрутить к ним класс определения PageRank, прикладываю класс с примером. может кто из прошаренных коддеров разберется, как выполнить с его помощью определенную функию, куда там ее вызов приписать...
Спустя 1 минута, 1 секунда (20.12.2011 - 22:32) NestoR написал(а):
пример использования:
Спустя 3 минуты, 42 секунды (20.12.2011 - 22:36) NestoR написал(а):
упс. пардон, не в ту тему пост
_____________
HTML, CSS (Bootstrap), JS(JQuery, ExtJS), PHP, MySQL, MSSql, Posgres, (TSql, BI OLAP, MDX), Mongo, Git, SVN, CodeIgnater, Symfony, Yii 2, JiRA, Redmine, Bitbucket, Composer, Rabbit MQ, Amazon (SQS, S3, Transcribe), Docker