
- Для каждого публичного адреса, который потенциально может быть прикрыт CDN, заводите второй — для прямого использования сервисами. Иначе после включения «рубильника в CDN» узнаете о себе много нового, как о явлении.
- Включайте опцию log slow queries на СУБД. Всегда найдется инженер, который «зарядит» запрос мимо индексов. Или администратор, неправильно настроивший резервное копирование.
- Виртуальные машины в облаках — расходный материал. Максимально автоматизируйте разворачивание серверов. Разрабатывайте сервис так, чтобы потеря одного сервера была безболезненна.
- Виртуализация как студенческое общежитие: вечеринка у одного (повышенная CPU или IO активность) может аукнуться всему этажу.
- Используйте проверенные технологии. Любая прикольная штука содержит массу подводных камней, которые зачастую обнаруживаются уже в продакшн.
- NoSql может из кареты превратиться в тыкву при первой потребности произвести join.
- Backend API должен быть не только простым в разработке авторами, но и удобным в использовании клиентами, которые отличаются своим многообразием (web/mobile/desktop) и имеют привычку от версии к версии показывать разные данные на одних и тех же экранах.
- Инженер, помни: задача выполнена, когда твой код принес пользу пользователю и прибыль заказчику. Коммит — всего лишь первый шаг на этом пути.
- Работа сервисов из-под root'a — дыра в безопасности. В крайнем случае, стартуй из-под root'a, переключайся с помощью setuid().
- Избыточное логгирование может отрицательно сказаться на производительности. Научитесь менять log level'a на лету, что позволит исследовать проблемы в момент их появления.
- SSL можно использовать не только для шифрования. Переход от ключей к сертификатам позволит организовать авторизацию и аутентификацию компонент в инфраструктуре.
- Linux-сисадмины скажут спасибо, если конфиги будут в /etc/myapp, логи в /var/log/myapp и т.д. Другими словами, храните файлы в общепринятых для OS директориях.
- Любой лог-файл потенциально может бесконтрольно вырасти. На стадии проектирования планируйте жизненный цикл лог-файлов и данных, которые они содержат.
- Настройте мониторинг всех компонентов, используя удобный сервис. Далее приготовьтесь его улучшать, чтобы не просыпаться по ночам от незначительных срабатываний.
- Создайте календарь с датами истечения срока использования сертификатов, подписок, ключей. Иначе «что-то перестанет работать» совершенно неожиданно.
- Перед тем, как улучшать производительность, изучите, как правильно выбрать метрики и что такое throughput и latency.
- Сервис должен выбирать тот объем данных, который он сможет корректно обработать. Иначе запрос,
update users set halyava_end_date='2016-01-01'
Rows matched: 300000 Changed: 300000 Warnings: 0
выполненный в начале декабря, может обернуться сюрпризом:
2016-01-01 00:00:00 Mail service is trying to send 300 000 email…
2016-01-01 00:00:01 Out of memory error
- Клиентские приложения должны корректно отрабатывать ситуацию, когда сервис перегружен или недоступен. Каждую последующую попытку соединиться выбирайте с увеличивающимся интервалом с элементами случайности. Иначе взлет после обновления/падения будет тяжелым.
- Серверу приложений история миграций ни к чему, лучше уметь надежно и быстро накатить его с чистого листа.
- Точно указывайте версии сторонних библиотек. Смена минорной версии может сломать все. Не используйте библиотеки из публичных репозиториев автоматически.
- Если не знаете, где искать ошибку, поищите ее сначала в сериализаторах, потом в десериализаторах.
- Пока для хранения и обработки дат можно использовать unix timestamp, лучше использовать unix timestamp.
- Скорость работы — это свойство продукта, которое может дорого стоить, но при этом быть не нужным.
- Распределенные системы хранения либо неконсистентны, либо тормозят, либо и то, и другое.
- Любая очередь — это инструмент мониторинга. Количество элементов в очереди, скорость их поступления и обработки могут прояснить происходящее в системе.
- Преждевременное избавление кода от копипасты — это преждевременная оптимизация.
- Если ты делаешь лишнюю операцию, то неважно, насколько быстро ты ее делаешь.
В комментариях готовы ответить на более конкретные вопросы. Кроме того, всю эту неделю я буду вести Твиттер бэкенд-разработчиков @backendsecret — http://bit.ly/20mJ9GP — где тоже буду рассказывать о полезном и отвечать на вопросы.
Комментарии (36)
Musia17
02.11.2015 11:55+4За пункты 5-6 не удержалась и вбросила ссыль на эту статью моим коллегам-разработчикам из-за которых мы уже год
компостируем себе мозгиизучаем на живом проекте OrientDB и Kafka. Там сейчас такое началось… :)
alekciy
02.11.2015 12:02+2Поясните п.1. Не очень понятна ситуация и пути выхода.
yamschik
02.11.2015 12:17+3Например: есть у вас myapp.myhost.com с которого nginx тянет статику и на котором живет backend API, используемое отображаемой страницой. Далее вы разрабатываете внутренний сервис, который использует вышеупомянутое API и из нежелания усложнять конфигурацию/пинать админов/и т.д. для вызовов используете адрес myapp.myhost.com. В час Х на перед доменом ставят CDN для ускорения загрузки страниц и все, что обращается на myapp.myhost.com начинает ходить через CDN со всеми вытекающими отсюда спецэффектами. По нашему мнению, самый простой вариант не создавать проблему — завести что-то типа origin.myapp.myhost.com и внутренние сервисы направлять на этот адрес.
lexore
02.11.2015 18:47+1Сходу, пару ситуаций:
1. Вы хотите послать запрос к приложению, а он приходит на CDN и не доходит до бекенда.
2. CDN начнет обновляться с CDN. Эпичность последствий, я думаю, вы можете вообразить.
kamazee
02.11.2015 13:05+1Linux-сисадмины скажут спасибо, если конфиги будут в /etc/myapp, логи в /var/log/myapp и т.д. Другими словами, храните файлы в общепринятых для OS директориях.
Любой лог-файл потенциально может бесконтрольно вырасти. На стадии проектирования планируйте жизненный цикл лог-файлов и данных, которые они содержат.
Мне кажется, в качестве еще более интересной практики можно продвигать использование уже готовых инструментов для сбора/записи/маршрутизации логов (начать можно просто с записи в syslog) — тогда сисадмины сами выберут, куда им складывать файлы (если вообще записывать логи в текстовые файлы), а разработчикам не придется в который раз изобретать ротацию и, возможно, инструменты для работы с самими логами.yamschik
02.11.2015 13:12+4Логи своих приложений — это пограничная зона ответственности. Когда удается договориться с админами — они ими рулят используя стандартные средства, когда нет — приходится познавать дзен.
Gendalph
02.11.2015 15:27+1Позвольте вставить свои 5 копеек как сисадмин: есть такая штуковина как FHS и PREFIX
FHS (Filesystem Hierarchy Standard) описывает что и куда складывать.
PREFIX — обычно передается configure-скрипту, чтобы указать кда положить всё дерево директорий, прописанное FHS.
Что это дает в сумме?
Вот вы ставите, скажем, nginx 1.9.5. По FHS он должен попасть в /usr/local, указываете ./configure --prefix=/usr/local и вуаля — он в /usr/local, логи в /usr/local/var/log и так далее.
prefix=/ только для того что ставится из пакетов (будь то deb, rpm или еще что).
С другой стороны, вы можете скачать свои сорцы в /usr/local/src/myapp собрать там и сделать checkinstall -D (или для rpm ключик заюзать) и ваша софтина теперь имеет право встать в /, а не в /usr/local. И сносится она легко — dpkg -r myapp
По логам — лично я считаю что лучше в syslog не писать. Пишите в $PREFIX/var/log/myapp/$instance.log, а админы уже прикрутят туда logcheck/logrotate, НО это лично моё мнение и я пока не рулил массово облаками, на уровне руления облаком всё может быть иначе (сбор логов, все дела).lexore
02.11.2015 18:43По логам — лично я считаю что лучше в syslog не писать.
Почему, если не секрет?
Пишите в $PREFIX/var/log/myapp/$instance.log
Не забывайте, что access_log на 300 rps — это 300 записей на диск в секунду.Gendalph
02.11.2015 18:53Почему, если не секрет?
С одной стороны, когда всё в одном месте — проще смотреть что происходило вообще.
На практике же syslog становится такой мусоркой, что без grep'а его смотреть невозможно.
Возможно с приходом systemd/journald и возможностью выбора что смотрет будет легче, но в продакшене Ubuntu 14.04, которая этого лишена напрочь.
Не забывайте, что access_log на 300 rps — это 300 записей на диск в секунду.
Опять-таки, зависит от того что вы пишете, чем и куда.
Например, в nginx можно не писать запросы на получение статики, а всё остальное писать через буфер — и вот 300 rps уже совсем не 300 wps.
С другой стороны, можно начать выдумывать костыли из разряда записи на отдельный диск (или сервер, особые извращенцы могут писать на tmpfs с ротацией лога по размеру в постоянное хранилище).
Да и симлинки никто не отменял — сделайте приложению симлинк в удобное вам место и пускай себе пишет.lexore
02.11.2015 19:00+3Для nginx — да, но мы тут больше говорим про приложения собственной разработки.
syslog — очень гибкая система, которая не ограничивается записью логов в /var/log/messages.
syslog позволяет:
— иметь отдельные правила для каждого приложения
— передать логи по сети на отдельный log сервер;
— сохранять их по папочкам, в зависимости от имени хоста и приложения.
Например:
/$host/$service/$day.log
Помнится, я даже делал разделение по дням и часам:
/$host/$service/$year/$month/$day/$hour.log
В современных дистрибутивах давно стоят rsyslogd и syslog-ng, которые это умеют.Gendalph
02.11.2015 19:13Я как-то не задумывался над этим.
В таком случае да, вы правы.yamschik
02.11.2015 20:47Мы тоже прошли похожий путь размышлений и в итоге в некоторых компонентах сделали управляемый извне уровень логгирования. По умолчанию в логи пишем только критические ошибки, но из админки можно переключить на более детальный, что позволяет более подробно изучать проблему не забивая попусту диск. Цена вопроса — изучение в деталях log4j и 100 строк кода
seriyPS
02.11.2015 15:28-2Пока для хранения и обработки дат можно использовать unix timestamp, лучше использовать unix timestamp.
Сомнительный совет как по мне.
ReklatsMasters
02.11.2015 21:45> Включайте опцию log slow queries на СУБД
Это создаст избыточное логирование. Мне кажется, если запросы более-менее постоянны, то можно (нужно) протестировать с помощью explain, а потом пускать в прод.yamschik
02.11.2015 22:14Как правило постоянны те запросы, которые написаны вручную. Если общение идет через ORM + проект развивается и местами рефакторится, то за полетом фантазии в составлении SQL запросов на всех уровнях не уследишь. А проблемными как правило оказываются единицы.
Gendalph
03.11.2015 01:14Я бы сказал так: включайте все slow-log'и, пока это не приводит к существенной деградации.
В одном случае у нас при включении slow-log'а крашились воркеры FPM, в другой — я открыл глаза разработчику на причину необъяснимых тормозов сайта (раз из пяти TTFB >5 секунд, причем проблема явно где-то коде сайта).yamschik
03.11.2015 10:20Согласен, каждый инструмент — это палка о двух концах. Если бездумно применять то можно только навредить. У нас ситуации когда включение slow log чего то ломало или тормозило как-то не наблюдалось.
VolCh
05.11.2015 10:42Как правило, log slow queries имеют настраиваемый порог срабатывания, можно добиться логирования только действительно аномально медленных запросов. А если он может устанавливаться на уровне сессии, то настраивать логирование можно хоть на уровне отдельных запросов: этот запрос логировать, если выполняется больше секунды, а этот — если больше 3-х часов.
VolCh
02.11.2015 23:03Linux-сисадмины скажут спасибо, если конфиги будут в /etc/myapp, логи в /var/log/myapp и т.д.
Не факт. Некоторые предпочитают, чтобы приложение лежало в одном каталоге. Особенно когда действует принцип «один-сервер — одно приложение».Gendalph
03.11.2015 01:15Это уже обсуждалось, выше: habrahabr.ru/company/parallels/blog/269927/#comment_8637989
xenohunter
Всё, кроме, пожалуй, 26 пункта — плюсую. Спасибо, утащил в сокровищницу!
Funbit
Да, 26-й пункт стоит однозначно убрать.
kolyaflash
Или добавить пояснение. Я могу представить такие ситуации, в которых этот пункт справедлив.
Funbit
Единственное оправданное применение «копипасты» — это одноразовый скрипт, который перестает быть полезен и удаляется сразу после использования. Но это как-то выходит за рамки темы «Чему мы научились, разрабатывая backend»…
Newbilius
Могу добавить пример: если у вас появилась в двух местах кода копипаста, это плохо, но он неё как правило можно избавиться множеством способов, которые потом усложнят её использовать в третьем месте. А вот как только эта копипаста расползлась по 3-4 местам, тогда можно убивать её более спокойно. Обычно ведь под копипастой имеется ввиду не абсолютно идентичные копии кода, а чуть-чуть отличающиеся. Обобщить слишком рано — усложнить доделки потом.
Аналогия: убивать копипасту слишком ранр — это как при появлении температуры тут же принимать жаропонижающее, вместо того, что бы изучить причины. Но и обратно, есть ситуации когда сбивать температуру нужно сразу, иначе пациент не доживёт до этапа анализа. (да, я только что из больницы :-( ).
Funbit
Мне кажется, вы приравниваете копипасту к преждевременной оптимизации. Вот последняя — да, на раннем этапе ни к чему хорошему не приведёт. А копипаста — совсем другое дело. Её главное опасное свойство — неконтролируемое размножение. Где есть 3 копипасты и «всё работает», тут же возникает желание добавить еще парочку, ну работает же, подумаешь, скопирую еще разок и всё, и рабочий день на полчасика короче… А потом люди боятся рефакторить чужой код (а некоторые и свой), т.к. боятся что-то испортить. В итоге со временем рефакторинг становится практически невозможным.
В общем, на мой взгляд преждевременная оптимизация и копипаста (или плохой дизайн) — это совсем не одно и то же.
VolCh
Единственное оправданное применение копипасты — красные тесты.
kamazee
Прежде, чем добавлять какой-то уровень абстракции, хорошо бы получить работающий (и покрытый тестами) Proof of Concept, а уже после, видя более-менее полную картину, избавляться от нее более осознанно, чем в самом начале.
kmmbvnr
Поддерживаю, бездумное избавление от копипасты, хуже самой копипасты.