Как стать автором
Обновить

Комментарии 46

Это всё отлично выглядит на сервисах «с одним HTTP-запросом и 175 строками кода», но Java создавалась не для этого. Интересно было бы сравнение сложности написания, поддержки и прозводительности чего-нибудь этакого энтерпрайзного, ну, знаете, так чтобы на миллион строк кода.
Так может победа-то как раз в том, чтобы сначала разбить задачу на 100500 кусочков по одному запросу и 175 строкам?

Но если серьезно, то архитектура определяет инструменты, а инструменты — архитектуру. Какие-то технологии тяготеют к монолитам, какие-то — к микросервисам.
В теории, ничто не мешает писать на Go и монолиты. Есть мнение, что связка «Go + микросервисы» во многом появилась из-за нынешней моды на микросервисы в целом. Однако это уже переросло в стереотип насчет языка, и такими темпами мы монолитов на Go не увидим — а ведь было бы интересно.
Если монолит в одном бинарнике, то это просто пугает (IMHO). Ведь тут тебе не JVM, а самое обычное OS окружение. Возможно программистам инкапсуляция надиктовывает из подсознания «не вали всё в кучу» и мысли об упаковке enterprise server-side service в один бинарник развеиваются ;)
поддержки и прозводительности чего-нибудь этакого энтерпрайзного, ну, знаете, так чтобы на миллион строк кода.

Вроде бы гугл специально для этого Go и создавал, т.к. текущий стек их в чем-то не устраивал. Да и у ребят из AeroFS фокус на микросервисную архитекруту, причем запущенную в докере, что довольно специфично.

И вообще, откуда таким сравнениям взяться, кто в здавом уме будет полностью монолит на 1кк строк переписывать?
Мы тебя поняли, Hugues Bruant просто не умеет готовить Java.
Вы переписали сервисы на go лишь из-за того, что у вас якобы жралось много памяти?
Не пробовали heap уменьшить и сделать class sharing? или хотя бы руками общие jar выложить на общий classpath?
Судя по-всему, они поменяли подход в масштабируемости и оркестрации сервисов в пользу сервисов docker и там решение было продиктовано другими — более значущими профитами, которые не отпугнули (переписать всё с Java) этого залихватского Senior Software Architect ;)
Вот об этом и речь, что за сутки без специфического глубокого знания тонкостей языка и инструментария получили решение с гораздо меньшим потреблением памяти. Оптимизировать можно что угодно, вопрос в затратах на решение.
Автор же в статье ответил конкретно на эти вопросы, подробно описав причины своего решения.
Мы с вами по-моему разные статьи читали. Человек взял и решил переписать все на Go основываясь, лишь на фразе «увеличение количества запущенных JVM»? Смешно)
Вы и правда другую статью читали, в этой человек решил попробовать переписать всего один сервис и сравнить производительность и ресурсоёмкость.
От статьи за километр разит пиаром.
Во-первых, непонятна сама цель портирования, если все работало без проблем.
Во-вторых, непонятен экономический выигрыш: стоимость портирования несравненно больше лишнего гигабайта памяти.
В-третьих, в разы увеличилась стоимость разработки и поддержки проекта, и как следствие, риски.
В-четвертых, почему сначала не попытались решить проблему в рамках экосистемы Java? «Маленький tomcat servlet с единственным HTTP-вызовом» говорит о заведомо неверно выбранной архитектуре. Пускать кучу Tomcat контейнеров по одному на каждый модуль и удивляться потом почему так много памяти отъедено. Есть куча легковесных решений на Java, умеющих работать с HTTP, и еще много чего.
В-пятых, зачем столько процессов? Специфика JVM такая, что процесс отъедает значительную память, поэтому лучше собирать решение по возможности внутри одной JVM, нежели пускать кучу процессов. Конечно, если не было целью продемонстрировать «Java vs Go».
В-шестых, вконце вскользь упомянулось быстродействие: улучшение лишь «в некоторых случаях». Видимо, хвастаться особо было не чем.
Во-первых, непонятна сама цель портирования, если все работало без проблем.

Просто ребята на хакатоне решили за один день
  1. Выучить go
  2. Попробовать переписать на нём какой-нибудь микро-сервис ради интереса

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

Спорно, у них и так там не только java-only стэк.
Конечно, если не было целью продемонстрировать «Java vs Go».

Да, они специально перенесли всю инфраструктуру на Docker, чтобы продемонстрировать на примере одного микросервиса «Java vs Go»
5.… внутри одной JVM, нежели пускать кучу процессов…

Громадное заблуждение. На собеседовании кандидата — это красный флаг.

В Java есть такое понятие stop-the-world. Да можно бороться, можно юзать off-heap, сделать свой сборщик мусора, написать VM внутри JVM на арреях (есть в бизнесе и даже такое). но побороть, к сожалению, невозможно. Может для студенческих проектов до Xms4Gb это не критично, но для бизнеса и >24Гб уже очень больно.
Спорный вопрос, все зависит от задачи. Если есть low latency задача, то может быть.Ну и если у меня куча памяти, то stop world будет не частным явлением.
Кстати, в Go1.5 задержки GC не превышают 20 мс никогда и теперь он типа low latency.
Знаю, может и Java этот сборщик переберется. Хотя плата за это — производительность чуть ниже.
У divan0 есть перевод кейнота с последнего гоферкона, вот. Если интересует сабж, то могу посоветовать прочесть. Там, в частности, раскрывается тема «почему GC для Go нужно писать как GC для Go, а не как GC для Java». Вкраце, языки разные и подходы к разработке GC тоже разные. Когда народ это понял, все стало хорошо.
В Java много разных сборщиков и в них есть разные настройки. В JVM сборщики пока ещё лучше чем в Go. Но у Go есть преимущество, он не всё аллоцирует в куче, большая часть данных размещается на стеке, если писать правильно.
Дык в Java тоже не все в хипе. Все локальные примитивы лежат на стеке.
В данном примере основная потеря производительности будет при передаче данных от одного процесса к другому: работа с памятью внутри одной JVM в сотни раз быстрее, чем сериализация/десериализация и дерганье сетевого стека, даже если учесть накладки с GC. Если сервис построен правильно, при необходимости его можно горизонтально масштабировать. Запускается много однотипных JVM-процессов, каждый из которых реализует сразу весь требуемый функционал, но в ограниченном объеме ресурсов (память, процессор, etc). А вся нагрузка равномерно распределена среди всех запущенных процессов.
От статьи за километр разит пиаром.

Статьи подобного рода — естественная реакция тех, кто попробовал что-то новое, остался доволен и хочет поделиться этим с миром.
Думается, что «хм, жрется много памяти, давайте все перепишем на X» — реакция скорее какого-то зеленого студента, а не «человека старой закалки». Вместо того, чтобы разобраться в проблеме и прокачать владение технологией, человек потянул в проект новую модную игрушку. Ну и конечно же его эксперимент нельзя повторить. Я не то, чтобы большой противник Go или фанат Java. И наверное это здорово, если язык и вправду позволяет получить более эффективный в плане потребления памяти код без необходимости ни в чем разбираться. Но следует отметить опасность, которую такие посты предоставляют для молодых и впечатлительных разработчиков.
Если речь шла о микросервисе, то очень даже грамотный подход.
Позвольте поинтересоваться, в чем же по вашему мнению заключается грамотность? Времени сэкономлено не было, так как посмотреть через YourKit, под что же используется память, и оптимизировать соответствующее место заняло бы явно меньше времени, чем изучение нового языка и переписывание на нем части системы. Не говоря уже о том, что в проекте теперь используется не один язык, а два, с необходимостью поддерживать клиентские библиотеки к разным сервисам на обоих. Не говоря уже о том, что такой подход — ни в чем не разбираться, а просто переписывать — в принципе неправильный. То есть, в следующий раз, когда что-то пойдет не так, автор статьи снова все с нуля перепишет?
Ага, а автор заметки вообще нуб, не знает такого слова как оптимизация. Лучше внимательнее почитайте статью. Они не просто с бухты барахты решили вечером за пивком «а не выучить ли нам новый язык и переписать пару программулин на яве», а провели анализ в результате которого выяснили: 1) increase in the number of running JVMs 2) reduced opportunity for the many JVMs to share read-only memory 3) memory isolation could in some cases confuse some sizing heuristics, which lead to larger caches being allocated by some services. И как это вы это сможете быстро оптимизировать, не переписывая весь микросервис с нуля? Потом пришли к идее переписать его на компилируемом AOT языке, потом выбрали Go, как простой в освоении язык с хорошей стандартной библиотекой.
increase in the number of running JVMs

Ну так в этом и есть корень зла. Микросервисы на Java реализуются не путем создания большого количества JVMs, а путем рамещения этих сервисов в одной JVM. Посмотрите как это работает в OSGi контейнерах. Автономность сервисов обеспечивается изоляцией класслоадеров. При этом жизнинный цикл сервисов полностью автономный (при надобности!). В тоже время, все библиотеки (бандлы) загружаются ровно один раз, понижая тот самый memory foot print.
И чем это лучше монолита?
Как будете эти микросервисы масштабировать?
Всегда можно поднять другой сервер со своей JVM, на котором будет работать часть сервисов.
Затем ещё, и ещё. Вот уже нужна какая-то контейнеризация, образы. А контейнеры толстые с JVM. Всё, в принципе, по статье ;)
По сути дела osgi и есть контейнер. Только в качестве образов используются jar.
Автор не зелёный студент и ничего не переписывал. Он всего лишь на «хакатоне» попробовал реализовать один из кучи существующих микросервисов на другом инструменте. После сравнил и показал экономическую целесообразность данного процесса.
Кстати очень интересно это всё сошлось с внедрением докера. Не было бы докера — сразу бы начались вопросы: а какой там твоему Go нужен рантайм, а какие либы, а как это будет контачить с нашими системами X, Y и Z, установленными там же, а не сломает ли чего-то там-то? С докером всё просто: вот вам контейнер, в нём всё работает, ставьте куда хотите, ничего кроме него для запуска не нужно, ничего во внешней системе не сломается.
С Go всё просто: вот вам статический бинарник, в нём все работает, ставьте куда хотите, ничего кроме него для запуска не нужно, ничего во внешней системе не сломается.
Это не «всё просто», чёрт его знает куда этот бинарник полезет писать файлы, какие захочет открыть порты, сколько занять места на диске своими данными и т.д. Докер ставит хорошие заборы.
Ну это не специфичная для go проблема же. Я лишь указал, что проблемы рантайма, конфликтов либ и так далее, которые вы описывали, отсутствуют для go по большей части. То, что в сабже докер в том числе для изоляции микросервисов, я особо и не спорю :)
Проблема не специфичная для go. Я просто хотел отметить, что с докером сисадмины чуствуют значительно больше контроля над системой и по крайней мере от них не исходит сопротивление внедрению новых технологий. Им не надо знать, как там Go линкуется и где ищет либы. Это просто не их дело. А чем меньше сопротивления новым технологиям — тем быстрее они внедряются.
Автор(статьи, а не перевода естественно) видимо хотел запиариться. А вышло так, что со стороны выглядит, будто они сначала не правильно юзали Java, а потом еще и переписали на Go ради экономии 1ГБ оперативки, которая стоит куда дешевле чем труд разработчиков. Сомнительный мув, имхо…
Есть ситуации, когда 1Гб умножается на каждом истансе и суммарно получается очень-очень нехилая сумма. Знаю успешные переписывания Python->Java->C++->C++ с Asm, когда нанять ~100 инженеров для портирования на другой низкоуровневый язык выходит банально дешевле. У каждого проекта есть свои нюансы.
Согласен, ситуации бывают разные. Но я говорил конкретно в контексте истории описанной в статье. Если судить о каком-нибудь проекте, который запущен на 1000 машинах, то это логично, что 1ГБ в итоге сэкономит приличную сумму денег.
Я сейчас сравниваю комментарии здесь с комментариями на известном англоязычном ресурсе. Там обсуждают, почему JVM потребляет столько памяти и разбирают конкретные примеры использования Java или Go и сколько у кого потребляется памяти на запущенный сервис. Здесь же понабежали крутые явисты и пытаются доказать, что автор мудак и надо было заниматься оптимизацией, а не переписывать велосипед. Что за привычка такая обсирать других и считать себя Д'Атаньяном?
Наверное, дело в том, что тут все-таки обсуждают статью, а не языки.
И статья написана очень странно. По сути, в ней нет ни одной причины, которая бы объясняла, почему у них был такой странный и неоптимизированный код на Java.

В сущности, статья воспринимация как «у меня был фиговый код на Java, я решил не копатся в нем, а переписать все на Go. И внезапно, расходы памяти упали на двузначные числа. Java — плоха». Ну последней фразы нет, но вывод напрашивается.
По этому эта статья и воспринимация в штыки.

> В сущности, статья воспринимация как «у меня был фиговый код на Java, я решил не копатся в нем, а переписать все на Go. И внезапно, расходы памяти упали на двузначные числа. Java — плоха».

Но если подумать…

А разве автор был способен за один день выучить язык и написать на нём крутой оптимизированный код?
Получается по сути сравнение плохого кода на Java и на Go.
На самом деле нет.
Архитектура приложений различается.
Если на Java они накручивали микросервисы на серверлеты и запускали ради этого tomcat сервера (а потом удивлялись, почему же там много памяти жрет), то на Go они написали чистый микросервис.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории