Что такое сервисная лавина? Что такое защита услуг? Какие меры защиты услуг? Как сделать предохранитель? Как ограничить ток? Как сделать изоляцию службы? Как понизить?
сценарий реального случая
Приведите реальный пример, с которым вы сталкивались. Интерфейс A зависит от службы B. Развертывание интерфейса A осуществляется в двух компьютерных залах, а развертывание службы B также развертывается в двух компьютерных залах. Если пользователь запрашивает сбой интерфейса, попытка будет повторена.Схема архитектуры развертывания выглядит следующим образом:
Описание: развертывание службы используетLinux+Nginx+PHP
стек технологий.
Ситуация, возникшая в то время, заключалась в том, что компьютерная комната, в которой находилась служба B, зависла, в результате чего интерфейс A вызвал службу B. После того, как тайм-аут вернулся, nginx повторил попытку к другому узлу A и продолжил вызывать службу B. После того, как все узлы A вышли из строя, он возвращается к При сбое клиента клиент повторяет попытку, поэтому предыдущий шаг выполняется снова. Эти запросы на тайм-аут занимают процесс PHP и не освобождаются. В то же время пользователь- Сторонний опыт считает, что он работает медленно, поэтому он постоянно обновляется и повторяет попытки, что приводит к резкому увеличению трафика PHP Пул процессов исчерпан, поэтому интерфейс A недоступен, а другие функции, зависящие от интерфейса A, не могут быть использованы, что приводит к лавина всего сайта.
Это типичный пример лавины функций, вызванной отсутствием изоляции сервисов, тогда возникает вопрос: если мы хотим исправить этот сбой и добавить слой защиты сервиса между интерфейсом и сервисом, что нам делать?
Более распространенная защита от услуг отрасли имеет следующее:
1. Ограничение тока
Когда обнаруживается, что количество сбоев службы достигает определенного порога, доступ запрещается, а дополнительный трафик ограничивается, чтобы предотвратить слишком большое количество неудачных запросов, приводящих к истощению ресурсов.
2. Изоляция службы
Различные типы интерфейсов развертываются изолированно. Сбой одного типа интерфейса или даже исчерпание пула процессов не повлияет на нормальный доступ других интерфейсов. Например, в информационной платформе, если интерфейсы публикации и чтения отключены. развернуты отдельно, даже если функция публикации не работает, функция чтения по-прежнему доступна.
3. Фьюзинг
Соединение отказывается от интерфейса, похожее на предохранитель, используемый в домашних условиях, предохранитель выдувается, когда сумма используемых электрических приборов превышает напряжение, вся цепь короткая, а цепь во всей области защищена для предотвращения более Потери.
4. Понижение
Для простых функций отображения при неудачном запросе возвращают значение по умолчанию. Для всего сайта или клиента, если нагрузка на сервер слишком высока, остановите другие неосновные службы, чтобы сделать больше ресурсов доступными для других служб.
Вышеизложенное — это то, что автор знает о лавине сервисов и мерах по защите сервисов.В области Java Hystrix больше используется в индустрии, поэтому давайте посмотрим, как он реализует вышеуказанные меры.
Что такое Хайстрикс?
Hystrix — это библиотека, которая управляет взаимодействием между распределенными сервисами, добавляя отказоустойчивость с задержкой и логику отказоустойчивости. Hystrix повышает стабильность обслуживания за счет изоляции потоков, чтобы предотвратить каскадную передачу ошибок и привести к лавинам обслуживания.
Главная цель Hystrix
1. Предотвращайте и контролируйте задержки и сбои, изолируя зависимости доступа сторонних клиентских библиотек;
2. Предотвратить каскадный сбой сложных распределенных систем;
3. Быстрая реакция на сбой и быстрое восстановление;
4. Обеспечьте откат и удобный даунгрейд;
5. Реализуйте мониторинг, сигнализацию и управление операциями в режиме, близком к реальному времени.
Принципы дизайна Hystrix
1, чтобы предотвратить однорантурный контейнер-зависимый от истощения пользовательских потоков обслуживания
2. Уменьшите нагрузку и быстро выходите из строя вместо того, чтобы стоять в очереди
3. Обеспечьте резервную стратегию, когда сбой службы можно предотвратить.
4. Используйте методы изоляции, чтобы уменьшить влияние произвольных зависимостей
5. Оптимизируйте время обнаружения с помощью метрик, мониторинга и предупреждений в режиме, близком к реальному времени.
6. В большинстве аспектов Hystrix низкая задержка изменений конфигурации и поддержка динамических изменений свойств позволяют выполнять операции модификации в реальном времени с малой задержкой, тем самым оптимизируя время восстановления.
7. Предотвращайте сбои во всем выполнении клиента зависимостей, а не только в сетевом трафике.
Как Hystrix достигает вышеуказанных целей
1. Все внешние вызовы инкапсулируются в объекты HystrixCommand или HystrixObservableCommand, которые обычно выполняются в отдельных потоках.
2. Время вызова тайм-аута превышает установленный порог. Существует значение по умолчанию, но для большинства зависимостей вы можете настроить это свойство так, чтобы производительность немного превышала 99,5 %, измеренную для каждой зависимости.
3. Поддерживайте пул потоков (или сигнал) для каждой зависимости.Если пул потоков зависимости заполнен, новые запросы зависимостей не будут продолжать ждать в очереди, а будут немедленно запрещены в доступе.
4. Подсчитайте количество успехов, неудач, тайм-аутов и отклоненных потоков.
5. Если процент отказов зависимых служб превышает пороговое значение, вручную или автоматически запустите прерыватель цепи, чтобы остановить все запросы к указанной службе на определенный период времени.
6. Обеспечьте резервную логику на случай сбоя запроса, отклонения, тайм-аута или короткого замыкания.
7. Отслеживайте метрики и изменения конфигурации почти в режиме реального времени.
Демонстрация фрагмента кода
После стольких разговоров, давайте посмотрим на код, чтобы быть более реалистичным Я перехватил кусок кода с официального сайта Hystrix следующим образом:
public class Order {
private final int orderId;
private UserAccount user;
public Order(int orderId) {
this.orderId = orderId;
user = new GetUserAccountCommand(new HttpCookie("mockKey", "mockValueFromHttpRequest")).execute();
}
}
Больше контента кода:GitHub.com/Netflix/h и выше…
Выше приведен пример, используемый Hystrix. В реальном коде нужно создать новую команду, а затем вызвать метод execute для получения результата. Так что же делает Hystrix в этом процессе?
Рабочий процесс Hystrix
Вышеприведенная картинка взята из официальной документации Hystrix, Если вы можете понять этот документ, вы можете почти понять, как выполняется Hystrix. Интерпретируйте поток выполнения Hystrix через последовательность на рисунке.
1. Инициализация, есть два способа инициализировать команду Hystrix: создать ее с помощью новой команды HystrixCommand или новой HystrixObservableCommand и создать команду Hystrix с использованием экземпляра службы и параметров, требуемых службой запроса.
2. После успешного создания Hystrix есть четыре способа выполнить фактическую команду и получить возвращаемый результат. Здесь Hystrix также использует адаптивное программирование для проектирования.Эта тема относительно обширна и не будет объясняться некоторое время, а позже будет подробно изучена.
Для экземпляра команды, созданной с помощью HystrixCommand, выполнить или поставить в очередь; для экземпляра команды, созданной с помощью HystrixObservableCommand, выполнить метод наблюдения или toObservable, вы можете запросить службу, а затем получить результат выполнения. Характеристики этих четырех методов:
execute - 会阻塞,然后返回依赖服务的结果
queue - 返回一个Future,然后可以通过get方法获得以来服务的结果。
observe - 订阅包含依赖服务响应结果的订阅器,当有结果时返回一个订阅器。
toObservable - 返回一个订阅器,当订阅它时,会知晓Hystrix命令并返回结果。
Исходный код выполнения выглядит следующим образом:
public R execute() {
try {
return queue().get();
} catch (Exception e) {
throw Exceptions.sneakyThrow(decomposeException(e));
}
}
public Future<R> queue() {
/*
* The Future returned by Observable.toBlocking().toFuture() does not implement the
* interruption of the execution thread when the "mayInterrupt" flag of Future.cancel(boolean) is set to true;
* thus, to comply with the contract of Future, we must wrap around it.
*/
final Future<R> delegate = toObservable().toBlocking().toFuture();
// 其他定义
}
Как видно из исходного кода, метод execute будет вызывать метод queue().get(), а queue() будет вызывать метод toObservable().toBlocking().toFuture(), указывая, что каждая команда Hystrix в конечном итоге вернется к реализации объекта Observable, даже если он возвращает простое значение.
3. Определите, включает ли Hystrix кэширование и имеет ли соответствующий запрос кэшированное значение, и возвращает кэшированный результат.
4. Если 3 не кэшируется, Hystrix проверит свой предохранитель.Если предохранитель включен в это время, Hystrix не выполнит команду и вернет результат понижения напрямую.
5. Если пул сигналов или потоков отклоняет запрос, вернуть результат перехода на более раннюю версию.
6. Hystrix инициирует операцию вызова внешней службы, вызывая метод HystrixCommand.run() или HystrixObservableCommand.construct(), и возвращает результат перехода на более раннюю версию в случае истечения времени ожидания или сбоя. Если метод запуска или построения превысит значение тайм-аута, определенное командой, поток выдаст TimeoutException, В это время, когда Hystrix перехватит исключение, он проигнорирует возвращаемое значение метода запуска или построения и войдет в резерв.
注意:没有任何方式可以阻止延迟的线程停止工作,在JVM中,Hystrix可以做到最好的就是抛出一个InterruptedException,如果Hystrix封装的服务没有捕获InterruptedException,Hystrix线程池中的线程会继续它的工作。
7, независимо от того, как запрос: успех, неудача, тайм-аут, предохранитель, состояние здоровья HYSTRIX будет сообщено на предохранителях, записывает состояние службы, используемое для определения того, будет ли активировать / наполовину запускать предохранители.
8. Откат, операция перехода на более раннюю версию вызовет условия для операции отката: Метод конструкции или запуска вызывает исключение Предохранитель открыт Недостаточный пул потоков и емкость очереди или сигнала Тайм-аут команды Hystrix
Для каждой команды Hystrix необходимо переопределить метод getFallback, а схема понижения реализована в функции отката.Если вам нужно использовать сетевой вызов в откате, вам нужно передать еще один HystrixCommand или HystrixObservableCommand. В HystrixCommand реализован метод getFallback, а в HystrixObservableCommand реализован метод sumWithFallback.
Если резервный метод не реализован или резервный метод вызывает исключение, Hystrix все равно вернет Observerable, но не вернет содержимое и немедленно завершит работу с уведомлением onError. Через уведомление onError вызывающей стороне Hystrix будет возвращено исключение. Старайтесь не писать резервные реализации, которые могут генерировать исключения.
9. Если все нормально, то Hystrix отправит успешный результат в Observable, и программа его получит.
Суммировать
Выше приведен процесс выполнения Hystrix, потому что недавно я хотел знать, как реализовать сервисный предохранитель в PHP, так как реализовать Hystrix, который лучше подходит для изучения Java. Далее я продолжу подробно изучать реализацию предохранителя Hystrix и в следующий раз поделюсь принципом реализации предохранителя Hystrix.
Знание процесса выполнения библиотеки может не только помочь вам устранить более сложные проблемы, возникающие во время разработки, но также изучить концепцию дизайна библиотеки, усвоить некоторые преимущества дизайна фреймворка из этих библиотек, а затем, если вам нужно реализовать связанные функции , вы можете быть использованы в качестве ссылки.
Оригинал статьи, ограниченный стиль написания, недостаток знаний и знаний, если есть неточности в статье, сообщите пожалуйста.
Если эта статья была вам полезна, ставьте лайк, спасибо ^_^
Для более интересного контента, пожалуйста, обратите внимание на личный публичный номер.