Случалось ли, что вы видели (чужой) код и хотели все переписать? Бывало такое, что вы не могли понять, почему кем-то было принято конкретное решение, не другое? Хотели ли вы воскликнуть:«А я бы сделал еще круче!»?
Если вы задумывались об этом, вам будет интересно послушать историю о том, как эти вопросы возникали у Александра и Кирилла и как они решались в условиях большой компании.
Разработчики расскажут, как в самом начале пути вытаскивали шашки и шли в атаку на проблемную архитектуру. Но все оказалось не так просто, и по мере погружения в проект парни стали понимать, что архитектура большой системы — компромисс между различными подходами и решениями, инновациями и легаси (наследованным кодом), централизацией и децентрализацией компонентов. Докладчики наработали очень много опыта в решении архитектурных задач и поделятся опытом и выработанными принципами, которых придерживаются в настоящее время.
Во время доклада будут обсуждаться непростые вопросы, возникающие при принятии решений о том, как будет жить и эволюционировать система.
Вместе со слушателями Александр и Кирилл проделают упражнение по созданию «таблицы технологий» и её эволюции. Также они покажут, насколько важно инженерное решение на любой из стадий развития системы.
34. 34
Проблемы архитектуры
● Сильная связанность между модулями
● Слабое тестовое прикрытие
● Регрессионная спираль смерти
○ частично решалась Selenium-тестами
○ но это дорого
48. 48
Проблема эволюции
● Начинали с одного проекта
○ одна команда
○ ui + три сервиса
● Более 10-ти однотипных проектов
○ несколько команд
○ десятки сервисов
○ технологически одинаковые
52. 52
● Spring Boot/Spring Cloud
● Ratpack
● Dropwizard
● Vert.x
● Restlet
● Spark
● KumuluzEE
Выбирайте то,
что больше
нравится
/
в чем есть
экспертиза
55. Принцип LSD
- L языков программирования
- S среднее число фреймворков на язык
- D типов источников данных
complexity = L * S * D
55
56. Немного LSD для вас
- три языка программирования
- два в среднем фреймворка на язык
- семь типов источников данных
- legacy WS, mongo db
- OLTP, OLAP
- elasticsearch, neo4j
- Мишкина база %)
complexity = 3 * 2 * 7 = 42 (!)
56
74. ~home > lazybones create api 0.0.1 rent-service
Creating project from template api 0.0.1 in 'rent-service'
Define value for 'group' [ru.joker]:
74
75. ~home > lazybones create api 0.0.1 rent-service
Creating project from template api 0.0.1 in 'rent-service'
Define value for 'group' [ru.joker]:
Define value for 'version' [0.0.1]:
75
76. ~home > lazybones create api 0.0.1 rent-service
Creating project from template api 0.0.1 in 'rent-service'
Define value for 'group' [ru.joker]:
Define value for 'version' [0.0.1]:
srv1
├──srv2
└──srv3
logging
sleuth
Define value for 'dependencies' [logging,sleuth]:
76
77. ~home > lazybones create api 0.0.1 rent-service
Creating project from template api 0.0.1 in 'rent-service'
Define value for 'group' [ru.joker]:
Define value for 'version' [0.0.1]:
srv1
├──srv2
└──srv3
logging
sleuth
Define value for 'dependencies' [logging,sleuth]:
Project created for rent-service!
77
81. TServerTransport serverTransport = new TServerSocket(
new
InetSocketAddress(InetAddress.getLocalHost(), port));
TProcessor processor = new
TInsuranceService.Processor<>(
//business value here
);
server = new TSimpleServer(
new
TServer.Args(serverTransport).processor(processor));
server.serve();
81
82. TSocket transport = new TSocket(host, port);
transport.open();
TBinaryProtocol tBinaryProtocol = new
TBinaryProtocol(transport);
TInsuranceService.Client client =
new TInsuranceService.Client(tBinaryProtocol);
perform(client); //business value here
transport.close(); 82
88. @Getter // generate getters
@Setter // generate setters
@Aspect // we are an aspect
@ToString // generate toString()
@EnableWs // SOAP is so enterprisy, we definitely need it
@Endpoint // Seriously, just read above
@EnableWebMvc // we want MVC
@EnableCaching // and we want to cache stuff
@Configuration // this class can configure itself
@RestController // we want some REST
@XmlRootElement // this component is marshallable
@EnableWebSocket // we want web socket, it's so new-generation
@RedisHash("cat") // this class is an entity saved in redis
@EnableScheduling // we want scheduled tasks
@EnableWebSecurity // and some built-in security
@NoArgsConstructor // generate no args constructor
@ContextConfiguration // we want context configuration for unit testing
@SpringBootApplication // this is a Sprint Boot application
@Accessors(chain = true) // getters/setters are chained (ala jQuery)
@EnableAspectJAutoProxy // we want AspectJ auto proxy
@EnableAutoConfiguration // and auto configuration
@EnableRedisRepositories // since it is an entity we want to enable spring data repositories for redis
@EnableWebSocketMessageBroker // we want a broker for web socket messages
88
91. Not smart
= This is main documentation
This document describes how to be the most fundamental and important
document in the world of documents
...
COPY-PASTE documentation from another document
...
91
92. Not so smart
= This is main documentation
This document describes how to be the most fundamental and important document
in the world of documents
include::https://raw.github.com/asciidoctor/asciidoctor/master/Gemfile[]
include::../other.adoc[]
include::/home/tolkv/git/docs-0/superdoc.adoc[]
92
93. Really smart
= This is main documentation
This document describes how to be the most fundamental and important document
in the world of documents
include::https://raw.github.com/asciidoctor/asciidoctor/master/Gemfile[]
include::gradle://gradle-advanced:service-with-deps:1.0/deps.adoc[]
include::gradle://:service/doc.adoc[]
93
94. Payment Service[jar,doc] Insurance Service [jar,doc]
One Point of View
[UberDoc.zip]
Rent Service[jar,doc] Other Service [jar,doc]
Агрегация информации
94
95. Парадокс централизации
Чтобы эффективно разрабатывать распределённые
приложения, нам нужны очень хорошие
централизованные библиотеки и инструменты
Например: логирование, health-checking, метрики,
обработка типовых ошибок, автодокументирование
95
96. Парадокс централизации
Чтобы эффективно разрабатывать распределённые
приложения, нам нужны очень хорошие
централизованные библиотеки и инструменты
Но: не выносите бизнес-логику или доменные объекты!
Не размывайте бизнес-контекст вашего API
96
168. 168
RentService
PaymentService
SecurityServiceBlockchainService
TraceId = X
SpanId = A
No TraceId
No SpanId
TraceId = X
SpanId = A
TraceId = X
SpanId = A
TraceId = X
SpanId = B
TraceId = X
SpanId = B
TraceId = X
SpanId = C
TraceId = X
SpanId = C
TraceId = X
SpanId = D
TraceId = X
SpanId = D
TraceId = X
SpanId = E
TraceId = X
SpanId = E
TraceId = X
SpanId = F
TraceId = X
SpanId = G
180. 1. Архитектура – функция от множества
переменных
Простить, потому что
180
181. 1. Архитектура – функция от множества
переменных
2. Архитектура – результат эволюции на
протяжении времени
Простить, потому что
181
182. 1. Архитектура – функция от множества
переменных
2. Архитектура – результат эволюции на
протяжении времени
3. Принципы должны быть “вечны”, а
инструменты актуальны и эффективны
Простить, потому что
182
184. 1. SOA принципы живы
2. Принцип LSD
Придерживайтесь принципов
184
185. 1. SOA принципы живы
2. Принцип LSD
3. Изоляция данных делает жизнь приятнее
Придерживайтесь принципов
185
186. 1. SOA принципы живы
2. Принцип LSD
3. Изоляция данных делает жизнь приятнее
4. Парадокс централизации
Придерживайтесь принципов
186
187. 1. SOA принципы живы
2. Принцип LSD
3. Изоляция данных делает жизнь приятнее
4. Парадокс централизации
5. Планируй ресурсы динамически
Придерживайтесь принципов
187
188. Links
Лекция Жени Кривошеева про архитектуру:
https://www.youtube.com/watch?v=_Kex5hwGE-w
Пример Smart-библиотеки:
https://github.com/lavcraft/grpc-spring-boot-starter
Пример реализации “умной документации”:
https://github.com/aatarasoff/documentation-plugin-demo
188