Многослойна архитектура, базирана на yii framework

слой
Нека си представим компания, която продава редица свои собствени продукти - както за външни потребители, така и за вътрешни. Най-вероятно всеки продукт няма да може да съществува отделно, като сферичен кон във вакуум, а ще бъде интегриран с други до известна степен. В резултат на това всички те заедно образуват определен слой от взаимосвързани и в същото време независимо развиващи се организми. И най-вероятно тяхното развитие се извършва от напълно различни екипи.

Именно за опита в организирането на архитектурата на цялата продуктова линия на такава компания искам да говоря. Нашите външни уеб продукти са онлайн версия, API за отворена справка и услуга за картографиране и обратна връзка. Вътрешни: CRM, таксуване, алгоритмични изчисления, статистически системи и износ-импорт на данни.

Нека изведем две концепции:

Уеб инфраструктура — набор от фирмени уеб продукти, които са свързани помежду си и работят в подобни тематични области.

Технологична база е единна кодова база за уеб инфраструктурата на компанията. Съдържа набор от програмни блокове с високи и ниски нива на абстракция. Блоковете от високо ниво са обекти, които вече са разработени от екипа за разработка в предметната област на компанията. Блоковете от ниско ниво са например набор от библиотеки или рамки.

За да гарантираме критериите за качество на технологичната база, решихме да заложим слоеста архитектура.Слоестата архитектура е системна архитектура, в която системата се състои от някакъв подреден набор от софтуерни подсистеми, наречени слоеве, така че:

  • на всеки слой не се знае нищо за свойствата (и дори съществуването) на следващите (по-високи) слоеве;
  • всеки слой може да взаимодейства при управление(отнася се до компоненти) с непосредствено предходния (долния) слой чрез предварително дефиниран интерфейс, без да знае нищо за вътрешната структура на всички предишни слоеве;
  • всеки слой има определени ресурси, които или скрива от други слоеве, или предоставя директно на следващия слой (чрез посочения интерфейс) някои от техните абстракции.
По този начин, в многослойна софтуерна система, всеки слой може да приложи някаква абстракция на данни. Връзките между слоевете са ограничени чрез предаване на стойностите на параметрите на извикването на всеки слой към слоя, съседен на дъното, и издаване на резултатите от това извикване от долния слой към горния. Няколко слоя не могат да използват глобални данни. По-пълно определение може да се намери в работата на Фаулър.

Без да разглеждаме мрежата и сървърите, които сами по себе си са отделни слоеве, нека разгледаме устройството на технологичната платформа. Има три слоя:

базирана
Фиг. 1. Слоеве на архитектурата на технологичната платформа

На фиг. 1 избрани три слоя:

  • Основен слой — основен слой. Тук се намират общи библиотеки и рамки на ниско ниво. Например, yii.
  • Споделен слой - слой от модули, които реализират някои системни функционалности, които могат да се използват в няколко проекта.
  • Приложен слой - приложен слой. Това ниво съдържа всички приложения с техните специфични модули.
В същото време важното е, че модулите трябва да могат лесно да се преместват от приложния слой към общия модулен слой. Това се обяснява много просто: когато стартира нов проект, обикновено се внедрява най-необходимата функционалност. С развитието на проекта той започва да придобива връзки с други продукти (ние решихменапример, изтеглете рецензии от един проект към кафенетата на другия ни проект) и може би някои от модулите може да са необходими за други проекти. Или проектът е разделен на части, а модулите са разделени на няколко приложения.

Нека разгледаме по-подробно файловата организация на приложението в слоя Application, като вземем предвид спецификата на yii.

фиг. 2. Организация на файловете на приложението yii

Както виждаме, има компоненти и разширения както на ниво приложение, така и на общо ниво (споделено). Ето структурата на приложението, което вече е изградено от хранилището. Разбира се, в системата за контрол на версиите можете да организирате всичко по различен начин. Например, имаме два режима на изграждане, когато всичко се излива в папката на приложението и когато се правят символни връзки към библиотеката с разширения. Първият е необходим за изолиране на различни приложения, когато не можем отделно да актуализираме разширения, без да актуализираме всички приложения, и за разполагане на множество екземпляри на една и съща машина. Или разполагане на различни клонове на един и същи сървър. Второто е удобно за разработчиците при работа с код.

И така, поставихме гъвкава основа за нашата уеб инфраструктура, но достатъчно ли е това? Не. Две важни неща липсват:

  • архитектурата на приложението трябва да бъде слабо свързана и споделена;
  • система за внедряване и сглобяване на продукта.
Сега за всеки елемент по-подробно.

Архитектура на приложението

Нека също използваме слоевете като основа на архитектурата на приложението. Нека изберем следните нива:

слой
Фиг. 3. Слоеве на yii приложение

Слоят от "тънки" контролери съдържа минимум логика и работи с разширението API. Слоят на бизнес логиката се състои от разширителен слой и слой на модел на данни. Разширителният слой на Yii и моделите на данни имат много силна степен на свързване, диаграмата показва това повечеудебелена стрелка.

Най-голяма степен на свързване съществува между приложението и тънките контролери. Възможността за повторно използване е минимална. Но свързването между слоя на „тънките“ контролери и слоя на бизнес логиката трябва да бъде възможно най-малко, тъй като можем и трябва да използваме повторно бизнес логиката в другите си приложения. И можем да направим това с помощта на гъвкавостта на Yii и неговата конфигурация.

Конфигурацията свързва набора от компоненти и разширения, от които се нуждаем. Пример за свързване на разширение:

'geoip' => масив ('class' => 'application.extensions.GeoIP.CGeoIP' ),

Разширението, което се инициализира в приложението, може да бъде достъпно с помощта на ключа geoip. Например:

При първия достъп до компонента класът CGeoIP ще бъде инициализиран. Гъвкавостта се крие в наличието на ключа :-) Можем да променим изпълнението по всяко време чрез конфигурацията и приложението ще работи както преди, използвайки ключа geoip.

Въз основа на тази гъвкавост можем лесно да управляваме връзката между приложението и слоя на бизнес логиката.

Чрез групиране на логиката на работа с определен обект на приложение в разширения, ние го правим разделим. По този начин всички модели са капсулирани в разширението и контролерът на приложението работи с данните чрез API на разширението.

Разширенията са допълнителен слой абстракция за нас, зад който можем да скрием източниците на данни, необходими за вътрешната работа на определени разширения API методи.

Нека бъдем малко креативни и измислим приложение:

архитектура
фигура 4. Пример за архитектура на yii приложение

Нашето приложение работи с няколко разширения. Разширенията работят върху набор от данни и са тясно свързани със слоя модел. Важен момент: степента на свързаност между слоевете нараства отгоре надолу. стегнативсички модели на данни са взаимосвързани.

многослойна
фиг. 5

Поставяме UserServiceRestClient в споделеното ниво и променяме класа, който да се използва в конфигурацията на приложението. Тъй като API е същият, заместването на внедряването се извърши без промяна на кода. Много гъвкав! Всички други приложения също работят с потребителската услуга, използвайки UserServiceRestClient.

И така, разбрахме архитектурата, но с този подход конфигурацията на приложението ще бъде доста голяма. Ръчното предписване на всички зависимости за приложението изобщо не е като джедай. Особено когато проектът е жив и има и миграции на бази данни. Всички тези проблеми могат да бъдат решени с помощта на вашата система за изграждане и внедряване на продукта.

Система за внедряване и изграждане

Какво трябва да прави системата за внедряване:

  • доставете кода в посочената директория на сървъра;
  • изтеглете всички зависимости на приложението (разширения на споделено ниво и рамка);
  • генериране на конфигурация на приложението;
  • извършване на миграции на sql база данни.
И също - задачите за изпълнение на модулни тестове, изграждане на версии за отстраняване на грешки на проекта и т.н. Не изброявам всичко, това е въпрос на вкус и вече е обърнато доста внимание на всички тези операции в Интернет. Например, нашата система за внедряване конфигурира свързан софтуер като nginx, Sphinx, RabbitMQ и създава документация. Удобно!

Като цяло задачите са общи: файлови операции, работа със системи за контрол на версиите, стартиране на помощни програми на трети страни (PHPUnit, например, или Doxygen) и т.н. Трябва да се обърне внимание на генерирането на конфигурация. Направихме го по шаблон с мета-конфигурационен файл:

фиг. 6

Когато генерира конфигурация, Phing анализира шаблона и заменя всички контейнери с подходящите параметри, зададени в мета конфигурационния файл. Оказа се много удобно. всичкозависимостите на приложението задават мета-конфигурацията:

## Списък с разширения, компоненти и др. за инсталиране ## EXTENSIONS = myExt, myExt2 COMPONENTS = component1, component2 HELPERS = myHeper, myTextHelper COMMANDS =

Мета-конфигурацията също съдържа бази данни, пътеки, хостове - като цяло всичко. Допълнително удобство за автоматизация отново е, че всички тези параметри могат да бъдат предадени през командния ред на Phing и отменени. И в бъдеще, например, да организирате асемблирането на пакети за *nix OS, която използвате.

По този начин мета-конфигурационният файл е абстрактен слой от формата и броя на конфигурациите в нашето приложение.

Долната линия е гъвкавост на конфигурацията на Yii + система за изграждане = лесно конфигурируеми и изграждащи се продукти.

И така, какво ни показа опитът от използването на такава схема на работа през годината?

  • Ако има нужда от повторно използване на някои разширения, това няма да е проблем, непрекъснатият процес на интеграция също е изграден без никакви проблеми.
  • Има необходима граница на гъвкавост, която улеснява разработването и увеличаването на функционалността на приложенията. Функционалните блокове могат да бъдат създадени изключително бързо, без да се мисли за производителността и качеството на кода.
  • Ако интерфейсът е обмислен, винаги можете без страх да завършите функционалността, да подобрите производителността, да промените хранилището на данни и да преработите.
  • Добре обмислената система за внедряване на приложения ви позволява бързо да внедрите системата за тестване и минимизира грешките по време на внедряване на производствени сървъри, свързани с човешко невнимание.
  • Поради изолацията на отделните функционални модули, винаги е възможно да се отдели отделен екип за разработка, който да работи с него. Това ви позволява да решите проблемите с растежа на отдела за развитие и да не се превръщате вголяма неуправлявана колективна ферма, където всеки работи върху всичко и по този начин само си пречи.