Насчет восстановления базы - интересный вопрос. Вряд ли тут есть генерное решение. Но в принципе можно к этому относиться как частному случаю ресета оффсета опредееленного консьюмера.
Если сама синхронизация очень тупая, в виде простых идемпотентных апсертов на стороне сабскрайберов, то все должно работать out of the box.
Если же вьюшки строятся сложнее (например мерж нескольких стримов или обогащение евентов синхронно (что не очень хорошо) в консьюмере, тут уже нужно конкретно по ситуации смотреть. Возможно что-то умнее придумать при помощи idempotencyId, timestamps, маппинга оффсета на стороне сабскрайбера с данными чтобы и написание умного рикавери процесса.
Есть конечно нюансы. Например в нашем случае используются топики, где храняться несколько месседжей на определенный _id (зависит от настроек топика кафки) и нужно иметь ввиду что когда будет идти восстановление, то в какой-то промежуток времени мы можем иметь во вьюшке не самые последние данные из тех что мы имеем.
Насколько я знаю, можно настроить топик хранить только последнюю копию документа монги.
Я люблю CQRS. В нашем легаси, как один из шагов в сторону мискросервисов, DDD, евентов + трушный CQRS, мы используем CDC. В нашем случае это Mongo + Kafka connector. И сабскрайберы подписываются на изменения определенных коллекций, и уже создают у себя нуные им вьюшки, в подходящщей базе данных и в подходящей структуре.
Тьфу тьфу работает стабильно и позволяет сделать анкаплинг сервисов и получить реальный профит.
Но нужно заранее думать о том как делать рикавери если что-то пошло не так. И если все делать правильно - рикавери сводится к рисету оффсета сабскрайбера на топик.
На функционал да, но данные будут неактуальными, это лишь скрытие проблемы. Что лучше при ошибке обновления данных - оставить то же значение или показать пустое значение / текст ошибки?
Это не сокрытие проблемы. Это часть анкаплинга и релаябилити. Как пример, автор изменил свое имя, и мы не проапдейтили статьи, потому сервис авторов изменил структуру событий и мы не может их обработать. Юзеру пофиг. Если имя обновится через час когда баг будет пофиксен, это равносильно тому что если бы бага не было с самого начало, а сам автор решил бы изменить свое имя на 1 час позже.
Все эти случаи должны обсуждаться с домейн экспертами. В критических случаях можно показывать возраст.
Вы когда на сайте банка заходите, и вам зашла зарплата, и вы сделали какие-то покупки, вам почти всегда показывают устаревшие данные.
А теперь представьте у банка проблема и один из их сервисов упал и его будут чинить сутки. Вы предпочтете видеть 0 или устаревшие данные с надписью - "Данные актуальны на ... и могут не содержать результаты последних операций"?
Никто не запрещает сделать простую обработку и возвращать частичные данные при отказе сервиса нижестоящего сервиса.
Вы мыслите как программист а не как домейн эксперт. В большинстве случаем старые данные намного ценнее странички с пустыми данными.
Вы выступаете за подход, когда изначально мы заводим шину сообщений, все операции обновления данных делаем через нее, а для синхронных запросов с фронта использовать децентрализованные заранее подготовленные представления данных.
Именно. Именно в этом случае вы реально получаете отдачу от микросервисов. И да - это сложно. Коммуникация между сервисами должна быть асинхронной.
Аргумент о зависимой разработке в микросервисах при синхронном API считаю несостоятельным - ведь вы, когда кладете сообщения в очередь для подписчиков, ровно так же их форматируете, и можете сломать там формат.
Да, поэтому там свои решения в виде схема реджистри и коррапшен лэйер и т.д. И опять же, это сложно.
И даже если структура месседжей изменилась, я просто не обновлю свои данные, а не буду возвращать пустые данные или вообще ошибку потому что сторонний сервер упал или изменил формат данных не сказав.
Тем более обидно когда на том стороннем сервисе данные меняются очень редко, а мне эти данные нужны всегда. И тут ваше возражение в виде "отдавать старые данные может быть плохой идеей" уже не катит. А любая проблема на том сервисе отразиться на моем сервисе. В конечном итоге страдают пользователи.
з.ы.
Я веду к тому, что трушные микросервисы сложны. А от нетрушных, очень профита. И даже эти профиты легко исчезают при появлении проблемы которые приходят с микро сервисами, одна из которых это нетворк.
Но я прекрасно понимаю что есть трейдофы, и иногда приходится ради фронтендеров городить backend for frontend, хоть я их и не люблю всей душой.
И если вы понимаете что это решение временное и никак не конечное (но мы то знаем что нет более постоянного решения чем временное), то ОК. Но многие новички могут начать пилить вот такие микросервисы, и потом не будут знать что с ними делать когда все сервисы будут переплетены между собой синхронными хттп запросами, и малейший баг в одном сервисе будет создавать снежный ком.
З.Ы.
У нас в легаси есть такой боттлнек, сервис аккаунты, и все остальные сервисы проверяют синхронно статус аккаунта - активный или неактивный. Если неактивный - возвращают ошибку и не дают сделать операцию.
Любая проблема на этом сервисе влияет на всю систему. Это реальная жопа. Хотя на самом деле, если подписаться на события сервиса аккаунта, и хранить информацию об аккаунтах у себя локально, в базе микро сервиса, то даже если все сломалось у сервиса аккаунтов, и мы недополучили сообщения о последних деактивированных или заного активированных аккаунтах, урон для бизнеса минимальный, потому что система работает, и пострадают только прямые пользователи сервиса аккаунт (но это бы случилось в любом случае ведь проблема именно в нем).
Нет. Вы заранее знаете где и откуда будут приходить запросы. Вы заранее подготавливаете уже агрегированные данные в удобном для запросов виде (структуре) и в удобной для соответствующих запросов базе данных.
Почитайте про DDD, CQRS.
Идея в том, чтобы реагировать на изменения в разных доменах, и каждый домен для себя строит нужные ему вьюшки с нужными данными уже внутри.
Например, вам нужно вернуть в апишке статью и данные автора. Сервис статей и сервис авторов находятся в разных доменах.
Вместо того чтобы в реалтайме ходить на 2 сервиса, вы заранее подготавливаете вьюшку где храните данные статьи и данные автора (только те данные что реально нужны, не весь объект автора который может содержать сотню полей в собственном домене).
Подписываетесь на изменения автора. Если автор изменил фамилию - ваши сабскрайберы обновляют вьюшку.
В итоге, если сервис авторов крашится, или еще чего - на уже существующий функционал это не влияет.
Сервис авторов может хромать и тормозить из-за нагрузки, но на отображение статей с данными автора это не повлияет, потому что вьюшка хранится в отдельной базе и с ней работает отдельный сервис, который скейлится по своим параметрам.
Ну это в кратце...
Потому как сейчас я не вижу преимуществ того что вы называете микросервисами.
Если кто-то из другой команды ломает свой сервис, то у меня сломается все, потому что мой апи напрямую зависит от чужого апи.
А что если у меня резкий скачок нагрузки, и мой сервис отлично авто-скейлится, но тот другой сервис не умеет или умеет но плохо? Время ответа моего апи будет зависеть от времени ответа чужого апи.
А что если мои запросы убивают тот второй сервис потому что он был не готов к таким фильтрам и сортировками? Хороше, он добавит индексы для меня, и еще +100500 клиентов, у убьет свой перформанс на write side .
Подписываясь на события другого сервиса, я могу строить у себя все что я хочу и как хочу, не мешая никому другому и не зависеть от других сервисов (до определенного уровня абстракции).
Тут конечно стоит упомянуть eventual consistency...
Что мешает тот же монолит загрузить на нужное железно, открыть только определенное АПИ где будет юзаться ваше железо, дать отдельную днску и поставить под отдельным лоад балансером, и вуаля - проблема решена. Юзай как отдельный сервис. Никто снаружи не обязан знать что это монолит.
Пока в базу не упретесь или не разрастетесь до размеров когда у вас сборка полдня идет, можете скейлиться с монолитом горизонтально/вертикально с любым железом.
Отдавать предпочтение нужно асинхронной коммуникации, CQRS, а не синхронным вызовам других сервисов.
Плакать хочется... Где перформанс? Эвэилабилити? Независимая разработка? Скейлинг? Или это проекты на 2 посетителя в день? Ну не нужны вам тогда микросервисы вообще...
Из личного опыта - если это стартап, не делайте свою жизнь и жизнь того кому придется поддерживать это микро сервисное чудо через 3-5 лет когда бизнес модель измениться 2-3 раза, когда стартап только начинает понимать что у него core, какая у него нагрузка, планы на будущее в плане масштабируемости (масштабируемости бизнеса) и где ему реально нужны плюшки от микросервисов.
Это не значит что нужно писать монолит-какашку. Начните с монолита, но с нормальной архитектурой. Не нужно писать спагетти. Разделите на модули, сервисы, отделите логику от отображения и стораджа (3tier, Onion, whatever), и в будут сможете малой кровью вынести core в микро сервисы.
Лучше когда монолит будут писать люди которые уже писали микросервисы и/или разбивали монолит на микросервисы. А если у вас мало-опытные разработчики, то лучше монолит какашка чем много маленьких какашек в виде микро-сервисов.
Очень понравилась идея. Воронку сами придумывали? Есть ли какие-то книги в этом направлении? Баззворды для поиска статей на похожую тематику на английском?
CQRS отличный паттерн. Особенно в связке с NoSQL базами. Позволяет создавать кайнд оф матириалайзд вьюз, просто на апликативной уровне а не на уровне базы (оракл, майкрософт). Как результат, позволяет не только строить независимые сервисы, но и быстрые и оптимизированные, потому что структура данных в базе заточена под определенные запросы.
Используем во многих местах, и пока довольны. Read сервисы получаются маленькими, оптимизированными, с предиктэбл перформансом, легко поддерживаемые и тестируемые.
Особенный профит в местах где количество запросов на чтение превосходит количество запросов на запись. Разделение ворклоада позволяет базе на запись не тормозить потому что с нее никто не читает и не нужно выделать ресурсы на чтение.
Я серьезно страдаю от плохого сна. Как только закрываю глаза, мозг сразу начинает думать как я буду решать задачи на работе, к которым у меня нет готовых решений.
Или даже не задачи на работе, а вот просто, приходит в мозг мысля - Как бы это запилить?
И все... мозг разгоняется, и в результате засыпаю очень долго, глубоко ночью, и днем разбитый.
К 7ми вечера начинает рубить, и если я не заснул до 10 вечера, открывается второе дыхание и опять пол ночи засыпаю.
Иногда заснуть помогает волшебная трава, но от нее отходняк у меня с утра...
Пытаюсь бороться с этим всякими психологическими штуками. Чтобы остановить мозг, представляю мысли в голове бумажкой, и выкидываю бумажку в выдуманную мусорку. Иногда помогает.
Нет. Камера не должна быть включенной. Просто мы мотоциклисты ставим телефон что бы дорогу смотреть. Для видео есть другие средства. Достаточно просто поездить и камере придет конец. Очень быстро.
Все так. У меня на одном камера накрылась, починили по гарантии. И вот новый тоже начал барахлить. Не выдерживают вибраций мотоцикла, и по итогу фокус пропадает и картинку двоит.
А вот что сотрудники эпл еще не знают, так это что камеры также не выдерживают вибрации фур и грузовиков.
Это важно. При тех же RPS при большом пейлоаде или сложной структурой данных, время сериализации может увеличиться.
А что если канал куда логи отправляются тормозит? Память то не резиновая. Обычно в таких случаях explicitly указывают размер очереди и поведение при заполнении. Например что логи будут дропаться если очередь слишком большая.
А то можно сильно удивиться когда что-то начнет падать по OOM или что канал будет забиваться... или CPU подскочить на сериализации в 3 часа ночи.
И кстати, такой проблемы нет?
user = { name: "alex" } logger("my name", { user, }; ->> ушло в очередь user.name = "ahmed"
Давно не писал на питоне, тем более с async/await поэтому возможно мой вопрос не в тему. Здесь имеется ввиду что асинхронный код не блокирует тред /процесс питона (GIL и все такое) или же логгер вообще будет сам по себе где то буферизировать логи и пушить их в какой-то стрим?
Я клоню к тому, что не случится ли ситуация когда нагрузка очень большая и код отрабатывает быстрее чем логи пушатся наружу, и какой-нибудь внутренний буфер/очередь забьется и начнет делать проблемы?
Вспоминаю как хейтил все эпплвское... Но после 2 недель работы на макбуке, уже лет как 8 наверное, я искренне не понимаю как можно работать на чем то еще.
Когда родители просят что-то починить потому что у них винда сломалась, у меня начинается дергаться глаз =))
Да и дело не только в операционке. Еще никто не придумал такой же удобный тачпад на лэптопах где можно было бы работать без мышки.
Да, главное это понимать. Happy Flow везде простой, а потом начинается...
Если back compatibility не предусмотрено, то танцы с бубном обеспечены.
На сколько я знаю, мы делаем не через дебезиум, а через стандартный коннектор - https://docs.mongodb.com/kafka-connector/current/
Этим уже девопсы занимаютсяу нас.
Насчет восстановления базы - интересный вопрос. Вряд ли тут есть генерное решение. Но в принципе можно к этому относиться как частному случаю ресета оффсета опредееленного консьюмера.
Если сама синхронизация очень тупая, в виде простых идемпотентных апсертов на стороне сабскрайберов, то все должно работать out of the box.
Если же вьюшки строятся сложнее (например мерж нескольких стримов или обогащение евентов синхронно (что не очень хорошо) в консьюмере, тут уже нужно конкретно по ситуации смотреть. Возможно что-то умнее придумать при помощи idempotencyId, timestamps, маппинга оффсета на стороне сабскрайбера с данными чтобы и написание умного рикавери процесса.
Есть конечно нюансы. Например в нашем случае используются топики, где храняться несколько месседжей на определенный _id (зависит от настроек топика кафки) и нужно иметь ввиду что когда будет идти восстановление, то в какой-то промежуток времени мы можем иметь во вьюшке не самые последние данные из тех что мы имеем.
Насколько я знаю, можно настроить топик хранить только последнюю копию документа монги.
Я люблю CQRS. В нашем легаси, как один из шагов в сторону мискросервисов, DDD, евентов + трушный CQRS, мы используем CDC. В нашем случае это Mongo + Kafka connector. И сабскрайберы подписываются на изменения определенных коллекций, и уже создают у себя нуные им вьюшки, в подходящщей базе данных и в подходящей структуре.
Тьфу тьфу работает стабильно и позволяет сделать анкаплинг сервисов и получить реальный профит.
Но нужно заранее думать о том как делать рикавери если что-то пошло не так. И если все делать правильно - рикавери сводится к рисету оффсета сабскрайбера на топик.
Это не сокрытие проблемы. Это часть анкаплинга и релаябилити. Как пример, автор изменил свое имя, и мы не проапдейтили статьи, потому сервис авторов изменил структуру событий и мы не может их обработать. Юзеру пофиг. Если имя обновится через час когда баг будет пофиксен, это равносильно тому что если бы бага не было с самого начало, а сам автор решил бы изменить свое имя на 1 час позже.
Все эти случаи должны обсуждаться с домейн экспертами. В критических случаях можно показывать возраст.
Вы когда на сайте банка заходите, и вам зашла зарплата, и вы сделали какие-то покупки, вам почти всегда показывают устаревшие данные.
А теперь представьте у банка проблема и один из их сервисов упал и его будут чинить сутки. Вы предпочтете видеть 0 или устаревшие данные с надписью - "Данные актуальны на ... и могут не содержать результаты последних операций"?
Вы мыслите как программист а не как домейн эксперт. В большинстве случаем старые данные намного ценнее странички с пустыми данными.
Именно. Именно в этом случае вы реально получаете отдачу от микросервисов. И да - это сложно. Коммуникация между сервисами должна быть асинхронной.
Да, поэтому там свои решения в виде схема реджистри и коррапшен лэйер и т.д. И опять же, это сложно.
И даже если структура месседжей изменилась, я просто не обновлю свои данные, а не буду возвращать пустые данные или вообще ошибку потому что сторонний сервер упал или изменил формат данных не сказав.
Тем более обидно когда на том стороннем сервисе данные меняются очень редко, а мне эти данные нужны всегда. И тут ваше возражение в виде "отдавать старые данные может быть плохой идеей" уже не катит. А любая проблема на том сервисе отразиться на моем сервисе. В конечном итоге страдают пользователи.
з.ы.
Я веду к тому, что трушные микросервисы сложны. А от нетрушных, очень профита. И даже эти профиты легко исчезают при появлении проблемы которые приходят с микро сервисами, одна из которых это нетворк.
Но я прекрасно понимаю что есть трейдофы, и иногда приходится ради фронтендеров городить backend for frontend, хоть я их и не люблю всей душой.
И если вы понимаете что это решение временное и никак не конечное (но мы то знаем что нет более постоянного решения чем временное), то ОК. Но многие новички могут начать пилить вот такие микросервисы, и потом не будут знать что с ними делать когда все сервисы будут переплетены между собой синхронными хттп запросами, и малейший баг в одном сервисе будет создавать снежный ком.
З.Ы.
У нас в легаси есть такой боттлнек, сервис аккаунты, и все остальные сервисы проверяют синхронно статус аккаунта - активный или неактивный. Если неактивный - возвращают ошибку и не дают сделать операцию.
Любая проблема на этом сервисе влияет на всю систему. Это реальная жопа. Хотя на самом деле, если подписаться на события сервиса аккаунта, и хранить информацию об аккаунтах у себя локально, в базе микро сервиса, то даже если все сломалось у сервиса аккаунтов, и мы недополучили сообщения о последних деактивированных или заного активированных аккаунтах, урон для бизнеса минимальный, потому что система работает, и пострадают только прямые пользователи сервиса аккаунт (но это бы случилось в любом случае ведь проблема именно в нем).
Нет. Вы заранее знаете где и откуда будут приходить запросы. Вы заранее подготавливаете уже агрегированные данные в удобном для запросов виде (структуре) и в удобной для соответствующих запросов базе данных.
Почитайте про DDD, CQRS.
Идея в том, чтобы реагировать на изменения в разных доменах, и каждый домен для себя строит нужные ему вьюшки с нужными данными уже внутри.
Например, вам нужно вернуть в апишке статью и данные автора. Сервис статей и сервис авторов находятся в разных доменах.
Вместо того чтобы в реалтайме ходить на 2 сервиса, вы заранее подготавливаете вьюшку где храните данные статьи и данные автора (только те данные что реально нужны, не весь объект автора который может содержать сотню полей в собственном домене).
Подписываетесь на изменения автора. Если автор изменил фамилию - ваши сабскрайберы обновляют вьюшку.
В итоге, если сервис авторов крашится, или еще чего - на уже существующий функционал это не влияет.
Сервис авторов может хромать и тормозить из-за нагрузки, но на отображение статей с данными автора это не повлияет, потому что вьюшка хранится в отдельной базе и с ней работает отдельный сервис, который скейлится по своим параметрам.
Ну это в кратце...
Потому как сейчас я не вижу преимуществ того что вы называете микросервисами.
Если кто-то из другой команды ломает свой сервис, то у меня сломается все, потому что мой апи напрямую зависит от чужого апи.
А что если у меня резкий скачок нагрузки, и мой сервис отлично авто-скейлится, но тот другой сервис не умеет или умеет но плохо? Время ответа моего апи будет зависеть от времени ответа чужого апи.
А что если мои запросы убивают тот второй сервис потому что он был не готов к таким фильтрам и сортировками? Хороше, он добавит индексы для меня, и еще +100500 клиентов, у убьет свой перформанс на write side .
Подписываясь на события другого сервиса, я могу строить у себя все что я хочу и как хочу, не мешая никому другому и не зависеть от других сервисов (до определенного уровня абстракции).
Тут конечно стоит упомянуть eventual consistency...
Что мешает тот же монолит загрузить на нужное железно, открыть только определенное АПИ где будет юзаться ваше железо, дать отдельную днску и поставить под отдельным лоад балансером, и вуаля - проблема решена. Юзай как отдельный сервис. Никто снаружи не обязан знать что это монолит.
Пока в базу не упретесь или не разрастетесь до размеров когда у вас сборка полдня идет, можете скейлиться с монолитом горизонтально/вертикально с любым железом.
Отдавать предпочтение нужно асинхронной коммуникации, CQRS, а не синхронным вызовам других сервисов.
Плакать хочется... Где перформанс? Эвэилабилити? Независимая разработка? Скейлинг? Или это проекты на 2 посетителя в день? Ну не нужны вам тогда микросервисы вообще...
Из личного опыта - если это стартап, не делайте свою жизнь и жизнь того кому придется поддерживать это микро сервисное чудо через 3-5 лет когда бизнес модель измениться 2-3 раза, когда стартап только начинает понимать что у него core, какая у него нагрузка, планы на будущее в плане масштабируемости (масштабируемости бизнеса) и где ему реально нужны плюшки от микросервисов.
Это не значит что нужно писать монолит-какашку. Начните с монолита, но с нормальной архитектурой. Не нужно писать спагетти. Разделите на модули, сервисы, отделите логику от отображения и стораджа (3tier, Onion, whatever), и в будут сможете малой кровью вынести core в микро сервисы.
Лучше когда монолит будут писать люди которые уже писали микросервисы и/или разбивали монолит на микросервисы. А если у вас мало-опытные разработчики, то лучше монолит какашка чем много маленьких какашек в виде микро-сервисов.
Что бы вам не говорили, микросервисы это сложно.
Очень понравилась идея. Воронку сами придумывали? Есть ли какие-то книги в этом направлении? Баззворды для поиска статей на похожую тематику на английском?
CQRS отличный паттерн. Особенно в связке с NoSQL базами. Позволяет создавать кайнд оф матириалайзд вьюз, просто на апликативной уровне а не на уровне базы (оракл, майкрософт). Как результат, позволяет не только строить независимые сервисы, но и быстрые и оптимизированные, потому что структура данных в базе заточена под определенные запросы.
Используем во многих местах, и пока довольны. Read сервисы получаются маленькими, оптимизированными, с предиктэбл перформансом, легко поддерживаемые и тестируемые.
Особенный профит в местах где количество запросов на чтение превосходит количество запросов на запись. Разделение ворклоада позволяет базе на запись не тормозить потому что с нее никто не читает и не нужно выделать ресурсы на чтение.
Спасиб. Пойду начальника разводить =)))
А эта новая линейка поддерживает подключение к 2-ум мониторам? М1 не умеет, поэтому не спешу переходить с интела Ж/
У меня есть трубка индика — подруга...
Я серьезно страдаю от плохого сна. Как только закрываю глаза, мозг сразу начинает думать как я буду решать задачи на работе, к которым у меня нет готовых решений.
Или даже не задачи на работе, а вот просто, приходит в мозг мысля - Как бы это запилить?
И все... мозг разгоняется, и в результате засыпаю очень долго, глубоко ночью, и днем разбитый.
К 7ми вечера начинает рубить, и если я не заснул до 10 вечера, открывается второе дыхание и опять пол ночи засыпаю.
Иногда заснуть помогает волшебная трава, но от нее отходняк у меня с утра...
Пытаюсь бороться с этим всякими психологическими штуками. Чтобы остановить мозг, представляю мысли в голове бумажкой, и выкидываю бумажку в выдуманную мусорку. Иногда помогает.
У меня 11 pro, и камера накрылась. Всего пару раз ставил на мотоцикл.
Нет. Камера не должна быть включенной. Просто мы мотоциклисты ставим телефон что бы дорогу смотреть. Для видео есть другие средства. Достаточно просто поездить и камере придет конец. Очень быстро.
Все так. У меня на одном камера накрылась, починили по гарантии. И вот новый тоже начал барахлить. Не выдерживают вибраций мотоцикла, и по итогу фокус пропадает и картинку двоит.
А вот что сотрудники эпл еще не знают, так это что камеры также не выдерживают вибрации фур и грузовиков.
Это важно. При тех же RPS при большом пейлоаде или сложной структурой данных, время сериализации может увеличиться.
А что если канал куда логи отправляются тормозит? Память то не резиновая. Обычно в таких случаях explicitly указывают размер очереди и поведение при заполнении. Например что логи будут дропаться если очередь слишком большая.
А то можно сильно удивиться когда что-то начнет падать по OOM или что канал будет забиваться... или CPU подскочить на сериализации в 3 часа ночи.
И кстати, такой проблемы нет?
user = { name: "alex" }
logger("my name", { user, }; ->> ушло в очередь
user.name = "ahmed"
Что уйдет в лог?
Давно не писал на питоне, тем более с async/await поэтому возможно мой вопрос не в тему. Здесь имеется ввиду что асинхронный код не блокирует тред /процесс питона (GIL и все такое) или же логгер вообще будет сам по себе где то буферизировать логи и пушить их в какой-то стрим?
Я клоню к тому, что не случится ли ситуация когда нагрузка очень большая и код отрабатывает быстрее чем логи пушатся наружу, и какой-нибудь внутренний буфер/очередь забьется и начнет делать проблемы?
Вспоминаю как хейтил все эпплвское... Но после 2 недель работы на макбуке, уже лет как 8 наверное, я искренне не понимаю как можно работать на чем то еще.
Когда родители просят что-то починить потому что у них винда сломалась, у меня начинается дергаться глаз =))
Да и дело не только в операционке. Еще никто не придумал такой же удобный тачпад на лэптопах где можно было бы работать без мышки.