В эпоху больших данных и стремительного роста трафика вопрос о том, как обеспечить безопасность и стабильность наших сервисов, является проблемой, на которую должно обратить внимание каждое предприятие и каждый разработчик. Так появились некоторые благородные термины, такие как микросервисы, распределенные, большие данные и т.д.... . Однако какой бы сложной ни была система или структура, они должны состоять из чего-то небольшого.
распределенный
Появление распределённых должно решить проблему того, что один сервис не выдерживает высокого давления, и в то же время решить ситуацию, когда весь сервис недоступен из-за отказа одного сервиса. Распределенные сервисы должны состоять из нескольких узлов, и каждый узел может разделять некоторое давление, так что изначально одна машина может поддерживать запросы 1 Вт qps, а с помощью 10 машин можно достичь запросов 10 Вт qps. А за счет размещения узлов в разных компьютерных залах уменьшается явление коллективного паралича, вызванное концентрацией узлов. Если у нас есть только одна машина, то независимо от того, где она развернута, вся служба не будет доступна после того, как мы повесим трубку.Если у нас есть 10 машин, которые распределены в городе А, городе Б...., даже если это вызвано погодой или другими причинами Узел в городе А недоступен. В настоящее время нам нужно только отключить трафик, изначально подключенный к городу А, и распределить трафик на оставшиеся 9 узлов. Весь сервис по-прежнему доступен, и достигается высокая доступность. Поскольку существует несколько узлов, как нам равномерно амортизировать или распределять трафик на один узел в соответствии с нашей стратегией?
балансировки нагрузки
Для распределенных сервисов распространенными алгоритмами балансировки нагрузки являются:
метод опроса
Распределяйте запросы к каждому узлу по очереди, например, первый запрос к узлу A, второй запрос к узлу B... Метод опроса очень справедлив для каждого узла и не заботится о текущем состоянии узла (например, количестве соединения с узлом, нагрузка и т. д.). Поэтому при использовании метода опроса конфигурация каждого узла должна быть как можно более согласованной (одинаковое количество ядер ЦП, одинаковая память...). Если конфигурация узла слишком низкая, нагрузка на тот же трафик может быть больше, поэтому в случае опроса это не очень справедливо, и трафик, выделенный для узла с низкой конфигурацией, может подвергаться слишком большой нагрузке. , Нет.
случайный метод
По сравнению с циклическим методом случайный метод может использовать некоторый случайный алгоритм для выбора одного из узлов для распределения, например, в настоящее время имеется 10 узлов.rand(1,10)случайным образом выбрать узел. Из вероятности и статистики можно узнать, что случайный алгоритм имеет тенденцию к среднему значению по мере увеличения количества вызовов, поэтому конечный эффект метода распределения с помощью случайного метода аналогичен эффекту метода опроса.
IP-хеширование
Иногда мы хотим, чтобы запрос клиента был привязан к определенному узлу, например запрос клиента А, каждый раз, когда я хочу, чтобы он был назначен узлу А. В настоящее время опрос или рандомизация определенно не осуществимы. Хорошо выделить его через IP клиента. Вы можете получить значение путем хэширования в соответствии с IP клиента, а затем использовать это значение для модуля количества узлы и число, полученное после модуля. Результатом является порядковый номер узла, который будет назначен этим запросом. Например, IP клиента192.168.10.1, а затем результат, полученный хэш-функцией:hashIndex(192.168.10.1)%10=5,Так5Это означает, что текущий порядковый номер должен быть присвоен5узел.
взвешенная круговая система
На самом деле, если конфигурация некоторых узлов отличается, разумнее распределять трафик по весу, например, узел А имеет 2-ядерный процессор, а остальные узлы имеют 4-ядерный процессор.Очевидно, узел А может нести нагрузку. Это относительно низко. В это время трафик может быть распределен в соответствии с весом. Узел с более низкой конфигурацией имеет меньший вес, а затем трафик распределяется для каждого узла в соответствии с порядком веса. Например, при обычном опросе каждый узел выделяется по очереди. После взвешивания по очереди выделяются все узлы, кроме узла А. Узел А может выделяться один раз каждые два раунда других узлов.
взвешенный случайный метод
Как и взвешенный циклический метод, взвешенный случайный метод также распределяет трафик в соответствии с весами, настроенными каждым узлом. Разница в том, что он запрашивает внутренние серверы случайным образом по весу, а не последовательно. Например, вероятность может быть назначена в соответствии с количеством ядер.Предполагая, что узел А имеет 2-ядерный ЦП, а остальные 9 узлов имеют 4-ядерный ЦП, тогда вероятность того, что узел А назначается каждый раз, равна2/(4*9+2).
минимальное количество подключений
Метод минимального количества подключений должен быть более гибким алгоритмом балансировки нагрузки, когда конфигурация каждого узла разная, помимо алгоритма, который вручную настраивает вес, трафик также может распределяться по количеству подключений к узлу, что метод минимального соединения. Каждый раз, в соответствии с текущим статусом подключения узлов, динамически выбирать узел с наименьшим количеством подключений для распределения трафика, максимально повышать эффективность использования каждого узла и распределять трафик более разумно.
Регистрация и обнаружение службы
ip + port
Когда у нас есть несколько кластеров и разработан алгоритм балансировки нагрузки, следующая проблема, которую необходимо решить, — это найти соответствующий узел для запроса.Например, запрос A должен быть выделен узлу A, так как же запрос найти узел A? Самый простой способ — это метод ip+port: сообщаем звонящему ip и порт, а звонящий выбирает соответствующий ip-узел по lb, чтобы служба была найдена.Этот метод более распространен для настройки апстрима nginx, и использовать nginx в качестве прокси-уровня сервера, который помогает нам обнаруживать сервисы. Однако недостатком этого метода является то, что он требует ручного вмешательства.Когда нам нужно динамически добавить или удалить узел, нам нужно изменить конфигурацию nginx.Если узел на линии выходит из строя, немного медленно вручную изменить конфигурация?
Зарегистрируйтесь и откройте для себя
Возможно, вы подумаете, что методы ip и port — это нормально, ведь когда узлов не много, конфигурация сложения и вычитания тоже очень быстрая. Однако в крупной микросервисной системе мы разделим сервисы на более мелкие детали.Мы разделим все приложение на микросервисы один за другим в соответствии с бизнес-классификацией, и каждый микросервис высокодоступен, поэтому каждый микросервис также состоит из нескольких узлы состоят из. В случае такого количества узлов очень трудоемко и небезопасно управлять по ip+port. Затем появляются сервисы регистрации и обнаружения.Посредством регистрации и обнаружения сервисов можно автоматически управлять узлами без вмешательства человека, что значительно повышает эффективность эксплуатации и обслуживания.
регистрация службы: Сообщите менеджеру свой айпи и порт, и вы сможете установить логотип заодноname.
#伪代码 注册一个鉴权节点
discover->register('192.168.0.1',8000,'auth')
обнаружение службы: ЗарегистрированоnameПерейти к поиску соответствующего узла.
#伪代码 发现一个节点
discover->find('auth')
Регистрация службы и обнаружение проверяют состояние выживания узла с помощью сердцебиения. Если сердцебиение узла выходит из строя, оно будет автоматически удалено. Конечно, наше обнаружение также должно быть кластером, который обладает высокой доступностью. В настоящее время обычно используетсяconsul,etcd,zookeeperи так далее.
тайник
С развитием информации объем данных становится все больше и больше, и пользователей становится все больше и больше.База данных, обеспечивающая только чтение и запись, больше не может удовлетворить потребности в быстром реагировании, потому что ввод-вывод занимает относительно много времени, поэтому мы обычно блокируем перед db В предыдущем кеше сначала читается кеш.После того, как кеш недействителен, мы читаем его из базы данных, считываем данные и записываем обратно в кеш, таким образом образуя замкнутый цикл. Благодаря кэшированию мы можем гарантировать, что большая часть запросов попадет в кеш, что не только повышает скорость ответа, но и играет роль в защите базы данных. Поскольку используется кеш, проблемы непротиворечивости данных не избежать. Когда мы пытаемся обновить часть данных, мы сначала обновляем кеш или обновляем базу данных?
Сначала обновите кэш, затем обновите базу данных.
- Если предположить, что сначала обновление кэша прошло успешно, а затем обновление базы данных завершилось неудачно, это приведет к несогласованности данных, и данные, считанные из базы данных после того, как кэш станет недействительным, также будут старыми.
- Предположим теперь, что есть два запроса A и B, работающие одновременно.
- Обновление кеша
- б обновить кеш
- Б обновить базу
- Обновить базу данных
Сначала обновите базу данных, затем обновите кеш.
- Предполагая, что сначала обновление базы данных прошло успешно, а затем обновление кеша не удалось, это также приведет к несогласованности данных, но по сравнению с первым обновлением кеша, а затем обновлением схемы базы данных, после того, как кеш станет недействительным, можно будет прочитать правильные данные. .
- Предположим теперь, что есть два запроса A и B, работающие одновременно.
- Обновление базы данных
- Б обновить базу
- б обновить кеш
- Обновление кеша
Помимо проблемы несогласованности двойной записи, действие по обновлению кеша не рекомендуется, потому что иногда данные в кеше - это сложные данные, это комплекс, вам нужно прочитать данные нескольких таблиц, чтобы сделать агрегацию , а если использовать json string, то десериализация каждый раз, и сериализация после обновления, весь накладные расходы все равно очень большие. И если в какой-то момент вы обновляете 10 раз, но не читаете ни разу, то операция многократного обновления кеша проходит впустую.
Сначала удалите кеш, затем обновите данные
Когда A запрашивает удаление кеша, B запрашивает чтение кеша:
- Удалить кеш
- B запрашивает кеш и обнаруживает, что кеша не существует
- B запрашивает базу данных и записывает старое значение, прочитанное обратно в кеш.
- A обновляет новое значение в базе данных
Как правило, для решения этой проблемы используется отложенное удаление.После того как А обновит базу данных, выполните еще одно удаление.
Сначала обновите базу данных, затем удалите кеш.
Аналогично, если обновление БД прошло успешно, а удаление кеша не удалось, то это тоже приведет к несогласованности данных, либо у вас кеш имеет архитектуру master-slave, и мастер удаляет успешно, но не успел синхронизироваться с ведомым , то это также вызовет кратковременную проблему несогласованности данных.
На самом деле неважно, какой метод может гарантировать непротиворечивость двойной записи кэша базы данных, не говоря уже о распределенной системе. Выбирайте только тот способ, который менее рискован или больше подходит для вашего бизнес-сценария. Остальное — мониторинг и оповещение.В некоторых сценариях, требующих высокой согласованности данных, рекомендуется своевременно уведомлять об аномальных данных посредством мониторинга и оповещения, а затем исправлять аномальные данные.
Ограничение тока интерфейса
Почему интерфейсу нужно ограничивать ток? Во-первых, каждый интерфейс делает разные вещи. Некоторые интерфейсы могут возвращать только некоторые статические конфигурации, некоторые интерфейсы должны выполнять сложные операции, а некоторые интерфейсы требуют много операций ввода-вывода.... Если нет ограничения по току, для некоторых ресурсоемких интерфейсов всплеск трафика может повесить нашу машину или БД за ней. Как оценить текущий лимит? Как правило, испытание под давлением используется для оценки qps, которое может выдержать интерфейс, и если qps превышает расчетное qps, мы отказываемся с этим бороться. Хороший алгоритм ограничения тока также очень важен.Распространенные алгоритмы ограничения тока следующие:
считать текущий лимит
Когда придет один, добавьте один, и когда общее количество достигнет установленного лимита в единицу времени, в услуге будет отказано. Недостаток этого решения в том, что не очень хорошо поддерживается пакетный трафик, например лимит 100 в 1с, первые 100мс будут израсходованы, а остальные 900мс не будут обслуживаться.
count++
count--
Фиксированный предел тока окна
По сравнению с пределом текущего счета фиксированное окно имеет концепцию окна. Основная идея фиксированного ограничения тока окна состоит в том, чтобы рассматривать определенный период времени как окно, и в этом окне есть счетчик, который используется для подсчета количества запросов в этом временном окне. превышает порог, будет ограничен поток. При открытии следующего окна он будет пересчитан. Но фиксированное окно имеет недостаток: предположим, что мой текущий лимит составляет 100 запросов в секунду, мое окно находится в s, последние 0,5 секунды первого окна потребляют 100 запросов в секунду, а затем первые 0,5 секунды второго окна потребляют 100 запросов в секунду. в сумме они составляют 200 запросов в секунду за 1 с, что явно не соответствует нашим текущим правилам ограничения.
Ограничение тока в скользящем окне
Чтобы решить проблему, вызванную фиксированным окном, мы можем установить окно как нефиксированное, каждый раз, когда приходит запрос, продвигать его вперед на 1 с, затем в этом 1 с окне, если верхний предел текущего предела не достигнуто, то услуга будет оказана, иначе отказ в обслуживании. Однако есть и проблема со скользящим окном, то есть оно не может решить проблему всплесков трафика, например, если текущий лимит израсходован в первую 1 мс, остальные 999 мс не могут быть обслужены.
Ограничение тока дырявого ведра
Идея алгоритма дырявого ведра такова: внешняя скорость переменная (запросы плотные или разреженные), в то время как вместимость ведра фиксирована, и ведро всегда выводится с постоянной скоростью.Когда его нельзя обработать( корзина заполнена), избыточные запросы будут регулироваться (переполнение корзины). Метод дырявого ведра подходит для сценариев, которые обрабатываются с постоянной скоростью.
корзина с жетонами
Идея ведра токенов заключается в том, чтобы помещать токены с постоянной скоростью.Когда токены в ведре заполнены, они не будут помещены, что указывает на то, что скорость запроса в это время не может идти в ногу со скоростью токена. вставка. Таким образом, когда служба простаивает, в ведре будет достаточно токенов, а когда происходит всплеск трафика, поскольку в ведре уже достаточно токенов, в определенной степени может быть удовлетворен всплеск трафика. Алгоритм корзины токенов поддерживает произвольную скорость исходящих корзин. Вам нужно каждый раз получать токены из корзины. Если вы получили токен, вы можете обработать задачу. Если вы не получите токен, вы ограничите поток.
Действие по установке токена не нужно обрабатывать в отдельном потоке.Вы можете использовать разницу во времени и скорость, чтобы рассчитать, сколько токенов нужно вставлять каждый раз, когда вы получаете токен.
速率:speed = 1/n #例如 1s 10个, 那么速率就是每1/10秒放入1个
时差:difftime:=now-lasttime
放入令牌:difftime/speed #这里注意算出的token别超出桶的容量
Сервисный предохранитель
Зачем нужен автоматический выключатель? В микросервисах из-за того, что сервис очень тонко разделен, часто возникаетСервис A->Сервис B->Сервис C, если служба C вызывает медленные запросы из-за некоторых трудоемких операций, а RT интерфейса увеличивается линейно, время ожидания всех запросов службы B будет истекать. A будет постепенно увеличиваться, и услуга A также будет недоступна. Можно обнаружить, что связанные службы недоступны из-за проблемы службы C, вызывающей лавину. Мы должны отключить связь между сервисом B и C, когда сервис C постоянно недоступен, что является предохранителем. Конечно, мы не всегда можем фьюзить, если сервис С хороший, мы должны продолжать предоставлять сервисы, то тут задействован алгоритм фьюза.
стратегия автоматического выключателя
-
Подсчет общего количества запросов за период времени
-
Подсчитайте процент отказов запросов за этот период
-
Если оба 1 и 2 удовлетворены, срабатывает предохранитель
-
После включения предохранителя на некоторое время попробуйте вставить небольшое количество
-
Если после полуоткрытия еще много отказов, снова предохранитель, иначе предохранитель будет закрыт.
Когда общее количество запросов достигает установленного нами числа, а частота отказов также достигает установленного нами стандарта, срабатывает прерыватель цепи. В это время автоматический выключатель сообщит нам, что служба недоступна, так что следующий запрос вернется напрямую. Через некоторое время (время настраивается), предполагая, что зависимая служба была восстановлена, прерыватель цепи попытается направить в нее некоторый трафик для тестирования.Если в это время еще много ошибок, это означает, что зависимая служба не был восстановлен, то он снова сработает предохранитель и будет ждать следующего времени полуоткрытия. Если с полуоткрытым трафиком все в порядке, автоматический выключатель будет замкнут, и обслуживание будет восстановлено.
понижение уровня обслуживания
В управлении сервисом переход на более раннюю версию также является более важным средством. Когда бизнес-трафик достигает пика, некоторые неважные службы могут выйти из строя, и эти неисправные службы могут вызвать цепную реакцию и повлиять на основной бизнес.В это время некоторые неважные службы (например, рабочие биты, комментарии и т. д. ...).
означает
- Вся служба не работает
- Связанный интерфейс напрямую возвращает пустой
- Интерфейс зависит от ресурса БД, который нужно отрезать и преобразовать для чтения нижних данных из локальной памяти.
Конечно, понижающие классы обычно можно использовать вместе с предохранителями.
if break { //熔断
return localCache //降级走本地缓存
}
Демон + изящный перезапуск
Если наш сервис вдруг аварийно завершает работу во время работы, было бы неловко предполагать, что в это время нет функции автоматического восстановления.
Путь стража
- если служба
k8s, тогда k8s автоматически подтянется, когда модуль выйдет. - через сторонних
supervisor, чтобы управлять нашим процессом - через систему
systemdуправлять нашим процессом
принцип сглаживания
Следует отметить, что в процессе перезапуска службы следует обращать внимание на плавность. 504 не может быть вызвано тем, что запрос обрабатывается из-за перезапуска. Как правило, основной процесс разветвляет дочерний процесс. Основной процесс отвечает за обработку старого запроса. После обработки основного процесса он автоматически завершается. Все новые запросы передаются для обработки дочернему процессу.После завершения основного процесса дочерний процесс становится новым основным процессом.
Отслеживание распределенных ссылок
В распределенной системе из-за разделения сервисов многие интерфейсы микросервисов могут быть вложены за интерфейсом шлюза, что, несомненно, увеличивает сложность устранения неполадок. НапримерA->B->C->D,
A нашел B из-за ошибки, B сказал, что это было вызвано ошибкой C, а C сказал, что это было вызвано ошибкой D. Если есть способ связать вместе узлы, распределенные в разных местах, и, наконец, отобразить информацию о времени, IP, ошибках и другую информацию о каждом узле через интерфейс, это может значительно повысить эффективность устранения неполадок.
Появление распределенной трассировки ссылок (trace) решает эту проблему.
Отслеживание ссылок обычно включает три основных этапа: сбор данных, хранение данных и отображение данных. Поскольку сбор данных должен вторгаться в код, это неизбежно приведет к различным методам написания, поэтомуOpenTracingПоявившийся,OpenTracingЭто набор протоколов распределенной трассировки, не зависящих от языка, с унифицированной спецификацией интерфейса, что облегчает доступ к различным системам распределенной трассировки.OpenTracingМодели данных, определенные в семантической спецификации,Trace,Spanа такжеReference.
Span
SpanПредставляет независимую единицу работы, это может быть вызов rpc, вызов функции или даже вызов, который, по вашему мнению, принадлежит модулю span.
Обозначьте модули, которые нас интересуют, с помощью промежутков, пролеты обычно включают в себя:
- Имя диапазона, например имя службы проверяющей стороны.
- отметка времени начала
- отметка времени окончания
Trace
TraceПредставляет полную ссылку трассировки, например: весь жизненный процесс запроса. Трассировка — это ориентированный ациклический граф (DAG), состоящий из одного или нескольких отрезков.
[Span A] ←←←(the root span)
|
+------+------+
| |
[Span B] [Span C] ←←←(Span C is a `ChildOf` Span A)
| |
[Span D] +---+-------+
| |
[Span E] [Span F] >>> [Span G] >>> [Span H]
↑
↑
↑
(Span G `FollowsFrom` Span F)
Временная шкала показана следующим образом:
––|–––––––|–––––––|–––––––|–––––––|–––––––|–––––––|–––––––|–> time
[Span A···················································]
[Span B··············································]
[Span D··········································]
[Span C········································]
[Span E·······] [Span F··] [Span G··] [Span H··]
Reference
Span может иметь причинно-следственную связь с одним или несколькими Span.Эта связь называетсяReference. В настоящее время OpenTracing определяет два отношения:ChildOf(отец-сын) отношения иFollowsFrom(следить) отношения.
-
ChildOf: выполнение родительского диапазона зависит от результата выполнения дочернего диапазона.Например, для вызова RPC родительский диапазон синхронно ожидает результата возврата дочернего диапазона. В это время дочерний Span является родительским Span ChildOf. -
FollowsFrom: выполнение родительского диапазона не зависит от результата выполнения дочернего диапазона, например некоторых асинхронных процессов.
Каждая запрошенная ссылка имеет уникальныйtraceID, с помощью traceID и spanID можно связать все промежутки в ссылке, и всю ссылку запроса можно будет увидеть с первого взгляда. Обычная трассировка распределенных ссылок — это Uber.Jaeger, ТвиттерZipin, Али鹰眼...
бревно
Это также распространенный метод устранения неполадок с помощью журналов.В соответствии с различными сценариями мы делим уровни журналов на следующие типы:
-
DEBUG: журнал уровня отладки, тип, который часто используется при отладке программ. -
TRACE: журнал уровня трассировки, который относится к некоторой информации, содержащей подробный процесс выполнения программы. -
INFO: Журнал информационного уровня, распечатайте некоторую информацию, которая, по вашему мнению, вам нужна. -
WARN: Журнал уровня предупреждения может быть потенциальной ошибкой.Для дальнейшего необходимо судить о серьезности проблемы, которая в целом не влияет на нормальную работу программы. -
ERROR: Журнал уровня ошибки, что означает, что где-то произошла ошибка, которая влияет на нормальные функции и требует подтверждения и исправления. -
FATAL: Логи фатального уровня, сбои программы, аварийные выходы и другие серьезные ошибки.
монитор
Надежность службы неотделима от мониторинга.С помощью мониторинга мы можем видеть ситуацию с qps службы, ситуацию с ошибкой http, ситуацию с затратами времени, ситуацию с загрузкой процессора и ситуацию с бизнес-данными, которые мы хотим отслеживать. . . . Три элемента системы мониторинга:收集指标,存储数据,页面展示.
Из них наиболее широко используютсяPrometheus+Grafana. Мониторинг Prometheus сообщает о 4 типах метрик:
Counter:
Счетчик — относительно простой тип индикатора, значение счетчика можно только увеличивать или сбрасывать на 0. Например, его можно использовать для подсчета объема запросов интерфейса и количества http-ошибок.counter.
httpReqs := prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "http_requests_total",
Help: "How many HTTP requests processed, partitioned by status code and HTTP method.",
},
[]string{"code", "method"},
)
prometheus.MustRegister(httpReqs)
httpReqs.WithLabelValues("404", "POST").Add(42)
m := httpReqs.WithLabelValues("200", "GET")
m.Inc()
Gauges
GaugesЕго можно использовать для обработки метрик, которые динамически изменяются с течением времени, таких как использование памяти, загрузка ЦП и т. д.
opsQueued := prometheus.NewGauge(prometheus.GaugeOpts{
Namespace: "our_company",
Subsystem: "blob_storage",
Name: "ops_queued",
Help: "Number of blob storage operations waiting to be processed.",
})
prometheus.MustRegister(opsQueued)
// 10 operations queued by the goroutine managing incoming requests.
opsQueued.Add(10)
// A worker goroutine has picked up a waiting operation.
opsQueued.Dec()
Histogram
гистограмма, аhistogramБудут сгенерированы три индикатора, а именно _count (количество), _sum (накопленная сумма) и _bucket (сегмент).
- _bucket: подсчитывать каждую точку выборки в каждую корзину (ведро)
- _sum: кумулятивная сумма (сумма) для каждого значения точки выборки.
- _count: совокупная сумма количества точек выборки (количество)
Например, теперь есть 100 тортов, и качество тортов 100 г. Мы надеемся разделить 100 тортов на соответствующие коробки в соответствии с их качеством.Теперь есть 5 коробок, которые можно поместить в каждую.0-20g,20-40g,40-60g,60-80g,80-100gкекс. Тогда _bucket — это эти 5 коробок.Предполагая, что коробка весом 20 г содержит 3 пирожных по 5 г, 10 г и 15 г, тогда _count равно 3, а _sum равно 5+10+15=30 г.
CakeHistogram = prometheus.NewHistogram(prometheus.HistogramOpts{
Name: "cakeHistogram",
Help: "cake histogram",
Buckets: prometheus.LinearBuckets(20,40,60,80,100),
})
cases:=[]int{1,2,3,4,...}
for i:=0;i<len(cases);i++{
CakeHistogram.Observe(cases[i])
}
Summary
summaryПодобно гистограмме, также генерируются три индикатора, а именно _count, _sum и quantile. _count и _sum имеют ту же концепцию, что и гистограмма. Значение квантиля - квантиль. Сводка может указывать квантиль при определении, например, 5 точек. Концепция 999th процентиль заключается в том, что число, меньшее этого числа, составляет 99,9%. Если у вас есть N выборочных значений, сначала отсортируйте их от меньшего к большему, а затем возьмите значения, ранжированные по φ*N. Сводка может отражать состояние всего индикатора через вероятность в процентах. Как правило, к φ добавляется диапазон колебаний, например 0,9:0,1, тогда окончательное значение φ находится в диапазоне 0,89–0,91.
GradeSummary = prometheus.NewSummary(prometheus.SummaryOpts{
Name: "man_grade",
Help: "man grade",
Objectives: map[float64]float64{0.5:0.01,0.9:0.001,0.99:0.01,0.999:0.01},
})
var salary = [10]float64{90,87,88,84,99,100,91}
for i:=0;i<len(salary);i++{
GradeSummary.Observe(salary[i])
}
Предпосылка индикаторов отчетности заключается в том, чтобы сначала установить компонент Exporter на свой компьютер, а затем сервер prometheus возьмет на себя инициативу по извлечению данных сборщика, или сборщик будет активно отправлять данные на шлюз push-уведомлений, а сервер prometheus затем извлечет данные из push-шлюза. Показатели вообще временно хранятся в памяти машины, из-за чего кривая дергается при выпуске версии вообще.
тревога
Аварийные сигналы - это средство для нас, чтобы понять проблему в первый раз.Бизнес-ошибка может быть предупреждена, и джиттер qps в течение определенного периода времени может быть предупрежден.Обычные методы оповещения:
- Корпоративный WeChat
- Почта
- Короткое сообщение
- телефон
CI/CD
В отсутствие CI/CD задача запуска кода становится очень громоздкой и требует сотрудничества нескольких человек.
Вам нужно скомпилировать его самостоятельно, а затем запустить модульный тест.Если вы обнаружите ошибку в середине, вы должны изменить код.После изменения кода вы должны вручную скомпилировать и протестировать... Эта серия повторяющихся действий все это снижает затраты от разработки до развертывания.
CI
持续集成(Непрерывная интеграция): разработчики могут часто интегрировать свой код в ветки общедоступного репозитория кода. CI может автоматически обнаруживать, извлекать, создавать и выполнять модульное тестирование после изменения исходного кода. Цель CI — быстро убедиться, что недавно внесенные разработчиками изменения хороши и подходят для дальнейшего использования в кодовой базе.
CD
持续交付(Непрерывная поставка): на основе непрерывной интеграции непрерывная поставка развертывает интегрированный код в предпроизводственной среде.
持续部署(Непрерывное развертывание). Непрерывное развертывание предназначено для автоматизации процесса развертывания в производственной среде на основе непрерывной доставки.
С помощью CI/CD мы можем освободить от повторяющейся работы, быстрее устранять проблемы, раньше получать результаты, реализовывать интеграцию разработки, эксплуатации и обслуживания и значительно повышать эффективность доставки.
Центр конфигурации
Чтобы уменьшить жесткое кодирование в нашем проекте, для некоторой информации о конфигурации, которая может часто меняться, зрелый центр конфигурации может принести нашему проекту много преимуществ: нет необходимости повторно модифицировать код из-за небольшой конфигурации. (например, цена товара, сегодня 9,9 юаня, завтра будет событие, я надеюсь, что оно будет изменено на 6,9 юаня). В зависимости от сценария изменение статических констант для чтения динамических конфигураций может повысить эффективность доставки.
выполнить
Как правило, когда проект выпущен, перейдите в удаленный центр конфигурации, чтобы вытащить соответствующий файл конфигурации в локальный, программа сопоставляет соответствующую конфигурацию со своими собственными переменными в соответствии с файлом конфигурации, и соответствующий код считывает соответствующие переменные.
Функции
- Визуальный фон конфигурации, простота в эксплуатации
- Запись версии, которая будет записывать запись каждой модификации конфигурации, если есть проблема, ее удобно отследить.
- Откат, если возникла проблема с вновь измененной конфигурацией, можно откатиться на предыдущую конфигурацию.
Исправление проблем
Учения по устранению неполадок аналогичны военным учениям.Хотя онлайн работает стабильно, если есть проблема, как ее устранить и решить? Цель состоит в том, чтобы проверить способность программиста устранять неполадки и быстро находить проблемы. Итак, как построить тренировочную среду? Напрямую использовать тестовую среду точно нельзя.Во-первых, это не может повлиять на обычный тест.Во-вторых, тестовая среда и реальная среда все же несколько отличаются. Пре-релиз и продакшн еще хуже, их внутренние связи являются реальными интернет-ресурсами и не могут повлиять на онлайн.
Строительство окружающей среды
Следовательно, необходимо построить такую учебную среду, которая близка к реальной среде, ресурсы (БД, кеш...) этой обучающей среды должны быть изолированы от производства, а онлайн-БД и другие ресурсы должны быть скопированы. к новой БД. Далее поток, поток должен быть близок к реальному потоку, желательно реальный поток, можно использовать что-то вродеGoReplayТакой артефакт воспроизведения http-трафика воспроизводит трафик на уровне lb, а затем воспроизводит скопированный трафик в обучающей среде для достижения эффекта воспроизведения реального трафика.
что сверлить
- БД отключена
- кеш отключен
- Услуга отключена
- ....
Смоделируйте какой-либо ресурс или другие сбои.При возникновении сбоя в первый раз следует подать сигнал тревоги, а затем проверить мониторинг и журналы, чтобы определить, какая служба и какая ссылка появились.
стресс тест
Используйте стресс-тестирование, чтобы узнать предел онлайн-обработки для достижения эффекта раннего предотвращения.Среда стресс-тестирования также должна быть близка к реальной среде.Теория среды стресс-тестирования может использовать среду упражнений.Если условия достаточны, вы можете также создайте отдельную среду стресс-тестирования.
Объект испытания под давлением
- может быть интерфейс
- может быть частью бизнеса
- ...
Оценка стресса
- RT: Соблюдайте время отклика
- ОШИБКА: обратите внимание на сообщение об ошибке
- ЦП: наблюдайте за загрузкой ЦП
- MEM: смотреть загрузку памяти
- БД: смотреть загрузку базы данных
- Подключения: обратите внимание на количество сетевых подключений
- IO: наблюдайте за дисковым вводом-выводом
- QPS: наблюдайте за кривой qps
Наконец, поддерживаемый qps оценивается с помощью стресс-теста. Где находится узкое место? Если в будущем трафик увеличится, где точка оптимизации? Если это интенсивное использование ЦП, следует добавить машинные ресурсы. Если это IO- интенсивные, могут быть добавлены ресурсы, связанные с БД.
Надежное кодирование
Все вышесказанное относится к надежности уровня обслуживания.Давайте представим надежность уровня программы. Как элегантно написать набор кода, тоже очень важно для программиста.
Рекомендуется использовать return вместо else
// bad case
if a {
do_a()
} else if b {
do_b()
}
// good case
if a {
do_a()
return
}
if b {
do_b()
return
}
Повторить попытку
Когда мы делаем вызовы rpc, для некоторых очень важных бизнес-сценариев мы можем дать несколько возможностей повторить попытку.
for i:=0;i<2;i++{
if _,err := rpc.getUserinfo();err==nil{
break
}
}
пул соединений
Повторно используйте соединения через пулы соединений, чтобы избежать частого установления новых соединений через трехсторонние рукопожатия.
redisPool := newRedisPoo()
conn := redisPool.Get()
Контроль времени ожидания
Любому rpc-запросу должен быть предоставлен определенный тайм-аут, чтобы избежать лавинного явления.
conn, err := net.DialTimeout(netw, addr, time.Second*2)
Избегайте повторного вызова ресурсов
В бизнесе частоfunc A()->func B() -> func C(), предполагая, что каждая функция должна получить информацию о пользователе, не обращайтесь к каждой функции, чтобы получить ее один раз (если только не сцена с очень высокими требованиями к реальному времени), и уменьшите количество ненужных запросов путем передачи параметров.
func A() {
user := DB.getUser()
B(user)
}
func B(user *User) {
C(user)
}
func C(user *User) {
}
Не используйте слишком много кода в теле функции
Когда функция имеет очень большое количество строк кода, это не способствует чтению.
func doSomething() {
//此书省略1000行
}
Имя функции должно соответствовать фактическому значению
Например, чтобы получить последних зарегистрированных пользователей.
//bad case
func getLoginUser()
//good case
func getRecentLoginUser()
поймать исключение
Не заставляйте вашу программу завершать работу из-за какого-либо исключения.
defer func (
if err:=recover;err!=nil{
log.Error("something panic (%+v)",err)
}
){}
Добро пожаловать, чтобы обратить внимание на одноименную общедоступную учетную запись и получать электронные книги, такие как компьютерная сеть, структура данных, Redis, MySQL, Java, Go, Python и т. д.