пятница, 5 мая 2017 г.

[prog.humour] Ну реально: "Why do all this RAII or GC shit, if you just can manage your runtime as a round robin?"

По наводке из G+ ленты Meeting C++ вышел на интересное на reddit-е:

Here is something that was described to me as a real production configuration that was done to solve memory leaking everywhere.

It was a Java service taking fairly high amount of traffic. In order to get consistent response times they setup this configuration in each machine:

1) Each machine runs 4 JVMs. 2) 1 JVM that is starting up 3) 1 JVM that is shutting down 4) 2 JVMs that are serving traffic. 5) Every 2 minutes a JVM starts/stops. 6) No JVM lives for more than 8 minutes.

I found that to be both horrifying and a rather clever way to work around the problem.

Т.е. рассказывают по некую систему на Java, которая должна была обрабатывать изрядный поток трафика. И для того, чтобы не бороться с утечками памяти люди просто сделали так, что у них одновременно работает четыре JVM: одна стартует, вторая завершается, две другие нормально работают и обслуживают трафик. Каждые 2 минуты одну из работающих JVM заглушают, а на ее место запускают новую JVM. В итоге ни одна из JVM не работает дольше 8 минут.

Был бы я лет на 10 помоложе, наверняка бы постебался на тему криворуких программистов в частности и атрофии головного мозга, которую вызывает использование Java вообще. Но количество набитых шишек все-таки дает о себе знать. Поэтому сейчас мне кажется, что это отличное инженерное решение. Ну что поделать, shit happens. А если можно построить железобетонное решение, которое работает не смотря на этот самый shit, то это просто здорово.

В связи с чем вспоминается две похожие истории.

Первая связана с патерном Disruptor, о котором много говорили в узких кругах несколько лет назад. Помнится, компания Lmax, которая Disruptor и описала, рассказывала, что у них JVM, внутри которой массированная обработка событий посредством патерна Disruptor и крутилась, просто-напросто раз в сутки перезапускалась. На сутки RAM для этой JVM хватало, а потом следовал простой "освежающий рестарт" и следовали очередные сутки работы нагруженного приложения.

Вторая история связана с одним из написанных на C++ проектов в компании Интервэйл. Там был родительский процесс диспетчер и N дочерних процессов. Каждый дочерний процесс выполнял запросы к удаленному серверу по HTTPS. Но время от времени, иногда после нескольких часов, иногда после нескольких дней непрерывной работы какой-нибудь из дочерних процессов тупо повисал. Непонятно почему. Просто зависал и все. Естественно, это обнаруживалось и процесс прибивался, но т.к. запрос не был выполнен, то это сказывалось на пользователе, чей запрос не обрабатывался. И хотя таких сбойных запросов оказывалось всего ничего, какие-то тысячные доли процента, но все равно неприятно.

Т.к. причину подвисаний нам найти не удалось (непонятно, на что нам было грешить -- на libcurl, openssl, CryptoPro или еще что), то мы просто сделали ограничение на время жизни дочерних процессов. Прожил больше нескольких часов -- будь добр, заверши свою работу, а мы вместо тебя запустим новый дочерний процесс. Поскольку такое принудительное умерщвление дочерних процессов приходилось на моменты, когда дочерний процесс запросы пользователей не обрабатывал, то получилось, что мы и от проблемы избавились, и запросы пользователей терять перестали.

PS. Пока писал, вспомнил еще одну историю. Совсем древнюю, относящуюся к временам, когда Ruby-On-Rails произвел эффект разорвавшейся бомбы. Помниться, читал какой-то блог пост, в котором автор описывал как они решали проблему обслуживания большого количества запросов в RoR-приложении. Способ был примитивный: на сервере запускалось несколько десятков серверов lighttpd и отдельный балансировщик разруливал нагрузку между ними. Но важно то, что RoR вместе с lighttpd не всегда работали устойчиво и иногда падали. Поэтому у них на серверах работал по крону специальный скрипт, который опрашивал инстансы lighttpd и, если обнаруживал отсутствие оного, то просто рестартовал упавший инстанс заново. Самая мякотка была в том, что рестарты происходили с темпом где-то раз в минуту. Т.е. раз в минуту какой-то инстанс RoR-приложения и lighttpd просто переставал работать. Ну, по крайней мере, я так запомнил :)

Комментариев нет: