Pull to refresh
31
0
Антон Куранов @Throwable

Пользователь

Send message

А кто запрещает в монолите использовать хоть для каждого компонента свой пул ресурсов? Так что не убедительно. Еще аргументы.

Может я немного отстал от жизни, AOP уже тоже вышел из моды? Я думал в статье коснутся деталей Spring AOP, AspectJ, java.lang.Proxy, ByteBuddy, а статья о том как добавить кучу boilerplate-а к бизнес коду.

Плюсы микросервисного подхода

Один из основных плюсов микросервисов — повышение показателей доступности и отказоустойчивости. Когда монолит падает, он полностью перестаёт работать.

С чего это? Монолит также может быть горизонтально отмасштабирован с load balancer-ом и high availability.

Ещё один плюс — повышение надёжности. Предположим, начинающий разработчик залил непроверенные изменения в прод. В случае с монолитом всё сразу упадёт, а с микросервисом сломается только участок системы, остальное будет работать. 

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

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

Зато весь процесс тестировать становится на порядки сложнее.

Так где плюсы-то?

Для Java нечто подобное уже реализовано в библиотеке JINQ. Только там парсится сам байткод лямбды, и поэтому очень много подковерной магии.

Я не боюсь Websocket, я использую его для онлайн шахмат в Телеграмме https://t.me/gamefactorybot :) Просто хотел поделиться своим опытом, согласно которому не все так просто чтобы сделать устойчивый коннект и гарантированную доставку месседжей. Основная проблема в том, что если что-то хорошо работает на ваших девайсах, это не означает, что то же самое будет также стабильно работать у Васи. Когда начала расти аудитория, было много комплейнов от юзеров. Пришлось вставлять средства мониторинга коннекшна в сам клиент и глубже изучать тему.

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

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

Согласно спецификации WebSocket есть специальное событие onclose, который в нашем случае прописан в коде и выполняется всегда при потере коннекта

При потере коннекта onclose может не вызваться вообще, так уж устроен tcp. Если у сокета отправочный буфер пустой, но он никогда и не закроется. Чтобы сокет закрылся, нужно обязательно через него что-то отправить, и то это произойдет не сразу, а лишь по таймауту на ACK и истечению повторов.

Кстати, было замечено, что у мобильных стеков tcp-таймауты на вебсокет выкручены на максимум, из-за чего возникает ощущение неразрывности коннекшна. Он тупо лагает, но не рвется. Приходится поверх въявную реализовывать свой механизм таймаутов на пинг-понгах.

ping-pong - что неплохо и на самом деле ping-pong ничего не кушает

Это для foreground приложений. А если приложение должно постоянно находиться в background и просыпаться лишь по приходу месседжа, то 3-4 часа -- это отвратительно. Постоянный пинг не даст телефону уйти в спящий режим и снизить энергопотребление.

Во всех роутерах по умолчанию с завода нет ограничений

Мы говорим о gateway-ях, корпоративных роутерах или проксях. Особенно последние безбожно дропают соединения без треффика по таймауту.

Можно сказать появились тепличные условия для восхождения WebSocket и почему бы и нет.

Далеко не все так просто. Не стоит сильно закладываться на Websocket, потому как:

  • Никто не отменял кратковременные потери связи. Поэтому придется так или иначе на клиенте придется поверх имплементировать или пользовать протокол с реконнектом типа MQTT, что усложнит ситуацию вцелом и в итоге не сильно будет отличаться от лонг поллинга.

  • При отсутствии треффика соединение автоматически не закрывается ни на одной из сторон. Получается так, что клиент уже отвалился, а сервер еще "держит" его соединение. То же самое с клиентом -- соединение еще открыто, но сервер уже его давно дропнул. Чтобы это решить, люди делают периодический heartbeat, но он сразу жрет батарею и вносит определенную задержку.

  • Когда соединение проходит через промежуточный роутер с маскарадингом или через прокси, они как правило убивают коннекшн при отсутствии треффика. И одному Админу известно во сколько выставлен таймаут в каждом конкретном случае. Поэтому хардбит придется делать часто: от 30 секунд до 1 минуты.

  • Было замечено с некоторыми моделями мобильных девайсов, что они могут аккумулировать которкие сообщения перед отсылкой их по вебсокету (до 20 секунд). А самому выставить параметры сокета, типа TcpNoDelay, нет никакой возможности.

Поэтому как протокол вебсокет хорош для приложений с интенсивным обменом траффика, но в сыром виде не совсем подходит для кейсов с обменом редкими сообщениями.

Глобально в Java имеется один небезопасный слой -- это reflection, который позволяет динамически инстанциировать и обращаться к объектам произвольных классов. Все интерпретируемые субъязыки наподобие SpEL, EL или Log4j2 EL, а также большинство data-binding фреймворков, использующих сериализацию, в той или иной форме используют reflection, а поэтому потенциально уязвимы. Основные причины две:

  • Семантическое core субъязыка позволяет выполнять "injections" через параметры.

  • Язык имеет полный неконтролируемый доступ ко всей платформе через reflection.

потому что чисто внутри себя Кафка умеет в сложные транзакции

Вот фиг его знает. Пишут, что умеет, если выставлен read_committed уровень изоляции.

The consumer's position is stored as a message in a topic, so we can write the offset to Kafka in the same transaction as the output topics receiving the processed data. If the transaction is aborted, the consumer's position will revert to its old value and the produced data on the output topics will not be visible to other consumers, depending on their "isolation level." In the default "read_uncommitted" isolation level, all messages are visible to consumers even if they were part of an aborted transaction, but in "read_committed," the consumer will only return messages from transactions which were committed (and any messages which were not part of a transaction).

Но на практике нигде нет внятной инфы как это физически реализовано (топики-то разные!) Поэтому закладываться на такие гарантии может быть чревато проблемами.

Странный какой-то вы кейс выбрали, возможно специфичный только для BPM. В подавляющем большинстве нужно: прочитать из одного топика, обработать/записать в базу и отправить в другой топик.

Хотелось бы также знать политику консьюмера при роллбеке транзакции: делается ли повтор, как контролировать delay и limit при повторе, отфутболится ли месседж в DLQ, остановить ли весь консьюмер и т.д. Тут масса нюансов и вопросов как это контролировать в спринге.

Вообще, при планировании распределенной архитектуры лучше закладываться на гарантию "at least once" и вручную везде обеспечивать идемпотентность. Насколько я понял, кафка не обеспечивает "exactly once" между двумя топиками.

К сожалению, клиент не всегда такой культурный и адекватный, как вы описали. Могут быть и возражения типа "хахаха, кем вы себя возомнили?", "а че с ценами не дружите?", "заплатим вдвое меньше -- для вас это и так хорошая цена". Причем клиенты достаточно солидные, и не испытывают недостатка в бюджете. Здесь Вы не идентифицировали основной тревожный звоночек такой "прижимистости": "Меня тупо разводят как лоха?". Как объяснить не сильно продвинутому человеку, почему Вася с Петей за то же самое запросили в 10 раз дешевле, чем вы?

С клиентами с сильно лимитированным бюджетом лучше вообще не иметь дела, ибо выйдет себе дороже. Сначала на этапе анализа будете получать минимальный фидбек и очень абстрактные требования, которые можно интерпретировать по-разному: что-нибудь попроще, на ваше усмотрение. Затем на этапе разработки начнется выклянчивание фич, типа "а можно во тут сделать так?" Потом бесконечные правки уже сделанного (и оговоренного ранее) функционала: вы не поняли, вместо "вот этого" нам нужно, чтобы было "вот так". После этого будут уже просто требовать новые фичи, ссылаясь на неправильную интерпретацию задания, даже если это подписанный Statement-of-Work. Затем сложности с приемкой и сертификацией -- будут придираться к любой фигне или нефункциональным требованиям. Затем заявлять, что анализ сделан из рук вон плохо, в таком виде продукт бесполезен для бизнеса и мы не сможем его оплатить, нужно для всеобщего блага всем немного поднапрячься, чтобы всем было хорошо. После этого практически всегда задержки по оплате, максимально увеличивая "период интеграции" продукта, которая полностью ляжет на ваши плечи. Затем откажутся от саппорта, а все проблемы будут репортить как баги софта. В итоге ваш проект обернется глубочайшим минусом.

Первый вариант: найти подрядчиков и исполнителей дешевле и объяснить, как изменится конечный результат.

А риски и ответственность, собственно, на себя брать? Меньший бюджет, дешевый провайдер => больше рисков для срыва сроков и вообще реализации проекта. При закладывании рисков в маржу финальная цена может даже возрасти.

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

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

Третий вариант: рассрочка. Возможность разбить оплату на несколько платежей

Поверьте опыту -- гарантированно закончится судами.

На правах гипотезы: скорость эксплуатации утечек чрезвычайно медленная, с низкой гарантией корректности результата, особенно в нагруженных системах. Ну а по поводу закрытия: в общем случае класс спекулятивных утечек в конкурентных средах невозможно "закрыть" впринципе. Они всегда будут существовать, пусть и гипотетически. Это как вы не видите ваших соседей за стенкой, но по иным факторам сможете составить информацию то, кто они и чем занимаются. Можно полностью сбрасывать кеш при переключении контекста, но это сразу затормозит систему в десятки раз.

Когда я был студентом, в моде был пирацетам (ноотропил). В качестве легких антидепрессантов хорошо заходят препараты, содержащие триптофан и магний.

То есть, если Алиса и Боб выполняют одновременно две транзакции, то возможно только два варианта последовательного выполнения:

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

Если поток транзакций является одновременно сериализуемым и линаризуемым (операции применяются мгновенно), то мы получаем модель строгой сериализуемости (Strict Serializable).

Они не обязаны "применяться мгновенно". Для Strict-serializable достаточно, чтобы было введено отношение "happened-before", которое задает частичный порядок для перекрывающихся регистров. При этом для операций с независимыми регистрами порядок может отсутствовать.

Для реализации сериализуемости могут использовать либо блокировк/и, либо механизм MVCC (Multi-Version Concurrency Control).

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

create sequence pet_seq start 1 increment 50

Добавлю, что в случае SEQUENCE при резервировании "блоками" не гарантируется непрерывное возрастание значений ID, а в случае с кластером теряется также упорядоченность. Просто был кейс, когда программист, чтобы сэкономить на индексе, сортировал события в таблице по ID вместо CREATION_TIME. Это работало на тестовых бенчах, но в кластере такая сортировка работать перестала.

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

В "изначальной" модели этим должна была заниматься ESB -- быть централизованным законодателем корпоративных интерфейсов, контролировать всю их эволюцию, версионирование и адаптирование по мере необходимости. Однако это не сработало так, как задумывалось: практически все интерфейсы "локальны" и неиспользуемы никем, кроме непосредственно систем консьюмера и продьюсера. А двум сторонам договориться между собой гораздо проще, нежели трем. В итоге сегодня ESB -- это кучка дармоедов и нахлебников, основной задачей которых является выбить себе денег на очередной бесполезный меппинг полей, тем самым усложняя обмен данными между системами. Так что полностью согласен слабую связанность.

Я пишу сиптью, про бизнес, который уже прошел трансформацию, денежку считает и понимает, зачем ему та или иная информационная система

Ну то есть, который уже имел негативный опыт с предыдущим провайдером и теперь он "подкован" и ищет "настоящих специалистов своего дела". Либо это тот бизнес, кого эти "настоящие специалисты" уже успели развести на модные цацки.

Я работаю с крупным бизнесом, очень крупным, но смогу заверить, никуда он не делся и ситуация там вообще не поменялась. И впринципе норм: клиент не должен вникать во все детали реализации, если они напрямую не связаны с его бизнес процессами. А с бизнесом мы сами разберемся, получим необходимую информацию, поймем все задачи и проблемы, и предложим адекватное решение. Гораздо хуже, когда клиент мнит из себя Архитектора Матрицы и указывает провайдеру как правильно и концептуально дизайнить решение, какими средствами пользоваться, по какой методологии работать и т.д.

Придумайте звездолёт и сразу появится армия коучей, которые за большую сумму научат вас как правильно им управлять

Дело в том, что в итоге они не научат вас управлять звездолетом, но предложат свой "концептуальнй процесс обучения управлению звездолетом", благодаря которому каждый сможет стать пилотом. А на претензии типа почему мой звездолет до сих пор не летает, всегда есть ответ, что проблема в вас, ибо вы неправильно следовали этому процессу.

Когда люди пытаются использовать стандарт как фреймворк единственное что они могут это следовать за нормами стандарта упуская из виду реализацию. Так, по моему мнению, и возникает карго-культ.

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

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

Information

Rating
Does not participate
Location
Madrid, Испания
Registered
Activity