Pull to refresh

Comments 69

Добрый день. Вопрос по тестам в php. Используете вы приемочные и функциональные тесты. Я так понимаю SoftMocks только для Unit-тестов? Ну и с таким большим кол-вом unit-тестов, можете ли что порекомендовать по структуре тестов. Как их правильно разложить. И второй вопрос по тестированию базы. Вы используете фикстуры? Или накатывается какая-то тестовая база через миграции?
Это сразу пяток хороших, больших вопросов :) Попробую ответить.

1. Приемочный и функциональные тесты у нас есть, мы их используем и автоматизировали, насколько это возможно. Приемочные тесты у нас — это селениум для веба и мобильного веба + свои автотесты для мобильных клиентов. Как это работает.

— Если на тестирование приходит новая фича: проверяем ее руками (возможно, выкладываем на прод с несколькими а/б тестами) -> фича дорабатывается, устаканивается описание, выбирается лучший дизайн/набор функций/текст из а/б тестов -> создаем задачу на написание к ней селениум-тестов -> собственно, пишем тесты
— Если на тестирование приходит улучшение старого функционала/изменение существующей страницы (дизайн, расположение элементов, whatever): проверяем задачу руками, параллельно в этой же git-ветке правятся/дорабатываются селениум-тесты. Либо, если задача срочная, то проверяем только руками, а параллельно ставим задачу на правку/доработку селениум-тестов; такая задача также получает максимальный приоритет.

2. Функциональными тестами у нас являются и юнит-тесты, и интеграционные тесты. В интеграционных проверяем взаимодействие кода с БД и различными внутренними сервисами (демонами) на C/C++/Go. Там же — проверяем взаимодействие серверной части кода с клиентами (клиенты при этом тоже мокаются).

3. SoftMocks используются только для юнит-тестов, да. В других местах они могут быть вредны.

4. С таким количеством юнит-тестов по структуре можно порекомендовать только одно: пишите тестируемый код :) Тогда и огромное количество тестов будет пробегать за считанные минуты. У нас ситуация чуть сложнее — юнит-тесты стали массово писать, когда кодовая база уже успела сильно разрастись. Приходится ухищряться :)

Например, в некоторых не совсем юнит-тестах у нас есть запросы к БД. Но! В тестах реализована заглушка: если из теста идет запрос к реальной БД, то вместо настоящей запрашиваемой таблички создается временная с такой же структурой, которая наполняется тестовыми данными и по окончании теста удаляется. Таблицы такие создаются в tmpfs, поэтому на скорость выполнения тестов влияют меньше, чем могли бы (хотя это тоже сильно сказывается на времени их прохождения).

Еще тесты у нас разбиваются на микросьюты и запускаются в облаке (подробнее, почему так, можно почитать тут: Переход на PHP 5.5 и юнит-тесты).

5. Про тестирование баз не совсем понял. Если имеется ввиду проверка взаимодействия кода с базой, то у нас есть и фикстуры, и обращения к «реальным» (на самом деле тоже замоканым временным) базам. Например, фикстуру для самого популярного объекта User мы генерим автоматически на основе текущей эталонной структуры БД, складываем ее в файл на всех серваках, где гоняются тесты, и подключаем инклюдом.

Если вопрос понял не правильно, то предлагаю продолжить дискуссию ниже :)
Вы все правильно поняли, спасибо за развернутый ответ. Еще такой вопрос, вы метрики используете по тестированию, условно чтобы coverage был >90%? Я так понял вы не сразу стали писать тесты, каков сейчас процент покрытия?
Метрики используем, стараемся держать покрытие всего проекта не ниже 50%. Какие-то части кода (например, биллинг или критичные части платформы) покрыты тестами практически полностью, какие-то — (старые скрипты, страницы, всякие геттеры/сеттеры) могут быть не покрыты вообще. Цель «повысить coverage до заветных 50%» ставилась перед руководителями команд разработки, coverage повышался постепенно. Добились такого результата примерно за год-полтора.
У вас была отдельная команда, которая этим занималась в течении полутора лет? Может у вас есть отдел чисто под написание тестов?
Лучше разработчика, написавшего какой-то код, этот код может знать только разработчик, который его поддерживает :) Поэтому и юнит-тесты к проекту писались силами самих разработчиков. Конечно, проект поделен на условные «подпроекты» (или области ответственности), каждый файл в проекте закреплен за одним или несколькими maintainer'ами, а также за определенной командой.

Статистика по coverage'у, помимо прочего, показывает код какой команды в какой степени покрыт юнит-тестами. Ну а так как задача на покрытие проекта тестами ставилась непосредственно руководителям различных команд разработчиков (и прогресс в достижении цели оценивался каджый квартал), то в их интересах было сделать так, чтобы у разработчиков было и время, и желание эти тесты писать. Поэтому 1) coverage поднимали плавно, не ломая сильно основного процесса разработки, но и не останавливая покрытие; 2) отдельной команды автоматизаторов не было.

Из полезных рецептов: сначала завели практику покрывать юнит-тестами все новые фичи (без этого задача не проходит code review). Если задача срочнаая, то, как и в случае с селениум-тестами, код выезжает на прод, но параллельно в баг-трекере создается задача на написание юнит-тестов к новому коду (которая также имеет высший приоритет). Потом потихонечку ставились отдельные задачи на покрытие тестами (и местами попутный рефакторинг для возможности покрытия тестами) старого кода.
Привет! У меня вопросы по Cassandra. Будет ли ваше решение в opensource? Сравнивали с новомодным ClickHouse? Кластер Cassandra внутри одного ДЦ? Если нет то как решали проблему линка между ДЦ?
Спасибо.
В текущем виде решение в opensource не готово, но мы планируем прийти к этому.
С ClickHouse не сравнивали, он вышел после того как мы запустили наш прототип.
Кластер Cassandra у нас в одном ДЦ.
Насчет opensource: пока не готовы, т.к. чувствуем, что надо бы огрести побольше боли и накопить опыта эксплуатации в разных сценариях. Например у нас в CTS сейчас едут в основном около-продуктовые данные. Хотим построить второй кластер — для технических метрик (времена ответов сервисов/баз/etc, потребление ресурсов, и т.п.). Там будет примерно столько же данных.
Плюс — java мир для нас не совсем пока родной и мы только учимся, например, понимать и тюнить JVM, развиваем/изучаем инструменты.

Clickhouse выглядит интересно, но нас довольно мало и мы пока не готовы быть «early adopters”, хотим подождать пока вырастет community, чтобы потом прильнуть к знанию великого all.
Данные, которые сейчас в CTS, едут из двух DC в один, у нас есть «гарантированный» линк между ними (сколько-то сотен мегабит), плюс — естественно — публичный интернет (ну трафик шифрованный, да :) ).

О проблеме линка между DC — что вы имеете в виду?
Я имел ввиду не клиентов кластера, а непосредственно сами машинки кластера. Обычно кластер размазанный по разным ДЦ начинает лагать от сетевых задержек между нодами из разных ДЦ. Не скажу про Cassandra, но на мускуле весьма острая проблема. Было собственно интересно, есть ли у вас проблемы и как вы их решали.
Понял. Кластер в одном DC с RF = 2 на данный момент, в разных стойках, вот это все.
А пишете/читаете с кворумом или как?

> выход из строя одной ноды в кластере не блокирует ни чтение, ни запись
Как это работает при RF=2?

Ну и вот это уж тоже как всё-таки на самом деле, то
> около 200 000 значений в секунду
или
> 100 000 значений в секунду; 140 миллионов метрик.
> А пишете/читаете с кворумом или как?
— сырые данные пишем с кворумом, но с DowngradingConsistency RetryPolicy
— ролапы пишем с CL = ALL
— читаем с CL = ONE

>> выход из строя одной ноды в кластере не блокирует ни чтение, ни запись
> Как это работает при RF=2?
Сырые данные пытаемся записать во все живые ноды, но если не получается, то в одну. Для time series мы сочли это приемлемым.

>Ну и вот это уж тоже как всё-таки на самом деле, то
>> около 200 000 значений в секунду
>или
>> 100 000 значений в секунду; 140 миллионов метрик.
Текущий поток данных 100к в секунду но справляемся и с более чем 200к
День добрый! Возможно вопрос не в тему, но я всё таки спрошу:
Почему после удаления платёжной карты из аккаунта — система продолжает проводить списания с (уже удалённой) карты?
С этим вопросом тебе поможет саппорт: https://eu1.badoo.com/help/, а не разработчики Платформы.
Добрый день.
1. Почему go а не nodejs? Ведь nodejs ближе должен быть так как все php разработчики сталкивались с javascript
2. Видите ли вы в перспективе полную замену php на go?
Привет!

Go появился в Badoo из C/C++ команды, а не PHP команды. А нам сишникам как раз ближе Go. Уже после этого Go начали использовать и те люди, которые большую часть времени используют PHP.

Но, в любом случае, я не думаю что похожесть — это сильная причина. Кто-то ищет такой язык, который не похож на его основной язык. Таким образом он сможет решать большее количество разных задач.

Go, например, в отличие от nodejs или PHP, дает строгую типизацию. Для тех кто всю жизнь использовал не строгую, строгая может оказаться тем самым, что им всегда не хватало.

А вообще стыдно вам должно быть за такой вопрос! :-)

Я вот даже сохранил себе цитату, т.к. очень часто ее приходится вспоминать:

A great way to end the conversation early and avoid learning anything is to ask questions like:
— Why aren't you using Y?
— You should be using Z! (this isn't a question)


Go классный, няшный, интересный. Он активно развивается, но развивается с осторожность, не распыляясь налево и направо. И он позволяет нам быстро и эффективно решать наши задачи.
Быстро и качественно решенные задачи — плюс для бизнеса, няшность и интересность — плюс для разработчика.

Что касается полного ухода с PHP на Go, то ответ однозначный — нет.

Те задачи что решаются на ПХП решаются им прекрасно. Да, многие ворочают нос от ПХП, но это инструмент, который очень долгое время нас не подводил. Мы знаем как его готовить, у нас десятки и десятки людей, которые пишут на нем и миллионы и миллионы строк кода, написанных на нем.

Бонусы полного перехода на что-то иное (даже на Го) слишком призрачны.

Но, с другой стороны, я думаю что кол-во Go кода будет однозначно расти. И какие-то ПХП-шные части могут быть на нем переписаны.
Ну мы уже умеем писать single-threaded софт поверх event loop с callback hell :) (хотя, насколько я знаю, с promise и подобными техниками — все уже не так больно).

Киллер фича Go — она ведь в «нормальной» concurrency, встроенной в язык.

В nodejs можно, полагаю, нарожать много процессов и таким образом заюзать все ресурсы железа, но возникает вопрос — а как хранить состояние, которое нужно всем? (например, в одной из наших задач — полтора миллиарда координат пользователей для near-realtime обработки и фильтрации).

С Promise совсем не больно, а даже приятно, нужно лишь один раз проникнуться. Один раз попробуете не захотите писать синхронный код больше никогда :-)
Нарожать кучу нормальных процессов — это разве не задача erlang/elixir? Не намекаю на то, что go плохой выбор, лишь интересны положительные/отрицательные стороны того и другого языка.
ну в данном случае имелись в виду os-level процессы, как средство одним nodejs приложением заюзать много cpu.

насколько я знаком с erlang elixir — тамошние процессы скорее ближе как раз к goroutines, в том смысле, что ими управляет рантайм и каким-то образом их выполняет на os-level threads/processes.
И насчет полной замены PHP на Go.

В вакууме — это вполне возможно, и насколько я знаю, в некоторых компаниях «Go микросервисы» смотрят во внешний мир, делают бизнес логику и отдают «странички» клиентам.
Был, например, доклад, упоминавший об этом на недавнем Highload.

В случае же Badoo — это не думаю, что нужно (@mkevac об этом тоже писал), работает же хорошо :)
Да и мало реально — миллионы строк уже написаны и работают, крутые и умные коллеги работают, инструменты и тестирование построены. Было бы контрпродуктивно это менять.
Доброго времени суток

планируете ли вы опенсорсить вашу систему интеграции между git, youtrack и билд системами с фичебранчами??
Привет. Я так понял речь про AIDA. Как вы правильно заметили эта система осуществляет интеграцию между многими компонентами в Badoo и она сильно завязана на наших процессах. Поэтому, к сожалению, в текущей её реализации, AIDA не универсальна и мы не можем опубликовать код в Open source.
да, я имею ввиду именно AIDA
На чем это написано на Go или на PHP?
я правильно понимаю что AIDA это какой то монолитный инструмент, который через web-hooks интегрирован с остальными системами (JIRA, GIT, TeamCity) через их стандартный API и невозможность вытащить это в Open-source обсуловлена тем что там всякие пароли и настройки с ключами чуть ли не в коде прописаны??
На чем это написано на Go или на PHP?

PHP
я правильно понимаю что AIDA это какой то монолитный инструмент

Скорее да, чем нет. Код находится в одном репозитории и деплоится он везде одинаково.
который через web-hooks интегрирован с остальными системами (JIRA, GIT, TeamCity) через их стандартный API

Если говорить именно про взаимодействие с вышеупомянутыми инструментами, то да. Но кроме этого в AIDA есть еще много логики поддерживающей наш процесс разработки, автоматизации и т.д. 

и невозможность вытащить это в Open-source обсуловлена тем что там всякие пароли и настройки с ключами чуть ли не в коде прописаны??

Дело не в приватности настроек, а том, что, повторюсь, AIDA завязана на наши процессы и не универсальна.
Дело не в приватности настроек, а том, что, повторюсь, AIDA завязана на наши процессы и не универсальна.


ну вот мне нравится именно ВАШ процесс =)
скажем если бы можно было настроить свой запуск тестов, свои вебхуки с jira и gitlab
и вместо teamcity

ну я так понимаю что просто куча модулей есть которые конкретно на инфраструктуру завязаны (типа выкатки .shot и т.п.)

эххх… жаль
Несколько вопросов.

0. А чего схему не показали?
1. Вы храните преагрегаты (min, max, mean и т.д.), типа ролапов или сырые данные? Если сырые, где и чем вычисляете агрегаты?
2. Что является ключом партишина? Сколько строк в партишине?
3. Какие запросы делаете? Если ли функционала, который комбинирует результаты нескольких партишинов?
4. Какая compaction strategy используется? DateTieredCompactionStrategy?
5. Используете ли SASI-индексы?
Подробное описание не уместилось бы в текущий формат, поэтому мы готовим полноценную статью на эту тему.

Если кратко по вашим вопросам:

1. Храним последнюю неделю сырых данных, остальные перекладываем в ролапы. Поддерживаются разные агрегирующие функции, но используем пока только AVG. Все вычисляется на php.

2. Сырые данные партицируются по идентификатору метрики и левой границе периода (сутки). Данные для разных метрик поступают с разной периодичностью, минимальная — раз в минуту. Так что, по факту, размер партиции от 1440 строк и меньше. Но есть и сильно разреженные метрики.

Если говорить про ролапы, то сейчас одна партиция — один архив. У метрики может быть несколько архивов. Размер зависит от retention и детализации.

3. Все верно, при запросе данных возвращается результат объединения партиций. А именно, данные из подходящего ролапа + сырые данные свернутые с такой же детализацией и агрегирующей функцией как и выбранный архив.

4. DateTieredCompactionStrategy — сейчас является depricated. Он заменен на TWCS. Но и от него мы отказались в пользу обычного STCS, в первую очередь потому что данные мы удаляем при перекладывании в ролапы, а не при помощи TTL. Да, требуется еженедельный major compaction.

5. Не используем, есть мнение что SASI-индексы пока не достаточно стабильные.
Расскажите про юнит тестирование Go демонов.
Если мокаете то чем, на сколько заморачиваетесь распараллеливанием тестов, какие соглашиения по наименованию и оформлению тестов, используете ли какие сторониие пакеты для тестов, и все такое.

Ну и если что онтересное останется — расскажите про интеграционные тесты Go.
Мне немного стыдно, но у нас для Go практически нет юнит тестов.

Мы, команда сишников, привыкли к тому что писать на Си юнит тесты сложно. Возможно, но требует настолько много усилий, что мы не видим в этом профита. Мы привыкли полагаться на свои небольшие функциональные/smoke тесты, написанные на Python и на полноценные подробные функциональные тесты, которые пишет наш отдел тестирования на PHP.

И вот эта вот привычка перешла на Go и мы пока не уделили этому должного внимания, чтобы ее перебороть. Все так же полагаемся на функциональные тесты, написанные отделом тестирования.

Хочу заметить что в Go довольно развиты инструменты для рефакторинга. И вот эти инструменты вместе с строгой типизацией позволяют вам быть более уверенными в правильности кода при рефакторинге. А ведь именно для этого часто пишут юнит тесты, так ведь?..

Интеграционные\функциональные тесты, как я уже написал, пишет отдел тестирования. Мы постарались сделать так, что демон на Go извне никак не отличается от демона на Си. Те же протоколы, те же конфиги, все то же самое. Так что отдел тестирования зачастую даже не задумывается о том, на чем написана система.
Возможно немного не формат :)
Порекомендуете инструменты / пакеты / подходы к unit-тестированию в Go, чтобы у вас научиться, когда этим плотно займемся?
Спасибо.
Мы сейчас утаскиваем много кишочков PHP в GO, в PHP тестов почти небыло.
Но немного приложив силу воли мы заимели довольно хорошее покрытие в GO.

Про юниты:
Начиная с 1.7 страндартная библиотека научилась всему что было в сторонних библиотеках и похоже что кроме нее ничего и не нужно, за исключением моков.
библиотеки для моков плохи все — но победил https://github.com/golang/mock как наименьшее зло — наименее увеличивающее размер каждого теста
для интерфейса типа Reader можно и ручками сделать stub, но как-то в реальных приложениях интерфейсы жирнеют сколько не дроби.

Мы используем http://labix.org/gocheck, но похоже теперь можно и на стандартную либу съезжать.

Бывает полезно гонять параллельно(t.Parallel) один тест много раз — чтобы понять что код thread-safe
За variable shadowing следит gometalinter, поэтому на эти проблемы тестов не делаем.

Файлики юнитов ложим прям рядом с файликами кода — и я считаю это абсолютно гениальным и удобным.

В Файлике с тестами можно использовать специальное название пакета my_package_test — тогда тесты будут думать что находятся в другом пакете от кода и тестировать его извне, хотя файлики тестов продолжат лежать рядом с кодом. Это редко нужно, но бывает + есть любители писать тесты не имея доступа к привату.
Вот тут есть хороший доклад по тестированию в Go https://www.youtube.com/watch?v=yszygk1cpEc
Отвечу про интеграционные тесты.
У нас есть devel окружение, на котором постоянно гоняются функциональные (веб, мобайл) тесты. Новые версии демонов заливаются на devel и становится сразу понятно сломана интеграция или нет — в случае чего начнут падать тесты.
Если интересен процесс «разработка\тестирование», то он ничем не отличается от любого другого демона — можно подсмотреть в статье https://habrahabr.ru/company/badoo/blog/254087/.
Может уже где то было, но я все таки уточню:
1. Та часть что на PHP у вас оформлена как мегаприложение или вы дробите все на части? По какому принципу дробите, есть ли какие то общие правила
2. Есть ли у вас какие то процедуры по борьбе с техническим долгом? ну например субботники чистки кода раз в месяц.
Привет!
1. Довольно большая часть нашего кода — это обертки над сервисами и базами, API для работы с очередями или фотографиями и тому подобное. Все это используется другими отделами и поэтому не может быть отдельным приложением. Практически весь PHP код находится в общем репозитории и использует некоторые общие куски кода. Поэтому, наверно можно сказать, что все оформлено как мегоприложение.

2. Мы стараемся планировать работы по техдолгу в общем пуле задач. Каких то конкретных критериев нет. Просто в какой то момент понемаем, что сейчас можно заняться задачами из беклога и тратим на них n человеко-недель.
Тогда еще такой небольшой вопросец: имеют ли разработчики у себя полностью работоспособную версию сайта? или обычно они работают с какой то жестко обрезанной копией сайта. Есть ли возможность запустить все тесты локально? или без инфраструктуры уже ничего сделать нельзя.
Да, у каждого разработчика есть своя «песочница» на специальным devel кластере.
Мы стараемся поддеживать на нем такую же инфраструктуру как и на продакшене. Там так же есть эмуляция нескольких ДЦ и все сервисы которые есть в боевом окружении. Мы внимательно следим за devel площадкой и даже мониторинг работает примерно так же.
Все тесты запусаются так же в этом окружении и для ускорения времени их выполнения (прогон всех 75тысяч юнит тестов занимает около минуты) мы запускаем тесты паралельно на специальном кластере машин.
ну а прогон тестов локально на машине разработчика возможен? как он например может отладить тест?
Да, конечно, конкретный тест или какой то сьют можно запустить локально и спокойно отлаживаться.

Под локальным я имею ввиду зайти по SSH на devel машину и запустить там тест.

demiurg@www1.d3:~/badoo $ phpunit UTests/_packages/Platform/PlatformEnvironmentTest.php
PHPUnit 5.3.2-a by Sebastian Bergmann and contributors.

............ 12 / 12 (100%)

Time: 667 ms, Memory: 32.00MB

OK (12 tests, 147 assertions)



Настроить окружение на своем ноутбуке и писать код без доступа к devel площадке — задача нетривиальная.
Как организована «песочница»? Это docker контейнеры, и у каждого разработчика свой собственный неперсекающийся набор контейнеров?
Песочница это просто папка с репозиторием в хоуме у разработчика на devel сервере.
Нас это пока вполне устраивает, до докера в данном месте мы пока не дошли, возможно в будущем докер окажется удобнее.
В дополнение к demi_urg

Есть такая штука как cppteam/ateam ideas.
Это просто документ, куда скидываются достаточно слабо структурированные идеи — что можно улучшить и где надо бы допилить.
Крупными мазками там также лежит техдолг, вида «нужно вот эту подсистему в будущем переделать, т.к. нам это понадобится для внедрения фичи X» или «я чувствую, что это заболит через какое-то время».

Оттуда мы черпаем в том числе задачи, когда планируем большие цели на следующий квартал. Оформляем их прилично, конечно.

Процедур особых нет, просто стараемся, чтобы работа по техдолгу / текущим «допилам» была где-то в пределах 20-40% времени на разработчика, не больше.

Добрй день!
У меня вопрос по мониторингу. Что вы используете как агенты? Что для навигации и отображения TS данных? Развивали на базе цианита (http://cyanite.io/) над кассандрой или что?

На Cyanite наше решение похоже мало. Только, пожалуй, тем что это тоже time series на Cassandra. Кроме этого мы смотрели и http://blueflood.io/ и http://opennms.github.io/newts/
Но вдохновлялись мы больше, как это ни странно, rrdtool который, кстати, мы пока тоже продолжаем использовать.
Как у нас устроен сбор данных тема довольно объемная. Если отвечать кратко, то по разному :)

Например, у нас есть целый отдел мониторинга и один из инструментов которым они пользуются является zabbix. К сожалению, я не могу рассказать более подробно, потому как не знаю всех нюансов.

Множество технических и бизнес метрик собирают для себя сами разработчики. Что бы следить за состоянием своей части приложения и понимать что происходит.
Каким образом:
— Очень много метрик мы получаем из Pinba.
— Большую часть данных отправляем прям из приложения и собираем при помощи LSD (см. раздел статьи LSD: Live Streaming Daemon).
— Если говорить про c/go сервисы, каждый сервис написанный у нас предоставляет довольно подробную информацию о своем состоянии.

А уже непосредственно за перекладывание данных в time series хранилище, а так же за навигацию и отображение отвечает наш собственный фреймворк (конечно же на php)

Спасибо, в целом я понял. Как минимум не посмотрев поближе вопросов не имею :)

Мы уже анонсировали чуть выше, что планируем описать наше решение подробнее в полноценной статье.
Хочу сказать еще немного про сбор данных. Поскольку в нашей компании паттерн использования LSD + time series фреймворк практически один, ребята из нашего отдела написали решение, которое не только автоматизирует этот процесс, но и добавили туда несколько просто офигенных фич.

Так что разработчику достаточно расставить в коде в нужных местах отправку события с вложенной в него структурой данных, и, например, сразу же иметь возможность видеть на дашборде графики, скажем, с количеством уникальных за сутки/час пользователей мужского пола из Парижа, к которым относится отправляемое событие. Внутри мы называет этот продукт Product Metrics, а его авторы выделились в отдельную команду Data-team. Они обещают подготовить для хабра отдельную статью про свое детище.

ага, я понял. Будем ждать вашу статью.

Как принимается решение о API демонов?(контракты)
Просто разработчик садится и делает как нравится или есть этап где показывается/аппрувится написанный на бумажке контракт(какие поля и в какой форме входят/выходят).
Есть ли какой-то SyleGuide как новые API должны выглядеть?

Вопрос мой пожалуй полуночно-сумбурен — понятно что есть стандартные хедеры, и с ними приходит некий protobuf, мне интересно то что внутри протобуфа.

Если говорить о демонах, то в тот момент когда от Feature команды приходит запрос о каком-то функционале, то мы договариваемся о том какие изменения в API понадобятся и делаем их. Тут все просто, т.к. стороны всего две.

Если говорить о взаимодейтсвии между четырмя мобильными командами (iOS, Android, Windows Mobile, Mobile Web), платформой, веб командой, то у нас есть отдельная небольшая выделенная команда, которая занимается только API. По одному участнику из вот этих вот команд. Их задача договориться со всеми, понять и предугадать все возможные проблемы, записать результат в документ. По этому документу будут дальше работать люди, реализующие задачи.

Но я сам далек от всего этого и от команды, рабтающей с API. Думаю что коллеги вам еще ответят более конкретно :-)
Думаю, что вопрос был всё-таки не про внешнее API, да и не наша сейчас вечеринка :–) Но если есть какие-то вопросы об этих вещах, то мы тоже всегда готовы рассказать.

Я рассказывал недавно об особенностях нашего внешнего API на девконфе, и у нас какое-то время назад была статья о том, что у нас внутри протобуфа и как мы это развиваем.
API демонов обычно довольно простые, и каких либо проблем с тем что где то сделали так, что пользоваться невозможно у нас не возникало. Единственное что у нас более менее унифицированно — это отдача статистики самом сервисом. И сделано это для того что бы не писать каждый раз сбор метрик.
Что у вас используется в качестве баз данных?
Используете ли хранимые процедуры или обходитесь без них?
Если есть хранимки то как происходит (и сколько длится по времени) накат обновлений?
Очень интересна тема шардирования. Можно ли кратко, по каким параметрам шардируетесь, какие алгоритмы используете, возможно какие-то opensource golang проекты применяете.
И еще, где всем любопытным можно еще вопросы позадавать помимо как здесь?
Старый добрый mysql, точнее percona server.
Хранимки не используем, ибо сложно (можно ли?) атомарно выкладывать как пхп-код, так и код хранимок.
В качестве шардированияя старый добрый virtual buckets, подробности можете найти в докладе нашего DBA.
В golang-разработке используется как минимум gogoprotobuf (быстрее чем стандартный гугловый, тут подробнее)
> И еще, где всем любопытным можно еще вопросы позадавать помимо как здесь?
задавайте здесь, не стесняйтесь.
Не могли бы вы рассказать подробнее про обработку фото (ресайз, наложение лого и тд). Какие библиотеки, фильтры используются?
Здравствуйте, если кратко, то сейчас схема такая:

При заливке фото нарезается несколько базовых типовых размеров (а-ля большой, средний, маленький)
в URL клиент явно указывает viewport, в который надо заресайзить картинку.

Дальше на nginx мы с помощью lua динамически выбираем для заданного viewport максимально близкий физический размер и делаем downscale из него на лету.
Помимо этого можно динамически накладывать фильтры — у нас это blur, pixelize и делать crop по координатам, которые переданы с клиента.

Также на все фотки на лету накладывается watermark, которым можно управлять через параметры URL.

Технически, мы и со стороны PHP и со стороны NGINX используем библиотеку http://www.leptonica.org
В обоих местах к ней написаны наши собственные биндинги (модуль к nginx и расширение к php)

Но сейчас есть множество готовых решений, которые дают похожий функционал из коробки.
Как в виде нативных модулей nginx, так и в связке с https://openresty.org/
Спасибо за развернутый ответ. А скажите, leptonica — почему выбрали ее?

Мне просто сейчас тоже надо выбрать инструмент как лучше даунскейлить фотки. Я провел множество разных тестов и у меня они показали, что downscale + Lanczos3 (который почти все предлагают по-умолчанию) работают одинаково медленно у всех кандидатов, libvips работает быстрее, так как видимо разбивает каждую фото на несколько частей и нагружает весь процессор, но в случае ресайза на сервере сразу нескольких фото это роли не играет. А если использовать более быстрый фильтр, где одна библиотека показывала преимущества перед другой, то фотографы сразу говорят «фу, мои фотки испорчены».

Но про leptonica слышу впревые. Вот мне и интересно, почему крупная компания выбрала leptonica? У нее есть какие-то преимущества перед более популярными библиотеками, к которым биндинги уже есть?
Артём немного перепутал, у нас в модуле для NGINX для операций с изображениями используется Intel Performance Primitives, а не Leptonica. У IPP сравнительно более сложный API, но она объективно работает быстрее той же лептоники, которую мы используем для аналогичных операций с изображениями в PHP.
Насколько быстрее — точно не помню, но процентов 25 было, если я не ошибаюсь.

Ранее у нас для всех операций с изображениями в PHP использовался ImageMagick. У него есть несколько безусловных плюсов: он тотально всеяден, там хорошая реализация bicubic interpolation, которая в итоге даёт очень приятный результат при ресайзе фотографий. Кроме того, ImageMagick — это такой Фотошоп под Линукс, там есть всё, что можно. Но у него есть один серьёзный минус — он ну очень медленный.

Изначально нам нужно было решить проблему — ресайз фото медленный. На тот момент (примерно 7 лет назад), Лептоника точно так же не очень была известна =), но с задачей ресайза справлялась примерно в два раза быстрее.
В процессе, как всегда, задача немного разрослась и теперь там не только ресайз, но и разнообразные операции над изображениями, но в Лептоника написана на понятном plain C и её патчить гораздо проще и приятнее, чем ImageMagick. Сейчас, возможно, есть какие-то другие библиотеки с аналогичным функционалом, но переходить на них будет уже сложнее из-за всяких кастомных вещей, которые мы добавили в Лептонику. В основном это функционал для генерации капчи, которая у нас выглядит примерно так:
image

Спасибо за дополнение. У меня в принципе та же проблема: ресайз фоток, который устраивает фотографов(bi-cubic подобным они сказали сразу нет, да я и сам вижу разницу), жутко медленный, причем одинаково медленный и в браузерах, и в остальных библиотеках, до которых у меня дотянулись руки и я сомневаюсь, что это вообще как-то возможно ускорить. Так что, наверное, выберу IM из-за популярности
У меня вопрос по счетчикам и другой связанной с ними информацией.

На сколько актуальными являются значения вроде «14541 человек в таком то городе», «451 человек сказали 'Да'» и т.п.?

Поддерживаете ли вы точное значение в данных счетчиках, или вам достаточно знать приблизительное число?

Если значения точны, то каким образом достигается консистентность между счетчиками и реальным количеством объектов, действий и т.д. и т.п.

спасибо
Привет!

Если я правильно понял вопрос, то вопрос о том, как считаются агригации по данным, которые расшардены по большому количеству сереров.
В целом схема такая: у нас есть специализированые сишные сервисы, которые хранят все нужные данные в памяти и умеют быстро считать что-то по нужным срезам. Для синхранизации этих данных с данными в шардах мы используем очереди. Когда интересующие нас данные меняются в шардах мы кидаем событие, все эти события приходят в общую очередь и апдейтят данные в сервисе. Сервис раз в какое то время перестраивает индексы. Таким образом задержка между реальными данными и «счетчиками» составляет несколько минут
Sign up to leave a comment.