中国商务商会官方网站/宣传软文是什么

中国商务商会官方网站,宣传软文是什么,做国外网站的站长,公众号营销上个月15日,上海MVP做了一次线下的技术分享活动,我分享的主题是《快速构建容器化的ASP.NET Core应用程序》,有关这次活动的简报,可以参考这里。另外,我的主题分享的PPT也可以点击这里下载。由于线下活动时间紧迫&#…

上个月15日,上海MVP做了一次线下的技术分享活动,我分享的主题是《快速构建容器化的ASP.NET Core应用程序》,有关这次活动的简报,可以参考这里。另外,我的主题分享的PPT也可以点击这里下载。由于线下活动时间紧迫,没有办法把所有的内容完全仔细地讲解一遍,最后使用一个小时左右的时间做了一个tasklist的案例演示,但也是走马观花,很多细节没有覆盖到。因此,特撰此文,将之前分享的内容再细化一下,希望能够给关注这方面内容的读者带来帮助。

我会尽量将细节问题解释清楚,于是,文章篇幅会比较长,因此,我会分三个部分进行介绍:

  1. ASP.NET Core应用程序容器化需要注意的内容

  2. 持续集成、持续部署与Azure DevOps

  3. Azure Kubernetes Service介绍

ASP.NET Core应用程序的构建

构建ASP.NET Core应用程序的方式有很多种,你可以使用Visual Studio 2017的项目模板直接创建,也可以在安装了.NET Core SDK之后,使用dotnet new命令创建,具体步骤在此也就不再细表,我仍然使用Visual Studio 2017的ASP.NET Core项目模板进行创建。在新建项目对话框中,我们可以选择启用Docker容器支持,这样的话,Visual Studio会在新建的ASP.NET Core项目中添加Dockerfile文件,同时会在解决方案中增加一个Docker Compose的项目,用以实现容器编排。然而,我并不太喜欢使用这一功能,虽然它能够带来很多方便,原因主要有二。首先,一个复杂的应用程序解决方案,项目往往不止一个,各项目的运行环境和配置都会有所不同,使用项目模板创建的Dockerfile和Docker Compose文件有可能还是需要进行修改,甚至重写;其次,我们需要对IDE自动生成的代码了如指掌,这样才能理解并在实际项目中正确使用,与其如此,不如自己根据实际需要自己编写,这样可以让自己对整个项目的各个技术细节都有着深刻的理解和认识。

640?wx_fmt=png

新建ASP.NET Core项目之后,就可以开始编写代码来实现我们的业务逻辑了。有关Visual Studio 2017开发ASP.NET Core应用程序的详细步骤在这里就不多介绍了,作为这次线下活动的演示案例,我开发了一个简单的App:tasklist,这个App使用Angular 6作为前端框架,TypeScript进行前端编程,后端使用ASP.NET Core Web API构建,基于MongoDB数据库,完整的代码可以在https://github.com/daxnet/tasklist找到。该案例项目使用MIT许可协议开源。

Tasklist的业务非常简单,就是允许用户能够增加、删除任务项目,它的界面如下:

640?wx_fmt=png

在这个界面中,用户可以在文本框中输入需要完成的任务项目,点击“新增”按钮可以将任务项目添加到列表,也可以在列表中点击“删除”按钮删除指定的项目,文本框下方列出了所有已添加的任务项目。整个后端ASP.NET Core Web API解决方案中各项目的依赖关系如下:

640?wx_fmt=png

具体的代码实现部分就不多介绍了,这里重点介绍一下ASP.NET Core应用程序容器化时需要注意的几点问题。

ASP.NET Core应用程序容器化所需注意的问题

应用程序的配置信息

容器化的应用程序往往都是在容器启动的过程中,将所需的配置信息通过环境变量注入容器,此时运行于容器中的应用就可以读取环境变量来获得运行参数。比如,使用docker run命令启动容器时,就可以使用-e参数来指定环境变量。因此,理解ASP.NET Core应用程序的配置系统是非常重要的,它有助于应用程序配置体系的设计。在《ASP.NET Core应用程序的参数配置及使用》一文中,我已经简要介绍过ASP.NET Core应用程序的配置系统,可供参考。

在此需要注意的一点是,ASP.NET Core配置系统通常使用冒号(:)来分隔配置数据模型中不同层次的名称。比如,有如下配置数据模型:

1
2
3
4
5
6
7
"mongo": {
  "server": {
    "host": "localhost",
    "port": 27017
  },
  "database": "tasklist"
}

如果在C#代码中要访问host,那么就需要使用下面的代码:

1
var mongoServerHost = Configuration["mongo:server:host"]

然而,如果应用程序需要运行在容器中,这个配置就需要写在容器的编排文件里,比如docker-compose.yml文件。但是,有些容器的编排系统,例如Kubernetes,就不支持在环境变量设置时出现冒号这样的“非法字符”,为此,ASP.NET Core的配置也支持使用双下划线分隔。比如:

640?wx_fmt=png

这样的话,不仅ASP.NET Core应用程序在容器中能够获得环境变量的配置,而且诸如Kubernetes这样的系统也能在启动容器时,将配置信息设置到环境变量中。

端口侦听

ASP.NET Core应用程序的端口侦听设置也是一个在容器化过程中非常重要的内容。通常,在开发阶段,我们偏向于在Main方法中通过代码的方式指定应用程序所侦听的端口号,比如:

1
2
3
4
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseUrls("http://*:8087")
        .UseStartup<Startup>();

但是这种方法缺点是很明显的:我们无法在部署应用程序的时候动态设置需要侦听的端口。对于ASP.NET Core应用程序而言,常见的做法有两种:通过命令行参数指定侦听端口,或者使用环境变量。通过命令行参数,只需要在启动应用程序时,指定—server.urls参数即可:

640?wx_fmt=png

或者,如果是使用环境变量,只需要配置ASPNETCORE_URLS变量即可,如下:

640?wx_fmt=png

因此,事实上我们并不需要在Main函数中去显式地指定侦听端口,只需要在最终部署的时候,设置ASPNETCORE_URLS环境变量即可。现在,让我们看看tasklist代码库中,docker-compose.yml文件中有关后端服务的环境变量配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
service:
  image: daxnet/tasklist-service
  build:
    context: service/tasklist
    dockerfile: TaskList.Service/Dockerfile
  links:
    - db
  depends_on:
    - db
  ports:
    - 9020:9020
  environment:
    - ASPNETCORE_ENVIRONMENT=Production
    - ASPNETCORE_URLS=http://*:9020
    - mongo__server__host=tasklist-db
    - mongo__server__port=27017
    - mongo__database=tasklist
  container_name: tasklist-service

在上面的配置中:

  • ASPNETCORE_ENVIRONMENT:指定ASP.NET Core应用程序运行环境,该参数将决定应用程序配置信息的读取方式

  • ASPNETCORE_URLS:指定ASP.NET Core应用程序的侦听端口

  • mongo__server__host:MongoDB的服务器名称

  • mongo__server__port:MongoDB的侦听端口

  • mongo__database:MongoDB的数据库名称

ASP.NET Core的容器版本

微软官方发布了.NET Core/ASP.NET Core的docker容器镜像,可以在https://hub.docker.com/r/microsoft/dotnet/中找到。开发人员需要根据不同的场景来选用不同的tag。比如:

  • 2.1-sdk:包含了.NET Core 2.1 SDK

  • 2.1-aspnetcore-runtime:包含了ASP.NET Core 2.1的运行库

  • 2.1-runtime:包含了.NET Core 2.1的运行库

此外,在这个repo下,还有一些预览版的tag,可以在https://hub.docker.com/r/microsoft/dotnet/tags/页面找到所有的tag。就ASP.NET Core而言,在2.0(含)之前,需要使用microsoft/aspnetcore这个docker容器镜像,而从2.1开始,则需要使用上面提到的microsoft/dotnet这个容器镜像。总之,对于容器镜像和tag的选择需要慎重,否则有可能出现一些奇奇怪怪的问题。

docker镜像构建上下文(Build Context)与Dockerfile的配套使用

在上面的docker-compose.yml片段中,我们指定了ASP.NET Core应用程序的docker镜像构建上下文,为service/tasklist目录,于是,接下来所有与构建docker镜像相关的操作,都会基于这个构建上下文来执行。首先,通过dockerfile指定了Dockerfile的位置是:service/tasklist/TaskList.Service/Dockerfile(注意这里已经将构建上下文路径带入进来);然后,我们了解一下Dockerfile的具体内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 9020
FROM microsoft/dotnet:2.1-sdk AS publish
WORKDIR /src
COPY . .
RUN dotnet restore
WORKDIR "/src/TaskList.Service"
RUN dotnet publish "TaskList.Service.csproj" -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
CMD ["dotnet", "TaskList.Service.dll"]

这个Dockerfile分成三个部分:第一部分指定运行时会采用microsoft/dotnet:2.1-aspnetcore-runtime这个tag,运行目录为/app目录,并会向外界暴露9020端口;第二部分就是应用程序的编译部分,这里采用microsoft/dotnet:2.1-sdk作为编译环境,先设置容器中的工作目录为/src,然后,将service/tasklist目录下的所有内容全部复制到容器中的/src目录(注意,虽然COPY指令后面是两个点号,但由于我们已经指定了镜像构建上下文,因此,第一个点号就表示service/tasklist目录,第二个点号就表示容器中的当前目录,也就是/src目录),接着就是标准的dotnet restore命令,然后就是进入到/src/TaskList.Service目录,执行dotnet publish指令,从而编译整个项目,并将编译结果输出到/app目录;到了第三部分,将第二部分的输出结果复制到第一部分容器中的/app目录(也就是最后那个点号所指定的目录),然后执行dotnet命令启动服务。

事实上,如果你在创建ASP.NET Core应用程序时,启用了docker支持,那么Visual Studio会在你的项目中添加一个Dockerfile,内容与上面的Dockerfile类似,不过需要注意的是,使用这个自动生成的Dockerfile之前,需要弄清楚镜像构建上下文,否则直接通过docker build命令是无法正常完成镜像构建的。

在容器化ASP.NET Core应用程序方面,我暂时先介绍这些内容;接下来看看前端部分需要做些什么。

前端应用:nginx的反向代理

在tasklist案例中,前端我采用的是Angular 6框架,使用TypeScript编写。由于是一个单页面应用,因此,我没有选择相对比较重的Jetty、Tomcat、IIS等Web容器,而是选择使用了比较轻量的nginx。当然,前端通过http请求访问ASP.NET Core Web API应用程序所提供的RESTful API接口,那么这里就有一个访问URL的问题。使用过Angular框架的开发者都知道,通过environment.ts(或者environment.prod.ts)代码文件,可以针对不同的运行环境(Development, Staging或者Production)来选择设置不同的配置数据,那么,后端服务的URL地址又该如何设置呢?

  1. 使用绝对路径:这不是个好的做法,这就要求将后端API的全路径都写死(Hard Code)在environment.prod.ts里,显然不是一种合理的做法

  2. 使用相对路径:这种做法会使得前端App调用后端API时,产生一个错误的URL。比如,假设前端运行在localhost:80,而后端是localhost:9020,那么如果我们指定API的URL是相对路径/api/service,那么当前端程序运行时,它请求的API地址就成了http://localhost/api/service,而不是http://localhost:9020/api/service

在tasklist中,我选择了使用相对路径,然后更改nginx的配置,设置了一条反向代理规则:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
events {
    worker_connections      4096;
}
http {
     
    server {
      listen    80;
      server_name   localhost;
       
      include  /etc/nginx/mime.types;
      location / {
        root /usr/share/nginx/html;
        index  index.html  index.htm;
      }
      location /api {
        proxy_pass http://tasklist-service;
      }
    }
    upstream tasklist-service {
      server tasklist-service:9020;
    }
}

在这里,当前端页面请求/api路径时,nginx会自动重定向到http://tasklist-service:9020/api,此时就能正确完成RESTful API调用。注意:这里的tasklist-service是ASP.NET Core应用程序的运行机器名,请参考docker-compose.yml文件中service配置部分的container_name设置。

同样,基于docker镜像构建上下文,我们可以使用容器来编译和运行前端代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 基于node 8容器作为编译环境
FROM node:8 AS build
# 首先安装Angular CLI
RUN npm install -g @angular/cli@6.1.5
# 然后将源代码复制到容器中
WORKDIR /src
COPY . .
# 执行npm install以及Angular的编译
RUN npm install
RUN ng build --prod
# 基于nginx容器作为运行环境
FROM nginx AS final
# 将nginx.conf配置文件复制到容器指定目录
COPY nginx.conf /etc/nginx/nginx.conf
# 将Angular编译输出复制到nginx的指定目录
COPY --from=build /src/dist/tasklist /usr/share/nginx/html

在容器中运行整个应用程序

在此,我选择使用Docker for Windows来运行整个tasklist应用程序。首先启动Docker for Windows,然后打开Windows命令行工具,进入到tasklist目录,执行:

1
docker-compose up --build

经过一段漫长时间的构建过程之后,所有的服务都会启动:

640?wx_fmt=png

在浏览器中打开我们的应用:

640?wx_fmt=png

总结

本文为ASP.NET Core应用程序容器化、持续集成、持续部署话题的第一部分,重点介绍了ASP.NET Core应用程序容器化时需要注意的地方,并展示了整个案例的运行效果。下文会接着讨论基于Azure DevOps的持续集成,看看如何使用Azure DevOps的服务来完成项目的自动编译。

原文地址: http://sunnycoding.cn/2018/10/07/dockerize-aspnetcore-cicd-with-azure-devops-and-kubernetes-part1


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

640?wx_fmt=jpeg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/319553.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

现代软件工程的《构建之法》

要想了解世界&#xff0c;就必须亲自来打造它。—— 帕韦泽&#xff08;Cesare Pavese&#xff09;国庆假日期间&#xff0c;我重读了邹欣老师的《构建之法》一书。我从事软件行业相关工作超过15年&#xff0c;每每在被问到给在校计算机专业大学生的学习建议时&#xff0c;我都…

【每日一题】8月10日题目精讲—排座椅

来源&#xff1a;牛客网&#xff1a; 时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 51200K&#xff0c;其他语言102400K 64bit IO Format: %lld题目描述 上课的时候总有一些同学和前后左右的人交头接耳&#xff0c;这是令小学班主任十分头疼的…

使用Consul做服务发现的若干姿势

从2016年起就开始接触Consul&#xff0c;使用的主要目的就是做服务发现&#xff0c;后来逐步应用于生产环境&#xff0c;并总结了少许使用经验。最开始使用Consul的人不多&#xff0c;为了方便交流创建了一个QQ群&#xff0c;这两年微服务越来越火&#xff0c;使用Consul的人也…

【每日一题】8月11日题目精讲—矩阵消除游戏

来源&#xff1a;牛客网&#xff1a; 时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K 64bit IO Format: %lld题目描述 牛妹在玩一个名为矩阵消除的游戏&#xff0c;矩阵的大小是n行m列&#xff0c;第i行第…

asp.net core集成CAP(分布式事务总线)

一、前言感谢杨晓东大佬为社区贡献的CAP开源项目&#xff0c;传送门在此&#xff1a;.NET Core 事件总线,分布式事务解决方案&#xff1a;CAP 以及 如何在你的项目中集成 CAP【手把手视频教程】&#xff0c;之前也在工作中遇到分布式数据一致性的问题&#xff0c;也一直都是基于…

.Net Core中利用TPL(任务并行库)构建Pipeline处理Dataflow

在学习的过程中&#xff0c;看一些一线的技术文档很吃力&#xff0c;而且考虑到国内那些技术牛人英语都不差的&#xff0c;要向他们看齐&#xff0c;所以每天下班都在疯狂地背单词&#xff0c;博客有些日子没有更新了&#xff0c;见谅见谅 什么是TPL?Task Parallel Library (T…

.NET Core Agent

熟悉java的朋友肯定知道java agent&#xff0c;当我看到java agent时我很是羡慕&#xff0c;我当时就想.net是否也有类似的功能&#xff0c;于是就搜索各种资料&#xff0c;结果让人很失望。当时根据 https://github.com/OpenSkywalking/skywalking-netcore 找到这个 https://d…

【每日一题】8月14日题目精讲 [SCOI2010]游戏

来源&#xff1a;牛客网&#xff1a; 时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K 64bit IO Format: %lld题目描述 lxhgww最近迷上了一款游戏&#xff0c;在游戏里&#xff0c;他拥有很多的装备&#x…

ASP.NET Core应用程序容器化、持续集成与Kubernetes集群部署(二)

在上文中我介绍了ASP.NET Core应用程序容器化时需要注意的几个问题&#xff0c;并给出了一个案例应用程序&#xff1a;tasklist。今天接着上文的内容&#xff0c;继续了解一下如何使用Azure DevOps进行ASP.NET Core应用程序的持续集成。为了便于讨论&#xff0c;本文会将持续集…

【每日一题】8月17日题目精讲-[SCOI2009]生日礼物

来源&#xff1a;牛客网&#xff1a; 时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K 64bit IO Format: %lld题目描述 小西有一条很长的彩带&#xff0c;彩带上挂着各式各样的彩珠。已知彩珠有N个&#xff…

Followme Devops step by step

接着上次分享的devops历程[Followme Devops实践之路], 大家希望能够出一个step by step手册, 那今天我就来和手把手来一起搭建这么一套环境, 演示整个过程!实验环境需要准备docker /docker compose建议大家使用国外的vps学习, 不需要考虑网络/gwf的问题/方便(本demo搭建在linod…

【每日一题】8月25日题目精讲 XOR-pyramid

文章目录题目描述&#xff1a;题解&#xff1a;代码&#xff1a;题目描述&#xff1a; 链接&#xff1a;https://ac.nowcoder.com/acm/problem/112798 来源&#xff1a;牛客网 输入描述: 输出描述: Print q lines — the answers for the queries. 示例1 输入 复制 3 8 4 1…

申请Office 365一年免费的开发者账号攻略(2018年10月份版本)

要进行Office 365开发&#xff0c;当然需要有完整的Office 365环境才可以。为了便于广大开发人员快速地启动这项工作&#xff0c;微软官方给所有开发人员提供了免费的一年开发者账号那么如何申请Office 365一年免费的开发者账号呢&#xff1f;网上已经有一些攻略了&#xff0c;…

开源若要天下闻,掌声须给教育人

引子故事一当我们介绍 Linux Kernel 项目历史的时候&#xff0c;我们会如此说&#xff1a;“1991 年&#xff0c;赫尔辛基大学的大学生 Linus torvald, 在自己的电脑上开发了一个能够运行在 X86 架构上的操作系统&#xff0c;并将它发布在互联网上&#xff0c;任何人都可以参与…

【每日一题】8月27日题目精讲 Is It A Tree?

链接&#xff1a;https://ac.nowcoder.com/acm/problem/105905 来源&#xff1a;牛客网 时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 10000K&#xff0c;其他语言20000K 64bit IO Format: %lld 题目描述 A tree is a well-known data struct…

好代码是管出来的——使用Jenkins搭建CI服务器

Jenkins是一个开源的跨平台的CI工具&#xff0c;它可以部署在Windows、Linux等平台上&#xff0c;并且Jenkins提供了非常丰富的插件来帮助完成编译、测试、部署等工作。  本文将介绍在Windows平台上使用Jenkins完成.Net Core应用的持续集成环境搭建&#xff0c;其主要内容有&…

牛客练习赛 59

A.小乔和小灰灰 前几天刚刚学了序列自动机&#xff0c;这题直接也没咋想暴力的做法&#xff0c;直接上序列自动机匹配子序列即可。 #define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #pragma GCC optimize(2) #include<iostream> #include<algorithm&…

.Net Core 2.1 通用主机(Core 在控制台应用程序中的应用)

一、介绍官方文档中说&#xff0c;Microsoft.AspNetCore.App 元包&#xff08;ASP.NET Core 2.1 或更高版本&#xff09;包含通用主机的Microsoft.Extensions.Hosting包&#xff0c;当创建控制台项目以后并没有相应的包。在官方案例中所用的Nuget包有&#xff1a;1. Microsoft.…

产品开发管理之流程和体系(总篇)

前言秋风瑟瑟&#xff0c;夏日的灼热犹在&#xff0c;就瞬间迎来刺骨寒风。凛冬将至&#xff0c;今天对我们来说&#xff0c;像贴面的利刃一样冰冷而真实。农民、建筑工人、司机、程序员、私企高管、私企老板、资本巨富&#xff0c;都被裹挟进了这个焦灼的时代&#xff0c;没有…

YbtOJ#593-木棍问题【费用流】

正题 题目链接:https://www.ybtoj.com.cn/contest/114/problem/3 题目大意 n∗mn*mn∗m的网格上有一些格子有木球&#xff0c;两个相邻木球直接可以有木棍。 两个LLL形的木棍会产生AAA的代价&#xff0c;两个III形的木棍会产生BBB的代价 对于每个kkk求出插入kkk根木棍时的最小…