LINUX.ORG.RU

java - let it crash?

 


1

1

Кто-нибудь пробовал кодить на Java в стиле let it crash? Какие подводные камни?

Есть какие-нибудь готовые фреймворки/гипервизоры итп? (прозреваю, какой-то набор примитивов для программирования внутри vm, в т.ч. специальные примитивы многопточности. Возможно понадобится пачка пред-прогретых java-машин, общающихся через какой-нибудь бинарный протокол, и поддерживаемых гипервизором. Плюс )

Огромный профит в том числе в том, что жирное приложение, стартующее 40 минут на девелоперской машине и напичканое багами, не будет 1 несчастным экзепшеном расфигачено в кровь-кишки-расчлененку, и требовать перезапуска.

Интересна именно сама Java8 SE, а не scala+akka итп

Для тех кто не в теме: суть в неиспользовании defensive programming. Нить упала? Да и черт бы с ней! Не надо пытаться отловить ошибки и нормализовать выполнение. Убиваем ее и запускаем заново. Память не может быть read? По сети пришло не то? Руководитель - наркоман, а тимлидер - макдак? Let it crash!

Автобусы опаздывают? Экстерминатус. Ваш начальник отказывается повысить зарплату? Экстерминатус. Бывшая жена вас достает? Экстерминатус. Существует ли проблема, которую нельзя разрешить Экстерминатусом? Я такой пока не нашел.

— Инквизитор Лорд Котеас

★★★★☆

Последнее исправление: stevejobs (всего исправлений: 1)

let it crash оправдан в языках где создание процесса является крайне дешевой операцией и в случае неполадки его проще перезапустить. в случае с жабой все скатится в обычный падающий от каждого чиха говнокод.

anonymous
()
Ответ на: комментарий от anonymous

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

А можно сделать наоборот. Для начала, все экзепшены поудалять, и весь код обработать одним большим catchall экзепшеном. Если что-то случилось (что угодно) - context shared state обнуляется, и этот метод запускается заново. И будет запускаться заново до тех пор, пока либо не исчерпает набор ретраев, либо таки не доползёт до конца.

Или вот еще, в конце например можно выставлять пост-условия. Например, мы знаем что после вычисления чего-то там, int min должен быть меньше int max. Если постусловие не прошло, это по сути ассерт, а мы вместо ассерта отправляем метод на повторное выполнение.

Всё это в рамках еще одного треда, одного тотал-ордера. Можно как-нибудь извратиться и навешать те же пост-условия на несколько тредов сразу. Вот для этого нужны готовые примитивы, потому что если самостоятельно об этом всём думать, как оно выполняется, можно мгновенно крышей поехать.

Вообще какбе такие предложения обычно считаются за «эталонный говнокод». Но вот может быть, все эти люди неправы, и на самом деле это просто гениальная идея, все говнюки, один я весь в белом стою красивый.

stevejobs ★★★★☆
() автор топика
Ответ на: комментарий от stevejobs

А можно сделать наоборот. Для начала, все экзепшены поудалять, и весь код обработать одним большим catchall экзепшеном. Если что-то случилось (что угодно) - context shared state обнуляется, и этот метод запускается заново. И будет запускаться заново до тех пор, пока либо не исчерпает набор ретраев, либо таки не доползёт до конца.

те у кого мозоли от эксепшенов обычно делают

try {
//shit
} catch(Exception e) {
throw new RuntimeException(e);
}

только там будет интим с InterruptedException и прочими узаконенными костылями

Deleted
()

Может я чего не понимаю, но вообще-то web-приложения на джаве примерно в такой философии и пишутся.

asaw ★★★★★
()
Ответ на: комментарий от Deleted

ага, и если вылетело этот экзепшен, перезапускать тред

но вот что делать, если количество доступных тредов закончилось? Там же можно создать не больше 5 тысяч нативных тредов, это очень мало. А гринтреды покинули нас в джаве 1.3, да и были они не на всех платформах.

придется вручную елозить по каким-то пулам, очередям, как-то их шедулить, мутить свою память со своими правилами

интересно как всё это правильно организовать

stevejobs ★★★★☆
() автор топика
Последнее исправление: stevejobs (всего исправлений: 1)
Ответ на: комментарий от stevejobs

у тебя есть банальный таск в ExecutorService, оборачиваешь его в try-catch - вылетел экзепшен тыкаешь таск второй раз

если не быдлокодить утечки в threadLocal то все норм, но при желании даже они лечаться - в томкате у них есть костыль

Deleted
()

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

просто не пользуйся явой

umren ★★★★★
()
Ответ на: комментарий от Deleted

блин, щаз на работе, некогда полно ответить. Кажется, тут надо обсудить несколько проблем: actors, communicating sequential processes, green threads, java memory model, software transaction memory), вычисление actions/efforts для планировщика, и еще всякое разное.

Вроде бы, возможность просто фигачить на каждый чих новый таск в ExecutorService еще не значит, что на этом можно удобно писать код, понимать как он работает, и главное - иметь некие гарантии относительно этого кода.

stevejobs ★★★★☆
() автор топика
Ответ на: комментарий от Deleted

Я так не смогу, воспитание неправильное.

+1

А почему не было предложено варианта ПРОВЕРЯТЬ коды возврата функций и обходить участки кода которым нужно чтобы параметры были те или иные?

Я тоже не люблю экзепшены, но если с данными что-то не то (размер не тот, числа не те и т.п.) - код лучше просто пропустить мимо этих данных, чем ловить потенциальные экзепшены...

P.S. Это я не про жабу, а так - ваапсче. И ежели уже свалилась программа - то это караул ахтунг алярм - срочно искать ошибку - где же мы пропустили важную проверку. Я вот такого подхода придерживаюсь.

I-Love-Microsoft ★★★★★
()
Последнее исправление: I-Love-Microsoft (всего исправлений: 2)
Ответ на: комментарий от stevejobs

Кажется, тут надо обсудить несколько проблем: actors, communicating sequential processes, green threads, java memory model, software transaction memory), вычисление actions/efforts для планировщика, и еще всякое разное.

И лучше всего начать с того, что такое гипервизор, блять.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Блин, как это сложно. Думал вот щаз две строчки напишу на лоре, сразу все всё поймут и скажут истину в последней инстанции. Но чем больше думаю над этим, тем больше ничего не понимаю :(

stevejobs ★★★★☆
() автор топика
Ответ на: комментарий от stevejobs

мне кажется ты решаешь не ту проблему и не теми средствами, плодить процессы и эмулировать эрланг и игнорируя эксепшены не используя даже сторонние средства это как то.. дико что ли

umren ★★★★★
()
Ответ на: комментарий от stevejobs

тут надо обсудить несколько проблем: actors, communicating sequential processes, green threads, java memory model, software transaction memory), вычисление actions/efforts для планировщика, и еще всякое разное.

или породить, в общем тебе если хочется вздрючить сию тему то опиши связно мысль (в ЖЖ например, благо он у тебя есть) и чтобы было что обсуждать то

Deleted
()
Ответ на: комментарий от stevejobs

ничего сложного нет - хуже того неблокирующие алгоритмы примерно так и работают, а ты замахнулся на чуть более жирный кусок

Deleted
()
Ответ на: комментарий от I-Love-Microsoft

не про жабу, а так - ваапсче

Если про жабу, а так - ваапсче, то на этих ваших крестах программа может вообще в любом месте свалиться, потому что по стандарту нет гарантий на out-of-thin air values, то есть в любой момент может случиться всё что угодно в зависимости от примененных оптимизаций xD Короче, давайте не будем о грустном, а сразу о джабе.

но так как похоже получается, что нужно всё равно делать свою память, и даже свою абстракцию над «операциями», всё равно будет о грустном, об очень-очень грустном

stevejobs ★★★★☆
() автор топика
Последнее исправление: stevejobs (всего исправлений: 2)
Ответ на: комментарий от stevejobs

Я на python тоже придерживаюсь принципа что падать не должно, но вместо экзепшенов (что действительно засирает код) - проверяю данные. Если упало - для меня это чудовищная ошибка и недосмотр...

I-Love-Microsoft ★★★★★
()
Ответ на: комментарий от stevejobs

let it crash это не только «перезапускалка» некоторых тасков. вот простой пример: БД с REST-интерфейсом к ней. Что мы делаем следуя этой философии: создаем супервизор MainSup, который запускает собсвенно саму бд BD и ставит ей политику «перезапускать при падении», MainSup запускает следующий супервизор AcceptorSup (с той же политикой что и BD) который создает сокет, и плодит внутри себя воркеров для приема соединений (acceptor pool) с политикой «пусть падают», этот же MainSup запускает еще один супервизор WorkerSup (с политикой BD) который плодит воркеров для обработки REST запросов с политикой «пусть падают» (т.е. в случае ошибки просто рвем коннект с клиентом).

Если на жабе можно изобразить подобную конструкцию, то дерзай.

anonymous
()
Ответ на: комментарий от anonymous

где нормально почитать список типов политик супервизора с объяснением? Ты сейчас вообще про что, про Эрланг?

изобразить-то можно, вопрос в том как изобразить это хорошо. Чтобы всё было отлично, замечательно, sexy. И чтобы нигде в кустах не стоял рояль, из которого торчат уши. Ты сюда ходи, здесь таски пускай, а сюда не ходи, снег на бошку упадет, умереть не умрешь, но всю жизнь мучиться будешь.

stevejobs ★★★★☆
() автор топика
Последнее исправление: stevejobs (всего исправлений: 3)
Ответ на: комментарий от I-Love-Microsoft

Я тут колупнулся в склерозе и вспомнил такую штуку.

Дело было давно, ещё до джавы и буйного развития интернет. То есть интернет и джава были, но джава сознанием масс ещё не овладела, а без интернета легко можно было обойтись.

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

Я спросил, какая СУБД, какие данные нужно анализировать, в каком виде представлять и какая конфигурация рабочего места. Запустил свой любимый Уиндоуз и сел лабать. Я немного знал саму контору, т.к. делал там сетку и иногда проводил апгрейд железа.

Если бы я знал, на что подписался! =)

В общем, когда проинсталлировал и запустил свою поделку, выяснилось, что база изначально была спроектирована нормально, как я представлял со слов знакомого, но впоследствии в неё вносились изменения, после которых база велась совершенно диким и варварским образом. Следующие несколько суток были просто адовыми. Мне пришлось нормализовать таблицы, доставать из архивов данные, и т.д.

Deleted
()
Последнее исправление: rht (всего исправлений: 2)

В Java достаточно надёжная виртуальная машина и let it crash имеет смысл применять к модулям. Нет смысла убивать нить или JVM. Просто поставть try { ... } catch (Exception e) { ... } и всё.

В общем то так все веб-приложения нормальными людьми и пишутся. Никто на эксепшны не дрочит. Вылетело исключение — автоматом стек размотался, транзакции откатились, исключение залоггировалось, юзеру отдали 500-ю и всё дальше продолжает нормально работать.

Legioner ★★★★★
()
Последнее исправление: Legioner (всего исправлений: 1)
Ответ на: комментарий от stevejobs

Программа может валится, написанная на чём угодно. У меня и на асме валилась и валила всё за собой, вываливая оффтоп в синий экран.

Deleted
()

А мне казалось все жабисты и так кодят в стиле let it crash.

entefeed ☆☆☆
()
Ответ на: комментарий от Legioner

А перезапускать упавшую задачу с теми же аргументами это как то тупо, на мой взгляд. Она с вероятностью 99% опять упадёт. Баги фиксить надо, а не перезапускать.

Legioner ★★★★★
()
Ответ на: комментарий от I-Love-Microsoft

подход неплохой, если жестко покрыть тестами всю область от «валидация данных» до «работы с ними».

umren ★★★★★
()
Ответ на: комментарий от stevejobs

об эрланге, почитай про OTP - там уже годами отточеные механизмы используются. про супервизоры с политиками там же. собственно, если получится сделать в жабе аналог OTP то считай let it crash у тебя взлетел.

anonymous
()

вызови через JNI функцию, написанную на языке программирования, а не на жабе. Например на С++... ах да, ты ж не можешь в С++, потому что у тебя там память утекает и в деструкторах надо экспешены бросать.

ckotinko ☆☆☆
()
Ответ на: комментарий от ckotinko

чото не понял, как в твоих крестах решается проблема let it crash? Первый же сегфолт утянет за собой всю программу.

stevejobs ★★★★☆
() автор топика

If it compiles, it is good; if it boots up, it is perfect.

Цитата хоть и неполная, но...

Solace ★★
()

Есть какие-нибудь готовые фреймворки/гипервизоры итп?

while true; do
java -jar EnterpriseServer.jar
done
PolarFox ★★★★★
()

Так можно делать когда пофиг на данные, которые крутились в этом потоке: можно потерять очередную фоточку котика, очередной тупой комментарий или очередной +/-1, не загрузилась часть странички - юзер ткнёт f5 и т.п.

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

ya-betmen ★★★★★
()
Ответ на: комментарий от anonymous

Я „жаба“ не пишу, только йава. И вообще, мне диссер дописать надо. Пока.

anonymous
()
try {
    //shit
} catch(Exception e) {
}

только надо уметь их правильно готовить. ты, видимо, не умеешь.

anonymous
()
Ответ на: комментарий от stevejobs

Сквозь мусор не видно сути? Так пиши так, чтоб суть была видна. К обработке ошибок нужно подходить с умом, и все будет ок.

anonymous
()

Всегда только так и писал. Подводный камень - интеграция. Let it crash для работы с данными внешних сервисов ничего не дает, ну упадет, а толку? Все равно в большинстве случаев внешний сервис поправить нельзя. Советую почитать про принцип надежных систем: http://en.wikipedia.org/wiki/Robustness_principle

«Be conservative in what you do, be liberal in what you accept from others»

dizza ★★★★★
()
Ответ на: комментарий от dizza

Let it crash для работы с данными внешних сервисов ничего не дает, ну упадет, а толку?

ну вот у нас была отправка данных внешнему сревису по http, он то залипнет на 5 мин, то вообще упадет - и хз заслалось али нет

решалось uid на посылку, и менно сабжевым подходом, только таймаут между попытками увеличивался экспоненциально с 5 мин до часа при поятоянных обломах максимум

Deleted
()
Ответ на: комментарий от Legioner

Нет смысла убивать нить или JVM.

JVM действительно нет смысла убивать, а вот нити - легко. Они по сути одноразовые и, собственно, для обработки запроса сервлетом как раз создается нить. Поэтому когда эта нить валится, никто об этом не жалеет.

Кстати, серьёзные банковские программы на C++ делаются по похожему принципу, только для обработки какой-нибудь транзакции форкается процесс (в юниксе это легко). И если там чего-то падает, то никто об этом тоже особо не плачет.

asaw ★★★★★
()
Ответ на: комментарий от Deleted

Я немного не про то говорю. Представь если ты получаешь данные от внешнего сервиса, и вот тебе приходит запись, которую ты не можешь обработать, например нет id (да, и такое бывает). Падать смысла нет, стоит ругнуться в лог и пропустить кривую запись.

dizza ★★★★★
()

Этот вопрос поднимался неоднократно.. вот тут, например. Это больше вопрос дизайна системы и применимо почти везде. В джаве достаточно инструментария чтобы это реализовать. Есть месседжи, тред-пулы, экзекьютеры, в конце концов акка(без скала можно).. важно помнить, что fault tolerance не означает, что можно забить хрен на ошибки и писать как хочешь, надеясь на Экстерминатус..

dycore
()

Еще один наелся, добро пожаловать в Erlang & Co

nomad
()
Ответ на: комментарий от asaw

JVM действительно нет смысла убивать, а вот нити - легко. Они по сути одноразовые и, собственно, для обработки запроса сервлетом как раз создается нить. Поэтому когда эта нить валится, никто об этом не жалеет.

Нити лежат в пулах и не убиваются, а переиспользуются. Создание нити это (относительно) тяжёлая операция и смысла нет создавать нить, если можно переиспользовать старую.

Хотя если при выполнении запроса вылетело исключение, чёрт его знает, в каком там состоянии остались ThreadLocal переменные и как к этому отнесётся следующая задача. Наверное и вправду лучше новую запустить. Но в целом вроде нет никаких других факторов, которые могут заставлять выкидывать старую нить.

Legioner ★★★★★
()
Ответ на: комментарий от dizza

представь себе что обработка каждой входящей записи выполняется в выделенной задаче - вот в случае инвалидной записи выполняется падение и перезапуск задачи

к слову асинхронную поддержку некоторых наркоманских tcp протоколов тоже так приходилось делать - при какойто хрени в потоке обработчик перезапускается и подключается заново (некоторые протоколы не имели меток или указателей длины потому при нарушении целостности нельзя проскипать)

Deleted
()
Ответ на: комментарий от Legioner

ThreadLocal

тредлокалы можно принудительно грохать через Thread.threadLocals (да хак через рефлекшен)

Deleted
()
Ответ на: комментарий от asaw

еще проблема в убийстве нити в том, что ее нельзя убить, нет такого метода в высокоуровневом API вообще. Разве что попробовать пропатчить JVM/JDK.

stevejobs ★★★★☆
() автор топика
Ответ на: комментарий от stevejobs

только при виде хорошего разработчика

аптайм пару месяцев вполне реален и то перезапускали из-за обновлений

другое дело что у нас там свой велосипед (что-то около 300k строк и порядка 50 maven модулей)

ps. был

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.