Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Подсказка
Это фрагмент из книги, архитектор современных веб-приложений с ASP.NET Core и Azure, доступный в .NET Docs или в виде бесплатного скачиваемого PDF-файла, который можно прочитать в автономном режиме.
"Если вы считаете, что хорошая архитектура дорогая, испытайте плохую архитектуру." - Брайан Фут и Джозеф Йодер
Большинство традиционных приложений .NET развертываются в виде отдельных единиц, соответствующих исполняемому файлу или одному веб-приложению, работающему в одном домене приложений IIS. Этот подход является самой простой моделью развертывания и обслуживает множество внутренних и небольших общедоступных приложений очень хорошо. Тем не менее, даже учитывая одну единицу развертывания, большинство нетривиальных бизнес-приложений получают преимущество от некоторого логического разделения на несколько уровней.
Что такое монолитное приложение?
Монолитное приложение — это приложение, полностью автономное с точки зрения его поведения. Он может взаимодействовать с другими службами или хранилищами данных в ходе выполнения своих операций, но ядро его поведения выполняется в рамках собственного процесса, и все приложение обычно развертывается как единое подразделение. Если такое приложение должно масштабироваться горизонтально, обычно все приложение дублируется на нескольких серверах или виртуальных машинах.
Универсальные приложения
Наименьшее количество проектов для архитектуры приложений — одно. В этой архитектуре вся логика приложения содержится в одном проекте, компилируется в одну сборку и развертывается в виде одной единицы.
Новый проект ASP.NET Core, созданный в Visual Studio или из командной строки, начинается как простой монолит "все в одном". Он содержит все поведение приложения, включая логику представления, бизнеса и доступа к данным. На рисунке 5-1 показана структура файлов однопроектного приложения.
Рис. 5-1. ASP.NET Core приложение для одного проекта.
В одном сценарии проекта разделение проблем достигается с помощью папок. Шаблон по умолчанию включает отдельные папки для обязанностей шаблона MVC моделей, представлений и контроллеров, а также дополнительные папки для данных и служб. В этом соглашении сведения о презентации должны быть ограничены, насколько возможно, папкой "Представления", а сведения о реализации доступа к данным — классами, хранящимися в папке данных. Бизнес-логика должна находиться в службах и классах в папке Models.
Хотя однопроектное монолитное решение простое, оно имеет некоторые недостатки. По мере роста размера и сложности проекта количество файлов и папок будет продолжать расти. Проблемы пользовательского интерфейса (модели, представления, контроллеры) находятся в нескольких папках, которые не группируются по алфавиту. Эта проблема ухудшается только при добавлении дополнительных конструкций на уровне пользовательского интерфейса, таких как фильтры или modelBinders, в собственные папки. Бизнес-логика разбросана между папками "Модели и службы", и нет четких признаков того, какие классы в папках должны зависеть от других. Это отсутствие организации на уровне проекта часто приводит к коду spaghetti.
Для решения этих проблем приложения часто развиваются в решениях с несколькими проектами, где каждый проект считается размещенным в определенном слое приложения.
Что такое слои?
По мере роста сложности приложений один из способов управления этой сложностью заключается в том, чтобы разбить приложение в соответствии со своими обязанностями или проблемами. Этот подход следует принципу разделения проблем и может помочь сохранить растущую базу кода, чтобы разработчики могли легко найти, где реализованы определенные функциональные возможности. Многоуровневая архитектура предлагает ряд преимуществ за пределами простой организации кода, хотя.
Упорядочив код на слои, общие низкоуровневые функциональные возможности можно повторно использовать во всем приложении. Это полезно, так как это означает, что требуется написать меньше кода, так как оно может позволить приложению стандартизировать одну реализацию, следуя принципу не повторять себя (DRY).
Благодаря многоуровневой архитектуре приложения могут вводить ограничения на взаимодействие между слоями. Эта архитектура помогает достичь инкапсуляции. При изменении или замене слоя следует повлиять только на те слои, которые работают с ним. Ограничение того, какие слои зависят от других слоев, влияние изменений можно уменьшить, чтобы одно изменение не повлияло на все приложение.
Слои (инкапсуляции) упрощают замену функциональных возможностей в приложении. Например, приложение может изначально использовать собственную базу данных SQL Server для хранения данных, но в дальнейшем может выбрать облачную стратегию хранения данных или стратегию через веб-API. Если приложение правильно инкапсулировало реализацию сохраняемости в логическом слое, этот уровень SQL Server может быть заменен новым, реализующим тот же общедоступный интерфейс.
Помимо возможности переключения реализаций в ответ на будущие изменения требований, слои приложений также могут упростить переключение реализаций в целях тестирования. Вместо того чтобы создавать тесты, работающие с реальным уровнем данных или слоем пользовательского интерфейса приложения, эти уровни можно заменить во время тестирования поддельными реализациями, которые предоставляют известные ответы на запросы. Этот подход обычно делает тесты намного проще для написания и значительно быстрее для выполнения, по сравнению с запуском тестов в реальной инфраструктуре приложения.
Логический слой — это распространенный способ улучшения организации кода в корпоративных приложениях программного обеспечения, и существует несколько способов, с помощью которых можно упорядочить код на слои.
Замечание
Слои представляют логическое разделение в приложении. Если логика приложения физически распределена по отдельным серверам или процессам, эти отдельные целевые объекты физического развертывания называются уровнями. Это вполне возможно и довольно распространено, когда N-уровневое приложение развертывается на одном уровне.
Традиционные приложения архитектуры N-Layer
Наиболее распространенная организация логики приложения на уровнях показана на рис. 5-2.
Рис. 5-2. Типичные слои приложений.
Эти слои часто сокращены как пользовательский интерфейс, BLL (уровень бизнес-логики) и DAL (уровень доступа к данным). Используя эту архитектуру, пользователи выполняют запросы через слой пользовательского интерфейса, который взаимодействует только с BLL. BLL, в свою очередь, может вызывать DAL для запросов доступа к данным. Слой пользовательского интерфейса не должен выполнять запросы к DAL напрямую, а также не взаимодействовать с сохраняемостью напрямую с помощью других средств. Аналогичным образом, BLL должен взаимодействовать с хранением данных только через DAL. Таким образом, каждый слой несет собственную хорошо известную ответственность.
Одним из недостатков этого традиционного подхода к слоистым структурам является то, что зависимости, определяемые во время компиляции, идут с верхней до нижней части. То есть уровень пользовательского интерфейса зависит от BLL, который зависит от DAL. Это означает, что BLL, которая обычно содержит наиболее важную логику в приложении, зависит от сведений о реализации доступа к данным (и часто на существовании базы данных). Тестирование бизнес-логики в такой архитектуре часто сложно, требуя тестовой базы данных. Принцип инверсии зависимостей можно использовать для решения этой проблемы, как показано в следующем разделе.
На рисунке 5-3 показан пример решения, разбив приложение на три проекта по ответственности (или уровню).
Рис. 5-3. Простое монолитное приложение с тремя проектами.
Хотя это приложение использует несколько проектов для организационных целей, оно по-прежнему развертывается как единое подразделение, и его клиенты будут взаимодействовать с ним как с одним веб-приложением. Это позволяет выполнять очень простой процесс развертывания. На рисунке 5-4 показано, как такое приложение может размещаться с помощью Azure.
Рис. 5-4. Простое развертывание веб-приложения Azure
По мере роста потребностей приложения могут потребоваться более сложные и надежные решения развертывания. На рисунке 5–5 показан пример более сложного плана развертывания, поддерживающего дополнительные возможности.
Рис. 5-5. Развертывание веб-приложения в службе приложений Azure
Внутренняя организация этого проекта на несколько частей, основанных на разделении ответственности, улучшает поддерживаемость приложения.
Этот модуль можно увеличивать или разворачивать, чтобы воспользоваться преимуществами облачной масштабируемости по требованию. Масштабирование означает добавление дополнительных ресурсов ЦП, памяти, дискового пространства или других ресурсов на серверы, на которые размещается ваше приложение. Масштабирование означает добавление дополнительных экземпляров таких серверов, будь то физические серверы, виртуальные машины или контейнеры. При размещении приложения в нескольких экземплярах подсистема балансировки нагрузки используется для назначения запросов отдельным экземплярам приложения.
Самый простой подход к масштабированию веб-приложения в Azure — настройка масштабирования вручную в плане службы приложений приложения. На рисунке 5-6 показан соответствующий экран панели мониторинга Azure для настройки количества экземпляров, обслуживающих приложение.
Рис. 5-6. Масштабирование плана службы приложений в Azure.
Чистая архитектура
Приложения, которые соответствуют принципу инверсии зависимостей, а также принципам проектирования Domain-Driven (DDD), как правило, приходят к аналогичной архитектуре. Эту архитектуру называли по-разному на протяжении многих лет. Одним из первых имен была шестнадцатеричная архитектура, за которой следуют порты и адаптеры. В последнее время это упомянуто как архитектура Луковая или Чистая архитектура. Последнее имя, чистая архитектура, используется в качестве имени для этой архитектуры в этой электронной книге.
В справочном приложении eShopOnWeb используется подход "Чистая архитектура" для организации кода в проекты. Вы можете найти шаблон решения, который можно использовать в качестве отправной точки для собственных решений ASP.NET Core в репозитории ardalis/cleanarchitecture GitHub или установив шаблон из NuGet.
Чистая архитектура помещает бизнес-логику и модель приложения в центр приложения. Вместо того, чтобы бизнес-логика зависела от доступа к данным или других проблем инфраструктуры, эта зависимость инвертируется: инфраструктура и сведения о реализации зависят от ядра приложений. Эта функция достигается путем определения абстракций или интерфейсов в ядро приложения, которые затем реализуются типами, определенными на уровне инфраструктуры. Распространенный способ визуализации этой архитектуры — использовать ряд концентрических кругов, аналогичных луку. На рисунке 5-7 показан пример этого стиля архитектурного представления.
Рис. 5-7. Чистая архитектура; луковичный подход
На этой схеме зависимости направляются к самому внутреннему кругу. Ядро приложения берет свое имя из его позиции в основе этой схемы. На схеме можно увидеть, что ядро приложения не имеет зависимостей от других уровней приложений. Сущности и интерфейсы приложения находятся в самом центре. Непосредственно за пределами, но по-прежнему в ядре приложения, расположены доменные службы, которые обычно реализуют интерфейсы, определенные во внутреннем круге. Вне ядра приложения интерфейс и уровни инфраструктуры зависят от ядра приложения, но не друг от друга (обязательно).
На рисунке 5-8 показана более традиционная схема горизонтального слоя, которая лучше отражает зависимость между пользовательским интерфейсом и другими слоями.
Рис. 5-8. Чистая архитектура; горизонтальное представление слоя
Обратите внимание, что сплошные стрелки представляют зависимости времени компиляции, а тиреная стрелка представляет зависимость только для среды выполнения. С чистой архитектурой слой пользовательского интерфейса работает с интерфейсами, определенными в приложении Core во время компиляции, и в идеале не должен знать о типах реализаций, определенных на уровне инфраструктуры. Однако во время выполнения эти типы реализации необходимы для выполнения приложения, поэтому они должны присутствовать и подключаться к интерфейсам Ядра приложений через внедрение зависимостей.
На рисунке 5-9 показано более подробное представление архитектуры приложения ASP.NET Core при построении этих рекомендаций.
Рис. 5-9. Диаграмма архитектуры ASP.NET Core в соответствии с принципами чистой архитектуры.
Так как ядро приложения не зависит от инфраструктуры, это очень легко писать автоматизированные модульные тесты для этого слоя. На рисунках 5-10 и 5-11 показано, как тесты вписываются в эту архитектуру.
Рис. 5-10. Модульное тестирование ядра приложений в изоляции.
Рис. 5-11. Тестирование интеграции инфраструктуры с внешними зависимостями.
Так как уровень пользовательского интерфейса не имеет прямой зависимости от типов, определенных в проекте инфраструктуры, также очень легко переключать реализации, чтобы упростить тестирование или в ответ на изменение требований приложения. Встроенное в ASP.NET Core использование и поддержка внедрения зависимостей делает эту архитектуру наиболее подходящим способом структурировать нетривиальные монолитные приложения.
Для монолитных приложений проекты Application Core, Инфраструктуры и пользовательского интерфейса выполняются как одно приложение. Архитектура приложения среды выполнения может выглядеть примерно так, как рис. 5–12.
Рис. 5-12. Пример архитектуры среды выполнения приложения ASP.NET Core.
Упорядочение кода в чистой архитектуре
В решении "Чистая архитектура" каждый проект имеет четкие обязанности. Таким образом, каждый проект относится к определенным типам, и вы часто найдете папки, соответствующие этим типам, в нужном проекте.
Ядро приложения
Ядро приложения содержит бизнес-модель, которая включает сущности, службы и интерфейсы. Эти интерфейсы включают в себя абстракции для операций, которые будут выполняться с помощью инфраструктуры, таких как доступ к данным, файловой системе, сетевые вызовы и т. д. Иногда службам или интерфейсам, определенным на этом уровне, потребуется работать с типами, не имеющими отношения к пользовательскому интерфейсу или инфраструктуре. Их можно определить как простые объекты передачи данных (DTOs).
Типы основных приложений
- Сущности (классы бизнес-модели, которые сохраняются)
- Агрегаты (группы сущностей)
- Интерфейсы
- Доменные службы
- Спецификации
- Пользовательские исключения и предложения Guard
- События домена и обработчики
Инфраструктура
Проект инфраструктуры обычно включает реализации доступа к данным. В типичном веб-приложении ASP.NET Core эти реализации включают DbContext Entity Framework (EF), все определенные объекты EF Core Migration
и классы реализации доступа к данным. Наиболее распространенным способом абстрагирования кода реализации доступа к данным является использование шаблона конструктора репозитория.
Помимо реализации доступа к данным, проект инфраструктуры должен содержать реализации служб, которые должны взаимодействовать с проблемами инфраструктуры. Эти службы должны реализовывать интерфейсы, определенные в application Core, и поэтому инфраструктура должна иметь ссылку на проект Application Core.
Типы инфраструктуры
- Типы EF Core (
DbContext
,Migration
) - Типы реализации доступа к данным (репозитории)
- Службы, относящиеся к инфраструктуре (например,
FileLogger
илиSmtpNotifier
)
Уровень пользовательского интерфейса
Уровень пользовательского интерфейса в приложении ASP.NET Core MVC является точкой входа для приложения. Этот проект должен ссылаться на проект Application Core, а его типы должны взаимодействовать с инфраструктурой строго через интерфейсы, определенные в Application Core. На уровне пользовательского интерфейса не должно допускаться прямое создание экземпляров или статические вызовы типов уровня инфраструктуры.
Типы слоев пользовательского интерфейса
- Контроллеры
- Пользовательские фильтры
- Настраиваемое промежуточное ПО
- Представления
- ViewModels
- Запуск
Класс Startup
или файл Program.cs отвечает за настройку приложения, а также для подключения типов реализаций к интерфейсам. Место, в котором выполняется эта логика, называется корнем композиции приложения и обеспечивает корректную работу внедрения зависимостей.
Замечание
Чтобы подключить инъекцию зависимостей во время запуска приложения, проект UI-слоя может потребоваться ссылаться на проект инфраструктуры. Эта зависимость может быть устранена с помощью пользовательского контейнера DI, который имеет встроенную поддержку загрузки типов из сборок. В этом примере самый простой подход — разрешить проекту пользовательского интерфейса ссылаться на проект инфраструктуры (но разработчики должны ограничить фактические ссылки на типы в проекте инфраструктуры корнем композиции приложения).
Монолитные приложения и контейнеры
Вы можете создать одно и монолитное веб-приложение или службу на основе монолитного развертывания и развернуть его в виде контейнера. В приложении структура может быть немонолитной и организована в виде нескольких библиотек, компонентов или слоев. Внешне это один контейнер с одним процессом, одним веб-приложением или одной службой.
Для управления этой моделью необходимо развернуть один контейнер для представления приложения. Чтобы масштабировать, просто добавьте дополнительные копии с балансировщиком нагрузки перед ними. Простота происходит от управления одним развертыванием в одном контейнере или виртуальной машине.
В каждом контейнере можно включить несколько компонентов, библиотек или внутренних слоев, как показано на рис. 5-13. Но, следуя принципу контейнера "контейнер делает одно дело и делает это в одном процессе", монолитный шаблон может быть конфликтом.
Недостатком этого подхода является, если или когда приложение растет, требуя его масштабирования. Если все приложение масштабируется, это не проблема. Однако в большинстве случаев некоторые части приложения являются узкими местами, которые требуют масштабирования, в то время как другие компоненты используются меньше.
Используя типичный пример электронной коммерции, скорее всего, вам потребуется масштабировать компонент сведений о продукте. Многие другие клиенты просматривают продукты, чем покупают их. Больше клиентов используют свою корзину, чем используют конвейер оплаты. Меньше клиентов добавляют комментарии или просматривают журнал покупок. И у вас, скорее всего, есть только несколько сотрудников, в одном регионе, которые должны управлять контентом и маркетинговыми кампаниями. Масштабируя монолитную структуру, весь код развертывается несколько раз.
Помимо проблемы "масштабировать все", изменения в одном компоненте требуют полного повторного тестирования всего приложения и полного повторного развертывания всех экземпляров.
Монолитный подход распространен, и многие организации разрабатываются с помощью этого архитектурного подхода. Многие имеют достаточно хорошие результаты, в то время как другие сталкиваются с ограничениями. Многие разработали свои приложения в этой модели, так как инструменты и инфраструктура были слишком сложными для создания ориентированных на обслуживание архитектур (SOA), и они не видели необходимости, пока приложение не выросло. Если вы обнаружите, что достигаете пределов монолитного подхода, разделение приложения с целью более эффективного использования контейнеров и микрослужб может стать следующим логическим шагом.
Развертывание монолитных приложений в Microsoft Azure можно достичь с помощью выделенных виртуальных машин для каждого экземпляра. С помощью масштабируемых наборов виртуальных машин Azure можно легко масштабировать виртуальные машины. Службы приложений Azure могут запускать монолитные приложения и легко масштабировать экземпляры без необходимости управлять виртуальными машинами. Службы приложений Azure также могут запускать отдельные экземпляры контейнеров Docker, упрощая развертывание. С помощью Docker можно развернуть одну виртуальную машину в качестве узла Docker и запустить несколько экземпляров. С помощью балансировщика Azure, как показано на рис. 5-14, можно управлять масштабированием.
Развертывание на различных узлах управляется традиционными методами. Узлами Docker можно управлять с помощью таких команд, как docker run, выполняемых вручную, или с помощью автоматизации, таких как конвейеры непрерывной доставки (CD).
Монолитное приложение, развернутое как контейнер
Существуют преимущества использования контейнеров для управления монолитными развертываниями приложений. Масштабирование экземпляров контейнеров гораздо быстрее и проще, чем развертывание дополнительных виртуальных машин. Даже при использовании наборов виртуальных машин для масштабирования виртуальных машин, их создание занимает время. При развертывании в качестве экземпляров приложений конфигурация приложения управляется как часть виртуальной машины.
Развертывание обновлений в виде образов Docker гораздо быстрее и эффективнее с точки зрения сети. Docker-образы обычно запускаются в течение нескольких секунд, ускоряя развертывание. Завершить работу экземпляра Docker так же легко, как выполнить команду docker stop
, что обычно занимает менее секунды.
Так как контейнеры по сути неизменяемы по проектированию, вам никогда не нужно беспокоиться о поврежденных виртуальных машинах, в то время как скрипты обновления могут забыть учесть определенную конфигурацию или файл, оставленный на диске.
Контейнеры Docker можно использовать для монолитного развертывания более простых веб-приложений. Этот подход улучшает непрерывную интеграцию и конвейеры непрерывного развертывания и помогает добиться успеха развертывания в рабочей среде. Нет больше "Он работает на моем компьютере, почему он не работает в рабочей среде?"
Архитектура на основе микрослужб имеет множество преимуществ, но эти преимущества поступают за счет повышения сложности. В некоторых случаях затраты перевешивают преимущества, поэтому монолитное приложение развертывания, работающее в одном контейнере или всего в нескольких контейнерах, является лучшим вариантом.
Монолитное приложение может быть не легко разложено на хорошо разделенные микрослужбы. Микрослужбы должны работать независимо друг от друга, чтобы обеспечить более устойчивое приложение. Если вы не можете доставлять независимые компоненты функций приложения, их разделение только усложняет задачи.
Приложению может еще не потребоваться масштабировать функции независимо. Многие приложения, когда они должны масштабироваться за пределами одного экземпляра, могут сделать это с помощью относительно простого процесса клонирования всего экземпляра. Дополнительная работа по разделения приложения на дискретные службы обеспечивает минимальное преимущество при масштабировании полных экземпляров приложения— это простое и экономичное.
В начале разработки приложения может не быть четкой идеи о том, где находятся естественные функциональные границы. При разработке минимального жизнеспособного продукта естественное разделение еще может не возникнуть. Некоторые из этих условий могут быть временными. Вы можете начать с создания монолитного приложения, а затем разделить некоторые функции для разработки и развертывания в качестве микрослужб. Другие условия могут быть важными для пространства проблем приложения, что означает, что приложение никогда не может быть разбито на несколько микрослужб.
Разделение приложения на множество дискретных процессов также представляет издержки. Существует более сложная сложность разделения функций на различные процессы. Протоколы связи становятся более сложными. Вместо вызовов методов необходимо использовать асинхронное взаимодействие между сервисами. При переходе к архитектуре микрослужб необходимо добавить множество стандартных блоков, реализованных в версии микрослужб приложения eShopOnContainers: обработка шины событий, устойчивость сообщений и повторные попытки, итоговая согласованность и многое другое.
Гораздо проще эталонное приложение eShopOnWeb поддерживает одноконтейнерное монолитное использование. Приложение включает в себя одно веб-приложение, включающее традиционные представления MVC, веб-API и Razor Pages. При необходимости можно запустить административный компонент приложения на основе Blazor, для работы которого требуется также запустить отдельный проект API.
Приложение можно запустить из корневого каталога решения с помощью команд docker-compose build
и docker-compose up
. Эта команда настраивает контейнер для веб-экземпляра, используя Dockerfile
найденный в корне веб-проекта контейнер и запускает контейнер на указанном порту. Вы можете скачать источник для этого приложения из GitHub и запустить его локально. Даже это монолитное приложение получает выгоды от развертывания в контейнерной среде.
Например, контейнерное развертывание означает, что каждый экземпляр приложения выполняется в одной среде. Этот подход включает среду разработчика, где выполняется раннее тестирование и разработка. Команда разработчиков может запустить приложение в контейнерной среде, которая соответствует рабочей среде.
Кроме того, контейнерные приложения масштабируются с меньшими затратами. Использование среды контейнера обеспечивает больший общий доступ к ресурсам, чем традиционные среды виртуальной машины.
Наконец, контейнеризация приложения заставляет разделение бизнес-логики и сервера хранения. По мере расширения приложения все контейнеры будут полагаться на одно физическое устройство хранения. Этот носитель хранилища обычно является сервером высокой доступности, на котором выполняется база данных SQL Server.
Поддержка Docker
Проект eShopOnWeb
выполняется в .NET. Поэтому он может выполняться в контейнерах под управлением Linux или Windows. Обратите внимание, что для развертывания Docker необходимо использовать тот же тип узла для SQL Server. Контейнеры на основе Linux позволяют уменьшить объем памяти и предпочтительнее.
Вы можете использовать Visual Studio 2017 или более поздней версии, чтобы добавить поддержку Docker в существующее приложение, щелкнув правой кнопкой мыши проект в обозревателе решений и выбрав добавить>поддержку Docker. Этот шаг добавляет необходимые файлы и изменяет проект для их использования. В текущем eShopOnWeb
примере уже есть эти файлы.
Файл уровня docker-compose.yml
решения содержит сведения о том, какие образы следует создавать и какие контейнеры следует запускать. Файл позволяет использовать docker-compose
команду для одновременного запуска нескольких приложений. В этом случае запускается только веб-проект. Его также можно использовать для настройки зависимостей, таких как отдельный контейнер базы данных.
version: '3'
services:
eshopwebmvc:
image: eshopwebmvc
build:
context: .
dockerfile: src/Web/Dockerfile
environment:
- ASPNETCORE_ENVIRONMENT=Development
ports:
- "5106:5106"
networks:
default:
external:
name: nat
Файл docker-compose.yml
ссылается на Dockerfile
в проекте Web
. Используется Dockerfile
для указания того, какой базовый контейнер будет использоваться и как приложение будет настроено на нем.
Web
' Dockerfile
:
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /app
COPY *.sln .
COPY . .
WORKDIR /app/src/Web
RUN dotnet restore
RUN dotnet publish -c Release -o out
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime
WORKDIR /app
COPY --from=build /app/src/Web/out ./
ENTRYPOINT ["dotnet", "Web.dll"]
Устранение неполадок Docker
После запуска контейнерного приложения он продолжает работать, пока не остановите его. Вы можете просмотреть, какие контейнеры работают с помощью команды docker ps
. Вы можете остановить запущенный контейнер с помощью docker stop
команды и указать идентификатор контейнера.
Обратите внимание, что запуск контейнеров Docker может быть привязан к портам, которые вы, возможно, захотите использовать в своей среде разработки. Если вы пытаетесь запустить или отладить приложение, используя тот же порт, что и запущенный контейнер Docker, вы получите сообщение об ошибке, указывающее, что сервер не может привязаться к такому порту. Еще раз остановите контейнер, чтобы устранить эту проблему.
Если вы хотите добавить поддержку Docker в приложение с помощью Visual Studio, убедитесь, что Docker Desktop работает при этом. Мастер не будет работать правильно, если Приложение Docker Desktop не запущено при запуске мастера. Кроме того, мастер проверяет текущий выбор контейнера, чтобы добавить правильную поддержку Docker. Если вы хотите добавить поддержку контейнеров Windows, необходимо запустить мастер установки при работающем Docker Desktop с настроенными контейнерами Windows. Если вы хотите добавить поддержку контейнеров Linux, запустите мастер, когда у вас работает Docker с настроенными контейнерами Linux.
Другие стили архитектуры веб-приложения
- Веб-Queue-Worker: основные компоненты этой архитектуры — это веб-интерфейс, обслуживающий клиентские запросы, и обработчик, выполняющий ресурсоемкие задачи, длительные рабочие процессы или задания. Веб-интерфейс взаимодействует с рабочим через очередь сообщений.
- N-уровень: архитектура N-уровня делит приложение на логические слои и физические уровни.
- Микрослужба: архитектура микрослужб состоит из коллекции небольших автономных служб. Каждая служба является самодостаточной и должна реализовывать возможности одной компании в ограниченном контексте.
Ссылки — распространенные веб-архитектуры
-
Чистая архитектура
https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html -
Луковичная архитектура
https://jeffreypalermo.com/blog/the-onion-architecture-part-1/ -
Шаблон репозитория
https://deviq.com/repository-pattern/ -
Шаблон решения "Чистая архитектура"
https://github.com/ardalis/cleanarchitecture -
Электронная книга «Архитектура микросервисов»
https://aka.ms/MicroservicesEbook -
DDD (Domain-Driven Design)
https://learn.microsoft.com/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/