В прошлой первой части мы рассмотрели само понятие Cloud native и модели облачных вычислений. А так же выделили концепцию облачных приложений. В этой части рассмотрим их принципы. Из определения Cloud native данного фондом The Cloud Native Computing Foundation (CNCF), мы уже выделяли следующие принципы, которые задают вектор разработки облачных приложений: Масштабируемость (Scalability) Устойчивость (Resilience) Управляемость (Manageable) Наблюдаемость (Observability) Как правило масштабируемость это одно из основных преимуществ облачных приложений. Масштабируемость позволяет адаптироваться к росту рабочих нагрузок. Так же характер роста нагрузок и доступность дополнительных ресурсов, позволяет выбрать подходящую стратегию масштабирования. Выделяют следующие типы масштабирования: Вертикальная масштабируемость (вверх или вниз) - добавление аппаратных ресурсов в вычислительный узел или их удаление из вычислительного узла, например процессора или памяти (рис. 2.1). Этот подход имеет ограничения, поскольку невозможно постоянно добавлять аппаратные ресурсы. Горизонтальная масштабируемость - добавление дополнительных вычислительных узлов или контейнеров в систему или их удаление из системы (рис. 2.2). Этот подход не имеет тех же ограничений, что имеет вертикальное масштабирование. Как правило такие платформы как Kubernetes изначально обеспечивают динамическое масштабирование. Соответственно чтобы сделать приложение масштабируемым, требуется в него вносить определенные изменения в зависимости от используемого стека. Это требует некого переосмысления в проектировании и разработке, и позволяет получить преимущество в будущем. Частым шагом к масштабированию является например разбиение монолитного приложения на микросервисы, так как монолит как правило, не позволяет масштабировать отдельные свои части. Микросервисная архитектура же позволяет масштабировать различные функциональные области приложения с разной скоростью, в зависимости от того, что нужно для них. Еще одной ключевой частью облачной архитектуры является ее отказоустойчивость. Что это значит? Как объясняет Мэтью Титмус в книге «Cloud Native Go»: "Устойчивость — это мера того, насколько хорошо система выдерживает ошибки и сбои и восстанавливается после них. Систему можно считать устойчивой, если она может продолжать работать правильно (возможно, на пониженном уровне), а не полностью выходить из строя при выходе из строя какой-либо части системы." Система устойчива, если она предоставляет свои услуги даже при наличии сбоев или изменений окружающей среды. При создании облачных систем, цель должна состоять в том, чтобы гарантировать, что приложения всегда будут доступны, независимо от того, происходит ли сбой в инфраструктуре или в нашем программном обеспечении. Облачные приложения работают в динамической среде, где все постоянно меняется, и следовательно могут и будут возникать сбои. Этого нельзя предотвратить.  При обсуждении устойчивости стоит определить три основных понятия: сбой, ошибка и отказ: Сбой (fault) — дефект, приводящий к неправильному внутреннему состоянию либо программного обеспечения, либо инфраструктуры. Например, вызов метода возвращает нулевое значение, даже если его спецификация требует возврата ненулевого значения. Ошибка (error) – это несоответствие между ожидаемым поведением системы и фактическим. Например, из-за сбоя связанного с возвратом методом нулевого значения, создается исключение NullPointerException (Java). Отказ (failure). Когда возникает сбой, который приводит к ошибке, может произойти отказ, в результате которого система перестанет отвечать на запросы и не сможет вести себя в соответствии со своими спецификациями. Например, если NullPointerException не перехвачен, ошибка вызывает отказ: система отвечает на любой запрос ответом 500. Ошибки могут спровоцировать отказы, поэтому важно разрабатывать отказоустойчивые приложения. Важной частью отказоустойчивости является обеспечение того, чтобы отказ не распространялся на другие компоненты системы, и чтобы он оставался изолированным, пока не будет устранен. Также важно, чтобы система могла самовосстанавливаться и облачная модель может это обеспечить. Поставщики облачных услуг также предоставляют некоторые инструменты, помогающие повысить устойчивость. Например если микросервис выходит из строя из-за ошибки, при помощи автомасштабирования (autoscaling) можно запустить новую копию и таким образом поглотить нагрузку, а не сбросить ее. Также инструменты облачных провайдеров как правило помогают например быстро увеличить ресурсы баз данных или платформ обработки данных, если им потребуется больше ЦП или памяти. Еще один механизм повышения отказаустойчивости который имеют поставщики облачных это распределение данных по регионам. Регион — это географическая область с одним или несколькими центрами обработки данных (data center). В пределах региона каждому центру обработки данных назначается одна из нескольких зон доступности. Таким образом если сервисы будут запущены в нескольких зонах доступности, это позволит сохранить функционирование при сбое центра обработки данных одной из зон.  А также автоматически релоцировать данные между зонами. Еще одним ключевым аспектом облачных вычислений является их управляемость - способность внешнего воздействия изменять состояние или выходные данные системы за конечный интервал времени.  Одним из аспектов управляемости является развертывание и обновление приложений при сохранении работоспособности всей системы и ее конфигурирование. Являясь настраиваемым, облачное приложение позволяет изменять свое поведение, не меняя свой код и не создавая новых версий себя. Обычно настраиваемыми параметрами являются URL-адреса источников данных, учетные данные службы и сертификаты. Другим типом конфигураций также могут быть флаги функций, которые определяют, следует ли включать определенные функциональности во время выполнения.  Облачные системы сложны, поэтому важно чтобы приложения, могли адаптироваться к меняющимся требованиям в отношении функциональности, среды и безопасности. Данная сложность должна решаться управлением с помощью автоматизации (о ее практиках будет рассказано в следующей части).  Наблюдаемость — это мера того, насколько хорошо можно сделать вывод о внутреннем состоянии системы на основе внешних результатов. В контексте разработки программного обеспечения система представляет собой отдельное приложение или распределенную систему в целом. Внешними выходными данными могут быть такие данные, как метрики, журналы и трассировки.  В 2013 году команда разработчиков Твиттера The Observability Engineering выделили четыре столпа наблюдаемости: Мониторинг (Monitoring) - измерение конкретных аспектов приложения для получения информации о его общем состоянии и выявления сбоев. Алертинг/Визуализация (Alerting/Visualization) - сбор данных о состоянии системы для совершения каких-либо действий. Например если при мониторинге приложения обнаруживается сбой, активируется предупреждение и необходимо предпринять действия для его устранения. Специальные информационные панели (dashboards) используются для визуализации собранных данных и отображения их на соответствующих графиках, чтобы обеспечить хорошее представление о поведении системы.  Инфрастуктура отслеживания распределенных систем (Distributed systems tracing infrastructure) - отслеживание данных проходящих через различные подсистемы. Агрегация/анализ журналов (Log aggregation/analytics) - отслеживание основных событий для определения поведения программного обеспечения и его отладки, если что-то пойдет не так. В облачной системе журналы агрегируются и собираются, чтобы обеспечить лучшее представление о поведении системы и обеспечить возможность запуска аналитики для извлечения информации из этих данных.  В этой части мы рассмотрели принципы, которые позволяют производить надежные облачные приложения, которые лучше удовлетворяют потребности клиентов, как внутренних так и внешних. В следующих частях коснемся практик автоматизации и архитектуры.