95
Платежная система за один год Дельгядо Филипп, ИТИС Банальности, проверенные опытом ver. 0.2

Платежная система за год / Филипп Дельгядо (Информационные технологии и системы)

  • Upload
    ontico

  • View
    378

  • Download
    4

Embed Size (px)

Citation preview

Платежная системаза один год

Дельгядо Филипп, ИТИС

Банальности, проверенные опытом

ver. 0.2

(С) Дельгядо Филипп, ИТИС, 2016

О чем этот докладЧто такое платежные системы, какие сложности при их разработке

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

Как строить и менять процесс разработки

Удачные и неудачные практики и решения

(С) Дельгядо Филипп, ИТИС, 2016

Основные вызовыСтарт проекта с нуля

Нет командыНет постановок

Высокие требования к проектуНадежностьПроизводительностьБезопасность

Сжатые сроки и ограниченный бюджет

Секретность

(С) Дельгядо Филипп, ИТИС, 20164

Проект1 большая комната

8 программистов

8 не только программистов

1 год

(С) Дельгядо Филипп, ИТИС, 2016

Платежные системыЧто сложного в платежных системах и как это сказывается на архитектуре проекта

Платежи – это очень просто

Пока не пришли юристы

(С) Дельгядо Филипп, ИТИС, 2016

Например115-ФЗ – О противодействии отмыванию доходов

161-ФЗ – О национальной платежной системе

152-ФЗ – О защите персональных данных

222-ФЗ – Об азартных играх

PCI DSS – О безопасности кредитных карт

И это далеко не все….

(С) Дельгядо Филипп, ИТИС, 2016

Требования к архитектуре

(С) Дельгядо Филипп, ИТИС, 2016

Требования к архитектуре

Очевидность кода и всех решенийКоманда активно развивается, некогда изучать.

(С) Дельгядо Филипп, ИТИС, 2016

Требования к архитектуре

Очевидность кода и всех решенийКоманда активно развивается, некогда изучать.

Простота code reviewИначе его никто не будет делать.

(С) Дельгядо Филипп, ИТИС, 2016

Требования к архитектуре

Очевидность кода и всех решенийКоманда активно развивается, некогда изучать.

Простота code reviewИначе его никто не будет делать.

Надежность решенияНельзя терять деньги.

(С) Дельгядо Филипп, ИТИС, 2016

Требования к архитектуре

Очевидность кода и всех решенийКоманда активно развивается, некогда изучать.

Простота code reviewИначе его никто не будет делать.

Надежность решенияНельзя терять деньги.

Высокая доступностьБез простоев, планируемых и непланируемых

(С) Дельгядо Филипп, ИТИС, 2016

Требования к архитектуре

Очевидность кода и всех решенийКоманда активно развивается, некогда изучать.

Простота code reviewИначе его никто не будет делать.

Надежность решенияНельзя терять деньги.

Высокая доступностьБез простоев, планируемых и непланируемых

Производительность

(С) Дельгядо Филипп, ИТИС, 2016

Принципы архитектуры

(С) Дельгядо Филипп, ИТИС, 2016

Принципы архитектуры

KISSKeep it simple, stupid

(С) Дельгядо Филипп, ИТИС, 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

Основная идеяПлатеж переходит между состояниями

Переходы вызываются предыдущим переходомвнешними событиями срабатыванием таймеров

Переход меняет состояние платежа, контекст, таймеры

Переход может делать что-то полезное, но идемпотемптно

(С) Дельгядо Филипп, ИТИС, 2016

Первый вариант реализации

Каждый переход выполняется асинхронно и в транзакции

Переходы и таймеры выстраиваем в очередь задач на пуле нитей

После падения повторяем последние переходы и восстанавливаем таймеры

В БД сохраняем состояние и контекст

Все сделано на стандартном java concurrency

(С) Дельгядо Филипп, ИТИС, 2016

Первый вариант реализации

Может работать только на одном сервере

Долгое восстановление после сбоя

Нужны ручные синхронизации

Код сложно отлаживать и модифицировать

(С) Дельгядо Филипп, ИТИС, 2016

Хотелось быМного обработчиков на разных серверах

На каждый платеж своя надежная очередь переходов

Очереди и таймеры с гарантией обработки

Все действия по платежу проводятся строго последовательно

Обработка каждого события - одна транзакция

(С) Дельгядо Филипп, ИТИС, 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

Что хорошоПроизводительность

Оптимистическая блокировка

История изменений

Атомарность изменений

Защита

И какие будут проблемыАтомарность изменений

Сложность администрирования

Не поддерживается ОРМами

Как это выглядит в БД

(С) Дельгядо Филипп, ИТИС, 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

Очередь на PostgreSQLИли как изобрести велосипед, но дешево

(С) Дельгядо Филипп, ИТИС, 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

Удачные практикиЧто из опыта спорно, но удачно

(С) Дельгядо Филипп, ИТИС, 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

ЛюдиНикто не понимает транзакций

Любят сложный код

Поголовная любовь к магии

Доверие обещаниям вендоров

(С) Дельгядо Филипп, ИТИС, 2016

Нерешенные задачиКак защитить данные от системного администратора

и при этом обеспечить автоматическую выкладку

(С) Дельгядо Филипп, ИТИС, 2016

Нерешенные задачиКак защитить данные от системного администратора

и при этом обеспечить автоматическую выкладку

Как не терять транзакций при падении ДЦза разумные деньги

(С) Дельгядо Филипп, ИТИС, 2016

Нерешенные задачиКак защитить данные от системного администратора

и при этом обеспечить автоматическую выкладку

Как не терять транзакций при падении ДЦза разумные деньги

Как найти много хороших разработчикови вписаться в бюджет

(С) Дельгядо Филипп, ИТИС, 2016

ОшибкиАктивное использование Spring

Слишком притягательна магия Spring SecurityИ слишком много разработчиков его любят

(С) Дельгядо Филипп, ИТИС, 2016

ОшибкиАктивное использование Spring

Слишком притягательна магия Spring SecurityИ слишком много разработчиков его любят

Тесты пишутся на чужеродном стекеТак получилось, что пишем на Python (PyTest)

(С) Дельгядо Филипп, ИТИС, 2016

ОшибкиАктивное использование Spring

Слишком притягательна магия Spring SecurityИ слишком много разработчиков его любят

Тесты пишутся на чужеродном стекеТак получилось, что пишем на Python (PyTest)

Погнались за модным DockerДля наших условий – слишком много костылей

(С) Дельгядо Филипп, ИТИС, 2016

Не идеальные инструменты

Youtrack

Git

Maven

(С) Дельгядо Филипп, ИТИС, 2016

Вопросы и контакты

Дельгядо Филипп,

[email protected]

[email protected]

vk.com/dphil

http://itasystems.ru/