Не совсем так, что rich, что anemic можно как жёстко прибить гвоздями к БД, так можно работу с данными вынести в отдельный слой. Это просто разные способы организации бизнес логики, в какой-то мере анемичная модель — это тот же транзакционный сценарий, только с ооп. Где сервисы описывают бизнес кейсы, а не логика рассредоточена по объектам доменной логики.
Противников/сторонников обоих подходов море, уже 10 лет бъются.
Оно то да, но потом смотришь код, который с одного аккаунта должен перевести на другой деньги, item какой-то и т.д. (естественно не уйдя в минус + могут быть какие-то ещё доп.проверки).
И спрашиваешь, так а если клиент «хакер» и дёрнет endpoint в 100 потоков одновременно, всё ли норм будет?
«Конечно, у нас же транзакция, ёпт».
А потом балансы не сходятся (транзакция необходимое, но недостаточное условие).
Конечно нет универсального решения, но state-данные по производительности лучше не в базу, а в отдельное in memory хранилище ложится. Да, latency больше по сравнению с локальной памятью, но и при цепочке вызовов микросервисов она растёт.
А вот масштабирование persistent слоя, это отдельный большой вопрос, который в микросервисах тоже никуда не исчезает.
Я вообще немного о другом, о том что если монолит, то это не обязательно исключительно вертикальное масштабирование одной железки, но вполне возможно и горизонтальное.
То же самое с масштабируемостью по ресурсам — когда 10 микросервисов будут жить каждый на своей машине, монолит на своей уже может захлебнуться по процу или памяти.
Так никто ж не запрещает развернуть application level монолита (если он, конечно, stateless) тоже на куче нод. А там балансируй хоть round robin’ом на все, либо по роутам/поддоменам каждый модуль на свою группу серверов.
p.s. я то против микросервисов ничего не имею, но и серебряной пулей они не являются, особенно когда не устаканен домен и у команды мало опыта.
Мысли:
* специализированные решения «лучше» работают (потребляют меньше ресурсов/денег, чаще проще в настройках и менеджменте) по сравнению с универсальными;
* если мониторинг начнёт генерить много данных и принимающая сторона «захлебнётся», это обычно не так критично чем ляжет BI слой;
* независимое масштабирование этих подсистем;
у которой, кстати, default isolation level «read uncommitted»
Да и durability по умолчанию отключена, но нужен был хайп для раскрутки, как она «делает» на записи реляционки.
Правильно, не рекурсия.
setTimeout выполнится сразу же — добавит в message queue новую отложенную задачу и закончит работу.
Первую фразу не совсем понял, но да, если нужно хранить картинки, то складировать их как файлы, а не в базу.
Просто не нужно в базу.
«Ребята не стоит вскрывать эту тему. Вы молодые, шутливые, вам все легко. Это не то...» и далее по тексту.
Депрекейтнули ещё в php 5.5, который релизнулся 20 June 2013
Люди пишет клиенты к товару
«Коменты», конечно, не клиенты. Автоподстановка )
Оптимистичная конкуренция являеться надежным механизмом гарантирования целостности данных без необходимости их блокирования при чтении юзером от начала и до конца сессии
Надёжным, но в случае когда параллельный поток успел первым, прийдётся заново повторять весь цикл, либо если возможен merge данных, тогда проводить его.
это называеться last write wins
Чаще всего это и нужно, но не просто перезатирание конечно, а гарантированная сериализация выполнения изменений.
В указанном кейсе с изменением текста, оптимистическая блокировка норм, в предыдущем посте как раз хотел привести пример с одновременным редактированием google docs разными пользователями там где это нужно. И оптимистические блокировки в ряде случаев, это лучшее решение, но часто не имеют смысла чтоб подавать как единственно правильное решение.
Кейсы:
1. Люди пишет клиенты к товару, и мы в агрегате хотим иметь количество/счётчик клиентов.
2. Списание с баланса пользователя, где нужно по хитрой логике высчитать скидку, проверить хватит ли денег и если ок, то сохранить событие и обновить баланс.
3. Какой-то донат с лимитом. Каждый может задонатить 1 цент, но общая сумма чтоб не превышала N долларов.
Зачем в этих случаях оптимистическая блокировка? Нам нужно изменить агрегат, на основе самых актуальных данных, в случае positive check false нужно вычитать актуальные данные, опять применить логику и попытаться сохранить и смысл? Хотя лока агрегата перед началом операции достаточно.
вы не понимаете как работает механизмы optimistic/pessimistic locking
вот давайте не вешать ярлыков.
Ну вот и я считаю что по одному кейсу обобщать смысла нет.
Тут уже много написали, добавлю чуть-чуть.
В php нет GIL и глобальных мьютексов, которые бы блокировали выполнение в несколько потоков на разных ядрах. Но и самой многопоточности из коробки тоже нет ))
Но если ставить extensions для этого, самый популярный из которых pthreads, то используются все ядра и соответствующее ускорение работы, в отличии от python.
Я имею некоторый опыт с php, js, ruby, python, java (и ещё всякого но в меньшей мере и не беру в расчёт). И не вижу ни в одном из этих языков принципиальной разницы в скорости написания логики, которая читает из базы, трансформирет данные и куда-то перекладывает/сохраняет. Пока имею ввиду не конкурентную логику, а в один поток. Что до кокурентности, то в скриптовых проще делать через пул-процессов, а не многопоточность, но таки можно распараллелить выполнение, просто кто-то не смог.
В общем у меня есть сомнения в знаниях php-шника, с которым ты «конкурировал» и делаешь глобальные выводы, о том что на go писать в разы быстрее чем на php (сюда по твоей логике вообще можно любой язык ставить, как минимум скриптовый). Так что в общем случае не убедительно.
Но задачи где нужно эффективно именно в многопоточность, да, на Go написать будет проще и быстрее чем на php/js/ruby/python, на этом поле php в общем-то и не играет.
оптимистичная конкуренция
должна работать с блокированием данных для других читающих
Здесь уже противоречение, она ж на то оптимистичная что ничего не блочится до самого последнего момента. Ну а конфликты всё равно на уровне приложения прийдётся разруливать, когда optimistic check не сработает. Хранилище ж понятия не имеет что делать с разными состояниями агрегата, тем более состояние одного из них может быть уже само по себе неактуальным, так как вычислялось на основе устаревших данных.
Имхо, optimistic check чаще не нужен чем нужен, проще сделать просто pessimistic lock на запись для агрегата перед самым его получением для изменения — надёжно, не нужно заново актуализировать состояние агрегата в приложении и его вычислять в случае optimistic check = fail, всё равно в большинстве случаев смерджить мы никак не сможем.
Грэг Янг, конечно голова, но мне кажется он описывал «фреймворк/flow» для любого абстрактого случая, но в частностях имеет смысл отходить от догм.
В таких задачах сравнивать производительность компилируемого языка и языка с виртуальной машиной без jit (не на php 8 он же писал) большого смысла нет. Победитель очевиден. Но, если сравнить с языками своей весовой категории — python, ruby, то уже будет всё вполне ок у php.
Ну и конечно сильно много неизвестных как что делалось, на Go очевидно что через корутины,каналы с использованием всех ядер. А на php неизвестно, это ж консольно запускалось скорее всего. По дефолту нет работы с потоками, использовался ли какой-то extension или делался ли форк основного процесса хотя бы по количеству ядер — неизвестно. С большой вероятностью всё работало в один поток, может ещё и логика/структуры данных не совсем удачно выбраны, пишут то как привыкли — вызывать in_array() в цикле, вроде и норм, но не когда итераций и элементов в массиве овер-дофига, вместо того чтоб как с хеш-мапой работать и подобное, что уводит big-O вверх.
Что до скорости разработки, хз, в таких задачах там всего-то и нужно if/else, циклы и работа со строками и массивами. На любом языке быстро делается. А вот чтоб распаралелить, «обычному» php-шнику будет сложнее, чем go-разработчику, для которых это типичная рутинная задача.
Кстати, здесь уже не раз упоминался swoole — экстеншн для php, как раз вдохновлялись golang’ом — корутины, каналы, отдельный шедулер и вот это вот всё. Но пока это ещё экзотика.
я тоже не вижу, зачем в PHP асинхронщина
Появляется всё больше задач где нужны постоянные соединения, а модель — fpm-процесс на коннект не работают, где нужно отправлять на внешний сервис(ы) сотни тысяч запросов и по-старинке поднимать десятки процессов, которые это синхронно рассылают уже не сильно то и современно.
Поэтому и появляются swoole, amphp, reactphp и т.д.
Swoole самый интересный и перспективный (имхо), всё думаю начать помогать им с документаций, да руки не доходят )
А пока и получается что бывает проще сбоку node.js поставить или тут-же пачку php-демонов запустить.
Дык я ж не спорю. Шишки разные набиты на личном опыте ))
И понимаю обе стороны.