Николай Сивко "Хорошо поддерживаемое в продакшне...
TRANSCRIPT
Мирглазамиразработчика1. Естьзадачастребованиями
2. Пишукод+тесты
3. Показалdemoзаказчику
4. ПередалвproducIon
ЕслибагилипроблемавproducIon:GOTO#1
Мирглазамиадмина• Выкатилновуюверсиюприложения
• В3:00утраSMS:“HTTP-50x>20rps”
• Приложениежрет4ядра,влогепусто
• Фронтенднедожидаетсяответаотсервисаза10sиотдаетпользователям504
• Разработчикпроситпроверитьсеть/БД/… ивообщеперезапустить
DevOps:РазрабАдмин?
СчегообычноначинаетсяDevOps?• ConInuousdeliveryидеплой10развчас!
• СпрячемотразработчикажелезкизаDockercоркестрацией!
• Чтобывсемасштабировалосьналетубудемходитьзаконфигамипосети,целостностьнамобеспечитPaxos/Ray!
• Такмыбезпроблембудемрастидопланетарногомасштабаничегонеменяякоде!
СчегообычноначинаетсяDevOps?• ConInuousdeliveryидеплой10развчас!
• СпрячемотразработчикажелезкизаDockercоркестрацией!
• Чтобывсемасштабировалосьналетубудемходитьзаконфигамипосети,целостностьнамобеспечитPaxos/Ray!
• Такмыбезпроблембудемрастидопланетарногомасштабаничегонеменяякоде!
Чегохочетбизнес?• ProducIonдолженработать
• Есличто-толомается,нужнобыстроопределитьпричинуипочинить
• Сделатьтак,чтобынеповторялось
DevOps:РазрабАдминРазработчикдумаетотом,какподдерживатьприложениевproducIonилисамэтоделает
ИЛИ
Когдаадминначинаетписатькод(этогоревсемье,нослучается:)
Будемговоритьпродиагностику• Посмотрим,каксделаноупопулярногософта:nginx,mongo,postgresql
• Какиевообщеестьподходы?
• Какделатьусебя?
• Входящиезапросы
• Бэкенды
• Статика,кэш
• Lua,perl,…
Nginx:error_log2016/10/1012:27:57[error]6219#0:*130819912upstreamImedout(110:ConnecIonImedout)whileconnecIngtoupstream,client:1.2.3.4,server:okmeter.io,request:"POST/metric/writeHTTP/1.1",upstream:"h�p://192.168.100.9:8088/metric/write",host:"okmeter.io"
• Укакогоименноклиентаошибка• Какойбэкенднеответил
Nginx:access_log1.2.3.4 - - [10/Oct/2016:14:04:38 +0300] "POST /metric/write HTTP/1.1" 200 2 "-" "Go-http-client/1.1" 0.103 - [0.039, 0.064] {192.168.100.5:8088, 192.168.100.4:8088} {504,200}
• Какойстатусвернуликлиенту• Чтовернулкаждыйбэкенд,сколькобылопопыток• Сколькождаликаждогобэкенда• Сколькождалпользователь
Nginx:debuglog• Показываетвсеэтапыобработкизапроса
• МожнотолькодляконкретныхIP/сетей(debug_connecIon)
• Можновциклическийбуфервпамяти
Nginx:stub_statusAcIveconnecIons:291serveracceptshandledrequests166309481663094831070465Reading:6WriIng:179WaiIng:106
Nginx:тёмныепятна• Сколькождалидиск:читалиданныесдиска,писалилог
• ДругиеблокировкиIOloop:логикаnginx,логикапользователя(lua)
• Данные
• Запросы+CPUboundлогика(aggregaIon)
• Ресурсы:диск,сеть,процессор
Mongo• serverStatus-server-wideметрики
• dbStats-db-wideметрики
• collStats–collecIon-wideметрики
Mongo:queryprofiler• CappedcollecIonспрофайлингомзапросов
• Включаетсядлявсехилитолькодля“медленных”
• Можетнегативноповлиятьнапроизводительность
Mongo:практикаМетрикмного,нобольшинствоизнихдляразработчикаmongoПользовательможеттолько:-прибитьплохойзапрос-исправитьзапросы/схемуданных/индексы-поменятьконфиг-добавитьресурсов
Mongo:тёмныепятна• Какойзапроспрямосейчасвсёубивает?
• Накакиезапросыуходятресурсы?
• Какиезапросыудерживаютлоки?
• Данные
• Запросы
• Ресурсы:диск,сеть,процессор
PostgreSQL:данные• pg_stat_all_(tables|indexes)
• pg_staIo_all_(tables|indexes)
PostgreSQL:запроcы• pg_stat_acIvity– чтопроисходитпрямосейчас
• pg_stat_statements–накопленныесчетчикипогруппамзапросов
PostgreSQL:локи• pg_stat_acIvity.wait_event– 9.6+
• pg_locks– можноJOINнаpg_stat_acIvityпоpid
PostgreSQL:тёмныепятна
Впостгресепочтиидельнаядиагностика.Постгресумный.Будькакпостгрес.
Зачеммывсеэтосмотрели?• Webприложенияпохожинаnginx,толькобольшевычисленийпослеполученияданных,уnginxхорошиелоги
• Mongo– примертого,каквсёпокрылисчетчиками,нозабылипросценариииспользованиядиагностики
• PG– примертого,какдолжнобыть
Диагностика:вопросы• Чемприложениезанятопрямосейчас?
• Чемприложениезанималосьввчерав18:43?
• Накакиезадачи/запросыбылипотраченыресурсы?
• Сколькоикакихошибокбыло?
• Сколькождалиответабазывчера/сегодня?
• ПочемуотдалиHTTP-400?
Подходы• Thread/stackdumpианалоги• Лог
• Счетчики/таймеры/мгновенныезначения
Thread/stackdumpианалоги• Мгновенныйснимок:вкакомместекоданаходитсяуправлениекаждого“потока”
• БольшепроrunIme,аневашкод
• Высокоуровневыеаналоги:какиезапросысейчасобрабатываеминакакойонистадии
Thread/stackdumpианалоги• Java:jstack<pid>
• Golang:– enablepprof– curlh�p://IP:PORT/debug/pprof/gorouIne?debug=2
Высокоуровневыеаналоги• PG:pg_stat_acIvity
• Mysql:SHOWPROCESSLIST
• Apache:mod_status
Лог• Правильнописатьлогиоченьсложно• Правильно=написатьнужноеиНЕписатьлишнее
• Общегорецептанет– всесистемыразные
• Предлагаюисходитьизсценариевиспользования
Лог:сценарийВывидитевлогеnginx:…..”GET /url HTTP/1.1" 504request_Ime=0.101 upstream_response_Ime=[0.101] upstream_addr={192.168.1.1:8000} upstream_status={504}
Чтовыбудетеделатьдальше?
Лог:сценарийВызахотитеузнать,чтовлогеу192.168.1.1поэтомузапросу!Чтотакое“этотзапрос”?
Лог:request_id• Навходегенеримidзапроса(nginx$request_idнапример)
• Ставимзаголовкомвовсезапросыдальше:X-Request-Id:123456
• Вовсехсервисахпишемвлог
• МожнодажевSQLкомментарий
Лог:request_idNginx…..”GET /url HTTP/1.1" 5040.101 [0.101] {192.168.1.1:8000} {504}req_id=123456192.168.1.1:<Imestamp>id:123456queryingsessionfromsession_db1<Imestamp>id:123456clientclosesconnecIon<Imestamp>id:123456GET/api/blabla4990.101sPG:<Imestamp><pid><user>@<db>from192.168.1.1[vxid:x/ytxid:0][SELECT]LOG:duraIon:147.020msexecute<unnamed>:/*123456*/select*fromsessionwheresession.id=$1AND…
Лог:итого• Нужноотличатьзапросыдруготдруга(requestid)
• Пишемнетолькозаконченныедействия(бываетнужноловитьзалипшие)
• Есликуда-тоидем,пишемконкретныйадрес
• Пишемвсеошибкиикакихобработали
• Замеряемвремязначимыхопераций
Лог:нагрузка• Подробноелогированиесоздаетнагрузку
• Есливводимразныеуровнилогирования,тонужнаручкапереключениябезперезапуска
• Клогамможноцеплятьпарсерыдляполученияметрик,ноэтотоженагрузка
Метрикиприложения• Счетчикисобытий(ошибки,запросы,…)
• Таймеры(замеряемпродолжительностькаких-тодействий)
• Мгновенныезначения(текущееколичествосоединений,размеркэша,…)
Метрикиприложения• Теряемчастьинформациипосравнениюслогом
• Носильнодешевлелогов
• Экспортируемвмониторингто,чтонасчитали
• Рисуемграфики
• Настраиваемалерты,еслинужно
Метрикиприложения:инструменты
• <your_lang>-metrics
• <your_lang>-statsd-client
Инструменты:<your_lang>-metrics• Либадлявашегоприложения,естьдлявсехЯП
• Аккумулируетзамерывпамяти
• Экспортируетвразличныесистемы(graphite,influx,лог,…)
Инструменты:statsd• UDPсерверпринимаетотстрелызамеровиз
приложения,агрегируетиэкспортируетвмониторинг
• КлиентыдлявсехЯП
• Семантикапримернотакаяжекакв*-metrics
• Естьбиблиотекиспредварительнойагрегациейнаклиенте
СчетчикиGolang
ТаймерыGolang
КейссHTTP-504
Ценаметрик(golang)• GetOrRegister 122 ns/op• CounterInc 10 ns/op• Timer_Time 879 ns/op• 2xNow 38 ns/op10.000rps*(10таймероввкаждом)=диагностиказаймет~9%одногоядра
Итого• DevOpsнужноначинатьсдиагностики
• Диагностика–этопросто
• Делайтедиагностикуисходяизсценариевиспользования
• Естьмногоготовыхинструментов• Послеэтогоможноdocker,CI/CDи100500микросервисов:)