![]() |
Модераторы: korob2001, ginnie |
![]() ![]() ![]() |
|
Secandr |
|
|||
![]() Связист ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 4043 Регистрация: 3.8.2003 Где: Russia, Volgograd Репутация: 1 Всего: 39 |
Добрый день,
у меня есть пара простеньких демонов на perl. Основная их задача - сбор статистики с оборудование и запись данных в БД. Есть несколько САР на perl. Столкнулся с тем, что демоны и САР периодически дохнут при работе с БД. Превышение интервала ожидания, потеря конекта к БД, рестарт БД, ошибки в запросах,... приводят к смерти софтины. Перепускать скотинку приходится руками, что доставляет определённые неудобства. Написать ревайвел слишком просто, хотелось бы решить проблему средствами perl. В голову приходит - обернуть DBI своим классом и переназначить часть функционала DBI. Проверять адекватность коннекта, запускать функционал DBI в eval, анализировать коды ошибок, переконекчиваться, перезаливать данные в БД. После некоторого числа попыток или таймаута в несколько минут, тихо и мирно умирать, удаляя за собой pid файл, освобождая разделяемую память и закрывая коннекты ко всем БД. Может уже кто-то написал такой модуль? Подскажите пожалуйста. |
|||
|
||||
Bulat |
|
|||
![]() татарский Нео ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1701 Регистрация: 22.3.2006 Где: Альметьевск Репутация: 5 Всего: 57 |
Универсального модуля не писал, но по своему опыту и продолжая твою мысль, можно сделать некую обертку для реконнекта, в ней же проверять залилось все необходимое в базу(если нет - перезаливать), а как таковой обработки ошибок не делал, все сообщения об ошибках писал в лог, на всякий случай, лог вешал на ротацию. ![]() -------------------- менеджер по кодеврайтингу ![]() |
|||
|
||||
Secandr |
|
|||
![]() Связист ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 4043 Регистрация: 3.8.2003 Где: Russia, Volgograd Репутация: 1 Всего: 39 |
Ну я думаю так.
Делаем класс, который просто переназначает соответствующие методы класса DBI и делов-то. Там нужно переписать connect, disconnect, prepare, execute, do, fetchrow_array В основной же библиотеке просто мнеяем use DBI на use myDBI и создание объекта. Всего 4 строчки. В своём модуле уже проверять состояние линка каждый раз при вызове родной функции DBI, реконектиться по необходимости, обрабатывать ошибки. На первом этапе просто подменить класс и посмотреть как оно будет работать. А дальше уже можно добавить доп. логику. Ввести несколько механизмов поведения. Например для селекта пытаться несколько раз выполнить запрос, пока не будет получен результат. Для важных update и insert ввести проверку на выполнение Там где проверка затруднена или требует много ресурсов научить при ошибке выходить, закрывая за собой всё что надо. Как вариант, не делать exit, а посылать самому себе сигнал kill, что бы его перехватил соответствующий блок основной программы и вышел как полагается. Для неважных запросов можно игнорировать ошибку и продолжить работу без повторной перезаливки, просто погадив в логи. P.S. Вопрос только в том, не буду ли я изобретать велосипед. И будет ли мой велосипед достойнее тех, что уже сделаны. Это сообщение отредактировал(а) Secandr - 25.2.2015, 10:41 |
|||
|
||||
Bulat |
|
|||
![]() татарский Нео ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1701 Регистрация: 22.3.2006 Где: Альметьевск Репутация: 5 Всего: 57 |
если ты собираешься делать все это :
то потянет на велик. ![]() Все что тебе требуется, в принципе, хорошо уложиться в новую функцию без создания своего класса, ну максимум две функции, если еще кошерное логирование прикрутить. Есть нормальный коннект - заливаем данные, нет - пробуем два-три раза, до удачной попытки. После двух-трех неудачных попыток, не насилуем никого и ничего, а умираем с криками и орами в лог! ![]() Добавлено через 53 секунды Ну можешь и по своей логике идти, только смысл переписывать ряд функций из DBI, которые и так хорошо работают! ![]() -------------------- менеджер по кодеврайтингу ![]() |
|||
|
||||
Secandr |
|
|||
![]() Связист ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 4043 Регистрация: 3.8.2003 Где: Russia, Volgograd Репутация: 1 Всего: 39 |
Ну вот когда у тебя несколько десятков тысяч строк и вдруг надо поменять DBI в этом всём на что-то другое начинается веселье.
Откровенно лень переписывать пучу кода. Да и опасно. Код-то не ради кода написан, код управляет оборудованием, а отказ в работе оборудования очень неприятен для предприятия... Проще написать скрипт, который заменит DBI на myDBI и тут же наступит счастье ![]() Ну а myDBI будет делать так
Это сообщение отредактировал(а) Secandr - 25.2.2015, 11:40 |
|||
|
||||
Bulat |
|
|||
![]() татарский Нео ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1701 Регистрация: 22.3.2006 Где: Альметьевск Репутация: 5 Всего: 57 |
Если в огромном коде, глобальный хендл к бд везде вызывается напрямую, без инкапсуляций или каких-то иных функций-оберток, то myDBI - возможно и самое оптимальное решение!
![]() -------------------- менеджер по кодеврайтингу ![]() |
|||
|
||||
Secandr |
|
|||
![]() Связист ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 4043 Регистрация: 3.8.2003 Где: Russia, Volgograd Репутация: 1 Всего: 39 |
Ну там подход немного другой. БД обёрнута и работа большей части библиотеки идёт не с БД напрямую а с сущностями более конкретными, которые описывают рабочее тело. И 80% кода, работающего с БД, лежит в отдельном классе большой библиотеки.
Но есть и печаль. Часть нетипичной работы с БД ведётся напрямую из софта, вызывающего библиотеку, причём не через библиотеку, а напрямую через DBI. В целом же, проще всё же вынести функционал работы с БД в отдельный класс и уже с ним работать и из основной библиотеки и из софта. Попутно перетащив часть рутинных операций в этот класс. P.S. С каждым годом переписывать код становится всё тяжелее ![]() |
|||
|
||||
tzirechnoy |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1173 Регистрация: 30.1.2009 Репутация: нет Всего: 16 |
Хотите, чтобы иногда ->fetchall_arrayref вызывался по три раза? Ну, сделайте обёртку вида fetchall_arrayref_hard(dbh, ..., 3).
А вообще -- задача правильной обработки ошыбок и корректного преобразования мира при их наличии -- это именно прикладная задача. Она каждый раз будет решаться на основе вашэго прикладного кода, потому внутри DBD этому дажэ помочь особенно нечему. Ну и, конечно -- сделайте, наконец, так, чтобы mysql не дох. Я дажэ не предлагаю перейти на postgres (хотя это, конечно, стоило бы сделать, но не по этой причине) -- но, знаете, почему-то у сотен тысяч человек mysql работает и не дохнет. |
|||
|
||||
Сумасшедший |
|
|||
Чилавек-Каропка ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1503 Регистрация: 15.8.2004 Где: Москва Репутация: 1 Всего: 107 |
Приношу извинения что не про перл, но почему бы в данном случае не воспользоваться mysql-proxy?
-------------------- Однажды ты спросишь, а я отвечу: "Время ожидания специалиста - 10 минут". Ты бросишь трубку, так и не узнав, что Ваш звонок очень важен для нас! |
|||
|
||||
Secandr |
|
|||
![]() Связист ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 4043 Регистрация: 3.8.2003 Где: Russia, Volgograd Репутация: 1 Всего: 39 |
tzirechnoy, если руки дойдут переписать класс, я его потом покажу. Там задача немного более широкая. Но в целом вы правы, не имея понятия о бизнеслогике, нет возможности как-то повысить надёжность.
По поводу "что бы mySQL не дох" могу сказать следующее. Проект управляет сетью размером в 3 города, не считая мелких узлов по области и в столице. Есть несколько серверных ферм. Есть исторически сложившаяся инфраструктура: системы учёта сети, система электронного документооборота, системы мониторинга, технического аудита,... Каждая из систем работает со своей БД. Это и mySQL и postgresql и mssql и тот же битрикс на файликах. Мой софт работает с этим со всем, собирает данные, анализирует это всё и по заданному шаблону применяет настройки к железу. Задача - добиться стабильной и предсказуемой работы софта в аварийные периоды. С одной стороны - обеспечить адекватность при потере большей части инфраструктуры. В этом случае лучше умереть и ничего не делать. С другой стороны обеспечить надёжность при мелких авариях. Софт должен подождать спада пиковой нагрузки на сервере БД или спокойно перенести его перезагрузку. Иначе будет большой лаг от желания изменить настройки оборудования до их применения. Сумасшедший, в свете вышеперечисленого mysql-proxy - дополнительная точка отказа. Мы сейчас кластеры стали делать из mysql и postgresql во избежание. |
|||
|
||||
Pfailed |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 933 Регистрация: 19.7.2009 Репутация: 22 Всего: 39 |
https://metacpan.org/pod/DBD::mysql#mysql_auto_reconnect
Ну а ошибки обрабатывать естественно надо. Я обычно устанавливаю RaiseError =>1, PrintError => 0 и ловлю ошибки через eval. |
|||
|
||||
Secandr |
|
|||
![]() Связист ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 4043 Регистрация: 3.8.2003 Где: Russia, Volgograd Репутация: 1 Всего: 39 |
Натыкался в документации на такое, попробую на днях.
|
|||
|
||||
Secandr |
|
|||
![]() Связист ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 4043 Регистрация: 3.8.2003 Где: Russia, Volgograd Репутация: 1 Всего: 39 |
Не успел ничего путного сделать за неделю.
Добавил
|
|||
|
||||
Secandr |
|
|||
![]() Связист ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 4043 Регистрация: 3.8.2003 Где: Russia, Volgograd Репутация: 1 Всего: 39 |
Не помогло.
Теперь вылетает без ошибок :( |
|||
|
||||
noize |
|
|||
![]() 5.18.2 ![]() Профиль Группа: Участник Сообщений: 89 Регистрация: 10.7.2010 Где: СПб Репутация: 3 Всего: 3 |
простенький пример из жизни:
Т.е. суть работы - обернуть обращение к бд в один метод и вызывать его из всех своих скриптов. А в самом методе проверять подключение, делать реконнект и пр. |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Perl" | |
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Perl: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |