Распределенные системы. Паттерны проектирования - страница 25
if err != nil {
fmt.Printf("Ошибка подключения к базе данных: %v", err)
}
// Простой веб-обработчик, выполняющий запрос http.HandleFunc("", func(res http.ResponseWriter, req *http.Request) {
_, err := db.Exec(*query)
if err != nil {
res.WriteHeader(http.StatusInternalServerError)
res.Write([]byte(err.Error()))
return
}
res.WriteHeader(http.StatusOK)
res.Write([]byte("OK"))
return
})
// Запуск сервера
http.ListenAndServe(*addr, nil)
}
Затем мы можем собрать контейнер-адаптер и поместить его в группу, которая будет выглядеть следующим образом: apiVersion: v1
kind: Pod
metadata:
name: adapter-example-health
namespace: default
spec:
containers:
- image: mysql
name: mysql
76 Часть I. Одноузловые паттерны проектирования
- image: brendanburns/mysql-adapter
name: adapter
Контейнер mysql остается неизменным, при этом необходимую обратную связь можно получить от контейнера-адаптера. На первый взгляд может показаться, что такой вариант при-менения паттерна Adapter является излишним. Мы, конечно, можем собрать свой собственный образ, который знает, как проверять работоспособность экземпляра mysql . Это верно, но подобный подход игнорирует преимущества, следующие из модульности. Если каждый разработчик будет реализовывать свою собственную модификацию контейнера со встроенной проверкой работоспособности, то потеряется возможность по-вторного (или совместного) его использования. Напротив, если применять паттерны вроде Adapter для разра-ботки модульных решений, состоящих из нескольких контей-неров, то приложение естественным образом декомпозируется на части, которые можно использовать повторно. Адаптер, раз-работанный для проверки работоспособности mysql , может быть совместно/повторно использован многими людьми. Кроме того, разработчики могут применять паттерн Adapter, используя об-щий контейнер для проверки работоспособности, не вдаваясь в детали наблюдения за базами данных mysql . Таким образом, модульность в целом и паттерн Adapter в частности не только способствуют совместному применению кода, но и позволяют воспользоваться знаниями других людей.
Надо отметить, что паттерны проектирования предназначены не только для их непосредственного применения в приложениях, но и для развития сообществ, участники которых могут взаимо-действовать между собой и делиться результатами. Часть II
Паттерны
проектирования обслуживающих систем В предыдущей главе мы рассмотрели паттерны группирования наборов контейнеров, совместно исполняемых на одной ма-шине. Подобные группы представляют собой тесно связанные, симбиотические системы. Они зависят от совместно исполь-зуемых локальных ресурсов: дискового пространства, сетевых интерфейсов, а также от межпроцессного взаимодействия. Та-кие наборы контейнеров являются не только важными паттер-нами, но и строительными блоками для более крупных систем. Требования к надежности, масштабируемости, разделению обязанностей обуславливают то, что реальные системы состоят из множества различных компонентов, развернутых на многих машинах. Компоненты в многоузловых паттернах связаны сла-бее, чем в одноузловых. Хотя эти паттерны и диктуют схему взаимодействия компонентов между собой, само взаимодей-ствие осуществляется через сетевые вызовы. Кроме того, па-раллельно выполняется множество вызовов, координируемых путем нестрогой синхронизации, а не с помощью ограничений реального времени.
Введение в микросервисы
С недавних пор термин «микросервисы» стал модным словеч-ком, описывающим системы с многоузловыми распределен-ными архитектурами. Микросервисами называются системы, созданные из множества разных компонентов, работающих в разных процессах и взаимодействующих посредством за-ранее определенных программных интерфейсов. Микросер-висы противопоставляются монолитным системам, которые Часть II. Паттерны проектирования обслуживающих систем