65.9K
CodeProject 正在变化。 阅读更多。
Home

Docker 化 ASP.NET Boilerplate 项目

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.93/5 (20投票s)

2017年6月13日

CPOL

6分钟阅读

viewsIcon

73063

使用 redis、haproxy 和 abp module zero core 模板在 Docker 容器中创建 Web Farm

引言

在本文中,我将一步一步地向您展示如何在 Docker 上运行 ABP module zero core 模板。然后,我们将讨论 Web Farm 的替代方案,例如使用 RedisHaproxy

您知道,Docker 是最流行的软件容器平台。我不会详细介绍如何在 Windows 上安装/配置 Docker 或使用 Docker 的优点。您可以在此处找到相关文档。还有一个入门指南

什么是 ABP Module Zero Core 模板?

Module zero core 模板 是使用 ASP.NET Boilerplate Framework 开发的入门项目模板。这是一个 .NET Core 项目,使用 Angular4 作为单页应用程序。同时,也有一个多页 MVC 应用程序。但在本文中,我将解释 Angular4 版本。

module zero core 模板项目中,有两个独立的项目,一个是作为 Web UI 的 Angular4 项目,另一个是 Angular UI 使用的宿主项目。在将其运行在 Docker 上之前,我们先来检查一下它,以便更好地理解项目。

入门

从网站创建模板

首先,我将从 https://www.aspnetboilerplate.com/Templates 网站下载 module zero core 模板。

框架:.NET Core2.0 + 单页 Web 应用程序 Angular + 包含 module zero
项目名称:Acme.ProjectName

在准备项目运行在 Docker 上之前,我们先运行一下项目。我打开 ProjectName\aspnet-core 文件夹中的 .sln 文件。

使用 EF Migrations 创建数据库

在运行项目之前,我们应该在程序包管理器控制台中使用 EF migrations 创建数据库。首先,我将 Acme.ProjectName.Web.Host 设置为启动项目。(右键单击 Host 项目并选择设置为启动项目)。然后,打开程序包管理器控制台,将默认项目选择为 EntityFrameworkCore,然后运行以下命令

update-database

运行此命令后,将以 ProjectNameDb 的名称创建数据库。

运行 Host 项目

现在,Host 项目已准备好运行。在 Visual Studio 中按 Ctrl+F5。它会打开 swagger 方法索引页。

所有这些服务都托管在项目的应用程序层,并由 Angular UI 使用。

运行 Angular 项目

在 Host 已运行的情况下,我们可以运行使用 API 的Angular 项目。要运行Angular 项目,请确保您的计算机上已安装node 和 npm

首先,在 ProjectName\angular 位置运行 cmd,然后运行命令 "npm install" 或直接运行 "yarn" 来获取客户端包。

在同一目录中运行 npm start 命令来启动 Angular 项目。

最后,您应该在输出屏幕中看到 "webpack: Compiled successfully" 这行。

我们已成功启动 Angular 项目。在浏览器中打开并导航到 https://:4200/

请使用以下凭据登录

用户名 admin
密码 123qwe

登录后,您将看到以下屏幕

有关更多详细信息,请在此处查看

总结一下我们为运行 Angular 项目所做的

  • ProjectName\angular 位置运行 cmd
  • 运行 yarnnpm install 命令(我在上述示例中使用了 yarn)。
  • 运行 npm start 命令。
  • 访问 localhost:4200 查看 Angular 项目是否正在运行。

一切运行正常。准备在 Docker 上运行...

在 Docker 上运行项目

如果您尚未安装 Angular CLI,则必须安装它。运行以下命令安装 Angular CLI。

npm install -g @angular/cli

确保 Angular CLI 已安装后,让我们查看文件和文件夹以配置 Docker 环境。在 ProjectName/aspnet-core 下有一个名为 docker 的文件夹。

docker/ng 文件夹中,有一个 docker-compose.yml 文件和两个用于运行 (up.ps1) 和停止 (down.ps1) docker compose 的 powershell 脚本。还有一个额外的文件夹和一个 powershell 脚本文件。

此脚本文件用于构建和发布宿主项目和 angular 项目。此外,此脚本将 docker 文件夹中的文件复制到 build 文件夹。首先,我将在 ProjectName/aspnet-core/build 位置运行 build-with-ng.ps1 脚本。

运行脚本后,当您查看 build 文件夹时,您会看到 outputs 文件夹。

在运行 up.ps1 命令之前

  • 您必须共享驱动器。要共享它,请右键单击 Docker 系统托盘,转到设置,导航到共享文件夹并勾选所有驱动器。
  • 数据库托管在本地机器上,而不是在 docker 上。托管在 Docker 上的网站将连接到您的本地数据库。使用受信任的连接字符串,连接将不成功。因此,请设置您的 SQL 数据库用户名和密码。要实现这一点,请修改文件 "...\aspnet-core\src\Acme.ProjectName.Web.Host\appsettings.Staging.json"。更新 Default ConnectionStrings > "Server=10.0.75.1; Database=ProjectNameDb; User=sa; Password=<请填写您的密码>;"

ProjectName/aspnet-core/build/outputs 位置运行 up.ps1 脚本,在 docker 上运行这两个项目。

Angular 和宿主项目现在正在运行。访问 https://:9901/ 访问宿主项目,访问 https://:9902/ 访问 Angular UI

使用 Redis 和 Haproxy 在 Docker 上运行 Module Zero Core 模板 Web Farm

在 Web Farm 中,有多个 Web 服务器,服务器前面有一个负载均衡器,还有一个用于存储共享会话/缓存的服务器。

在我们的示例中,Angular 应用程序将是客户端,haproxy 将是负载均衡器,host app 将是 Web 服务器,redis 将是共享服务器。

ProjectName\aspnet-core\docker\ng 位置创建一个名为 haproxy.cfg 的配置文件。

haproxy.cfg

(复制粘贴代码行会导致编码问题,请直接下载文件 => 下载 haproxy.cfg)

global
    maxconn 4096
    
defaults
    mode http
    timeout connect 5s
    timeout client 50s
    timeout server 50s
    
listen http-in
    bind *:8080
    
    server web-1 outputs_abp_host_1:80
    server web-2 outputs_abp_host_2:80
    
    stats enable
    stats uri /haproxy
    stats refresh 1s

haproxy.cfg 的重要行是 server web-1server web-2。我复制了宿主应用程序。这将创建两个宿主应用程序在 docker 容器中。

修改了 docker-compose.yml

(复制粘贴代码行会导致编码问题,请直接下载文件 => 下载 docker-compose.yml)

version: '2'

services:

    abp_redis:
        image: redis
        ports:
            - "6379:6379"

    abp_host:
        image: abp/host
        environment:
            - ASPNETCORE_ENVIRONMENT=Staging
        volumes:
            - "./Host-Logs:/app/App_Data/Logs"

    abp_ng:
        image: abp/ng
        ports:
            - "9902:80"
            
    load_balancer:
        image: haproxy:1.7.1
        volumes:
            - "./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg"
        ports:
            - "9904:8080"

build-with-ng.ps1

替换以下行

(Get-Content $ngConfigPath) -replace "21021", "9901" | Set-Content $ngConfigPath

用这一行

(Get-Content $ngConfigPath) -replace "21021", "9904" | Set-Content $ngConfigPath

现在 Angular UI 将连接到 haproxy。Haproxy 将请求分发到 Web 服务器。

用以下内容覆盖 up.ps1

docker rm $(docker ps -aq)
docker-compose up -d abp_redis
sleep 3
docker-compose up -d abp_host
docker-compose up -d abp_ng
sleep 2
docker-compose scale abp_host=2
sleep 2
docker-compose up -d load_balancer

要使用 redis 缓存,请将 Abp.RedisCache 库安装到 ProjectName.Web.Core 项目。并按以下方式更新 ProjectNameWebCoreModule.cs

[DependsOn(...,
     typeof(AbpRedisCacheModule))]
public class ProjectNameWebCoreModule : AbpModule
{

并在 PreInitialize 方法(ProjectNameWebCoreModule.cs)中添加 redis 缓存配置。

public override void PreInitialize()
{
    ...

    Configuration.Caching.UseRedis(options =>
    {
        var connectionString = _appConfiguration["Abp:RedisCache:ConnectionString"];
        if (connectionString != null && connectionString != "localhost")
        {
            options.ConnectionString = AsyncHelper.RunSync(() => 
                    Dns.GetHostAddressesAsync(connectionString))[0].ToString();
        }
    })
    
    ...

appsettings.staging.json 中添加 redis 配置。

appsettings.staging.json

{
  ...,
  "Abp": {
    "RedisCache": {
      "ConnectionString": "outputs_abp_redis_1"
    }
  }
}

outputs_abp_redis_1 是 redis 容器的名称,此名称由 docker 自动定义。更改后,宿主项目将解析部署在其上的机器的 DNS。现在,当我运行 build-with-ng.ps1 up.ps1 时,Web Farm 项目将运行。结果是

如您所见,所有容器都在工作。当您访问 https://:9902 时,您可以看到 Angular UI 正在工作。

我将如何知道 Haproxy 和 Redis 是否正常工作?

有工具可以跟踪 haproxy 活动(haproxy Web 界面)并获取 redis 存储的数据(redis cli)。

Haproxy Web 界面

当您访问 https://:9904/haproxy 时,您将看到类似以下内容

当您在 Angular 应用程序的页面之间导航或运行宿主项目 (https://:9904/) 的任何 api 时,您可以看到 haproxy 正在将请求路由到不同的机器。您可以在 Session rate>Cur 选项卡下跟踪哪些机器正在运行,这些选项卡对于 web-1web-2 正在变化。

Redis cli

要了解 redis 是否正常工作,您可以使用 redis-cli。运行 docker exec -it outputs_abp_redis_1 redis-cli 命令以交互模式运行 redis-cli 来连接运行在 docker 容器中的 redis 服务器。然后,要测试 redis 是否正在运行,请键入 ping 命令,如果正常工作,它将返回 PONG。现在,当我键入 keys * 命令时,我应该得到应用程序缓存的键。

如您所见,redis 工作正常。缓存键已正确存储在 redis 中。

源代码

您可以在 Github 上的此链接处获取修改后的源代码。

历史

  • 2018 年 2 月 22 日:初始版本
© . All rights reserved.