All streams
Search
Write a publication
Pull to refresh
31
0
Антон Куранов @Throwable

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

Send message

Я не боюсь 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. Однако в моем понимании это по большей части следование моде, диктуемой "великими" брендами, бездумное и неоправданное использование навязываемых технологий и инноваций, и как индикатор -- полное отсутствие критики и критического мышления.

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

Я бы сказал не небесспорная, а как раз очень даже спорная, по которой уже 100 лет не утихают дебаты.

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

и

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

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

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

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

Сбивчивая речь и непоследовательность в изложении мыслей

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

при написании кода задействованы те же участки мозга, что и при восприятии и формировании устной речи

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

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

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

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

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

Сильные инженеры нередко оказываются хорошими спикерами — именно их вы чаще всего можете увидеть выступающими на тематических конференциях.

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

Основная проблема такого подхода состоит в том, что внесение любого

...и дальше идет типичная мантра карго культа микросервисов...

может потребовать множественных изменений в различных подсистемах

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

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

Фигня! Запускайте столько монолитов, сколько душе угодно -- это будет дешевле и в разы меньше по ресурсам, чем микросервисы. Причем никто не запрещает выделять разные инстансы для разных задач. Но главное -- все инстансы взаимозаменяемые.

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

...настолько же быстрый, простой, надежный, контролируемый, легко тестируемый и поддерживаемый!

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

Самый демагогичный на сегодняшгий день вопрос, на который существует миллион ответов и ни одного, признанного верным. В вашем случае не будет концептуально хуже, если вы соберете обратно все *-subsystem в единый System и запакуете все в единый .jar без лишнего геморроя.

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

Information

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