День 2246. #ЗаметкиНаПолях
Не Смешивайте CQRS и MediatR. Начало
Экосистема .NET постепенно приравняла CQRS к использованию MediatR. Развеем некоторые распространённые заблуждения и выделим преимущества каждого шаблона.
CQRS в чистом виде
CQRS — это паттерн, разделяющий операции чтения и записи в приложении. Он предполагает, что модели, используемые для чтения данных, должны отличаться от моделей, используемых для записи. Никаких конкретных деталей реализации, никаких предписанных библиотек, просто архитектурный принцип.
Он возник из понимания того, что во многих приложениях, особенно в сложных доменах, требования к чтению и записи данных принципиально различаются. Операции чтения часто требуют объединения данных из нескольких источников или представления их в определённых форматах для UI. Операции записи должны обеспечивать соблюдение бизнес-правил, поддерживать согласованность и управлять состоянием домена.
Такое разделение даёт несколько преимуществ:
1. Оптимизированные модели чтения и записи для их конкретных целей.
2. Упрощённое обслуживание, поскольку проблемы чтения и записи независимы.
3. Расширенные возможности масштабирования для операций чтения и записи.
4. Более чёткая граница между логикой предметной области и потребностями представления.
MediatR
MediatR — это реализация шаблона посредника. Его основная цель — уменьшить прямые зависимости между компонентами, предоставляя единую точку связи. Вместо того, чтобы компоненты знали друг о друге, используется посредник, который их соединяет.
MediatR предоставляет несколько функций:
1. Внутрипроцессный обмен сообщениями между компонентами.
2. Поведения конвейера (pipeline behaviors) для сквозных проблем.
3. Обработка уведомлений (по модели публикация/подписка).
Косвенность, которую вводит MediatR, является его наиболее критикуемым аспектом. Она может усложнить отслеживание кода, особенно для новичков. Однако можно решить эту проблему, определив запросы в том же файле, что и обработчики.
Почему они часто появляются вместе?
Частое сочетание CQRS и MediatR не беспричинно. Модель запроса/ответа MediatR хорошо согласуется с разделением команд/запросов в CQRS. Команды и запросы могут быть реализованы как запросы MediatR, с обработчиками, содержащими фактическую логику реализации.
Вот пример команды в MediatR:
CQRS с MediatR предлагает несколько преимуществ:
1. Согласованная обработка как команд, так и запросов.
2. Поведения конвейера для регистрации, проверки и обработки ошибок.
3. Чёткое разделение проблем с помощью классов обработчиков.
4. Упрощённое тестирование с помощью изоляции обработчиков.
Однако это удобство достигается ценой дополнительной абстракции и сложности. Нам нужно определить классы запросов/ответов и их обработчики, написать код для отправки запросов и т.д. Это может быть излишним для простых приложений.
Вопрос не в том, является ли этот компромисс универсально хорошим или универсально плохим, а в том, подходит ли это для вашего конкретного контекста.
Окончание следует…
Источник: https://www.milanjovanovic.tech/blog/stop-conflating-cqrs-and-mediatr
Не Смешивайте CQRS и MediatR. Начало
Экосистема .NET постепенно приравняла CQRS к использованию MediatR. Развеем некоторые распространённые заблуждения и выделим преимущества каждого шаблона.
CQRS в чистом виде
CQRS — это паттерн, разделяющий операции чтения и записи в приложении. Он предполагает, что модели, используемые для чтения данных, должны отличаться от моделей, используемых для записи. Никаких конкретных деталей реализации, никаких предписанных библиотек, просто архитектурный принцип.
Он возник из понимания того, что во многих приложениях, особенно в сложных доменах, требования к чтению и записи данных принципиально различаются. Операции чтения часто требуют объединения данных из нескольких источников или представления их в определённых форматах для UI. Операции записи должны обеспечивать соблюдение бизнес-правил, поддерживать согласованность и управлять состоянием домена.
Такое разделение даёт несколько преимуществ:
1. Оптимизированные модели чтения и записи для их конкретных целей.
2. Упрощённое обслуживание, поскольку проблемы чтения и записи независимы.
3. Расширенные возможности масштабирования для операций чтения и записи.
4. Более чёткая граница между логикой предметной области и потребностями представления.
MediatR
MediatR — это реализация шаблона посредника. Его основная цель — уменьшить прямые зависимости между компонентами, предоставляя единую точку связи. Вместо того, чтобы компоненты знали друг о друге, используется посредник, который их соединяет.
MediatR предоставляет несколько функций:
1. Внутрипроцессный обмен сообщениями между компонентами.
2. Поведения конвейера (pipeline behaviors) для сквозных проблем.
3. Обработка уведомлений (по модели публикация/подписка).
Косвенность, которую вводит MediatR, является его наиболее критикуемым аспектом. Она может усложнить отслеживание кода, особенно для новичков. Однако можно решить эту проблему, определив запросы в том же файле, что и обработчики.
Почему они часто появляются вместе?
Частое сочетание CQRS и MediatR не беспричинно. Модель запроса/ответа MediatR хорошо согласуется с разделением команд/запросов в CQRS. Команды и запросы могут быть реализованы как запросы MediatR, с обработчиками, содержащими фактическую логику реализации.
Вот пример команды в MediatR:
public record CreateHabit(string Name, string? Description, int Priority) : IRequest<HabitDto>;
public sealed class CreateHabitHandler(
ApplicationDbContext dbContext,
IValidator<CreateHabit> validator)
: IRequestHandler<CreateHabit, HabitDto>
{
public async Task<HabitDto> Handle(
CreateHabit request, CancellationToken ct)
{
await validator
.ValidateAndThrowAsync(request);
var habit = request.ToEntity();
dbContext.Habits.Add(habit);
await dbContext.SaveChangesAsync(ct);
return habit.ToDto();
}
}
CQRS с MediatR предлагает несколько преимуществ:
1. Согласованная обработка как команд, так и запросов.
2. Поведения конвейера для регистрации, проверки и обработки ошибок.
3. Чёткое разделение проблем с помощью классов обработчиков.
4. Упрощённое тестирование с помощью изоляции обработчиков.
Однако это удобство достигается ценой дополнительной абстракции и сложности. Нам нужно определить классы запросов/ответов и их обработчики, написать код для отправки запросов и т.д. Это может быть излишним для простых приложений.
Вопрос не в том, является ли этот компромисс универсально хорошим или универсально плохим, а в том, подходит ли это для вашего конкретного контекста.
Окончание следует…
Источник: https://www.milanjovanovic.tech/blog/stop-conflating-cqrs-and-mediatr
👍24👎1
День 2247. #ЗаметкиНаПолях
Не Смешивайте CQRS и MediatR. Окончание
Начало
CQRS без MediatR
CQRS можно реализовать так же легко и без MediatR. Вы можете определить команды и запросы как простые интерфейсы:
Теперь реализуем обработчики:
и зарегистрируем их в DI-контейнере
Наконец, используем обработчик в контроллере:
В чем разница между этим подходом и подходом c MediatR?
Этот подход обеспечивает такое же разделение задач, но без косвенности. Он прямой, явный и часто достаточный для многих приложений.
Однако ему не хватает некоторых удобств, которые предлагает MediatR, таких как поведение конвейера и автоматическая регистрация обработчиков. Вам также необходимо внедрять обработчики в контроллеры, что может быть обременительным для более крупных приложений.
Итого
CQRS и MediatR — это отдельные инструменты, которые решают разные проблемы. Хотя они могут хорошо работать вместе, воспринимать их как нечто неделимое вредно. CQRS разделяет задачи чтения и записи, в то время как MediatR разделяет компоненты через посредника.
Важно понимание того, что предлагает каждый шаблон, и принятии обоснованных решений на основе вашего конкретного контекста. Иногда вам нужны оба, иногда только один, а иногда ни один. В этом суть продуманной архитектуры: выбор правильных инструментов для ваших конкретных потребностей.
Источник: https://www.milanjovanovic.tech/blog/stop-conflating-cqrs-and-mediatr
Не Смешивайте CQRS и MediatR. Окончание
Начало
CQRS без MediatR
CQRS можно реализовать так же легко и без MediatR. Вы можете определить команды и запросы как простые интерфейсы:
public interface ICommandHandler<in TCommand, TResult>
{
Task<TResult> Handle(
TCommand command, CancellationToken ct = default);
}
// аналогично для IQueryHandler
Теперь реализуем обработчики:
public record CreateOrderCommand(
string CustomerId, List<OrderItem> Items)
: ICommand<CreateOrderResult>;
public class CreateOrderCommandHandler :
ICommandHandler<CreateOrderCommand, CreateOrderResult>
{
public async Task<CreateOrderResult> Handle(
CreateOrderCommand command,
CancellationToken ct = default)
{
// реализация
}
}
и зарегистрируем их в DI-контейнере
builder.Services
.AddScoped<ICommandHandler<CreateOrderCommand, CreateOrderResult>, CreateOrderCommandHandler>();
Наконец, используем обработчик в контроллере:
[ApiController]
[Route("orders")]
public class OrdersController : ControllerBase
{
[HttpPost]
public async Task<ActionResult<CreateOrderResult>>
CreateOrder(
CreateOrderCommand command,
ICommandHandler<CreateOrderCommand, CreateOrderResult> handler)
{
var result = await handler.Handle(command);
return Ok(result);
}
}
В чем разница между этим подходом и подходом c MediatR?
Этот подход обеспечивает такое же разделение задач, но без косвенности. Он прямой, явный и часто достаточный для многих приложений.
Однако ему не хватает некоторых удобств, которые предлагает MediatR, таких как поведение конвейера и автоматическая регистрация обработчиков. Вам также необходимо внедрять обработчики в контроллеры, что может быть обременительным для более крупных приложений.
Итого
CQRS и MediatR — это отдельные инструменты, которые решают разные проблемы. Хотя они могут хорошо работать вместе, воспринимать их как нечто неделимое вредно. CQRS разделяет задачи чтения и записи, в то время как MediatR разделяет компоненты через посредника.
Важно понимание того, что предлагает каждый шаблон, и принятии обоснованных решений на основе вашего конкретного контекста. Иногда вам нужны оба, иногда только один, а иногда ни один. В этом суть продуманной архитектуры: выбор правильных инструментов для ваших конкретных потребностей.
Источник: https://www.milanjovanovic.tech/blog/stop-conflating-cqrs-and-mediatr
👍20👎1
День 2248. #BestPractices
Мастерство Пулл-Реквестов: как Легко Пройти Обзор Кода. Начало
Как разработчики, мы часто работаем параллельно, создавая ветки для новых функций, исправляя ошибки и внося обновления. Но когда приходит время внести эти изменения в основную кодовую базу, пулл-реквесты (PR) становятся мостом между изолированной разработкой и совместной работой в команде. Каждого разочаровывает, когда PR отклоняют или отправляют на доработку. Легко можно потратить часы на функцию, а потом понять, что твоя реализация не соответствует видению команды. Однако со временем мы узнаём, что эффективные PR касаются не только самого кода. Они и про то, как мы сообщаем о наших изменениях. Рассмотрим, как создавать пулл-реквесты, которые делают процесс обзора более плавным, быстрым и эффективным для всех участников.
1. Начните с информативного заголовка
Первое впечатление имеет значение даже в мире кода. Заголовок пулл-реквеста — это наш шанс немедленно донести суть изменения. Думайте о нём как о заголовке статьи; он должен быть коротким, понятным и информативным. Вместо:
"Обновил код"
"Исправил баг"
"Изменения за вчера"
Используйте более описательные заголовки, например:
feat: Добавил OAuth2 аутентификацию для конечных точек API
fix: Устранил состояния гонки при обработке сеанса пользователя
refactor: Оптимизированы запросы к БД при поиске пользователя
Хорошо составленный заголовок помогает рецензентам понять изменение, не открывая PR. Он задает тон всему процессу обзора кода.
2. Установите контекст (не предполагайте, что все знают проблему)
Прежде чем погрузиться в код, важно предоставить контекст. Не все могут быть знакомы с конкретной проблемой, которую мы решаем, и важно объяснить, почему произошли изменения. Чёткое описание PR упрощает и ускоряет рецензирование. Вот шаблон для хорошо структурированного описания PR:
Это гарантирует, что рецензенты поймут проблему, выбранный подход и то, как проверить решение. PR без контекста может существенно замедлить процесс, поэтому всегда включайте достаточно информации, чтобы команда могла понять ваши изменения.
3. Сохраняйте PR сфокусированным
Нас всех подбивает решить сразу несколько проблем. Но это часто приводит к слишком большим PR, которые могут обескуражить рецензентов. Вместо этого пытайтесь разбить работу на более мелкие, целенаправленные PR. Каждый PR должен решать определённую задачу. Например, если мы создаём систему управления пользователями, можно разбить её на более мелкие задачи:
PR 1: feat: Добавление основной модели и миграции
PR 2: feat: Реализация конечных точек аутентификации
PR 3: feat: Добавление UI управления пользователями
PR 4: feat: Интеграция подтверждения по email
Каждый PR должен быть нацелен на одну фичу или исправление ошибки, что сделает процесс обзора проще для всех. Это ведёт к более быстрым обзорам и меньшему количеству доработок.
Окончание следует…
Источник: https://dev.to/budiwidhiyanto/the-art-of-pull-requests-a-developers-guide-to-smooth-code-reviews-38bk
Мастерство Пулл-Реквестов: как Легко Пройти Обзор Кода. Начало
Как разработчики, мы часто работаем параллельно, создавая ветки для новых функций, исправляя ошибки и внося обновления. Но когда приходит время внести эти изменения в основную кодовую базу, пулл-реквесты (PR) становятся мостом между изолированной разработкой и совместной работой в команде. Каждого разочаровывает, когда PR отклоняют или отправляют на доработку. Легко можно потратить часы на функцию, а потом понять, что твоя реализация не соответствует видению команды. Однако со временем мы узнаём, что эффективные PR касаются не только самого кода. Они и про то, как мы сообщаем о наших изменениях. Рассмотрим, как создавать пулл-реквесты, которые делают процесс обзора более плавным, быстрым и эффективным для всех участников.
1. Начните с информативного заголовка
Первое впечатление имеет значение даже в мире кода. Заголовок пулл-реквеста — это наш шанс немедленно донести суть изменения. Думайте о нём как о заголовке статьи; он должен быть коротким, понятным и информативным. Вместо:
"Обновил код"
"Исправил баг"
"Изменения за вчера"
Используйте более описательные заголовки, например:
feat: Добавил OAuth2 аутентификацию для конечных точек API
fix: Устранил состояния гонки при обработке сеанса пользователя
refactor: Оптимизированы запросы к БД при поиске пользователя
Хорошо составленный заголовок помогает рецензентам понять изменение, не открывая PR. Он задает тон всему процессу обзора кода.
2. Установите контекст (не предполагайте, что все знают проблему)
Прежде чем погрузиться в код, важно предоставить контекст. Не все могут быть знакомы с конкретной проблемой, которую мы решаем, и важно объяснить, почему произошли изменения. Чёткое описание PR упрощает и ускоряет рецензирование. Вот шаблон для хорошо структурированного описания PR:
## Проблема
Текущая система аутентификации пользователей не поддерживает вход через соцсети, что вызывает затруднения при регистрации. Мы наблюдаем 40% отказов на этапе регистрации.
Связанный тикет: AUTH-123
## Решение
Реализована аутентификация OAuth2 с Google:
- Добавлено промежуточное ПО OAuth2 для обработки аутентификации Google
- Создана новая логика сопоставления профилей пользователей
- Реализовано управление сеансами для входа через соцсети
## Технические подробности
- Использует passport-google-oauth20
- Добавлены новые поля: googleId, socialProfile
- Изменена модель пользователя для поддержки нескольких методов аутентификации
## Тестирование
1. Нажмите «Войти через Google»
2. Авторизуйте тестовое приложение
3. Проверьте успешное перенаправление на панель управления
4. Проверьте, содержит ли профиль пользователя данные Google
## Конфигурация
Требуются новые переменные среды:
- GOOGLE_CLIENT_ID
- GOOGLE_CLIENT_SECRET
- OAUTH_CALLBACK_URL
Это гарантирует, что рецензенты поймут проблему, выбранный подход и то, как проверить решение. PR без контекста может существенно замедлить процесс, поэтому всегда включайте достаточно информации, чтобы команда могла понять ваши изменения.
3. Сохраняйте PR сфокусированным
Нас всех подбивает решить сразу несколько проблем. Но это часто приводит к слишком большим PR, которые могут обескуражить рецензентов. Вместо этого пытайтесь разбить работу на более мелкие, целенаправленные PR. Каждый PR должен решать определённую задачу. Например, если мы создаём систему управления пользователями, можно разбить её на более мелкие задачи:
PR 1: feat: Добавление основной модели и миграции
PR 2: feat: Реализация конечных точек аутентификации
PR 3: feat: Добавление UI управления пользователями
PR 4: feat: Интеграция подтверждения по email
Каждый PR должен быть нацелен на одну фичу или исправление ошибки, что сделает процесс обзора проще для всех. Это ведёт к более быстрым обзорам и меньшему количеству доработок.
Окончание следует…
Источник: https://dev.to/budiwidhiyanto/the-art-of-pull-requests-a-developers-guide-to-smooth-code-reviews-38bk
👍18👎2
День 2249. #BestPractices
Мастерство Пулл-Реквестов: как Легко Пройти Обзор Кода. Окончание
Начало
4. Сообщения коммитов: чистота и ясность
Хорошее сообщение коммита не просто объясняет код. Оно помогает всем понять, почему было сделано изменение и как оно вписывается в общую картину.
Хорошее сообщение коммита
- предоставляет контекст: объясняет причину изменения;
- улучшает сотрудничество: будущие разработчики смогут отслеживать историю проекта и легко понимать цель каждого коммита;
- экономит время: уменьшают необходимость в дополнительных вопросах и предотвращают доработки во время процесса проверки;
Примеры плохих сообщений коммитов:
- «Исправлено»
Это расплывчато и не указывает, что исправлено или почему.
Лучше:
fix(auth): устранена ошибка входа пользователя, вызванная истекшими токенами.
- «Обновления»
Не сообщает рецензенту, что было изменено или почему обновление было необходимо.
Лучше:
chore: обновлены зависимости для исправления уязвимостей безопасности
- «Работа в процессе»
Не описывает никаких значимых изменений и предполагает, что код неполный. Также усложняет процесс проверки, так как рецензент не знает, смотрит ли он на готовую функцию или только на черновик.
Лучше:
feat(api): добавлены конечные точки аутентификации пользователя
5. Контрольный список готовности к обзору кода
Перед отправкой PR используйте следующий контрольный список, чтобы убедиться, что всё готово. Контрольный список важен, т.к.:
- Экономит время рецензентов: сводит к минимуму вероятность того, что рецензенты попросят об исправлениях, позволяя им сосредоточиться на логике кода.
- Улучшает согласованность: гарантирует, что все PR соответствуют одному стандарту, что делает процесс обзора более гладким для всех.
- Уменьшает количество повторных проверок: двойная проверка вашего кода и тестов позволяет избежать нескольких раундов обзоров.
Пример контрольного списка:
Распространённые проблемы с PR
1. В PR слишком много изменений
Разбейте задачу на более мелкие, более управляемые PR. Сначала для изменений схемы БД, затем для модификаций API, а затем — для корректировок UI. Это позволит рецензентам сосредоточиться на чём-то одном за раз.
2. Непоследовательные сообщения коммитов
Они затрудняют отслеживание изменений: одни слишком расплывчаты, другие — слишком подробные. Используйте стандартный формат сообщений коммитов и убедитесь, что все его соблюдают. Это сделает историю проекта намного более читаемой и улучшит совместную работу.
Итого
Создание эффективных PR — навык, который улучшается с практикой. Каждый PR — это возможность для обучения. Каждый комментарий, предложение или вопрос в обзоре кода помогает нам расти как разработчикам и улучшать наши методы кодирования.
Цель не просто слить наш код с основной веткой; а создать высококачественную кодовую базу, которую всем будет легко понимать и поддерживать. Уделяя особое внимание нашим PR, мы инвестируем в успех проекта и наш рост как разработчиков.
Источник: https://dev.to/budiwidhiyanto/the-art-of-pull-requests-a-developers-guide-to-smooth-code-reviews-38bk
Мастерство Пулл-Реквестов: как Легко Пройти Обзор Кода. Окончание
Начало
4. Сообщения коммитов: чистота и ясность
Хорошее сообщение коммита не просто объясняет код. Оно помогает всем понять, почему было сделано изменение и как оно вписывается в общую картину.
Хорошее сообщение коммита
- предоставляет контекст: объясняет причину изменения;
- улучшает сотрудничество: будущие разработчики смогут отслеживать историю проекта и легко понимать цель каждого коммита;
- экономит время: уменьшают необходимость в дополнительных вопросах и предотвращают доработки во время процесса проверки;
Примеры плохих сообщений коммитов:
- «Исправлено»
Это расплывчато и не указывает, что исправлено или почему.
Лучше:
fix(auth): устранена ошибка входа пользователя, вызванная истекшими токенами.
- «Обновления»
Не сообщает рецензенту, что было изменено или почему обновление было необходимо.
Лучше:
chore: обновлены зависимости для исправления уязвимостей безопасности
- «Работа в процессе»
Не описывает никаких значимых изменений и предполагает, что код неполный. Также усложняет процесс проверки, так как рецензент не знает, смотрит ли он на готовую функцию или только на черновик.
Лучше:
feat(api): добавлены конечные точки аутентификации пользователя
5. Контрольный список готовности к обзору кода
Перед отправкой PR используйте следующий контрольный список, чтобы убедиться, что всё готово. Контрольный список важен, т.к.:
- Экономит время рецензентов: сводит к минимуму вероятность того, что рецензенты попросят об исправлениях, позволяя им сосредоточиться на логике кода.
- Улучшает согласованность: гарантирует, что все PR соответствуют одному стандарту, что делает процесс обзора более гладким для всех.
- Уменьшает количество повторных проверок: двойная проверка вашего кода и тестов позволяет избежать нескольких раундов обзоров.
Пример контрольного списка:
## Перед коммитом
- [ ] Все тесты проходят
- [ ] Нет предупреждений компилятора
- [ ] Документация обновлена
- [ ] В коммите нет приватных данных
- [ ] Ветка синхронизирована с main
- [ ] Код отвечает стилю кодирования проекта
Распространённые проблемы с PR
1. В PR слишком много изменений
Разбейте задачу на более мелкие, более управляемые PR. Сначала для изменений схемы БД, затем для модификаций API, а затем — для корректировок UI. Это позволит рецензентам сосредоточиться на чём-то одном за раз.
2. Непоследовательные сообщения коммитов
Они затрудняют отслеживание изменений: одни слишком расплывчаты, другие — слишком подробные. Используйте стандартный формат сообщений коммитов и убедитесь, что все его соблюдают. Это сделает историю проекта намного более читаемой и улучшит совместную работу.
Итого
Создание эффективных PR — навык, который улучшается с практикой. Каждый PR — это возможность для обучения. Каждый комментарий, предложение или вопрос в обзоре кода помогает нам расти как разработчикам и улучшать наши методы кодирования.
Цель не просто слить наш код с основной веткой; а создать высококачественную кодовую базу, которую всем будет легко понимать и поддерживать. Уделяя особое внимание нашим PR, мы инвестируем в успех проекта и наш рост как разработчиков.
Источник: https://dev.to/budiwidhiyanto/the-art-of-pull-requests-a-developers-guide-to-smooth-code-reviews-38bk
👍9
День 2250. #SystemDesign101
Начинаю серию постов про System Design. Это будут небольшие шпаргалки, описывающие ту или иную технологию. Надеюсь, вам понравится.
1. Виды коммуникаций API
Архитектурные стили определяют, как различные компоненты системы взаимодействуют друг с другом. В результате они обеспечивают эффективность, надёжность и простоту интеграции с другими системами, предоставляя стандартный подход к проектированию и созданию API. Вот наиболее часто используемые стили:
SOAP
- Зрелый, всеобъемлющий, на основе XML;
- Лучше всего подходит для корпоративных приложений.
RESTful
- Популярный, простые в реализации методы HTTP;
- Идеально подходит для веб-сервисов.
GraphQL
- Язык запросов, запрашивает только нужные данные;
- Снижает сетевые издержки, ускоряет ответы.
gRPC
- Современный, высокопроизводительный;
- Подходит для архитектур микросервисов.
WebSocket
- Двунаправленные, постоянные соединения в реальном времени;
- Идеально подходит для обмена данными с малой задержкой.
Webhook
- Управляемый событиями, использует обратные вызовы HTTP, асинхронный;
- Уведомляет системы о событиях.
Источник: https://github.com/ByteByteGoHq/system-design-101
Начинаю серию постов про System Design. Это будут небольшие шпаргалки, описывающие ту или иную технологию. Надеюсь, вам понравится.
1. Виды коммуникаций API
Архитектурные стили определяют, как различные компоненты системы взаимодействуют друг с другом. В результате они обеспечивают эффективность, надёжность и простоту интеграции с другими системами, предоставляя стандартный подход к проектированию и созданию API. Вот наиболее часто используемые стили:
SOAP
- Зрелый, всеобъемлющий, на основе XML;
- Лучше всего подходит для корпоративных приложений.
RESTful
- Популярный, простые в реализации методы HTTP;
- Идеально подходит для веб-сервисов.
GraphQL
- Язык запросов, запрашивает только нужные данные;
- Снижает сетевые издержки, ускоряет ответы.
gRPC
- Современный, высокопроизводительный;
- Подходит для архитектур микросервисов.
WebSocket
- Двунаправленные, постоянные соединения в реальном времени;
- Идеально подходит для обмена данными с малой задержкой.
Webhook
- Управляемый событиями, использует обратные вызовы HTTP, асинхронный;
- Уведомляет системы о событиях.
Источник: https://github.com/ByteByteGoHq/system-design-101
👍29👎1
День 2251. #УрокиРазработки
Уроки 50 Лет Разработки ПО
Урок 46. Помните, что разница между плохим и хорошим может быть малозаметной
Во многих случаях разницу между качественным и некачественным продуктом определяют небольшой дополнительный анализ, опрос, проверка или тестирование. Это не обычные ошибки, которые время от времени совершают все, а проблемы, возникающие из-за поспешности, небрежности или невнимания к деталям.
Чтобы избежать малозаметных разрывов между плохим и хорошим, часто нужно лишь немного подумать, прежде чем продолжать. Все мы встречали множество программных продуктов с ошибками, которые должны были быть обнаружены во время тестирования, или с плохим дизайном, по которому было видно, что пользовательскому опыту не уделили должного внимания. Например, сайт сообщает, что у вас есть непрочитанное уведомление. Но при нажатии на значок уведомления появляется сообщение: «У вас нет сообщений». Или форма на сайте, которая из-за ошибки в Javascript не проходит валидацию, и клиент не может её отправить. Подобные дефекты мелкие, но очень раздражают и заставляют задуматься: «А что, если во всём остальном эта компания тоже работает спустя рукава»?
Вот некоторые категории проблем, ухудшающих качество ПО, которых разработчики могут избежать:
1. Предположения
Бизнес-аналитик может ошибиться в своих предположениях или записать предположение, сделанное клиентами, но затем забыть проверить, насколько оно верно.
2. Идеи решения
Клиенты часто предлагают бизнес-аналитикам свои идеи решения вместо требований. Если бизнес-аналитик не заглянет за пределы предложенного решения, чтобы понять реальную потребность, то может взяться за решение неправильной задачи или выбрать неадекватное решение, которое придётся исправлять позже.
3. Регрессионное тестирование
Если не выполнить регрессионное тестирование после быстрого изменения кода, то можно пропустить ошибку в изменённом коде. Даже небольшое изменение может неожиданно сломать что-то ещё.
4. Обработка исключений
Разработчики могут настолько сосредоточиться на «счастливом пути» в ожидаемом поведении системы, что могут забыть о распространённых ошибках. Отсутствующие, ошибочные или неправильно отформатированные данные могут привести к неожиданным результатам или даже сбою системы.
5. Воздействие изменений
Иногда люди внедряют изменения, не задумываясь о том, как они повлияют на другие части системы или сопутствующие продукты. Изменение одного аспекта поведения системы может привести к нарушению взаимодействия с пользователем, если аналогичная функциональность, имеющаяся в других местах, не будет изменена соответствующим образом.
Качество не бесплатно в смысле стоимости. Предотвращение, обнаружение и исправление дефектов требуют дополнительных ресурсов. Тем не менее устранение малозаметных разрывов между плохим и хорошим обязательно окупится, так как вам не придётся тратить ещё больше ресурсов на устранение проблем.
Источник: Карл Вигерс “Жемчужины Разработки”. СПб.: Питер, 2024. Глава 6.
Уроки 50 Лет Разработки ПО
Урок 46. Помните, что разница между плохим и хорошим может быть малозаметной
Во многих случаях разницу между качественным и некачественным продуктом определяют небольшой дополнительный анализ, опрос, проверка или тестирование. Это не обычные ошибки, которые время от времени совершают все, а проблемы, возникающие из-за поспешности, небрежности или невнимания к деталям.
Чтобы избежать малозаметных разрывов между плохим и хорошим, часто нужно лишь немного подумать, прежде чем продолжать. Все мы встречали множество программных продуктов с ошибками, которые должны были быть обнаружены во время тестирования, или с плохим дизайном, по которому было видно, что пользовательскому опыту не уделили должного внимания. Например, сайт сообщает, что у вас есть непрочитанное уведомление. Но при нажатии на значок уведомления появляется сообщение: «У вас нет сообщений». Или форма на сайте, которая из-за ошибки в Javascript не проходит валидацию, и клиент не может её отправить. Подобные дефекты мелкие, но очень раздражают и заставляют задуматься: «А что, если во всём остальном эта компания тоже работает спустя рукава»?
Вот некоторые категории проблем, ухудшающих качество ПО, которых разработчики могут избежать:
1. Предположения
Бизнес-аналитик может ошибиться в своих предположениях или записать предположение, сделанное клиентами, но затем забыть проверить, насколько оно верно.
2. Идеи решения
Клиенты часто предлагают бизнес-аналитикам свои идеи решения вместо требований. Если бизнес-аналитик не заглянет за пределы предложенного решения, чтобы понять реальную потребность, то может взяться за решение неправильной задачи или выбрать неадекватное решение, которое придётся исправлять позже.
3. Регрессионное тестирование
Если не выполнить регрессионное тестирование после быстрого изменения кода, то можно пропустить ошибку в изменённом коде. Даже небольшое изменение может неожиданно сломать что-то ещё.
4. Обработка исключений
Разработчики могут настолько сосредоточиться на «счастливом пути» в ожидаемом поведении системы, что могут забыть о распространённых ошибках. Отсутствующие, ошибочные или неправильно отформатированные данные могут привести к неожиданным результатам или даже сбою системы.
5. Воздействие изменений
Иногда люди внедряют изменения, не задумываясь о том, как они повлияют на другие части системы или сопутствующие продукты. Изменение одного аспекта поведения системы может привести к нарушению взаимодействия с пользователем, если аналогичная функциональность, имеющаяся в других местах, не будет изменена соответствующим образом.
Качество не бесплатно в смысле стоимости. Предотвращение, обнаружение и исправление дефектов требуют дополнительных ресурсов. Тем не менее устранение малозаметных разрывов между плохим и хорошим обязательно окупится, так как вам не придётся тратить ещё больше ресурсов на устранение проблем.
Источник: Карл Вигерс “Жемчужины Разработки”. СПб.: Питер, 2024. Глава 6.
👍5👎1
День 2252. #ЗаметкиНаПолях
Пример Сопоставления по Шаблону
Сегодня поделюсь с вами фрагментом кода от Жеральда Барре (aka Meziantou), в котором используется сопоставление по шаблону, а также метод SplitAny, использующий SearchValues<char>.
В примере ниже приведён простой сопоставитель версий, который проверяет, удовлетворяет ли версия (version) ограничениям (constraints). Ограничения — это строка, которая может содержать несколько ограничений, разделённых
Источник: https://www.meziantou.net/nice-example-of-csharp-list-pattern-matching.htm
Пример Сопоставления по Шаблону
Сегодня поделюсь с вами фрагментом кода от Жеральда Барре (aka Meziantou), в котором используется сопоставление по шаблону, а также метод SplitAny, использующий SearchValues<char>.
В примере ниже приведён простой сопоставитель версий, который проверяет, удовлетворяет ли версия (version) ограничениям (constraints). Ограничения — это строка, которая может содержать несколько ограничений, разделённых
,
или ;
. Каждое ограничение может быть одной версией или диапазоном версий. В свою очередь, диапазон может выглядеть как >1.0.0
, >=1.0.0
, <1.0.0
, <=1.0.0
, =1.0.0
, или 1.0.0
.using System.Buffers;
var version = "1.5.0";
var constraints = ">=1.0.0,<2.0.0";
Console.WriteLine(
VersionMatcher.IsValid(version, constraints));
class VersionMatcher
{
private static readonly SearchValues<char>
SplitChars = SearchValues.Create([',', ';']);
public static bool IsValid(
ReadOnlySpan<char> version,
ReadOnlySpan<char> constraints)
{
var parsed = Version.Parse(version);
foreach (var partRange in
constraints.SplitAny(SplitChars))
{
var part = constraints[partRange].Trim();
if (part.IsEmpty)
continue;
var satisfy = part switch
{
['=', .. var r] => parsed == Version.Parse(r),
['<', '=', .. var r] => parsed <= Version.Parse(r),
['<', .. var r] => parsed < Version.Parse(r),
['>', '=', .. var r] => parsed >= Version.Parse(r),
['>', .. var r] => parsed > Version.Parse(r),
_ => parsed == Version.Parse(part),
};
if (!satisfy)
return false;
}
return true;
}
}
Источник: https://www.meziantou.net/nice-example-of-csharp-list-pattern-matching.htm
👍10👎2
День 2253. #ЧтоНовенького #NET10
Новинки Превью 2 ASP.NET Core 10
В последнем выпуске ASP.NET Core 10 Preview 2 представлены несколько улучшений в Blazor, в создании документации OpenAPI и в инструментах разработчика. Большинство изменений присланы контрибьюторами и основаны на обратной связи от разработчиков.
1. Переработана навигация в Blazor
При использовании NavigateTo для навигации по той же странице (например, при изменении только строки запроса) браузер больше не будет принудительно прокручивать страницу вверх. В предыдущих версиях разработчикам приходилось вручную обходить это поведение.
Компонент NavLink теперь по умолчанию игнорирует строки запроса и фрагменты (часть URL после #) при сопоставлении с помощью NavLinkMatch.All. Это означает, что ссылка будет активна, даже если строки запроса или фрагменты в URL изменятся. В AppContext есть переключатель, который позволит вернуться к предыдущему поведению, если вам это необходимо. Для кастомного поведения сопоставления NavLink теперь предоставляет переопределяемый метод ShouldMatch.
Визуализация повторного подключения, когда клиент теряет WebSocket-соединение с сервером, обновилась в шаблоне проекта, и представляет новый компонент ReconnectModal, который разделяет CSS и JavaScript для более строгого соответствия политике безопасности контента (CSP). Настраиваемое событие components-reconnect-state-changed обеспечивает более детальный контроль над состояниями подключения, включая новую фазу retrying (повторной попытки).
2. Изменения в OpenAPI
Разработчики API получат встроенную поддержку для автоматического преобразования описаний <summary> в исходном коде в документы OpenAPI. Для этого нужно добавить в файл проекта следующую строку:
Тогда во время компиляции генератор исходного кода соберёт комментарии и создаст документ OpenAPI. Однако в конечных точках минимальных API придётся использовать именованные методы, а не лямбды, чтобы использовать эту функцию. Например, вместо
использовать вызов метода
и определить метод Hello с описанием
3. Прочие изменения
При использовании атрибута
Здесь при отсутствии значения в форме DueDate будет установлено в null.
Новые метрики аутентификации для панели управления Aspire отслеживают события входа/выхода и попытки авторизации, а телеметрия продолжительности запроса помогает выявлять узкие места производительности.
Источники:
- https://www.infoq.com/news/2025/03/aspnet-core-10-preview2
- https://github.com/dotnet/core/blob/main/release-notes/10.0/preview/preview2/aspnetcore.md
Новинки Превью 2 ASP.NET Core 10
В последнем выпуске ASP.NET Core 10 Preview 2 представлены несколько улучшений в Blazor, в создании документации OpenAPI и в инструментах разработчика. Большинство изменений присланы контрибьюторами и основаны на обратной связи от разработчиков.
1. Переработана навигация в Blazor
При использовании NavigateTo для навигации по той же странице (например, при изменении только строки запроса) браузер больше не будет принудительно прокручивать страницу вверх. В предыдущих версиях разработчикам приходилось вручную обходить это поведение.
Компонент NavLink теперь по умолчанию игнорирует строки запроса и фрагменты (часть URL после #) при сопоставлении с помощью NavLinkMatch.All. Это означает, что ссылка будет активна, даже если строки запроса или фрагменты в URL изменятся. В AppContext есть переключатель, который позволит вернуться к предыдущему поведению, если вам это необходимо. Для кастомного поведения сопоставления NavLink теперь предоставляет переопределяемый метод ShouldMatch.
Визуализация повторного подключения, когда клиент теряет WebSocket-соединение с сервером, обновилась в шаблоне проекта, и представляет новый компонент ReconnectModal, который разделяет CSS и JavaScript для более строгого соответствия политике безопасности контента (CSP). Настраиваемое событие components-reconnect-state-changed обеспечивает более детальный контроль над состояниями подключения, включая новую фазу retrying (повторной попытки).
2. Изменения в OpenAPI
Разработчики API получат встроенную поддержку для автоматического преобразования описаний <summary> в исходном коде в документы OpenAPI. Для этого нужно добавить в файл проекта следующую строку:
<PropertyGroup>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
Тогда во время компиляции генератор исходного кода соберёт комментарии и создаст документ OpenAPI. Однако в конечных точках минимальных API придётся использовать именованные методы, а не лямбды, чтобы использовать эту функцию. Например, вместо
app.MapGet("/hello",
(string name) =>$"Hello, {name}!");
использовать вызов метода
app.MapGet("/hello", Hello);
и определить метод Hello с описанием
static partial class Program
{
/// <summary>
/// Отправляет приветствие.
/// </summary>
/// …
public static string Hello(string name)
{
return $"Hello, {name}!";
}
}
3. Прочие изменения
При использовании атрибута
[FromForm]
со сложным объектом в минимальных API пустые строки в теле формы теперь преобразуются в null, а не вызывают ошибку парсинга. Это поведение соответствует логике обработки форм, не принимающих сложные объекты, в минимальных API:app.MapPost("/todo", ([FromForm] Todo todo)
=> TypedResults.Ok(todo));
public record Todo(int Id, DateOnly? DueDate,
string Title, bool Completed);
Здесь при отсутствии значения в форме DueDate будет установлено в null.
Новые метрики аутентификации для панели управления Aspire отслеживают события входа/выхода и попытки авторизации, а телеметрия продолжительности запроса помогает выявлять узкие места производительности.
Источники:
- https://www.infoq.com/news/2025/03/aspnet-core-10-preview2
- https://github.com/dotnet/core/blob/main/release-notes/10.0/preview/preview2/aspnetcore.md
👍15
День 2254. #SystemDesign101
REST API или GraphQL
REST
➕ Использует стандартные методы HTTP, такие как GET, POST, PUT, DELETE для операций CRUD.
➕ Хорошо работает, когда вам нужны простые, единообразные интерфейсы между отдельными сервисами/приложениями.
➕ Стратегии кэширования просты в реализации.
➖ Может потребоваться несколько циклов для сбора связанных данных из отдельных конечных точек.
GraphQL
➕ Предоставляет клиентам единую конечную точку для запроса именно тех данных, которые им нужны.
➕ Клиенты указывают требуемые поля во вложенных запросах, и сервер возвращает данные, содержащие только эти поля.
➕ Поддерживает мутации для изменения данных и подписки для уведомлений в реальном времени.
➕ Отлично подходит для агрегации данных из нескольких источников и хорошо работает с быстро меняющимися требованиями к внешнему интерфейсу.
➖ Переносит сложность на сторону клиента и может допускать опасные запросы, если не защищён должным образом.
➖ Стратегии кэширования могут быть сложнее, чем REST.
Выбор между REST и GraphQL зависит от конкретных требований приложения и команды разработчиков. GraphQL хорошо подходит для сложных или часто меняющихся потребностей интерфейса, в то время как REST подходит для приложений, где предпочтительны простые и последовательные контракты.
Ни один из подходов не является панацеей. Тщательная оценка требований и компромиссов важна для выбора правильного стиля. И REST, и GraphQL являются допустимыми вариантами для раскрытия данных и поддержки современных приложений.
Источник: https://github.com/ByteByteGoHq/system-design-101
REST API или GraphQL
REST
➕ Использует стандартные методы HTTP, такие как GET, POST, PUT, DELETE для операций CRUD.
➕ Хорошо работает, когда вам нужны простые, единообразные интерфейсы между отдельными сервисами/приложениями.
➕ Стратегии кэширования просты в реализации.
➖ Может потребоваться несколько циклов для сбора связанных данных из отдельных конечных точек.
GraphQL
➕ Предоставляет клиентам единую конечную точку для запроса именно тех данных, которые им нужны.
➕ Клиенты указывают требуемые поля во вложенных запросах, и сервер возвращает данные, содержащие только эти поля.
➕ Поддерживает мутации для изменения данных и подписки для уведомлений в реальном времени.
➕ Отлично подходит для агрегации данных из нескольких источников и хорошо работает с быстро меняющимися требованиями к внешнему интерфейсу.
➖ Переносит сложность на сторону клиента и может допускать опасные запросы, если не защищён должным образом.
➖ Стратегии кэширования могут быть сложнее, чем REST.
Выбор между REST и GraphQL зависит от конкретных требований приложения и команды разработчиков. GraphQL хорошо подходит для сложных или часто меняющихся потребностей интерфейса, в то время как REST подходит для приложений, где предпочтительны простые и последовательные контракты.
Ни один из подходов не является панацеей. Тщательная оценка требований и компромиссов важна для выбора правильного стиля. И REST, и GraphQL являются допустимыми вариантами для раскрытия данных и поддержки современных приложений.
Источник: https://github.com/ByteByteGoHq/system-design-101
👍15
День 2255. #ЧтоНовенького
AutoMapper и MediatR Станут Коммерческими
🔥 BRKNG!!! 🔥
В рядах бесплатного опенсорса на очереди ещё 2 потери. Джимми Богард объявил, что два его самых популярных творения AutoMapper и MediatR станут коммерческими.
Далее перевод поста от самого Джимми.
UPD: MassTransit 9й версии тоже будет коммерческим.
Источник: https://www.jimmybogard.com/automapper-and-mediatr-going-commercial/
AutoMapper и MediatR Станут Коммерческими
🔥 BRKNG!!! 🔥
В рядах бесплатного опенсорса на очереди ещё 2 потери. Джимми Богард объявил, что два его самых популярных творения AutoMapper и MediatR станут коммерческими.
Далее перевод поста от самого Джимми.
Как я до этого дошёл
Эти два проекта зародились, когда я работал в Headspring, консалтинговой компании, которой я отдал более 12 лет. Около 5 лет назад, в январе 2020, я решил уйти и попробовать себя в качестве индивидуального консультанта. Хотя это был пугающий переход, он оказался более полезным, чем я мог надеяться, почти во всех областях.
Область, в которой не всё было так хорошо, и совсем не намеренно, была работа с проектами с открытым кодом (OSS). В определённый момент количество моих контрибуций резко снизилось. Это не было намерением, но стало естественным побочным эффектом того, что я сосредоточился на своём консалтинговом бизнесе.
В Headspring моё время на OSS напрямую поощрялось и спонсировалось ими. Я мог использовать время между проектами, чтобы инвестировать в существующие или новые OSS, потому что это приносило пользу клиенту, компании и сотрудникам (мне и моим коллегам).
С уходом из этой компании, а затем после её продажи Accenture в том же году, у меня больше не было прямого крупного спонсора моей работы над OSS. Моё свободное время уходило на развитие и обеспечение успеха моей консалтинговой компании.
Уделив время, чтобы посмотреть, как идут дела на всех фронтах, я испытал небольшой шок, глядя на свою работу над OSS. Я понял, что эта модель не является устойчивой для долгосрочного успеха проектов, которые я по-прежнему поддерживаю и в которые верю. Мне нужно иметь возможность платить за своё время работы над этими проектами и получать прямую обратную связь от платящих клиентов, как это было раньше в Headspring.
Как это будет выглядеть?
Я точно не знаю. Сейчас я работаю над этими деталями и поделюсь ими, когда разберусь. У меня есть много примеров того, что работает хорошо, а что нет, по крайней мере с моей точки зрения, а также того, что, по моему мнению, будет хорошо работать для этих проектов.
В краткосрочной перспективе ничего не изменится. Я по-прежнему буду мало отзывчивым в GitHub Issues, я только что выпустил пару релизов текущей работы.
Моя цель — иметь возможность платить за время, которое можно потратить на фактическое улучшение этих проектов, создание сообществ, помощь большему количеству пользователей и, в целом, на то, что люди МНОГО раз просили меня сделать за эти годы, но я этого не делал, потому что это не было моей работой. OSS был, есть, но больше не будет для меня хобби. Я хочу, чтобы это хотя бы стало частью моей работы и финансировало настоящую работу.
Я не могу полагаться на донаты, я не хочу заставлять разработчиков платить что-либо или делать что-либо и я определенно не думаю, что это дело Microsoft — «платить мне деньги». <…>
Когда это произойдет?
Я не знаю. Я всё ещё использую своё свободное время, чтобы разобраться с этим, так как моя основная работа — всё ещё консультации. Но я планирую быть открытым во всём этом процессе. <…>
<…> Я не хочу, чтобы эти проекты завяли и умерли, я хочу, чтобы они росли, развивались и процветали. Но не только эти проекты — я хочу, чтобы ВСЕ мои проекты OSS (Respawn и т.д.) процветали.
Заключительные благодарности
Спасибо всем, кто внёс свой вклад за эти годы, и особенно Лучиану Баргаоану, который поддерживал AutoMapper после того, как я «выпал из игры». Также спасибо моим спонсорам на GitHub. И, наконец, спасибо сообществу, я никогда не надеялся, что что-то из того, что я создал, поможет кому-то, кроме моих клиентов, коллег и компании, но всегда приятно слышать, что это так.
UPD: MassTransit 9й версии тоже будет коммерческим.
Источник: https://www.jimmybogard.com/automapper-and-mediatr-going-commercial/
👍18👎1
Ваши первые мысли от новостей о коммерциализации OSS (ПО с открытым кодом)?
Anonymous Poll
10%
Это новый тренд. Открытый код - мертворождённая концепция.
14%
Это правильное решение для поддержки продуктов, которые невозможно поддерживать за донаты.
26%
Это предательство сообщества и контрибьюторов.
50%
Это отдельные случаи. Рынок решит, что будет использовать.
Продолжите ли вы использовать платную версию ПО, которое было бесплатным?
Anonymous Poll
9%
Да, если ПО качественное, готов заплатить.
36%
Не против разумной платы для компаний (бесплатно для личного пользования).
26%
Нет, буду использовать старую бесплатную версию (бесплатный форк).
29%
Нет, найду аналог.
День 2256. #ЗаметкиНаПолях
Теорема CAP: Сложности Выбора в Распределённых Системах
Теорема CAP, сформулированная Эриком Брюэром в 2000 году и позже доказанная формально, гласит, что в распределённой системе можно добиться только двух из следующих трёх гарантий:
1. Согласованность (Consistency) — каждое чтение получает самую последнюю запись или ошибку. Это означает, что данные одинаковы во всём кластере, поэтому вы можете читать или писать с любого узла и получать те же данные.
2. Доступность (Availability) — каждый запрос получает ответ, даже если это не самые последние данные. Т.е. система остаётся доступной даже в случае отказа одного или нескольких узлов.
3. Устойчивость к фрагментации (Partition tolerance) — система продолжает функционировать, даже если между узлами происходит фрагментация сети (разрыв связи). Кластер должен по-прежнему отвечать, даже если некоторые узлы не могут общаться.
Почему нельзя иметь всё?
Распределённая система по своей сути нуждается в устойчивости к фрагментации, поскольку сети могут выходить из строя, а узлы могут терять связь. Это оставляет нам два варианта:
- CP (согласованность + устойчивость к фрагментации): система жертвует доступностью. Если происходит разделение, узлы могут отклонять операции чтения/записи для поддержания согласованного состояния. Пример: MongoDB
- AP (доступность + устойчивость к фрагментации): система жертвует строгой согласованностью, то есть она может обслуживать устаревшие или несогласованные данные во время фрагментации. Пример: Cassandra
- CA (согласованность + доступность): возможно только в системе без фрагментаций — по сути, в базе данных с одним узлом. Пример: PostgreSQL
Почему устойчивость к фрагментации не подлежит обсуждению?
Разрывы сети будут происходить, поэтому мы всегда должны учитывать устойчивость к фрагментации (P). Поэтому реальный выбор — между согласованностью (CP) и доступностью (AP) во время фрагментации:
- AP, узлы остаются в сети, даже если они не могут взаимодействовать друг с другом. Они повторно синхронизируют данные после разрешения фрагментации, но данные между узлами могут быть несогласованными.
- CP, данные остаются согласованными между всеми узлами, но некоторые узлы могут стать недоступными во время фрагментации.
Система CA теоретически гарантирует согласованность и доступность, пока все узлы находятся в сети. Однако, если происходит фрагментация, это приведёт к несогласованности данных или простою. Поскольку сбои в сети неизбежны, системы CA не существуют на практике в распределённой среде.
За пределами CAP: теорема PACELC
CAP рассказывает нам о компромиссах во время фрагментации сети, но что происходит, когда её нет? PACELC гласит:
- Если есть фрагментация (P), система должна выбрать между доступностью (A) и согласованностью (C).
- В противном случае (Else) система должна выбирать между задержкой (L) и согласованностью (C).
Это расширяет CAP, учитывая производительность и объясняя, почему базы данных, такие как DynamoDB, предпочитают меньшую задержку строгой согласованности.
Выбор правильной БД для вашего варианта использования
- Нужна ли мне сильная согласованность (CP) или можно допустить некоторую несогласованность (AP)?
- Насколько критична доступность для приложения?
- Что произойдёт, если части системы временно отключатся?
В системе AP вы можете столкнуться с несогласованными конфликтами чтения и записи. Некоторые базы данных AP разрешают конфликты записи автоматически, в то время как другие требуют разрешения конфликтов на уровне приложения (пользователя).
В системе CP сетевые фрагментации могут привести к временному простою или снижению производительности.
Источник: https://dev.to/lovestaco/understanding-the-cap-theorem-choosing-your-battles-in-distributed-systems-26cl
Теорема CAP: Сложности Выбора в Распределённых Системах
Теорема CAP, сформулированная Эриком Брюэром в 2000 году и позже доказанная формально, гласит, что в распределённой системе можно добиться только двух из следующих трёх гарантий:
1. Согласованность (Consistency) — каждое чтение получает самую последнюю запись или ошибку. Это означает, что данные одинаковы во всём кластере, поэтому вы можете читать или писать с любого узла и получать те же данные.
2. Доступность (Availability) — каждый запрос получает ответ, даже если это не самые последние данные. Т.е. система остаётся доступной даже в случае отказа одного или нескольких узлов.
3. Устойчивость к фрагментации (Partition tolerance) — система продолжает функционировать, даже если между узлами происходит фрагментация сети (разрыв связи). Кластер должен по-прежнему отвечать, даже если некоторые узлы не могут общаться.
Почему нельзя иметь всё?
Распределённая система по своей сути нуждается в устойчивости к фрагментации, поскольку сети могут выходить из строя, а узлы могут терять связь. Это оставляет нам два варианта:
- CP (согласованность + устойчивость к фрагментации): система жертвует доступностью. Если происходит разделение, узлы могут отклонять операции чтения/записи для поддержания согласованного состояния. Пример: MongoDB
- AP (доступность + устойчивость к фрагментации): система жертвует строгой согласованностью, то есть она может обслуживать устаревшие или несогласованные данные во время фрагментации. Пример: Cassandra
- CA (согласованность + доступность): возможно только в системе без фрагментаций — по сути, в базе данных с одним узлом. Пример: PostgreSQL
Почему устойчивость к фрагментации не подлежит обсуждению?
Разрывы сети будут происходить, поэтому мы всегда должны учитывать устойчивость к фрагментации (P). Поэтому реальный выбор — между согласованностью (CP) и доступностью (AP) во время фрагментации:
- AP, узлы остаются в сети, даже если они не могут взаимодействовать друг с другом. Они повторно синхронизируют данные после разрешения фрагментации, но данные между узлами могут быть несогласованными.
- CP, данные остаются согласованными между всеми узлами, но некоторые узлы могут стать недоступными во время фрагментации.
Система CA теоретически гарантирует согласованность и доступность, пока все узлы находятся в сети. Однако, если происходит фрагментация, это приведёт к несогласованности данных или простою. Поскольку сбои в сети неизбежны, системы CA не существуют на практике в распределённой среде.
За пределами CAP: теорема PACELC
CAP рассказывает нам о компромиссах во время фрагментации сети, но что происходит, когда её нет? PACELC гласит:
- Если есть фрагментация (P), система должна выбрать между доступностью (A) и согласованностью (C).
- В противном случае (Else) система должна выбирать между задержкой (L) и согласованностью (C).
Это расширяет CAP, учитывая производительность и объясняя, почему базы данных, такие как DynamoDB, предпочитают меньшую задержку строгой согласованности.
Выбор правильной БД для вашего варианта использования
- Нужна ли мне сильная согласованность (CP) или можно допустить некоторую несогласованность (AP)?
- Насколько критична доступность для приложения?
- Что произойдёт, если части системы временно отключатся?
В системе AP вы можете столкнуться с несогласованными конфликтами чтения и записи. Некоторые базы данных AP разрешают конфликты записи автоматически, в то время как другие требуют разрешения конфликтов на уровне приложения (пользователя).
В системе CP сетевые фрагментации могут привести к временному простою или снижению производительности.
Источник: https://dev.to/lovestaco/understanding-the-cap-theorem-choosing-your-battles-in-distributed-systems-26cl
👍29
2257.svg
303.7 KB
День 2257. #Шпаргалка
Шпаргалка по Языку C#
Эта ментальная карта языка C# от Steven Giesel включает в себя большинство функций вплоть до версии C# 14 (которая выйдет в ноябре 2025 года).
SVG содержит ссылки на соответствующие разделы документации. Для вашего удобства я её русифицировал.
Источник: https://steven-giesel.com/blogPost/91563474-ffe6-4c47-b7ee-fb04b5731a74/c-language-mind-map-v14
Шпаргалка по Языку C#
Эта ментальная карта языка C# от Steven Giesel включает в себя большинство функций вплоть до версии C# 14 (которая выйдет в ноябре 2025 года).
SVG содержит ссылки на соответствующие разделы документации. Для вашего удобства я её русифицировал.
Источник: https://steven-giesel.com/blogPost/91563474-ffe6-4c47-b7ee-fb04b5731a74/c-language-mind-map-v14
5👍32👎1
День 2258. #УрокиРазработки
Уроки 50 Лет Разработки ПО
Урок 47. Не поддавайтесь уговорам руководителя или клиента сделать работу наспех
Мы не должны позволять руководителям, клиентам или коллегам уговаривать нас делать работу плохо. Все мы должны взять на себя обязательство следовать лучшим профессиональным практикам, адаптируя их так, чтобы получать наибольший положительный эффект в каждой ситуации. Оказавшись в ситуации, вызывающей дискомфорт в профессиональном плане, постарайтесь описать, что вам нужно для того, чтобы сделать что-то, что не будет считаться плохой работой. Как и многое другое, эту философию можно довести до крайности. Ищите баланс в достижении профессионального мастерства, не впадая в чрезмерный догматизм и жёсткость.
Умение противостоять силе
Люди, наделённые властью, могут пытаться повлиять на вас разными способами, чтобы заставить сделать то, что вы считаете плохой работой. Клиенту не нравятся ваши оценки сроков и стоимости. Он пытается надавить на вас, чтобы сбалансировать бюджет или достичь личных целей. Мотивация понятна, но это не повод менять оценку.
Он сам может испытывать давление, о котором вы не подозреваете. Он имеет право знать, как вы получили вашу оценку, и обсудить возможность её корректировки. Однако менять оценку только потому, что она кому-то не нравится, означает отказываться от вашей интерпретации реальности.
Спешка в программировании
Предположим, у вашей команды появляется новый проект. Ваши партнёры по бизнесу могут попытаться потребовать немедленно приступить к программированию, не имея экономического обоснования и чётких требований. Возможно, у них выделены финансы на проект, которые они хотят быстрее потратить, прежде чем потеряют их. IT-персонал тоже может испытывать желание как можно быстрее приступить к работе. Разработчики могут не захотеть тратить время на обсуждение требований, поскольку те, скорее всего, все равно изменятся.
В таких случаях пишется много бесцельного кода, а результат неясен. Слишком часто никто не несёт ответственности за отсутствие цели, поскольку она всё равно не была чётко определена. Не лучше ли IT-отделу попытаться противостоять давлению со стороны бизнеса и не «идти туда, не знаю куда»?
Нехватка знаний
Люди, которые не зарабатывают этим на жизнь, не понимают разницы между написанием кода и разработкой ПО и могут не понимать подходов к разработке, которые вы пропагандируете. Например, считать ненужным код-ревью, отказываться тратить время на обсуждение требований, настаивать на доставке продукта, даже если он не соответствует всем критериям выпуска.
Но клиенты вряд ли оценят ускоренную поставку продукта, полноценное использование которого может потребовать масштабных исправлений.
Если ваш руководитель отказывается от предложенного вами методичного подхода, у вас есть 3 варианта:
1. Объяснить подход так, чтобы его преимущества стали более очевидными.
2. Всё равно использовать подход, несмотря на отказ руководителя.
3. Следовать указаниям руководителя и применить неоптимальный подход.
Лучше попробовать вариант 1, а если не удастся, то 2.
В обход процессов
Процессы разрабатываются и устанавливаются не просто так. Возможно, вам придётся объяснить, почему необходимо следовать подходу, который вы отстаиваете. Укажите, насколько это повышает качество и ценность проекта. Эта информация поможет другому человеку понять, почему вы сопротивляетесь его просьбам. Однако иногда встречаются просто неразумные люди. Они могут пожаловаться вашему руководителю, что вы тратите время на ненужные действия или отказываетесь сотрудничать. Руководитель может поддержать вас или оказать на вас дополнительное давление. Во втором случае вам придётся выбирать: уступить давлению, согласившись с потенциальными негативными последствиями для проекта и вашей психики, или продолжить использовать известные вам лучшие профессиональные подходы.
Источник: Карл Вигерс “Жемчужины Разработки”. СПб.: Питер, 2024. Глава 6.
Уроки 50 Лет Разработки ПО
Урок 47. Не поддавайтесь уговорам руководителя или клиента сделать работу наспех
Мы не должны позволять руководителям, клиентам или коллегам уговаривать нас делать работу плохо. Все мы должны взять на себя обязательство следовать лучшим профессиональным практикам, адаптируя их так, чтобы получать наибольший положительный эффект в каждой ситуации. Оказавшись в ситуации, вызывающей дискомфорт в профессиональном плане, постарайтесь описать, что вам нужно для того, чтобы сделать что-то, что не будет считаться плохой работой. Как и многое другое, эту философию можно довести до крайности. Ищите баланс в достижении профессионального мастерства, не впадая в чрезмерный догматизм и жёсткость.
Умение противостоять силе
Люди, наделённые властью, могут пытаться повлиять на вас разными способами, чтобы заставить сделать то, что вы считаете плохой работой. Клиенту не нравятся ваши оценки сроков и стоимости. Он пытается надавить на вас, чтобы сбалансировать бюджет или достичь личных целей. Мотивация понятна, но это не повод менять оценку.
Он сам может испытывать давление, о котором вы не подозреваете. Он имеет право знать, как вы получили вашу оценку, и обсудить возможность её корректировки. Однако менять оценку только потому, что она кому-то не нравится, означает отказываться от вашей интерпретации реальности.
Спешка в программировании
Предположим, у вашей команды появляется новый проект. Ваши партнёры по бизнесу могут попытаться потребовать немедленно приступить к программированию, не имея экономического обоснования и чётких требований. Возможно, у них выделены финансы на проект, которые они хотят быстрее потратить, прежде чем потеряют их. IT-персонал тоже может испытывать желание как можно быстрее приступить к работе. Разработчики могут не захотеть тратить время на обсуждение требований, поскольку те, скорее всего, все равно изменятся.
В таких случаях пишется много бесцельного кода, а результат неясен. Слишком часто никто не несёт ответственности за отсутствие цели, поскольку она всё равно не была чётко определена. Не лучше ли IT-отделу попытаться противостоять давлению со стороны бизнеса и не «идти туда, не знаю куда»?
Нехватка знаний
Люди, которые не зарабатывают этим на жизнь, не понимают разницы между написанием кода и разработкой ПО и могут не понимать подходов к разработке, которые вы пропагандируете. Например, считать ненужным код-ревью, отказываться тратить время на обсуждение требований, настаивать на доставке продукта, даже если он не соответствует всем критериям выпуска.
Но клиенты вряд ли оценят ускоренную поставку продукта, полноценное использование которого может потребовать масштабных исправлений.
Если ваш руководитель отказывается от предложенного вами методичного подхода, у вас есть 3 варианта:
1. Объяснить подход так, чтобы его преимущества стали более очевидными.
2. Всё равно использовать подход, несмотря на отказ руководителя.
3. Следовать указаниям руководителя и применить неоптимальный подход.
Лучше попробовать вариант 1, а если не удастся, то 2.
В обход процессов
Процессы разрабатываются и устанавливаются не просто так. Возможно, вам придётся объяснить, почему необходимо следовать подходу, который вы отстаиваете. Укажите, насколько это повышает качество и ценность проекта. Эта информация поможет другому человеку понять, почему вы сопротивляетесь его просьбам. Однако иногда встречаются просто неразумные люди. Они могут пожаловаться вашему руководителю, что вы тратите время на ненужные действия или отказываетесь сотрудничать. Руководитель может поддержать вас или оказать на вас дополнительное давление. Во втором случае вам придётся выбирать: уступить давлению, согласившись с потенциальными негативными последствиями для проекта и вашей психики, или продолжить использовать известные вам лучшие профессиональные подходы.
Источник: Карл Вигерс “Жемчужины Разработки”. СПб.: Питер, 2024. Глава 6.
👍17
День 2259. #ЗаметкиНаПолях
Почему GraphQL? Начало
Недавно мы коротко сравнили REST с GraphQL. Теперь подробно рассмотрим, почему существует GraphQL и когда его использовать.
GraphQL (создан Facebook в 2012, код открыт в 2015) предназначен для решения распространённых проблем неэффективности REST API.
Особенности:
- Точная выборка данных: клиенты указывают, какие данные им нужны, что снижает избыточную (получение слишком большого количества данных) и недостаточную (недостаточное количество данных) выборку.
- Единая конечная точка: в отличие от REST, который часто требует нескольких запросов к разным конечным точкам, GraphQL объединяет данные из нескольких источников в одном запросе.
- Строго типизированная схема: API самодокументируются с чётко определённой схемой, которая обеспечивает стабильность и предсказуемость.
- Данные в реальном времени: поддерживает подписки на обновления в реальном времени.
- Агрегация данных: легко объединяет данные из нескольких источников в один ответ.
Это приводит к более быстрым приложениям, более простому обслуживанию и в целом лучшему опыту разработчика.
Когда использовать?
1. Оптимизация производительности для мобильных и веб-приложений
- Никакой избыточной или недостаточной выборки.
- Более быстрое время загрузки: повышает производительность, особенно для мобильных приложений и сред с низкой пропускной способностью.
2. Панели мониторинга в реальном времени
GraphQL поддерживает подписки, которые позволяют клиентам получать обновления в реальном времени при изменении данных. Это идеально подходит для таких приложений, как чаты, панели мониторинга в реальном времени или уведомления.
3. Агрегация и управление версиями API
Вместо того, чтобы использовать различные конечные точки REST или параметры запросов, вы можете предоставить один API GraphQL, который извлекает данные из различных сервисов. Вы можете развивать схемы, не нарушая существующих клиентов, в отличие от строгого управления версиями в REST.
4. Опыт разработчика
- Самодокументирование: схема GraphQL действует как документация, упрощая разработчикам понимание и использование API.
- Мощные инструменты: такие инструменты, как Apollo Client и GraphiQL, обеспечивают превосходный опыт разработчика, включая автоматическое завершение, подсветку ошибок и тестирование запросов.
Ключевые отличия от REST
1. Получение данных
Одна общая конечная точка, в отличие от нескольких в REST.
2. Производительность
Один запрос GraphQL для получения всех данных снижает нагрузку на сеть.
3. Кэширование
В REST встроенный механизм HTTP-кэширования. В GraphQL такого нет, но можно использовать сторонние библиотеки (Apollo, Relay).
4. Схема
Строго типизированная, самодокументирующаяся схема.
5. Порог изучения
Более высокий, чем REST из-за уникальных концепций и языка запросов.
6. Загрузка файлов
Не поддерживается нативно, как в REST, требует обходных путей.
7. Обновления в реальном времени
Встроенная поддержка через подписки, в отличие от REST, где требуются дополнительные шаги, например, WebSockets.
8. Развитие API
Схема может меняться, не нарушая клиентов. В REST требуется версионирование.
Окончание следует…
Источник: https://dev.to/lovestaco/why-graphql-a-developer-friendly-guide-to-api-evolution-51j5
Почему GraphQL? Начало
Недавно мы коротко сравнили REST с GraphQL. Теперь подробно рассмотрим, почему существует GraphQL и когда его использовать.
GraphQL (создан Facebook в 2012, код открыт в 2015) предназначен для решения распространённых проблем неэффективности REST API.
Особенности:
- Точная выборка данных: клиенты указывают, какие данные им нужны, что снижает избыточную (получение слишком большого количества данных) и недостаточную (недостаточное количество данных) выборку.
- Единая конечная точка: в отличие от REST, который часто требует нескольких запросов к разным конечным точкам, GraphQL объединяет данные из нескольких источников в одном запросе.
- Строго типизированная схема: API самодокументируются с чётко определённой схемой, которая обеспечивает стабильность и предсказуемость.
- Данные в реальном времени: поддерживает подписки на обновления в реальном времени.
- Агрегация данных: легко объединяет данные из нескольких источников в один ответ.
Это приводит к более быстрым приложениям, более простому обслуживанию и в целом лучшему опыту разработчика.
Когда использовать?
1. Оптимизация производительности для мобильных и веб-приложений
- Никакой избыточной или недостаточной выборки.
- Более быстрое время загрузки: повышает производительность, особенно для мобильных приложений и сред с низкой пропускной способностью.
2. Панели мониторинга в реальном времени
GraphQL поддерживает подписки, которые позволяют клиентам получать обновления в реальном времени при изменении данных. Это идеально подходит для таких приложений, как чаты, панели мониторинга в реальном времени или уведомления.
3. Агрегация и управление версиями API
Вместо того, чтобы использовать различные конечные точки REST или параметры запросов, вы можете предоставить один API GraphQL, который извлекает данные из различных сервисов. Вы можете развивать схемы, не нарушая существующих клиентов, в отличие от строгого управления версиями в REST.
4. Опыт разработчика
- Самодокументирование: схема GraphQL действует как документация, упрощая разработчикам понимание и использование API.
- Мощные инструменты: такие инструменты, как Apollo Client и GraphiQL, обеспечивают превосходный опыт разработчика, включая автоматическое завершение, подсветку ошибок и тестирование запросов.
Ключевые отличия от REST
1. Получение данных
Одна общая конечная точка, в отличие от нескольких в REST.
2. Производительность
Один запрос GraphQL для получения всех данных снижает нагрузку на сеть.
3. Кэширование
В REST встроенный механизм HTTP-кэширования. В GraphQL такого нет, но можно использовать сторонние библиотеки (Apollo, Relay).
4. Схема
Строго типизированная, самодокументирующаяся схема.
5. Порог изучения
Более высокий, чем REST из-за уникальных концепций и языка запросов.
6. Загрузка файлов
Не поддерживается нативно, как в REST, требует обходных путей.
7. Обновления в реальном времени
Встроенная поддержка через подписки, в отличие от REST, где требуются дополнительные шаги, например, WebSockets.
8. Развитие API
Схема может меняться, не нарушая клиентов. В REST требуется версионирование.
Окончание следует…
Источник: https://dev.to/lovestaco/why-graphql-a-developer-friendly-guide-to-api-evolution-51j5
2👍14
День 2260. #ЗаметкиНаПолях
Почему GraphQL? Окончание
Начало
Схема
Схема GraphQL определяет, какие данные могут запрашивать клиенты. Она служит контрактом между клиентом и сервером, гарантируя структурированный и эффективный поиск данных. Схемы обычно пишутся с использованием языка определения схем (SDL), что делает их простыми для чтения и понимания. Схема состоит из типов объектов, каждый из которых содержит поля, определяющие, какие данные доступны, например:
Здесь:
- Query определяет доступные запросы.
- Тип User содержит такие поля, как имя, email, посты и количество подписчиков.
- Тип Post включает заголовок и тело поста.
Операции
1. Запросы
Запросы GraphQL эквивалентны запросам REST GET — они извлекают данные, не изменяя их.
2. Мутации
Мутации позволяют клиентам создавать, обновлять или удалять данные, аналогично методам REST: POST, PUT, PATCH, DELETE. Например:
3. Подписки
Подписки GraphQL позволяют обновлять данные в режиме реального времени с помощью WebSockets. В отличие от запросов, которые требуют ручного опроса, подписки отправляют обновления при изменении данных:
Это позволяет обновлять клиента без выполнения повторных запросов.
Когда использовать REST?
- Простые API: если у API простые требования к данным, простота REST может быть более подходящей.
- Потребности в кэшировании: встроенное HTTP-кэширование REST более надежно, чем сторонние решения GraphQL.
- Загрузка файлов: REST изначально поддерживает загрузку файлов, в то время как GraphQL требует дополнительной настройки.
- Устаревшие системы: если вы работаете с существующим REST API, переход на GraphQL может не стоить усилий, если на то нет веской причины.
Итого
GraphQL предлагает современную альтернативу REST, позволяя клиентам получать именно то, что им нужно, из одной конечной точки. Это приводит к более быстрым приложениям, более простому обслуживанию и лучшему опыту разработки. Однако GraphQL требует обучения и внесения изменений в бэкэнд, поэтому важно оценить, подходит ли он для ваших потребностей API.
Источник: https://dev.to/lovestaco/why-graphql-a-developer-friendly-guide-to-api-evolution-51j5
Почему GraphQL? Окончание
Начало
Схема
Схема GraphQL определяет, какие данные могут запрашивать клиенты. Она служит контрактом между клиентом и сервером, гарантируя структурированный и эффективный поиск данных. Схемы обычно пишутся с использованием языка определения схем (SDL), что делает их простыми для чтения и понимания. Схема состоит из типов объектов, каждый из которых содержит поля, определяющие, какие данные доступны, например:
type Query {
user(id: ID!): User
}
type User {
name: String
email: String
bio: String
posts(limit: Int): [Post]
followersCount: Int
}
type Post {
title: String
content: String
}
Здесь:
- Query определяет доступные запросы.
- Тип User содержит такие поля, как имя, email, посты и количество подписчиков.
- Тип Post включает заголовок и тело поста.
Операции
1. Запросы
Запросы GraphQL эквивалентны запросам REST GET — они извлекают данные, не изменяя их.
2. Мутации
Мутации позволяют клиентам создавать, обновлять или удалять данные, аналогично методам REST: POST, PUT, PATCH, DELETE. Например:
mutation {
updateUser(id: "123", bio: "Exploring GraphQL!") {
name
bio
}
}
3. Подписки
Подписки GraphQL позволяют обновлять данные в режиме реального времени с помощью WebSockets. В отличие от запросов, которые требуют ручного опроса, подписки отправляют обновления при изменении данных:
subscription {
newPost {
title
content
}
}
Это позволяет обновлять клиента без выполнения повторных запросов.
Когда использовать REST?
- Простые API: если у API простые требования к данным, простота REST может быть более подходящей.
- Потребности в кэшировании: встроенное HTTP-кэширование REST более надежно, чем сторонние решения GraphQL.
- Загрузка файлов: REST изначально поддерживает загрузку файлов, в то время как GraphQL требует дополнительной настройки.
- Устаревшие системы: если вы работаете с существующим REST API, переход на GraphQL может не стоить усилий, если на то нет веской причины.
Итого
GraphQL предлагает современную альтернативу REST, позволяя клиентам получать именно то, что им нужно, из одной конечной точки. Это приводит к более быстрым приложениям, более простому обслуживанию и лучшему опыту разработки. Однако GraphQL требует обучения и внесения изменений в бэкэнд, поэтому важно оценить, подходит ли он для ваших потребностей API.
Источник: https://dev.to/lovestaco/why-graphql-a-developer-friendly-guide-to-api-evolution-51j5
👍10
День 2261. #SystemDesign101
Как работает gRPC?
RPC (Remote Procedure Call – Удалённый Вызов Процедур) называется «удалённым», потому что он обеспечивает связь между удалёнными сервисами, когда они развёрнуты на разных серверах в архитектуре микросервисов. С точки зрения клиента он действует как локальный вызов функции.
На схеме выше показан поток данных для gRPC.
1. Выполняется REST-запрос от клиента. Тело запроса обычно имеет формат JSON.
2–4. Сервис заказов (клиент gRPC) получает REST-запрос, преобразует его и выполняет вызов RPC к сервису платежей. gPRC кодирует заглушку клиента в двоичный формат и отправляет её на низкоуровневый транспортный уровень.
5. gRPC отправляет пакеты по сети через HTTP2. Благодаря двоичному кодированию и сетевой оптимизации gRPC примерно в 5 раз быстрее JSON.
6–8. Сервис платежей (сервер gRPC) получает пакеты из сети, декодирует их и вызывает серверное приложение.
9–11. Результат возвращается из серверного приложения, кодируется и отправляется на транспортный уровень.
12–14. Сервис заказов получает пакеты, декодирует их и отправляет результат клиентскому приложению.
Источник: https://github.com/ByteByteGoHq/system-design-101
Как работает gRPC?
RPC (Remote Procedure Call – Удалённый Вызов Процедур) называется «удалённым», потому что он обеспечивает связь между удалёнными сервисами, когда они развёрнуты на разных серверах в архитектуре микросервисов. С точки зрения клиента он действует как локальный вызов функции.
На схеме выше показан поток данных для gRPC.
1. Выполняется REST-запрос от клиента. Тело запроса обычно имеет формат JSON.
2–4. Сервис заказов (клиент gRPC) получает REST-запрос, преобразует его и выполняет вызов RPC к сервису платежей. gPRC кодирует заглушку клиента в двоичный формат и отправляет её на низкоуровневый транспортный уровень.
5. gRPC отправляет пакеты по сети через HTTP2. Благодаря двоичному кодированию и сетевой оптимизации gRPC примерно в 5 раз быстрее JSON.
6–8. Сервис платежей (сервер gRPC) получает пакеты из сети, декодирует их и вызывает серверное приложение.
9–11. Результат возвращается из серверного приложения, кодируется и отправляется на транспортный уровень.
12–14. Сервис заказов получает пакеты, декодирует их и отправляет результат клиентскому приложению.
Источник: https://github.com/ByteByteGoHq/system-design-101
👍19
День 2262. #TipsAndTricks
Применяем Естественную Сортировку в PowerShell
PowerShell не предоставляет встроенного способа использовать естественную сортировку. Рассмотрим, как это можно сделать при помощи простого скрипта.
Что такое естественная сортировка?
Естественная сортировка упорядочивает строки таким образом, чтобы это было более удобно для человека. Например, естественная сортировка следующих строк:
выдаст:
Как видите, естественная сортировка упорядочивает строки на основе чисел в строке, а не лексикографического порядка символов.
Простой способ получить естественную сортировку в PowerShell — использовать командлет Sort-Object с пользовательским блоком скрипта. Блок скрипта должен возвращать значение, по которому вы хотите выполнить сортировку. В этом случае вы можете использовать регулярное выражение для извлечения числового значения из строки и дополнить его нулями, чтобы гарантировать правильную сортировку чисел. Например, строка file1.txt будет преобразована в file00001.txt. Вы можете использовать столько нулей, сколько вам нужно, чтобы гарантировать правильную сортировку чисел.
Кстати, возможность естественной сортировки строк появится в .NET 10 с помощью нового компаратора строк.
Источник: https://www.meziantou.net/how-to-use-a-natural-sort-in-powershell.htm
Применяем Естественную Сортировку в PowerShell
PowerShell не предоставляет встроенного способа использовать естественную сортировку. Рассмотрим, как это можно сделать при помощи простого скрипта.
Что такое естественная сортировка?
Естественная сортировка упорядочивает строки таким образом, чтобы это было более удобно для человека. Например, естественная сортировка следующих строк:
file1.txt
file10.txt
file2.txt
выдаст:
file1.txt
file2.txt
file10.txt
Как видите, естественная сортировка упорядочивает строки на основе чисел в строке, а не лексикографического порядка символов.
Простой способ получить естественную сортировку в PowerShell — использовать командлет Sort-Object с пользовательским блоком скрипта. Блок скрипта должен возвращать значение, по которому вы хотите выполнить сортировку. В этом случае вы можете использовать регулярное выражение для извлечения числового значения из строки и дополнить его нулями, чтобы гарантировать правильную сортировку чисел. Например, строка file1.txt будет преобразована в file00001.txt. Вы можете использовать столько нулей, сколько вам нужно, чтобы гарантировать правильную сортировку чисел.
Get-ChildItem | Sort-Object { [regex]::Replace($_.Name, '\d+', { $args[0].Value.PadLeft(100) }) }
Кстати, возможность естественной сортировки строк появится в .NET 10 с помощью нового компаратора строк.
Источник: https://www.meziantou.net/how-to-use-a-natural-sort-in-powershell.htm
👍9👎4
День 2263. #SystemDesign
Нельзя Реализовать Доставку Ровно-Один-Раз
Люди часто имеют фундаментальные заблуждения о том, как ведут себя распределённые системы. Например, в распределённой системе вы не можете иметь доставку сообщения ровно-один-раз (exact-once). Браузер и сервер, сервер и БД, сервер и очередь сообщений - это распределённые системы. Невозможно реализовать семантику доставки exact-once ни в одной из них.
Существует три типа семантики доставки:
- максимум-раз (at-most-once),
- хотя-бы-раз (at-least-once)
- только-раз (exact-once).
Первые два осуществимы и широко используются.
В письме, которое я вам отправляю, я прошу вас позвонить мне, как только вы его получите. Вы этого не делаете. Либо вам не понравилось моё письмо, либо оно потерялось на почте. Я могу отправить 1 письмо и надеяться, что вы его получите, или отправить 10 и предположить, что вы получите хотя бы 1. Но отправка 10 писем на самом деле не даёт никаких дополнительных гарантий. В распределённой системе мы пытаемся гарантировать доставку сообщения, ожидая подтверждения того, что оно получено, но что угодно может пойти не так: сообщение потеряется, подтверждение потеряется, получатель сломается, он просто медленный, есть сетевые задержки и т.п.
Атомарные протоколы вещания гарантируют надёжную и упорядоченную доставку сообщений. Но мы не можем доставлять сообщения надёжно и упорядоченно из-за разрывов сети и сбоев без высокой степени координации. Эта координация имеет свою цену (задержка и доступность), при этом всё ещё полагаясь на семантику at-least-once.
Репликация состояний стейт-машины — хороший пример. Изменения состояния идемпотентны, и многократное применение одного и того же изменения состояния не приводит к несоответствиям, пока порядок применения соответствует порядку доставки. Т.е. гарантия семантики at-least-once достаточна и упрощает реализацию. Но, если у наших сообщений есть побочные эффекты, всё пропало.
Есть несколько вариантов отправки подтверждения получателем:
1. Перед обработкой
Отправитель получает подтверждение, и удаляет (отмечает доставленным) сообщение. Но, если получатель выходит из строя до или во время обработки, данные теряются навсегда. Это семантика доставки at-most-once.
2. После обработки
Если процесс сбоит после обработки сообщения, но до доставки подтверждения, отправитель выполнит повторную доставку. Это доставка at-least-once.
RabbitMQ пытается предоставить такие гарантии:
При использовании подтверждений производители, восстанавливающиеся после сбоя канала или соединения, должны повторно передавать любые сообщения, для которых не было получено подтверждение от брокера. Здесь существует вероятность дублирования сообщений, поскольку брокер мог отправить подтверждение, которое не достигло производителя (из-за сбоев сети и т.п.). Поэтому приложениям-потребителям необходимо будет выполнять дедупликацию или обрабатывать входящие сообщения идемпотентным образом.
На практике мы достигаем доставки exact-once, подделывая её. Либо сами сообщения должны быть идемпотентными, то есть их можно применять более одного раза без неблагоприятных последствий, либо мы устраняем необходимость в идемпотентности посредством дедупликации (проверяя, получали ли мы такое сообщение ранее). Идеально - если наши сообщения не требуют строгого упорядочения.
Сделать сообщения идемпотентными не так просто. Обычно это требует изменения того, как мы думаем о состоянии. Вместо того, чтобы сообщать действия, которые должен сделать получатель, сообщения должны запрашивать желаемый результат этих действий. А клиент должен знать, как этого добиться. Тогда не страшно, если сообщение будет доставлено больше одного раза.
Итого
Не существует такого понятия, как доставка exact-once. Мы должны выбрать меньшее из двух зол, которое в большинстве случаев является доставкой at-least-once. Это можно использовать для имитации семантики exact-once, гарантируя идемпотентность или иным образом устраняя побочные эффекты от операций.
Источник: https://bravenewgeek.com/you-cannot-have-exactly-once-delivery/
Нельзя Реализовать Доставку Ровно-Один-Раз
Люди часто имеют фундаментальные заблуждения о том, как ведут себя распределённые системы. Например, в распределённой системе вы не можете иметь доставку сообщения ровно-один-раз (exact-once). Браузер и сервер, сервер и БД, сервер и очередь сообщений - это распределённые системы. Невозможно реализовать семантику доставки exact-once ни в одной из них.
Существует три типа семантики доставки:
- максимум-раз (at-most-once),
- хотя-бы-раз (at-least-once)
- только-раз (exact-once).
Первые два осуществимы и широко используются.
В письме, которое я вам отправляю, я прошу вас позвонить мне, как только вы его получите. Вы этого не делаете. Либо вам не понравилось моё письмо, либо оно потерялось на почте. Я могу отправить 1 письмо и надеяться, что вы его получите, или отправить 10 и предположить, что вы получите хотя бы 1. Но отправка 10 писем на самом деле не даёт никаких дополнительных гарантий. В распределённой системе мы пытаемся гарантировать доставку сообщения, ожидая подтверждения того, что оно получено, но что угодно может пойти не так: сообщение потеряется, подтверждение потеряется, получатель сломается, он просто медленный, есть сетевые задержки и т.п.
Атомарные протоколы вещания гарантируют надёжную и упорядоченную доставку сообщений. Но мы не можем доставлять сообщения надёжно и упорядоченно из-за разрывов сети и сбоев без высокой степени координации. Эта координация имеет свою цену (задержка и доступность), при этом всё ещё полагаясь на семантику at-least-once.
Репликация состояний стейт-машины — хороший пример. Изменения состояния идемпотентны, и многократное применение одного и того же изменения состояния не приводит к несоответствиям, пока порядок применения соответствует порядку доставки. Т.е. гарантия семантики at-least-once достаточна и упрощает реализацию. Но, если у наших сообщений есть побочные эффекты, всё пропало.
Есть несколько вариантов отправки подтверждения получателем:
1. Перед обработкой
Отправитель получает подтверждение, и удаляет (отмечает доставленным) сообщение. Но, если получатель выходит из строя до или во время обработки, данные теряются навсегда. Это семантика доставки at-most-once.
2. После обработки
Если процесс сбоит после обработки сообщения, но до доставки подтверждения, отправитель выполнит повторную доставку. Это доставка at-least-once.
RabbitMQ пытается предоставить такие гарантии:
При использовании подтверждений производители, восстанавливающиеся после сбоя канала или соединения, должны повторно передавать любые сообщения, для которых не было получено подтверждение от брокера. Здесь существует вероятность дублирования сообщений, поскольку брокер мог отправить подтверждение, которое не достигло производителя (из-за сбоев сети и т.п.). Поэтому приложениям-потребителям необходимо будет выполнять дедупликацию или обрабатывать входящие сообщения идемпотентным образом.
На практике мы достигаем доставки exact-once, подделывая её. Либо сами сообщения должны быть идемпотентными, то есть их можно применять более одного раза без неблагоприятных последствий, либо мы устраняем необходимость в идемпотентности посредством дедупликации (проверяя, получали ли мы такое сообщение ранее). Идеально - если наши сообщения не требуют строгого упорядочения.
Сделать сообщения идемпотентными не так просто. Обычно это требует изменения того, как мы думаем о состоянии. Вместо того, чтобы сообщать действия, которые должен сделать получатель, сообщения должны запрашивать желаемый результат этих действий. А клиент должен знать, как этого добиться. Тогда не страшно, если сообщение будет доставлено больше одного раза.
Итого
Не существует такого понятия, как доставка exact-once. Мы должны выбрать меньшее из двух зол, которое в большинстве случаев является доставкой at-least-once. Это можно использовать для имитации семантики exact-once, гарантируя идемпотентность или иным образом устраняя побочные эффекты от операций.
Источник: https://bravenewgeek.com/you-cannot-have-exactly-once-delivery/
👍16👎1