У меня есть некоторый опыт в реализации систем на базе микросервисной архитектуры и я хотел бы поделится вопросами (и ответами), которые возникают при реализации подобных проектов. К сожалению, я не имею права распространяться о проектах в которых я участвовал, поэтому я выдумал собственный сферический проект в вакууме. В этом проекте нам встретится множество стандартных проблем.

Хочу сразу заметить, что имплементация будет рудиментарной и служит только базой для постановки вопросов. В любом случае, я надеюсь, вы найдете в статье пару интересных мыслей и ссылок.

Мы увидим, сколько интересных моментов могут возникнуть при написании всего трех классов и зададимся вопросом, должен ли в данном случае принимать решение архитектор или разработчик может решить эту проблему сам.

image

Основная идея проекта


Итак, представьте себе, что светлое будущее наступило и машины с автопилотом резво бегают по городам и селам. Возникает вопрос: а нужен ли вам в таких условиях личный автомобиль?

Я предлагаю вам другой подход. Смотрите, вы идете ко мне на сайт, регистрируетесь, заполняете анкету. В анкете будет примерно следующее: хочу каждый день с понедельника по пятницу в 8:15 выйти из дома (пункт А) сесть в мерседес и доехать до работы (пункт Б). Потом вечером в 18:00 выйти из офиса (пункт Б) сесть в ауди и доехать до дома (пункт А). Там же еще можете пометить галочкой пункт: хочу иметь возможность уехать с работы раньше, машину готов ждать не более 8 минут.

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

За все удовольствие с вас попросят 150 у.е. в месяц. Звучит неплохо, не правда ли?

Естественно под капотом у этого сервиса будет много логики, т.к. надо много что учитывать. Например, мы должны быть конкурентоспособны, т.е. надо предложить людям вариант подешевле. Для этого можно предусмотреть совместные поездки. Мы можем посмотреть, что сосед нашего клиента, оказывается, тоже едет в ту же сторону, но на 5 минут позже. Может предложить им ездить вместе, а за это предложить скидку?

Наш сервис будет давать нам множество данных из которых мы можем добыть много интересной информации:

  • кто, куда, когда и с кем ездит.
  • кто, где и сколько времени проводит
  • что, когда, у каких моделей машин ломается
  • кто какие машины предпочитает
  • …..

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

Для того, чтобы это было возможно нам надо предусмотреть возможность сбора и анализа информации.

В общем и целом речь идет о большом и сложном проекте, который можно назвать модным словом «cognitive solution» для бизнеса с элементами из мира Internet of Things.

Методология разработки и анализ требований


Естественно, сначала необходимо проанализировать все требования к проекту, решить какую методологию мы применим (waterfall, rup, scrum, …). Но в данном случае мы все эти этапы пропустим, т.к. практически все поднятые в этой статье вопросы возникнут в любом случае, независимо от выбранной методологии.

Язык, фреймворк, архитектура


Изначально я Java Developer, и потому имплементация будет на java. Не обессудьте.

Кстати вот сразу вопрос, является ли выбор языка программирования задачей архитектора или он «выше этого»?

Для тех, кто думает что нет, что язык программирования второстепенен и вообще, важна только команда, я предлагаю провести маленький мысленный эксперимент. Подумайте, на каком языке вы бы такой проект точно не делали, т.е. считаете, что это было бы однозначно неправильное решение. А теперь представьте себе, что архитектор решил таки сделать проект именно на этом языке. А когда вы будете гневно возмущаться, он вам скажет: это второстепенный вопрос, главное команда!

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

А какой фреймворк возьмем? Если немного погуглить, то станет понятно, что особо вариантов нет, мы будем делать на Spring Framework. Причина проста, в Spring Cloud есть все, что нам потребуется.

Еще у нас будут всякие API Gateway’и, Config Service’ы, Message Broker’ы, Docker, Workflow, Rule Engine и много всяких других заумных слов по мелочи.

Есть два основных подхода к проектированию микросервиса.
  • Domain Driven Design
  • Functional Driven


Domain Driven Design означает определение доменных объектов и имплементирование всех необходимых действий, которые требует ваш заказчик. Например заказчик какой нибудь аптечной системы говорит: мне нужно иметь возможность вносить новое лекарство в систему, удалять старые, а вот редактирование уже внесенного лекарства надо запретить. Вы делаете класс «Medicine» со всеми нужными полями и имплементируете названный функционал. Так у вас появляется MedicineService. Т.е. при таком подходе начальной точкой является доменные объекты.

Functional Driven означает, что за точку отсчета берется необходимый функционал, а уж какие какие доменные объекты вам придется привлечь, уже второстепенное дело.

Лично я всегда начинаю с доменных объектов, а потом проверяю, можно ли таким образом реализовать необходимый функционал. Если нет, то смотрю, может нужно добавить еще один доменный объект в сервис? По идее, как только пришлось это сделать, значит пора смотреть в сторону «функционального» подхода.

Сервисов с одним доменным объектом весьма не много, можно сразу начинать с функционала, но мне так проще.

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

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

Возьмем за стартовую точку некоторый абстрактный класс Vehicle

 public abstract class Vehicle {
….
   protected String model;
   protected int wheelNumber;
   protected Date manufactureYear;
   protected EngineType engineType; 
   protected Producer producer;
}

Как мы выяснили у нас будут разные Vehicle, давайте сделаем парочку:

public class Car extends Vehicle {
   public Car() {
       wheelNumber = 4;
   }
}

и еще один для бедных, но спортивных:

public class Bicycle extends Vehicle {
 
   public Bicycle() {
       wheelNumber = 2;
   }
}

Замечательно. Теперь нам нужен тот, ради кого мы все это делаем: наш клиент, он же источник нашего дохода. Назовем эту сущность Customer’ом

public class Customer {
   private String firstName;
   private String lastName;
   private Date birthDay;
}

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

public class Contract {
   private long customerId;
   private long vehicleId;
}

Итого мы имеем одну иерархию классов с Vehicle на вершине, Customer и Contract. Предлагаю сделать из них VehicleService, ContractService и CustomerService.

Что означает 'микро' в слове 'микросервис'?
Раньше меня мучал вопрос, а что означает «микро» в слове «микросервис»? По идее это означает «маленький». Но что значит маленький?

Часто встречается мнение, что микросервис должен помещаться в голову одного человека, или чтобы его могла сделать команда из трех человек и все такое. Это бесспорно имеет смысл, но я, как еще один вариант, предлагаю немного другой взгляд на этот вопрос.

Когда вы реализуете, а лучше, если еще только думаете сделать какой нибудь микросервис, то спросите себя: если я сильно ошибусь с этим сервисом, смогу ли я себе позволить выкинуть его и написать новый с абсолютного нуля?

Если ваш ответ «да», то это микросервис. А если нет, то и нет. И что важно, задавайте себе этот вопрос регулярно по мере реализации. Если вдруг у вас проскочил ответ «нет», начинайте рефакторить/дробить/переосмысливать этого монстра. Хотя обычно к этому времени все полимеры уже <..censored..>

Рудиментарную имплементацию сервисов вы можете посмотреть тут.

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

Что бы засунуть наши сервисы в докер нам потребуется плагин для мавена (смотрите в pom.xml docker-maven-plugin) и dockerfile.

Все сервисы мы будем запускать через docker-compose, для этого в корне проекта лежит docker-compose.yml.

Обратите так же внимание на файл .env и его содержимое. Больше об этом файле найдете в документации . Без этого файла у меня на машине с Windows 7 не получилось инициализировать MySQL.

Что у меня получилось?


Начнем с плюсов:

  • эта штука работает.

На этом плюсы к сожалению закончились

Минусы:

Их к сожалению очень много, поэтому рассмотрим только пару штук выборочно.

Прежде чем я начну разбирать недостатки, хочу упомянуть один маленький, но чрезвычайно важный момент: микросервисная архитектура изначально предполагает, что в системе работают как минимум два экземпляра каждого сервиса, которые делят нагрузку. Если это правило не соблюдается, то, по моему мнению, речь о микросервисной архитектуре можно сразу же прекращать. Да, я знаю, это спорно, но мое мнение именно таково.

К сожалению, избыточность не гарантирует 100% доступность сервисов и поэтому, если есть другой разумный способ поддержания работоспособности системы, то его можно и нужно использовать.

Добавление нового типа транспорта в систему


Диаграмма классов это не архитектура
Часто слышу такое высказывание: диаграмма классов это не архитектура. Объясняется это примерно так: что и как там в модуле сделано меня не интересует, мне важно что модули делают и как они между собой коммуницируют. Как правило, говорят это люди, которые программистом никогда не работали, но каким то образом сразу же стали архитекторами. Что я могу на это сказать? Может они действительно правы, но мой опыт говорит об обратном. И сейчас мы рассмотрим как раз такой случай.


Итак, для начала спросим себя, правильный ли подход к решению управления транспортными средствами мы применили? Поясню вопрос. Например мы хотим предложить нашим клиентам аренду скутера.

Сейчас VehicleService выглядит вот так.

image

Нам нужно добавить новую сущность Scooter в систему. У нас все построено на наследовании, поэтому конечный результат будет выглядеть так:

image

Мы напишем новый класс Scooter в VehicleService, протестим, скомпилим, задеплоим. А если у нас будут десятки типов транспортных средств? Будем каждый раз писать новый класс, тестить, компилить и т.д.? Есть ли другой способ?

Можно, например, сделать так. Сделаем класс VehicleType.

public class VehicleType {
    private String name;
    private List<VehicleProperty> properties;
    ….
}

Как видите у VehicleType есть VehicleProperty:

public class VehicleProperty<T> {
   private String name;
   private T value;
   private String description;
…..
}

Сделаем еще класс Vehicle:

public class Vehicle {
  private VehicleType vehicleType ;
  private List<VehicleProperty> customProperties;
   …...
}

Теперь, если хотим добавить скутер в систему, то мы создадим сначала VehicleType «Scooter»:

VehicleProperty wheelNumberProperty = new VehicleProperty<Integer>("wheelNumber", 2, "number of wheels");
…….
VehicleType scooterType = new VehicleType("Scooter");
 scooterType.addProperty( wheelNumberProperty);
……..

А если нам нужно создать экземпляр скутера:

Vehicle scooter1 = new Vehicle(scooterType);
….. 

Таким образом мы можем добавлять в систему сколько угодно новых типов не создавая новые классы в VehicleService.

image

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

Скрытый business case
Вообще вопрос изменения чего либо в сервисе требует отдельного внимания. Поясню на примере.

У меня был такой случай. На митинге презентирую клиенту нашу будущую архитектуру. Ответил на вопросы. Вроде все хорошо, всем все нравится, все довольны. И тут главный айтишник клиента задает такой простой вопрос: как быстро вы можете добавить новое поле к доменному объекту «АBC»? Простой ведь вопрос, правда? Я и ответил просто: добавить поле — 2 минуты, написать тесты еще от нескольких минут до пары часов, потом прогон всех тестов (может длится часами), и т.д. В общем назвать какую то конкретную цифру я не смог и думаю что никто не сможет, пока это хотя бы раз не было сделано. Вроде как я правильно ответил, но ощущение, что ответ неверен меня не покидало. И вот однажды я таки понял, как я должен был ответить.

На сегодняшний день мой ответ звучит так: «А как часто это должно происходить?» Если это исключительная ситуация, то в принципе не важно сколько длится добавление поля, лишь бы этот срок был адекватным с точки зрения бизнеса. Если же это происходит часто, то надо бы задать вопрос: а не является ли это Business case? И если да, то этот функционал нужно изначально закладывать в систему и тогда ответ должен быть: 20-30 минут (это вранье, конечно, но звучит хорошо), может дольше, если случай тяжелый.

Также возникает другой вопрос: как так получилось, что этот business case всплыл только сейчас?
И еще более важный вопрос, а нет ли других подобных business case’ов, которые мы упустили?

Следующий момент. Смотрите, если наш VehicleService падает, то мы не можем ни создать новый экземпляр велосипеда в системе (например мы закупили новую партию велосипедов и хотим добавить их в систему), ни арендовать велосипед. Т.е. ни наши клиенты, ни наши сотрудники в офисе ничего сделать не могут. Было бы гораздо лучше, если бы даже в случае проблем в офисе наши клиенты могли бы делать заказы и приносить нам деньги. Как это можно сделать? Похоже надо делить наш VehicleService на два, один для клиентов и один для наших сотрудников.

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

Предположим, опять же, наш VehicleService упал. Это значит, что ни машины, ни велосипеды арендовать нельзя. Было бы не плохо, чтобы если сервис для машин не доступен, то сервис для велосипедов работал бы дальше. Как это можно сделать? Делить VehicleService на несколько сервисов по одному на каждый тип транспортного средства?

На самом деле последние два примера возможных проблем не совсем корректны, т.к. они могут быть решены через избыточность, т.е. должны работать несколько экземпляров сервиса. Но, как я говорил в начале, никакая избыточность не даст 100% доступности. Именно поэтому надо стараться решить вопрос доступности сервиса еще каким нибудь разумным альтернативным способом.

На нашей улице случился праздник, к нам набежала куча клиентов, которые хотят арендовать у нас машину. Сервис не справляется, но это не проблема, мы стартуем еще один экземпляр и все снова в порядке. Но теперь у нас два экземпляра сервиса не только для машин, но и для велосипедов. Плохо ли это? Не знаю, но уж точно не хорошо. Весьма возможно что с этим можно жить, надо смотреть.

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

  • Car
  • Bicycle
  • Scooter
  • Traktor
  • ……

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

А можно и по другому. При старте каждый сервис должен постучаться к VehicleTypesService сообщить ему о своем существовании. Это решение вроде хорошо выглядит, но не отвечает на вопрос что делать, если нам надо не добавить, а удалить вид транспортного средства. Например, через полгода мы поняли, что моноколесами никто не пользуется, мы хотим удалить его из системы. Как мы это сделаем?

А вот еще интересный вопрос. Как видите у Vehicle есть поле EngineType.

public abstract class Vehicle {
   …...
   protected EngineType engineType;
 

В моей рудиментарной имплементации EngineType имеет enum’ы:

  • Gas
  • Diesel
  • Elektro

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

Сделаем вместо EngineType список EngineType’ов (и тогда у 99% машин вдруг появится список с одним элементом)?

public abstract class Vehicle {
   …...
   protected List<EngineType> engineTypes;
 

А может добавим новый тип в enum, что то вроде Gibrid?

Кто в этом случае принимает решение и, соответственно, несет за него ответственность?

Можно ли сказать, что здесь идет речь об архитектуре или это слишком «мелкий» вопрос?

На примере поля EngineType хочу задать еще один вопрос: а нужно ли нам вообще знать какой двигатель у машины? Ведь нашему клиенту с большой долей вероятности абсолютно все равно, заливаем мы в бак солярку или бензин. А вот, например, возможность захватить с собой велосипед (т.е. большой ли багажник или есть ли специальный крепеж для велосипеда), может оказаться очень даже важным.

На самом деле тип двигателя конечно же важен, но не для клиента, а для нас, компании, которая этот сервис предоставляет. Одна из причин — статистика (например по затратам на топливо или необходимому ремонту). Она будет сильно различаться для каждого типа двигателя. Отсюда возникает еще один вопрос: а не должны ли быть доменные объекты (или их представления) различными для нашего backend’a и frontend’a?

Как ответить на вопросы подобного рода? Я знаю только один способ: надо почаще разговаривать с людьми из бизнеса, спрашивать у них, что и где они хотят видеть? К сожалению они сами частенько не знают ответы на эти вопросы.

Сложные запросы


Предположим, я хочу посмотреть всех клиентов с их договорами, которые живут на улице Апельсиновой в славном городе Берлине. Т.е. я хочу увидеть что то вроде такой таблички:
Фамилия, Имя Номер договора Дата подписания договора Машина
Пупкин, Вася 12345 01.01.2017 Audi Q4
...... ...... ...... ......

Как вы видите в таблице содержатся данные из трех микросервисов: CustomerService, VehicleService и ContractService. Как мы будем их собирать вместе? В случае монолита вопрос решается одним запросом в базу, а что делать когда у нас три базы?

image

Есть разные варианты решения этой маленькой проблемы и в следующий раз мы их обсудим.

Спасибо, Кэп!
А теперь минуточку внимания. Когда надо было задаваться этими вопросами? Ответ: конечно же перед тем как писать код. И отвечать на эти вопросы должен в том числе и архитектор.

Как происходит процесс принятия решений и донесения оных до команды программистов
А теперь небольшой «поток сознания» на тему: как вообще происходит процесс принятия решений и донесения оных до команды программистов? Я знаю две теоретические возможности, а все остальное только их миксы в различных пропорциях:

  1. Приходит дядя и показывает презентацию со всякими красявостями в виде диаграмок сдобренных мудреными словами. Частенько он дает понять, что имеет за плечами большой опыт, понимает что делает и все такое, а потому решение принято окончательно и бесповоротно. Услышав ропот из дальнего ряда быстренько заявляет, что всегда открыт для новых идей.Фактически архитектор здесь является полноценным диктатором.
  2. Приходит дядя, говорит, что он «художник» и видит «картину» вот так. При этом прямо говорит, что «рисовать» будет не он, а люди в «зале», а потому в их кровных интересах видение картины ругать и по возможности предлагать альтернативы. В этом случае архитектор стремится снять с себя какую либо ответственность.

Лично мне ближе, (повторюсь, ближе, а не полностью устраивает) второй вариант. Для этого существуют, наверное, десятки причин, рассмотрим некоторые из них.

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

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

Другая причина кроется в неполном знании системы и ее окружения. Представьте себе, что после презентации архитектуры вы получаете вопрос: «а как это все вяжется с тем фактом, что нам надо тянуть данные из чужой системы биллинга?» И тут архитектор вдруг узнает, что оказывается, есть сторонняя система с которой нам надо интегрироваться. И все это знают, кроме архитектора. Да, такое тоже бывает.

Важно объяснить, почему было принято именно это решение, а не какое либо другое, в чем преимущества и упомянуть недостатки. В этом случае люди понимают что происходит, становятся гораздо более терпеливы.

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

На последок еще две мысли.

Во первых, если ты считаешь, что твоя архитектура хороша, то это значит, что ты ее еще никому не показывал. К коду это, кстати, тоже относится.

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

Однажды я прошляпил этот момент и только на Sprint Review абсолютно случайно узнал, что программист сделал совсем не так, как было ему сказано. На вопрос: написано же черным по английски, посылай «event», почему ты шлешь http request? был получен ответ: ну я подумал, что так будет лучше. Естественно все проконтролировать невозможно, надо доверять своей команде. Но, как говорят немцы, доверие хорошо, а контроль лучше.

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


Однажды кому-нибудь умному захочется выяснить, почему клиенты расторгают или не продлевают договора и уходят к конкурентам? Может в последний раз машина не понравилась/опоздала? А может человек ездил раньше со своим коллегой, который перешел к нашим конкурентам и переманил своего попутчика к ним?

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

Как это можно сделать мы обсудим в следующей статье.

Проблемы с инфраструктурой


Микросервисная архитектура накладывает весьма определенные требования на инфраструктуру всего приложения, а именно, нам нужны

  • единая точка входа, он же API Gateway
  • поиск сервисов, он же Service Discovery
  • одна точка конфигурации, он же Config Service
  • центральная точка сбора и анализа логов
  • мониторинг
  • ……

Эти и другие вопросы в следующей части.
Поделиться с друзьями
-->

Комментарии (67)


  1. SergeyUstinov
    22.06.2017 19:03
    +5

    Мне кажется, что большая часть описанных проблем возникает из-за того, что пытаемся создать модель классов, а структура БД является «вспомогательной» (ORM).
    Но сам по себе описанный проект ближе к тем задачам, для которых разрабатывались реляционные базы. И логичнее продумывать архитектуру не от классов java, а от er диаграммы базы. В таком случае большей части описанных проблем не появится. А если вспомнить о прочих проблемах, которые приносит за собой ORM, то описанный подход выглядит как сплошная проблема.


    1. darkneo
      23.06.2017 09:45
      +6

      И логичнее продумывать архитектуру не от классов java, а от er диаграммы базы.

      Почему именно от ERD БД, а не от ERD предметной области? Ведь БД нужна для хранения данных о доменных объектах, а не наоборот, не БД определяет состав полей доменных объектов
      Отсюда возникает еще один вопрос: а не должны ли быть доменные объекты (или их представления) различными для нашего backend’a и frontend’a?

      В Domain-Driven Design-е с самого начала постулируется положение о том, что есть ограниченные области предметной области (тавтология такая вот), каждая из которых оперирует своими доменными объектами. Для взаимодействия между областями есть адаптеры.

      Подобный же подход, кроме всего прочего, постулируется и в SOLID, в части Interface Segregation.

      Это так, мысли под утренний кофе, а не указание на что-либо.


      1. SergeyUstinov
        23.06.2017 11:54
        +1

        Почему именно от ERD БД, а не от ERD предметной области? Ведь БД нужна для хранения данных о доменных объектах, а не наоборот, не БД определяет состав полей доменных объектов

        Потому что ERD предметной области — это нечто достаточно эфемерное, что нельзя непосредственно воплотить в артефактах системы. А ERD БД — это вполне конкретная вещь, которую можно напрямую трансформировать в SQL код создания объектов БД, можно нормализовать и т.д. А как, например, нормализовать ERD предметной области? :)))

        Как я вижу создание микросервисов для такой задачи:
        Рисуем укрупненную ERD предметной области. Под неё рисуем укрупненную ERD базы и анализируем связи — где можно разрезать на микросервисы. При этом также думаем и о прочих аспектах работы пользователя с системой, но отталкиваемся именно от схемы БД.
        При дроблении на микросервисы сразу же думаем, нет ли уже готовых кусков. Например, для машин и покупателей из этого примера смотрим на решения из сферы MDM — Product information management (PIM) и Customer Information Management (CIM). Изобретение велосипедов всегда чревато проблемами. :)))

        После дробления на микросервисы рисуем уже детальные ERD баз (для каждого микросервиса свою схему, чтобы в дальнейшем можно было хранить все данные как в одном инстансе сервера БД для всех микросервисов, так и в множестве разных инстансов). Можно даже сразу подумать о возможном горизонтальном разбиении данных — даже запустив 100 екземпляров микросервиса, можно легко столкнуться с недостаточной производительностью. Ведь в любом случае надо контролировать, чтобы одна и та же физическая машина не была зарезервирована в одно и то же время для разных поездок. А это означает, что БД очень легко может стать узким местом. А при неудачном разбиении на микросервисы для решения такой проблемы может потребоваться переразбиение на микросервисы с нуля и переписывание большей части кода.

        И только потом, когда для каждого микросервиса, который будем создавать (часть можно позаимствовать в готовом виде), продумана схема БД, надо начинать продумывать классы java, которые будут оптимально работать именно с такими данными. И эти классы наверняка будут не такими, как описаны в статье.


        1. mayorovp
          23.06.2017 12:57

          Без "укрупненной ERD базы" это делается еще проще.


          1. SergeyUstinov
            23.06.2017 13:18
            +1

            :)))
            Возможно. Мне проще сразу рисовать схему бд.

            Но главное, что я хотел подчеркнуть — сперва создаем схему бд, потом, на основе схемы бд — классы java. Иначе в таких системах будет сплошной ой.

            И, кстати, если создавать что-то похожее на инстаграм, то подход «от схемы БД» будет неправильным. Там другие требования к работе с данными и те же объектные БД будут прекрасно работать. И разрабатывать архитектуру надо по другому.

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


            1. mayorovp
              23.06.2017 13:22

              В каких — таких системах?


              1. SergeyUstinov
                23.06.2017 13:32
                +1

                ERP системы, бухгалтерия, торговля, логистика и т.п. Реляционные СУБД создавались в первую очередь в расчете на такие задачи, и очень хорошо для таких задач подходят.

                Сервис по аренде автомобилей относится к этому «типу» приложений.
                А тот же инстаграмм — это уже другой тип приложений.


                1. VolCh
                  24.06.2017 02:27

                  Если условный java(ака C с классами) подход не очень подходит, а РСУБД подходит хорошо, то не встаёт ли вопрос, что всю значимую логику нужно перенести в БД? Если решили, что приоритет у ООП, то вопрос выбора хранилища становится вторичным — ничего значимого доверять ему нельзя, хотя и не стоит ради принципа избавляться от протечек абстракций, дающих значимые (обычно в плане консистентности данных и производительности аналитических отчётов) преимуществ


                  1. SergeyUstinov
                    24.06.2017 11:59
                    +1

                    Переносить всю логику в БД не получится, да и не очень нужно. Но в «учетных» системах никогда не получается использовать «чистый» ООП, так как критически важно оперировать с данными как множествами. И в результате нарушается инкапсуляция.


        1. Lofer
          23.06.2017 14:08
          +3

          Потому что ERD предметной области — это нечто достаточно эфемерное, что нельзя непосредственно воплотить в артефактах системы. А ERD БД — это вполне конкретная вещь, которую можно напрямую трансформировать в SQL код создания объектов БД, можно нормализовать и т.д. А как, например, нормализовать ERD предметной области? :)))

          Вроде бы всегда разделяли логическую модель данных (количество в штуках или деньгах) и физическую модель данных (количество в long или double в поле count и amount).

          Понятное дело, что как программист, вы можете сразу родить анемичную свернутую модель, «интуитивно», но постулировать такой путь как «best practice» сомнительно. И проектировать от «физики» точно не есть хорошо


          1. SergeyUstinov
            23.06.2017 15:28
            +1

            Типы полей в ERD БД очень часто вообще не указываются. Диаграмму надо рисовать в первую очередь для нормализации (денормализации), а типы данных для этой задачи не важны.
            Схема БД (ERD) — это в первую очередь логическая структура данных, а не физическая. Вы её точно ни с чем не путаете?


            1. Lofer
              23.06.2017 16:34

              Схема БД (ERD) — это в первую очередь логическая структура данных, а не физическая. Вы её точно ни с чем не путаете?

              Ключевые слова, на которые среагировал это «База данных» и ".А ERD БД — это вполне конкретная вещь, которую можно напрямую трансформировать в SQL код создания объектов БД"
              Диаграмму надо рисовать в первую очередь для нормализации (денормализации), а типы данных для этой задачи не важны.

              А без типов не сгенерить схему для БД и SQL для генерации. Да и нормальзация — это обычно термин из области БД.

              вот и выходит что «физическая модель»
              была бы приписка
              Conceptual data model, Logical data model, Physical data model — не вопрос :)


              1. SergeyUstinov
                23.06.2017 17:09

                :)))
                Разошлись в терминологии.
                Я говорил о Conceptual data model и Logical data model
                То есть сперва делаем Conceptual data model, потом рисуем первую версию Logical data model (без кучи деталей), потом режем на модули, потом рисуем для каждого модуля Logical data model с большей детализацией, но всё еще без типов данных и не все поля перечислены, потом рисуем структуру классов java (то есть «натягиваем» код на схему бд, а не наоборот).
                И в дальнейшем, параллельно с реализацией классов java, создаем Physical data model (sql скрипты, которые непосредственно создают таблицы, ограничения, индексы и т.д.)


                1. Lofer
                  23.06.2017 17:32

                  Это другое дело :) Это по всем правилам :)


              1. SergeyUstinov
                23.06.2017 17:38

                Пример:
                Захотели написать приложение для торговли запчастями. Делаем совсем базовый вариант.

                Какие сущности будут нужны:
                Товары
                Покупатели
                Поставщики
                Места хранения

                Заказы продажи
                Заказы покупки

                Операции с товарами — поступления, отгрузки, перемещения

                Это и есть концептуальная модель данных (по крайней мере с моей точки зрения).

                Предположим, порезали на модули на этом этапе.

                И дальше пишем код и параллельно делаем логическую и физическую схему данных.

                И тут натыкаемся на замечательную вещь. У заказа продажи есть такая особенность, что утвержденный заказ создает «резерв» товаров — уменьшает «свободный остаток» товаров на складе. А, предположим, остатки товаров и все контроли, связанные с товарами (нельзя отгрузить больше товаров, чем есть в наличии и т.п.), мы реализовали в модуле «товародвижения», а заказы продажи в модуле «продажи»…
                То есть два куска очень тесно связанных данных оказались в разных модулях, что может доставить много «приятных» минут.
                И на уровне концептуальной модели подобные приколы увидеть нельзя.


                1. Lofer
                  23.06.2017 17:54
                  +1

                  Предположим, порезали на модули на этом этапе.

                  И дальше пишем код и параллельно делаем логическую и физическую схему данных.

                  А вот это и есть проблема.
                  потому что получается «И тут натыкаемся на замечательную вещь. » — это значит что бизнес анализ не завершен, а архитектор не провел валидацию доменной модели/ SergeyUstinov «Это и есть концептуальная модель данных (по крайней мере с моей точки зрения). ».
                  Один из результатов работы архитектора — валидация целостности доменной модели, что он получил от бизнес аналитика. с точки зрения: кто делает, что делает, над чем делает и зачем делает. Роли/Системы, действия, данные и конечный результат.
                  То есть два куска очень тесно связанных данных оказались в разных модулях, что может доставить много «приятных» минут.

                  Задача архитектора грамотно «нарезать», что бы не было косяков после в разработке.


                  1. SergeyUstinov
                    23.06.2017 18:47
                    +1

                    Согласен.
                    Я об этом и говорю — именно создание корректной и полной (но не обязательно детальной) логической модели данных (ERD) позволяет грамотно нарезать на модули систему.
                    До тех пор, пока не получена корректная (нормализованная) и достаточно полная схема БД — как можно говорить о корректной доменной модели?

                    В статье много рассуждается о структуре классов, а вот о корректной логической схеме данных — ни слова. Это часто встречается среди программистов, которые работают с ORM. Многие вообще не думают о схеме БД.

                    Но если для каких-то типов задач такой подход дает удовлетворительный результат, то для «учетных» систем такой подход чреват наступлением на очень серьезные грабли.


                    1. Lofer
                      23.06.2017 19:15
                      +1

                      До тех пор, пока не получена корректная (нормализованная) и достаточно полная схема БД — как можно говорить о корректной доменной модели?

                      Простите, но вы путаете причину со следствием.
                      В начале делается доменная модель, последнее — физическая модель, в конкретном случае «схема БД»

                      Domain model
                      A domain model is a system of abstractions that describes selected aspects of a sphere of knowledge, influence or activity (a domain[3]). The model can then be used to solve problems related to that domain. The domain model is a representation of meaningful real-world concepts pertinent to the domain that need to be modeled in software. The concepts include the data involved in the business and rules the business uses in relation to that data.

                      A domain model generally uses the vocabulary of the domain so that a representation of the model can be used to communicate with non-technical stakeholders.
                      Usage

                      A domain model is generally implemented as an object model within a layer that uses a lower-level layer for persistence and «publishes» an API to a higher-level layer to gain access to the data and behavior of the model.

                      In the Unified Modeling Language (UML), a class diagram is used to represent the domain model.


                      1. SergeyUstinov
                        23.06.2017 20:39
                        +1

                        :)))
                        Правильно.
                        Сначала рисуем доменную модель с Conceptual data model:

                        A domain model generally uses the vocabulary of the domain so that a representation of the model can be used to communicate with non-technical stakeholders.

                        А после нам надо проверить — а нет ли каких пробелов в нашей доменной модели / концептуальной схеме данных?
                        Для этого мы рисуем логическую схему данных в виде нормализованной ER диаграммы.
                        A logical data model or logical schema is a data model of a specific problem domain expressed independently of a particular database management product or storage technology (physical data model) but in terms of data structures such as relational tables and columns, object-oriented classes, or XML tags. This is as opposed to a conceptual data model, which describes the semantics of an organization without reference to technology

                        И при построении этой логической модели данных мы как раз и проверяем, нет ли ошибок в концептуальной модели данных.
                        И если (вернее, когда))) мы находим нестыковки — надо вернуться к доменной модели / концептуальной модели данных, и исправить допущенные ошибки.
                        Как вообще можно искать ошибки, не пытаясь построить нормализованную ER диаграмму?

                        А физическая модель — это схема БД, оптимизированная под конкретную СУБД, часто частично денормализованная и т.п.

                        То, что мы сначала рисуем доменную (концептуальную) модель, не значит, что мы не должны править эту модель после попытки нарисовать логическую структуру данных (нормализованную ER диаграмму).


                        1. Lofer
                          23.06.2017 21:15

                          То, что мы сначала рисуем доменную (концептуальную) модель, не значит, что мы не должны править эту модель после попытки нарисовать логическую структуру данных (нормализованную ER диаграмму).

                          Именно это и значит — не должны.
                          Если вынуждены «затачивать» доменную модель под физику — это не верно.
                          Это значит то, что доменная модель была не верна изначально!


                          1. SergeyUstinov
                            23.06.2017 21:36
                            +1

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

                            О чем статья? Создали доменную модель, на её основе выработали архитектуру приложения, но потом обнаружили, что у нас проблемы.
                            С моей точки зрения, причина этих проблем — неправильная доменная модель, в первую очередь в части концептуальной модели данных. И чтобы избавиться от проблем, надо найти и устранить ошибки / неточности / пробелы в доменной модели.
                            А как найти ошибки в схеме данных? — попробовать построить нормализованную реляционную схему данных. Теория реляционных БД как раз и разрабатывалась под такие задачи.

                            Схема данных — это не физика. Это именно логическая модель данных.


                            1. VolCh
                              24.06.2017 02:55

                              Схема данных БД приложения — это логическая модель системы хранения данных приложения в общем случае. Это слой(один из) абстракции между доменной моделью и их физическим хранением. Даже РСУБД имеет полное право наплевать на заданные ей логические схемы и хранить данные как ей заблагорассудится, хоть в денормализованном виде вообще, хоть в нормализованном, но по столбцам, а не по строкам — лишь бы соблюдала контракт.


                              1. SergeyUstinov
                                24.06.2017 12:07

                                С точки зрения прикладного программиста схема БД, выраженная в конкретных SQL инструкциях для СУБД — это скорее физическая модель, так как на этом уровне часто делают денормализацию. Хотя по классике это, разумеется, логическая модель, а физическую знает только СУБД.

                                Но удобно разделять «логическую» схему БД — нормализованную ER диаграмму, которая может не содержать многих деталей (типы полей, некоторые поля или вообще не содержать некоторых второстепенных таблиц) и «физическую» схему БД, которая уже «адаптирована» под конкретную СУБД, возможно, частично денормализована и содержит все детали.


                    1. VolCh
                      24.06.2017 02:45
                      +1

                      Доменная модель в общем случае не связана со схемой БД от слова «никак». На уровне домена мы можем (или даже должны) оперировать денормалмзованными моделями, а на уровне схемы БД можем их нормализовать, и наоборот. Маппинг доменной модели на схему БД — обычно задача отдельного слоя приложения, протечки в котором чаще всего допустимы лишь во имя нефункциональных требований типа потребления ресурсов.


                      1. SergeyUstinov
                        24.06.2017 12:12
                        -1

                        Для «учетных» систем корректная схема данных является критичной. И если при проработке доменной модели мы ошибемся — будут очень большие проблемы.
                        Я не знаю других способов проверить корректность структуры данных на уровне доменной модели, кроме как попробовать составить логическую схему данных — нормализованную ER диаграмму.


                1. oxidmod
                  23.06.2017 17:54

                  Но как вы создаете этот заказ? Вы хотите создать заказ на 10 единиц товара. Вам каким-то образом нужно провалидировать это число «10». Например спросив у сервиса который отвечает за остатки а есть ли у него 10 товаров. Лучше даже не так. Сказав ему, что закинь в резерв 10 товаров и в ответ получите идентификатор резерва или ошибку о недостаточном количестве. Теперь у себя вы создаете заказ связав его с полученным идентификатором резерва.
                  Клиент переходит на оплату и оплачивает заказ. В зависимости от результата оплаты вы уведомляете сервис «товародвижения» что резерв подтвержден или аннулирован.


                  1. SergeyUstinov
                    23.06.2017 19:03

                    Именно в торговле запчастями с резервами всё не так просто.
                    Часто есть понятие торговли «под заказ» — клиент делает заказ, и ему привозят через некоторое время (от поставщика или с другого склада).
                    Или например кладовщик собирает заказ и видит, что деталь бракованная, и перемещает в зону «брак». И при этом надо что то делать с заказом продажи — ведь теперь товара под него не хватает.

                    В одном случае, когда система начала не справляться с нагрузкой из-за блокировок, вообще пришлось создавать отдельный «микросервис» для обработки резервов. Вот здесь это обсуждали.


                    1. oxidmod
                      23.06.2017 19:17
                      +1

                      Но это не имеет никакого отношения к схеме бд.
                      Есть конкретные бизнес-требования, есть конкретные решения.
                      Доменная модель должна прорабатываться от бизнесса, а не от схем бд/блокировок

                      зы. Перешел на топик и меня смутило:

                      В процессе обсуждения выявили как минимум одну задачу, которую нельзя решить при использовании распределенных баз — это резервирование на нескольких складах.


                      Для этого существует двух-фазный коммит


                      1. SergeyUstinov
                        23.06.2017 21:03

                        Как при создании доменной модели вы проверяете, что в концептуальной модели данных (которая является составной частью доменной модели) нет существеннных ошибок или пробелов, которые в свою очередь могут привести к крупным ошибкам в архитектуре приложения?

                        А по поводу топика и двухфазного коммита — в обсуждении под распределенными базами подразумевается решение 1С:
                        Механизмы обмена данными позволяют создавать территориально распределенные информационные системы обменивающиеся данным в офф-лайн режиме, без постоянного соединения.


                        1. Lofer
                          23.06.2017 21:42

                          Как при создании доменной модели вы проверяете, что в концептуальной модели данных (которая является составной частью доменной модели) нет существеннных ошибок или пробелов, которые в свою очередь могут привести к крупным ошибкам в архитектуре приложения?

                          В доменной модели ничего не проверяется, потому что это «поставновка задачи» фактически. т.е. в в номеклатуре есть имя, артикул, производитель, вес.

                          А что бы было еще веселее — вот вам еще куча бизнес-правил и ограничений, вроде «уникального артикула» и «цена не менее 0».
                          И убейтесь об стену, но ваша физика должна эти данные сохранить. и обеспечить исполнение этих правил. Как? Хотите индексы в БД стройте, хотите в бизнес-логику пихайте — это ваша проблема.
                          Это работа архитектора


                          1. SergeyUstinov
                            23.06.2017 22:22

                            Я под доменной моделью понимаю некую схему, которая возникает в мозгу архитектора после получения информации от заказчика. И эта схема (которая в мозгу) является исходными данными при формировании архитектуры.

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

                            Причем ошибки являются правилом, а не исключением.

                            Самая трудная отдельная задача в разработке программной системы — это точно решить, что разрабатывать. Ни одна другая задача работы над концепциями не является столь трудной, как разработка подробных технических требований, включая все интерфейсы пользователей, машинные интерфейсы и интерфейсы к другим программным системам. Ни одна другая часть работы не наносит такого ущерба готовой системе, если сделана неправильно. Ни одна другая часть не исправляется позднее с бульшим трудом.
                            Поэтому наиболее важной функцией, осуществляемой разработчиками для своих клиентов, является повторяющееся получение и уточнение требований к продукту. Правда заключается в том, что клиенты не знают, чего хотят. Обычно они не знают, на какие вопросы нужно дать ответ, и почти никогда не задумывались над задачей настолько детально, как это нужно указать в спецификации. Даже простой ответ — «сделайте так, чтобы новая программная система работала так, как наша старая ручная система обработки информации» — оказывается в действительности слишком упрощенным. Клиенты никогда не хотят этого в точности. Более того, сложные программные системы действуют, движутся, работают. Динамику этого действия трудно себе представить. Поэтому при планировании любых действий необходимо оставить резерв для многократного взаимодействия между клиентом и проектировщиком при описании системы.
                            Я пойду дальше и стану утверждать, что на практике клиенты, даже вместе с инженерами-программистами, не в состоянии указать полно, строго и корректно точные требования к современному программному продукту, прежде чем будут созданы и опробованы какие-либо версии продукта, спецификации к которому они составляют.

                            Хоть и написано до моего рождения, но в этой области вообще ничего не изменилось. :)))

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


                            1. Lofer
                              23.06.2017 22:39

                              Более того, сложные программные системы действуют, движутся, работают. Динамику этого действия трудно себе представить.
                              Хоть и написано до моего рождения, но в этой области вообще ничего не изменилось. :)))


                              Лет эдак 25...30 назад даже UML нотация покрывали эту потребность. С тех пор появились новые нотации, новые приемы и новые инструменты, которые практически на 100% решают такие задачи, вплоть до самовалидации. на этапе рисования.
                              Я пойду дальше и стану утверждать, что на практике клиенты, даже вместе с инженерами-программистами, не в состоянии указать полно, строго и корректно точные требования к современному программному продукту, прежде чем будут созданы и опробованы какие-либо версии продукта, спецификации к которому они составляют.

                              На моей памяти, нормально сделанные проекты при соблюдении методологии таких проблем не было. Сдавались с первого раза и шли в работу, как минимум 5 проектов с более чем годовым циклом (для примерной оценки объема)


                              1. SergeyUstinov
                                23.06.2017 23:00

                                На моей памяти, нормально сделанные проекты при соблюдении методологии таких проблем не было. Сдавались с первого раза и шли в работу, как минимум 5 проектов с более чем годовым циклом (для примерной оценки объема)

                                Какой методологии? Водопада?


                                1. Lofer
                                  23.06.2017 23:06

                                  Какой методологии? Водопада?

                                  От проектной метологии не зависит. И водопад тоже был и Scrum.


                                  1. SergeyUstinov
                                    23.06.2017 23:42
                                    +1

                                    Ну что тут сказать — круто! Совсем как Слепаков спел. :)))

                                    Ведь у меня и всех моих знакомых такие проблемы были…
                                    Иногда больше, иногда меньше — но на всех проектах.


                              1. SergeyUstinov
                                23.06.2017 23:18

                                Лет эдак 25...30 назад даже UML нотация покрывали эту потребность. С тех пор появились новые нотации, новые приемы и новые инструменты, которые практически на 100% решают такие задачи, вплоть до самовалидации. на этапе рисования.

                                ???
                                Ваши клиенты хорошо знают UML и новые нотации / инструменты? И с их помощью тот же начальник отдела логистики, например, легко может себе представить алгоритм построения маршрута?

                                И например все эти команды, которые уже более 10 лет разрабатывают автопилот (всягие гуглы и апплы) — просто не в курсе этих новых инструментов, раз не могут легко представить себе, как именно автопилот должен работать? :)))


                                1. Lofer
                                  24.06.2017 12:42

                                  Ваши клиенты хорошо знают UML и новые нотации / инструменты? И с их помощью тот же начальник отдела логистики, например,
                                  легко может себе представить алгоритм построения маршрута?

                                  Я вас удивлю, наверное, но 10....20 минут достаточно что бы «начальник отдела логистики» вполне мог обсуждать и проводить review представленных диаграмм процессов и моделей данных. Примените корретную мотивацию :)


                        1. Lofer
                          23.06.2017 21:58

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


                          1. SergeyUstinov
                            23.06.2017 22:28

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

                            Создание нормализованной ER диаграммы как раз и является, по моему мнению, хорошим инструментом для поиска неувязок в концептуальной схеме данных и в целом в доменной модели.
                            Правда, это хорошо работает только при создании «учетных» систем, при создании приложений другого типа этот инструмент не очень полезен.


                            1. Lofer
                              23.06.2017 22:49

                              Создание нормализованной ER диаграммы как раз и является, по моему мнению, хорошим инструментом для поиска неувязок в концептуальной схеме данных и в целом в доменной модели.

                              В общем да.
                              BA в принципе в три стадии проходит: запись «потока сознания», свертка модели данных/очистка от противоречивых данных, рефакторинг (если требуется изменение существующей системы).
                              Правда, это хорошо работает только при создании «учетных» систем, при создании приложений другого типа этот инструмент не очень полезен.

                              Абсолютно без разницы — результат одинаков и не зависит от приложения если соблюдается методология.


                1. mayorovp
                  23.06.2017 18:38

                  Такие приколы сложно увидеть на любом уровне если не знать куда смотреть.


              1. VolCh
                24.06.2017 02:33
                +1

                Схема БД — не логическая структура данных, а структура хранения данных.


  1. alexhott
    22.06.2017 19:24
    +10

    Я вас огорчу, но вы пока занимаетесь детскими задачами. Откройте например постановление 354 по расчету платы за коммуналку и запроектируйте.


    1. VolCh
      24.06.2017 03:00

      А тем не чистая функция, пускай и от сотни параметров?


  1. SirEdvin
    22.06.2017 20:05
    +2

    А какой фреймворк возьмем? Если немного погуглить, то станет понятно, что особо вариантов нет, мы будем делать на Spring Framework. Причина проста, в Spring Cloud есть все, что нам потребуется.

    Да ладно? http://www.gajotres.net/best-available-java-restful-micro-frameworks/. Выбор более чем есть. Я не особо вкурсах, но Spring Cloud же правда не tomcat использует?


    Для тех, кто думает что нет, что язык программирования второстепенен и вообще, важна только команда, я предлагаю провести маленький мысленный эксперимент. Подумайте, на каком языке вы бы такой проект точно не делали, т.е. считаете, что это было бы однозначно неправильное решение. А теперь представьте себе, что архитектор решил таки сделать проект именно на этом языке. А когда вы будете гневно возмущаться, он вам скажет: это второстепенный вопрос, главное команда!

    Потому что заставлять писать команду на языке, который она не знает довольно глупо, нет? Но такого языка нет, все решается затратами и неудобством. Если нужно писать на haskell и мне объяснят, почему именно на нем (скажем, какая-то важная либа есть только под него) то так и быть. Почему нет?


    1. VolCh
      24.06.2017 03:05

      С точки зрения бизнеса ЯП и прочий техстэк имеет три глобальных метрики в целом:
      — стоимость реализации имеющейся командой
      — стоимость реализации новой командой
      — покупка готового (или почти)/решения


  1. Ogoun
    22.06.2017 20:41

    А можно и по другому. При старте каждый сервис должен постучаться к VehicleTypesService сообщить ему о своем существовании. Это решение вроде хорошо выглядит, но не отвечает на вопрос что делать, если нам надо не добавить, а удалить вид транспортного средства.


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


    1. VolCh
      24.06.2017 03:12

      А если актуальность важна, но не сильно? Например, выбор способа отправки поздравления друга с днём рождения за несколько часов до его наступления, с учётом условий типа «предпочтительнее емэйл, но если на момент отправки он будет лежать, то отправить смс, а если лежит прямо сейчас и время отправки в сла не укладывается, то мыло не предлагать»


      1. Ogoun
        25.06.2017 20:35

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


  1. sshikov
    22.06.2017 22:17
    +1

    >единая точка входа, он же API Gateway
    >поиск сервисов, он же Service Discovery
    >одна точка конфигурации, он же Config Service
    >центральная точка сбора и анализа логов
    >мониторинг

    И в итоге мы получаем… получаем… ну например полноценную реализацию OSGI. Где микросервисы — вовсе не автономные непонятно какие процессы, а управляемые объекты в управляемой среде, где есть и поиск/дискавери, и сбор/анализ логов, и мониторинг, и конфигурация, и многое другое.


  1. Lofer
    22.06.2017 22:49

    >поиск сервисов, он же Service Discovery

    UDDI?


  1. ngalayko
    22.06.2017 23:15
    +6

    Во первых, если ты считаешь, что твоя архитектура хороша, то это значит, что ты ее еще никому не показывал. К коду это, кстати, тоже относится.

    комментарии подтверждают


  1. AlexLeonov
    22.06.2017 23:34

    Внимательно прочел, нашел одну принципиальную ошибку — что мешает разным сервисам пользоваться одной (ОК, физически разными, но реплицируемыми или federated) базами данных? Ответ: ничто не мешает.

    Сервис — это превращатель request в response. Какую он там БД использует — исключительно его дело, не так ли?


    1. Borz
      23.06.2017 00:19

      и в какой-то момент вы получаете на одну БД десяток сервисов использующих некую таблицу N для своих нужд и не только читающих из неё, но и пишущих. А завтра вам надо в эту таблицу для сервиса K добавить колонку с NOT_NULL флагом.
      Что будем делать?


      1. mayorovp
        23.06.2017 06:38
        +1

        Если про колонку знает только 1 сервис из десятка — ей не надо ставить NOT NULL флаг


        1. VolCh
          24.06.2017 03:15

          А что делать с многочасовым блокирующим alter table? Уход с мускуля не предлагать. :)


          1. oxidmod
            24.06.2017 12:40

            Оставлю это здесь


    1. VolCh
      24.06.2017 03:29

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


  1. p9202583853
    23.06.2017 00:18

    Весьма интересно! С удовольствием подожду продолжения!

    ...умл диаграмки можно и наряднее, красивенько чтоб
    image


  1. Nelly2k
    23.06.2017 09:26

    А что автор еще пореккомендует почитать/посмотреть по архитектуре микросервисов, очень инетересует практический вопрос authorisation and authentication?


    1. schroeder
      23.06.2017 10:01
      -1

      Я бы порекомендовал основательно покопаться на этом сайте(Обратите внимание на комменты, бывают очень интересно):

      http://microservices.io/index.html

      По поводу Security. У Spring'а есть Spring Security. Но вообще лично я очень трепетно отношусь к таким вещам, ибо понимаю я в них не много, а потенциальный ущерб от них огромен. Для меня это примерно как дать студенту программировать софт для космических ракет. Он(студент) наверное таки что то сделает и это будет даже работать, но однажды вся эта штука взорвется красивым феерверком и уничтожит всю вашу работу. Поэтому я иду к спецам и спрашиваю, что и как делать. IMHO конечно.


  1. kraso4niy
    23.06.2017 09:26

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


    Не согласен с этим пунктом.
    Есть много ситуации когда важно получить отклик и это влияет на архитектуру.
    Или важно понять приоритеты задач.
    Далее этот пункт также порождает выбор языка, фреймворка, технологий.


  1. Rus695
    23.06.2017 12:25

    Серебренной пули не существует ;) Каждый изобретает свой велосипед подход, к достижению им же самим заданной планки перфекционизма. Всегда интересно сравнить свой и чужой опыт в этом процессе.
    Ждем продолжения!


  1. dikkini
    23.06.2017 12:34

    А у меня еще вопрос: вы про системного архитектора или программного архитектора?


  1. benbor
    23.06.2017 14:37
    +6

    Спасибо за статью
    Но судя по заголоку:


    Это вопрос должен решать архитектор. Или нет?

    и началу статьи:


    Мы увидим,… и зададимся вопросом, должен ли в данном случае принимать решение архитектор или разработчик может решить эту проблему сам.

    ожидал в статье больше выводов, в стиле: Да, это должен решить программист, а это архитектор.


  1. cepro
    23.06.2017 14:40
    +1

    Спасибо! Ждем продолжения.


  1. akava
    27.06.2017 11:29

    Привет,
    статья интересная. Сразу видна ищущая душа и хороший опыт в разработке.
    Для полного ответа нужно писать хорошую статью. Попробую сделать это к/за выходные.

    Если же коротко (дальше будет критика и помидоры), то статья написана программистом, хорошим Lead разработчиком, но еще не архитектором.
    Было принято вагон решений, практически в каждом абзаце, но они необоснованны. Но я даже больше больше скажу: их невозможно обосновать в данных условиях.

    Почему? Нету требований. Особенно нефункциональных (те самые Quality Attributes: https://msdn.microsoft.com/en-us/library/ee658094.aspx).
    Без нефункциональных требований (NFR) практически любая архитектура подойдет для озвученной задачи.
    С точки зрения снижения стоимости: девушка на телефоне с журналом заявок (даже не экселькой) подходит. Вот и Solution. Забирай, мне не жалко.
    Косвенно про NFR было сказано только в секции «Добавление нового типа транспорта в систему». Quality Attribute (QA) называет Modifiability. Рассмотрены два варианта: Runtime configuration и Development. Вариантов намного больше: https://image.slidesharecdn.com/sap3chapter7-140630124448-phpapp02/95/software-architecture-in-practice-chapter-7-4-638.jpg (картинка из Software Architecture in Practice. Обратите внимание на Artifacts (это то, что меняется) и Environment (это когда меняется).
    Так же упоминается выбор языка программирования (Conceptual Integrity, Maintainability, Reusability), Отказоустойчивость (Availability и Reliability), мониторинг и логирование (Supportability),… Но без конкретики работать с этим нельзя.

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

    Если коротко (еще короче чем выше):
    Когда будешь задумываться о нефункциональных требованиях — станешь на путь к System Architect-ору.
    Когда будешь задумываться о бизнесе и пользе клиентам — станешь на путь к Solution Architect-ору.

    Литература для расширения сознания:
    Книга Software Systems Architecture: Working with Stakeholders Using Viewpoints and Perspectives https://www.amazon.com/Software-Systems-Architecture-Stakeholders-Perspectives-ebook/dp/B0061LAKW0
    В ней про NFR и работу с бизнесом.

    Видео: Евгений Кривошеев — Как не угробить архитектуру сразу же https://www.youtube.com/watch?v=_Kex5hwGE-w
    В ней как раз о решениях, которые принимает архитектор. Очень доступно.

    Видео: Who is solution architect? — Architecture Community Gomel https://www.youtube.com/watch?v=oNFGvEiPFoU
    Моя презентация про Solution Architect. В ней тоже про решения и роль архитектора на проекте.