Так получается самые нагруженные методы просто через сервлеты написаны? В чём тогда вообще смысл использовать спринг? Чтобы его в критических местах не использовать? Может просто взять другой фреймворк?
Горизонтально масштабируемые транзакционные бд, которых к сожалению не так много.
Шардирование имеющихся бд. Скорее всего наиболее часто используемый вариант на данный момент. Но тут конечно минус, вся кодовая база должна поддерживать шардирование.
@bibendi нужно отметить один важный момент - это производительность, БД становится узким местом при таком подходе. Думаю стоит про это упомянуть. И да, понятно, что мы платим эту цену за надёжность и непротиворечивость доставки.
Понятно что не думает как человек. Но в весах модели заложена логика, которая собственно есть в текстах. Иначе как он решает задачи про шестерёнки(в какую строну будет крутиться последняя шестерёнка, если первую повернуть влево/вправо). И это очень похоже на наш интеллект в части того, как мы пользуемся логикой для решения задач.
В целом же предлагают использовать обратносовместимые изменения при релизе. Поэтому по идее откатывать ничего не нужно. А есть какие нибудь инструменты с поддержкой отката?
Очень сложно добиться нужного результата. Да какой то результат будет, но почти наверняка не, то что вы хотели. Постоянно пробую разные чаты, есть подписка openai. Удачных кейсов по разработке у себя могу по пальцам пересчитать. Чаще быстрее самому написать
single thread executor работает медленее чем обычный synchronized в 2 раза. Хоть на долгих, хоть на быстрых операциях. SpinLock работает так же как и ReentrantLock или synchronized. Поэтому для java ваши выводы не применимы
"То есть можно "говнокодить" на уровне приложения и не следить за его производительностью? Не согласен совсем. И я привел пример почему, на основе опыта Paypal."
Опыт paypal ничего нам не говорит о java и nodejs, так как мы не знаем что они там и как переписали и какого уровня по и разработчики были на java и на nodejs. На любом языке можно написать плохо.
Что касается асинхронного и синхронного подхода, то средства нужно выбирать под задачу. Если у вас есть nfr с большой нагрузкой то возможно нужно будет использовать асинхронный код. Если же у вас их нет, то асинхронный код - обычный оверинжиниринг, который ни к чему кроме увелечения стоимости разработки и поддержки не ведёт. И да в реальных тестах r2dbc не всегда может показать результаты лучше, так как упретесь вы скорее всего раньше в базу.
Подход ваш понятен, попробую на java потестить и сравнить
По поводу r2dbc. postgres https://www.postgresql.org/docs/current/libpq-async.html имеет интерфейсы для асинхронной работы. И r2dbc postgres драйвер использует их, поэтому тут про блокировку на уровне java просто некорректно говорить. Там вызов PQsendQuery отправляет query, PQgetResult получает результат.
"Одной из основных причин является то, что в Java Spring принято вызывать блокирующие операции ввода-вывода (например JDBC не имеет не блокирующего интерфейса вовсе) и блокирующие же механизмы синхронизации."
Кем это принято? Для какого пула задач? В каких ситуациях? Даже на спринге можно написать вполне себе неплохое реактивное приложение. Все для это есть. И я видел много примеров в том числе на работе.
"Как не оборачивай блокирующий код в какой нибудь CompletableFuture, он не перестанет быть блокирующим. Просто будет асинхронно блокировать поток пула потоков, чем вызывать создание нового потока в пуле"
Я бы сказал как не оборачивай в асинхронный код все равно упрешься в ресурсы базы и её возможности. И какой язык не возьми все равно упрешься в это. И как может переход на nodejs что то дать вообще не ясно. Или там какой то другой асинхрон? Там нет пула потоков? Ограничения на коннекшены? База при работе из nodejs вдруг становиться резиновая?
Мой мессадж про многоядерное окружение касался той темы когда вам нужно чтобы условно ресурсы каждого цп были утилизированы. То есть у вас есть допустим пул объектов которые хотим шарить между потоками. Тут получается нужно делать n single thread executor и на каждом запускать задачи и как то потоки задач разделять по этим n экзекьюторам.
Пример с java крайне не удачный. Начать хотябы с того что в том же spring есть project reactor, который позволяет писать в реактивном стиле не требуя иметь thread per request. И там же есть r2dbc для подключения к базе. Если есть действительно потребность минимизировать потребление ресурсов то можно посмотреть на vertx или quarkus, у которых так же есть варианты с асинхронностью.
В java ваш подход ложится в single thread executor service. Но как утилизировать ресурсы многоядерного окружения в вашем подходе?
Могу посоветовать вам хорошую книгу "Learning Domain-Driven Design" Vlad Khononov, чтобы лучше понять концепции DDD. А так согласен с автором комментария выше. Нет понимания DDD. Разбирать это конечно слишком долго все.
Тут интресно что там с vacuum на постргрес, ресурсов будет потреблять на порядок больше, особенно io
А может это специально созданный алгоритм для введения противника в заблуждение?
События в бд не надёжно. Только репликация и полинг даст хорошую гарантию.
Так получается самые нагруженные методы просто через сервлеты написаны? В чём тогда вообще смысл использовать спринг? Чтобы его в критических местах не использовать? Может просто взять другой фреймворк?
Тема не раскрыта. Утверждение что передача json занимает 200 мс, а protobuf 20 мс нужно проверить. Напишите хотя бы простейший перф тест.
Чтение с wal лога хороший вариант согласен. Единственное бывает не всегда доступен в инфраструктуре компании.
На мой взгляд тут 2 варианта.
Горизонтально масштабируемые транзакционные бд, которых к сожалению не так много.
Шардирование имеющихся бд. Скорее всего наиболее часто используемый вариант на данный момент. Но тут конечно минус, вся кодовая база должна поддерживать шардирование.
@bibendi нужно отметить один важный момент - это производительность, БД становится узким местом при таком подходе. Думаю стоит про это упомянуть. И да, понятно, что мы платим эту цену за надёжность и непротиворечивость доставки.
Понятно что не думает как человек. Но в весах модели заложена логика, которая собственно есть в текстах. Иначе как он решает задачи про шестерёнки(в какую строну будет крутиться последняя шестерёнка, если первую повернуть влево/вправо). И это очень похоже на наш интеллект в части того, как мы пользуемся логикой для решения задач.
Нашёл у liquibase и flyway в enterprise. Буду иметь ввиду. Но в целом конечно в автоматическом режиме выглядит конечно рискованно у liquibase.
В целом же предлагают использовать обратносовместимые изменения при релизе. Поэтому по идее откатывать ничего не нужно. А есть какие нибудь инструменты с поддержкой отката?
Я насколько понял, этот инструмент покрывает кейс использования бд в нескольких сервисах. В целом вроде бы интересно.
Очень сложно добиться нужного результата. Да какой то результат будет, но почти наверняка не, то что вы хотели. Постоянно пробую разные чаты, есть подписка openai. Удачных кейсов по разработке у себя могу по пальцам пересчитать. Чаще быстрее самому написать
Вы просто подменяете тезисы. Я не писал про невероятные усилия.
Попробовал на java https://github.com/pkokoshnikov/habr_803273
single thread executor работает медленее чем обычный synchronized в 2 раза. Хоть на долгих, хоть на быстрых операциях. SpinLock работает так же как и ReentrantLock или synchronized. Поэтому для java ваши выводы не применимы
"То есть можно "говнокодить" на уровне приложения и не следить за его производительностью? Не согласен совсем. И я привел пример почему, на основе опыта Paypal."
Опыт paypal ничего нам не говорит о java и nodejs, так как мы не знаем что они там и как переписали и какого уровня по и разработчики были на java и на nodejs. На любом языке можно написать плохо.
Что касается асинхронного и синхронного подхода, то средства нужно выбирать под задачу. Если у вас есть nfr с большой нагрузкой то возможно нужно будет использовать асинхронный код. Если же у вас их нет, то асинхронный код - обычный оверинжиниринг, который ни к чему кроме увелечения стоимости разработки и поддержки не ведёт. И да в реальных тестах r2dbc не всегда может показать результаты лучше, так как упретесь вы скорее всего раньше в базу.
Подход ваш понятен, попробую на java потестить и сравнить
По поводу r2dbc. postgres https://www.postgresql.org/docs/current/libpq-async.html имеет интерфейсы для асинхронной работы. И r2dbc postgres драйвер использует их, поэтому тут про блокировку на уровне java просто некорректно говорить. Там вызов PQsendQuery отправляет query, PQgetResult получает результат.
"Одной из основных причин является то, что в Java Spring принято вызывать блокирующие операции ввода-вывода (например JDBC не имеет не блокирующего интерфейса вовсе) и блокирующие же механизмы синхронизации."
Кем это принято? Для какого пула задач? В каких ситуациях? Даже на спринге можно написать вполне себе неплохое реактивное приложение. Все для это есть. И я видел много примеров в том числе на работе.
"Как не оборачивай блокирующий код в какой нибудь CompletableFuture, он не перестанет быть блокирующим. Просто будет асинхронно блокировать поток пула потоков, чем вызывать создание нового потока в пуле"
Я бы сказал как не оборачивай в асинхронный код все равно упрешься в ресурсы базы и её возможности. И какой язык не возьми все равно упрешься в это. И как может переход на nodejs что то дать вообще не ясно. Или там какой то другой асинхрон? Там нет пула потоков? Ограничения на коннекшены? База при работе из nodejs вдруг становиться резиновая?
Мой мессадж про многоядерное окружение касался той темы когда вам нужно чтобы условно ресурсы каждого цп были утилизированы. То есть у вас есть допустим пул объектов которые хотим шарить между потоками. Тут получается нужно делать n single thread executor и на каждом запускать задачи и как то потоки задач разделять по этим n экзекьюторам.
Пример с java крайне не удачный. Начать хотябы с того что в том же spring есть project reactor, который позволяет писать в реактивном стиле не требуя иметь thread per request. И там же есть r2dbc для подключения к базе. Если есть действительно потребность минимизировать потребление ресурсов то можно посмотреть на vertx или quarkus, у которых так же есть варианты с асинхронностью.
В java ваш подход ложится в single thread executor service. Но как утилизировать ресурсы многоядерного окружения в вашем подходе?
А как mdc делать например? Таскать все параметры и каждый раз в логер передовать?
Могу посоветовать вам хорошую книгу "Learning Domain-Driven Design" Vlad Khononov, чтобы лучше понять концепции DDD. А так согласен с автором комментария выше. Нет понимания DDD. Разбирать это конечно слишком долго все.