Upload
ontico
View
378
Download
4
Embed Size (px)
Citation preview
(С) Дельгядо Филипп, ИТИС, 2016
О чем этот докладЧто такое платежные системы, какие сложности при их разработке
Как жить, когда много конкурирующих транзакций и сложная предметная область
Как строить и менять процесс разработки
Удачные и неудачные практики и решения
(С) Дельгядо Филипп, ИТИС, 2016
Основные вызовыСтарт проекта с нуля
Нет командыНет постановок
Высокие требования к проектуНадежностьПроизводительностьБезопасность
Сжатые сроки и ограниченный бюджет
Секретность
(С) Дельгядо Филипп, ИТИС, 20164
Проект1 большая комната
8 программистов
8 не только программистов
1 год
(С) Дельгядо Филипп, ИТИС, 2016
Платежные системыЧто сложного в платежных системах и как это сказывается на архитектуре проекта
(С) Дельгядо Филипп, ИТИС, 2016
Например115-ФЗ – О противодействии отмыванию доходов
161-ФЗ – О национальной платежной системе
152-ФЗ – О защите персональных данных
222-ФЗ – Об азартных играх
PCI DSS – О безопасности кредитных карт
И это далеко не все….
(С) Дельгядо Филипп, ИТИС, 2016
Требования к архитектуре
Очевидность кода и всех решенийКоманда активно развивается, некогда изучать.
(С) Дельгядо Филипп, ИТИС, 2016
Требования к архитектуре
Очевидность кода и всех решенийКоманда активно развивается, некогда изучать.
Простота code reviewИначе его никто не будет делать.
(С) Дельгядо Филипп, ИТИС, 2016
Требования к архитектуре
Очевидность кода и всех решенийКоманда активно развивается, некогда изучать.
Простота code reviewИначе его никто не будет делать.
Надежность решенияНельзя терять деньги.
(С) Дельгядо Филипп, ИТИС, 2016
Требования к архитектуре
Очевидность кода и всех решенийКоманда активно развивается, некогда изучать.
Простота code reviewИначе его никто не будет делать.
Надежность решенияНельзя терять деньги.
Высокая доступностьБез простоев, планируемых и непланируемых
(С) Дельгядо Филипп, ИТИС, 2016
Требования к архитектуре
Очевидность кода и всех решенийКоманда активно развивается, некогда изучать.
Простота code reviewИначе его никто не будет делать.
Надежность решенияНельзя терять деньги.
Высокая доступностьБез простоев, планируемых и непланируемых
Производительность
(С) Дельгядо Филипп, ИТИС, 2016
Принципы архитектуры
KISSKeep it simple, stupid
No magicНе доверяем сложным (особенно чужим) решениям
(С) Дельгядо Филипп, ИТИС, 2016
Принципы архитектуры
KISSKeep it simple, stupid
No magicНе доверяем сложным (особенно чужим) решениям
IDE driven developmentЕсли IDE не поддерживает фреймворк, то мы его не используем
(С) Дельгядо Филипп, ИТИС, 2016
Принципы архитектуры
KISSKeep it simple, stupid
No magicНе доверяем сложным (особенно чужим) решениям
IDE driven developmentЕсли IDE не поддерживает фреймворк, то мы его не используем
Static typing Лучшие тестеры – это компилятор и инспекции
(С) Дельгядо Филипп, ИТИС, 2016
Принципы архитектуры
KISSKeep it simple, stupid
No magicНе доверяем сложным (особенно чужим) решениям
IDE driven developmentЕсли IDE не поддерживает фреймворк, то мы его не используем
Static typing Лучшие тестеры – это компилятор и инспекции
All can crash
(С) Дельгядо Филипп, ИТИС, 2016
Обычная трехзвенка
Java 8Jetty, Jackson, Velocity, Log4j2, Flyway, JUnit
SpringIoC, MVC, JDBC Templates, Security
PostgreSQLPostgreSQL 9.5, pg-crypto
Json4rpc
(С) Дельгядо Филипп, ИТИС, 2016
Особенности платежа
Платеж всегда сложныймного состояний и переходов
(С) Дельгядо Филипп, ИТИС, 2016
Особенности платежа
Платеж всегда сложныймного состояний и переходов
Платеж может быть долгимнельзя запихнуть платеж в один поток или одну транзакцию
(С) Дельгядо Филипп, ИТИС, 2016
Особенности платежа
Платеж всегда сложныймного состояний и переходов
Платеж может быть долгимнельзя запихнуть платеж в один поток или одну транзакцию
Платеж должен быть надежнымвсе промежуточные стадии надо гарантированно записать на диск
(С) Дельгядо Филипп, ИТИС, 2016
Особенности платежа
Платеж всегда сложныймного состояний и переходов
Платеж может быть долгимнельзя запихнуть платеж в один поток или одну транзакцию
Платеж должен быть надежнымвсе промежуточные стадии надо гарантированно записать на диск
Платежи бывают разныенадо уметь быстро менять логику
(С) Дельгядо Филипп, ИТИС, 2016
Особенности платежа
Гарантии доставкиХитрая логика дожатия всех внешних взаимодействий
(С) Дельгядо Филипп, ИТИС, 2016
Особенности платежа
Гарантии доставкиХитрая логика дожатия всех внешних взаимодействий
Всюду таймерыНичто не должно быть вечным
(С) Дельгядо Филипп, ИТИС, 2016
Особенности платежа
Гарантии доставкиХитрая логика дожатия всех внешних взаимодействий
Всюду таймерыНичто не должно быть вечным
Ручная проверка зависших операций
(С) Дельгядо Филипп, ИТИС, 2016
Особенности платежа
Гарантии доставкиХитрая логика дожатия всех внешних взаимодействий
Всюду таймерыНичто не должно быть вечным
Ручная проверка зависших операций
Все можно поменять рукамиНо со строгим аудитом
(С) Дельгядо Филипп, ИТИС, 2016
Основная идеяПлатеж переходит между состояниями
Переходы вызываются предыдущим переходомвнешними событиями срабатыванием таймеров
Переход меняет состояние платежа, контекст, таймеры
Переход может делать что-то полезное, но идемпотемптно
(С) Дельгядо Филипп, ИТИС, 2016
Первый вариант реализации
Каждый переход выполняется асинхронно и в транзакции
Переходы и таймеры выстраиваем в очередь задач на пуле нитей
После падения повторяем последние переходы и восстанавливаем таймеры
В БД сохраняем состояние и контекст
Все сделано на стандартном java concurrency
(С) Дельгядо Филипп, ИТИС, 2016
Первый вариант реализации
Может работать только на одном сервере
Долгое восстановление после сбоя
Нужны ручные синхронизации
Код сложно отлаживать и модифицировать
(С) Дельгядо Филипп, ИТИС, 2016
Хотелось быМного обработчиков на разных серверах
На каждый платеж своя надежная очередь переходов
Очереди и таймеры с гарантией обработки
Все действия по платежу проводятся строго последовательно
Обработка каждого события - одна транзакция
(С) Дельгядо Филипп, ИТИС, 2016
Второй вариантКластеризация
Безотказность
Простота
Нужно делать свою надежную очередь задач и распределенную блокировку :(
(С) Дельгядо Филипп, ИТИС, 2016
Много операцийОдин платеж – около 10 транзакций
Каждая транзакция изменяет несколько сущностейконтексты, лимиты, проводки, состояния, таймеры
Часто меняются общие для всех сущностилимиты, аккумулирующие счета
По ТЗ нужно 100 платежей в секунду
Итого нужны тысячи IOPS
(С) Дельгядо Филипп, ИТИС, 2016
Очень много операций
Один платеж – около 10 транзакций
Каждая транзакция изменяет несколько сущностейконтексты, лимиты, проводки, состояния, таймеры
Часто меняются общие для всех сущностилимиты, аккумулирующие счета
По ТЗ нужно 100 платежей в секунду
Итого нужны тысячи IOPS Ой!
(С) Дельгядо Филипп, ИТИС, 2016
Простое решение4KB Random write
Цена
400GB SAS Enterprise SSD 40 000 IOPS 600$
400GB SAS 12Gb/s Enterprise SSD 85 000 IOPS 3000$
1.6TB SATA III Enterprise SSD 14 000 IOPS 3500$
(С) Дельгядо Филипп, ИТИС, 2016
Платежиupdate – дорогая операция
блокировки, лишний seek
Особенно когда конкурентная
(С) Дельгядо Филипп, ИТИС, 2016
Платежиupdate – дорогая операция
блокировки, лишний seek
Особенно когда конкурентная
Заменим на insert
Текущее значение кэшируем
Раз в N операций объединяем
(С) Дельгядо Филипп, ИТИС, 2016
Очень много таблиц…
Много таблиц и связей
Сложно менять структуру
Без ОРМа не выжить
контекст платежа
(С) Дельгядо Филипп, ИТИС, 2016
Как можно решить проблему
Храним объекты в виде JSONJackson позволяет гибко описывать сериализацию через аннотации
(С) Дельгядо Филипп, ИТИС, 2016
Как можно решить проблему
Храним объекты в виде JSONJackson позволяет гибко описывать сериализацию через аннотации
В специальном типе ::json или ::jsonb
(С) Дельгядо Филипп, ИТИС, 2016
Как можно решить проблему
Храним объекты в виде JSONJackson позволяет гибко описывать сериализацию через аннотации
В специальном типе ::json или ::jsonb
Выкидываем ORM
(С) Дельгядо Филипп, ИТИС, 2016
Как можно решить проблему
Храним объекты в виде JSONJackson позволяет гибко описывать сериализацию через аннотации
В специальном типе ::json или ::jsonb
Выкидываем ORM
Отдельные поля для индексов и PK
(С) Дельгядо Филипп, ИТИС, 2016
А еще…Храним номер версии сериализации
он точно будет быстро расти
Заранее готовим код для обновления версийон точно пригодится
(С) Дельгядо Филипп, ИТИС, 2016
А еще…Храним номер версии сериализации
он точно будет быстро расти
Заранее готовим код для обновления версийон точно пригодится
Учим десериализатор поддерживать конфликтыа лучше бы и полиморфизм
(С) Дельгядо Филипп, ИТИС, 2016
А еще…Храним номер версии сериализации
он точно будет быстро расти
Заранее готовим код для обновления версийон точно пригодится
Учим десериализатор поддерживать конфликтыа лучше бы и полиморфизм
Прописываем приоритет индексных полей над содержимымили делаем записи иммутабельными
В результате
(С) Дельгядо Филипп, ИТИС, 2016
Что хорошоПроизводительность
Оптимистическая блокировка
История изменений
Атомарность изменений
Защита
В результате
(С) Дельгядо Филипп, ИТИС, 2016
Что хорошоПроизводительность
Оптимистическая блокировка
История изменений
Атомарность изменений
Защита
И какие будут проблемыАтомарность изменений
Сложность администрирования
Не поддерживается ОРМами
Как это выглядит в БД
(С) Дельгядо Филипп, ИТИС, 2016
create table operations ( id bigint not null primary key, refId bigint, state varchar(20), schema bigint not null, data json );
Как это выглядит в БД
(С) Дельгядо Филипп, ИТИС, 2016
create table operations ( id bigint not null primary key, refId bigint, state varchar(20), schema bigint not null, data json ); select id,
data->'amount'->>'amount', data->'amount'->>'currency' from operations;
Как это выглядит в БД
(С) Дельгядо Филипп, ИТИС, 2016
create table operations ( id bigint not null primary key, refId bigint, state varchar(20), schema bigint not null, data json ); select id,
data->'amount'->>'amount', data->'amount'->>'currency' from operations;
Лучше так не делать
(С) Дельгядо Филипп, ИТИС, 2016
NoSQL?Активно используем join
Используем транзакции, блокировки
Используем все инструменты обеспечения надежности
Используем sequence
(С) Дельгядо Филипп, ИТИС, 2016
Вспомним, что нам хотелось
Много обработчиков на разных серверах
На каждый платеж своя распределенная очередь переходов и таймеров с гарантией обработки
Все действия по платежу проводятся строго последовательно
Обработка каждого события - одна транзакция
(С) Дельгядо Филипп, ИТИС, 2016
Очередь на skip locked
ROW queue1 alpha
2 beta
3 gamma
4 delta
queue eventalpha a1
alpha a2
beta b1
gamma g4
delta d2
delta d3
Таблица очередей: Queue
Таблица событий: Event
(С) Дельгядо Филипп, ИТИС, 2016
Очередь на skip locked
ROW queue1 alpha
2 beta
3 gamma
4 delta
queue eventalpha a1
alpha a2
beta b1
gamma g4
delta d2
delta d3
select q.queue, e.event from q join e order by e.event asc limit 1for updateskip locked;
(С) Дельгядо Филипп, ИТИС, 2016
Очередь на skip locked
ROW queue1 alpha
2 beta
3 gamma
4 delta
queue eventalpha a1
alpha a2
beta b1
gamma g4
delta d2
delta d3
select q.queue, e.event from q join e order by e.event asc limit 1for updateskip locked;
P P
(С) Дельгядо Филипп, ИТИС, 2016
Очередь на skip locked
ROW queue1 alpha
2 beta
3 gamma
4 delta
queue eventalpha a1
alpha a2
beta b1
gamma g4
delta d2
delta d3
select q.queue, e.event from q join e order by e.event asc limit 1for updateskip locked;
(С) Дельгядо Филипп, ИТИС, 2016
Очередь на skip locked
ROW queue1 alpha
2 beta
3 gamma
4 delta
queue eventalpha a1
alpha a2
beta b1
gamma g4
delta d2
delta d3
select q.queue, e.event from q join e order by e.event asc limit 1for updateskip locked;
PP
ЗамечанияДобавление события ничего не блокирует
Число обработчиков на производительность почти не влияет
Корректно работает на всех уровнях изоляции
(С) Дельгядо Филипп, ИТИС, 2016
ЗамечанияДобавление события ничего не блокирует
Число обработчиков на производительность почти не влияет
Корректно работает на всех уровнях изоляции
Удалять обработанные события надо в той же транзакции
(С) Дельгядо Филипп, ИТИС, 2016
ЗамечанияДобавление события ничего не блокирует
Число обработчиков на производительность почти не влияет
Корректно работает на всех уровнях изоляции
Удалять обработанные события надо в той же транзакции
Для событий можно указывать дату актуальностии можно не делать других таймеров
(С) Дельгядо Филипп, ИТИС, 2016
ЗамечанияДобавление события ничего не блокирует
Число обработчиков на производительность почти не влияет
Корректно работает на всех уровнях изоляции
Удалять обработанные события надо в той же транзакции
Для событий можно указывать дату актуальностии можно не делать других таймеров
В запросе нужно явно указывать время жизни транзакциисобытия не должно слишком долго обрабатываться
(С) Дельгядо Филипп, ИТИС, 2016
(С) Дельгядо Филипп, ИТИС, 2016
ТестированиеФункциональные тесты обязательны
дампы БД сильно ускоряют прохождение тестов
Интеграционные тесты для отладкии с ними спокойнее
Unit-тесты в крайнем случаеи лучше без mock’ов
Все тесты должны быть запускаемы у программистаа не только из CI
Без разрешения Test Lead продакшн не обновляется
(С) Дельгядо Филипп, ИТИС, 2016
Безопасное обновление
Первый шагЧитаем староеПишем старое и новое
Второй шагКопируем старое в новое
Третий шагЧитаем новоеПишем новое
Четвертый шагУдаляем старое
V1OldNew
V1
V2
OldNew
OldNew
V2 New
(С) Дельгядо Филипп, ИТИС, 2016
Как все это организоватьЧтобы и программисты не задолбались, и заказчик не плакал
(С) Дельгядо Филипп, ИТИС, 2016
Каждому проекту – своя методология
(С) Alistair Cockburn
Оригинал статьи http://goo.gl/PFnoe0
Перевод на http://goo.gl/SUCgzC
(С) Дельгядо Филипп, ИТИС, 2016
Разработка в вакууме
Нет проверенных постановок
Исследовательские задачи
Демонстрация продукта может быть в любое время
Много исследовательских задач
(С) Дельгядо Филипп, ИТИС, 2016
Разработка в вакууме
Нет проверенных постановок
Исследовательские задачи
Демонстрация продукта может быть в любое время
Много исследовательских задач
Почти KANBAN
(С) Дельгядо Филипп, ИТИС, 2016
Запуск
Много неожиданных требований
Ежедневное обновление продукта
Объемы задач непредсказуемы
(С) Дельгядо Филипп, ИТИС, 2016
Запуск
Много неожиданных требований
Ежедневное обновление продукта
Объемы задач непредсказуемы
Однодневный SCRUM
(С) Дельгядо Филипп, ИТИС, 2016
Развитие
Двухнедельное планирование с закрытым списком
Объемы задач предсказуемы
Регулярные выкладки
(С) Дельгядо Филипп, ИТИС, 2016
Развитие
Двухнедельное планирование с закрытым списком
Объемы задач предсказуемы
Регулярные выкладкиНе SCRUM
(С) Дельгядо Филипп, ИТИС, 2016
Основные практикиЗачем??
Бережем свой труд
До трех не обобщать
Слона едим по частям
(С) Дельгядо Филипп, ИТИС, 2016
Основные практикиЗачем??
Бережем свой труд
До трех не обобщать
Слона едим по частям
Шашечки или ехать
(С) Дельгядо Филипп, ИТИС, 2016
Еще немножко граблейНеправильные выборы, вечная боль, сделанные ошибки
(С) Дельгядо Филипп, ИТИС, 2016
ЛюдиНикто не понимает транзакций
Любят сложный код
Поголовная любовь к магии
Доверие обещаниям вендоров
(С) Дельгядо Филипп, ИТИС, 2016
Нерешенные задачиКак защитить данные от системного администратора
и при этом обеспечить автоматическую выкладку
(С) Дельгядо Филипп, ИТИС, 2016
Нерешенные задачиКак защитить данные от системного администратора
и при этом обеспечить автоматическую выкладку
Как не терять транзакций при падении ДЦза разумные деньги
(С) Дельгядо Филипп, ИТИС, 2016
Нерешенные задачиКак защитить данные от системного администратора
и при этом обеспечить автоматическую выкладку
Как не терять транзакций при падении ДЦза разумные деньги
Как найти много хороших разработчикови вписаться в бюджет
(С) Дельгядо Филипп, ИТИС, 2016
ОшибкиАктивное использование Spring
Слишком притягательна магия Spring SecurityИ слишком много разработчиков его любят
(С) Дельгядо Филипп, ИТИС, 2016
ОшибкиАктивное использование Spring
Слишком притягательна магия Spring SecurityИ слишком много разработчиков его любят
Тесты пишутся на чужеродном стекеТак получилось, что пишем на Python (PyTest)
(С) Дельгядо Филипп, ИТИС, 2016
ОшибкиАктивное использование Spring
Слишком притягательна магия Spring SecurityИ слишком много разработчиков его любят
Тесты пишутся на чужеродном стекеТак получилось, что пишем на Python (PyTest)
Погнались за модным DockerДля наших условий – слишком много костылей
(С) Дельгядо Филипп, ИТИС, 2016
Вопросы и контакты
Дельгядо Филипп,
vk.com/dphil
http://itasystems.ru/