├── 0 whydotnet ├── 1.whydotnetcore.md ├── 2.dotnetabout.md ├── 3.net-standard.md ├── 4.tencentcloudsdk.md └── resource │ ├── std-project-cs.png │ ├── techpower17.png │ ├── tencentcloudsdk.png │ └── toolarch.png ├── 1 docker ├── 1.dotnetdockerbasic.md ├── 2.netdocker.md ├── 3.buildingnetdockerimages.md ├── 4.visualstudiotoolsfordocker.md └── resource │ ├── createdockerappwithvs2017.png │ ├── dockerbasic.png │ ├── dockerregisterontencentyun.png │ ├── publishdockertotencentyun.png │ ├── publishdockertotencentyun0.png │ └── settings-shared-drives-win.png ├── 2 microservices ├── 1.microserviceandcontainer.md ├── 2.microservicecontainer.md ├── 3.deployservice.md ├── 4.servicediscovery.md ├── 5.servicehealth.md ├── 6.serviceupdate.md └── 7.servicegov.md ├── 3 tke ├── 0.tkeabout.md ├── 1.tkeprepareapp.md ├── 2.tkeprepareccr.md ├── 3.tkedeploycluster.md ├── 4.tkedeployapplication.md ├── 5.tkekubernetesscale.md ├── 6.tkeappupdate.md └── resource │ ├── ccrbasic1.png │ ├── ccrbasic2.png │ ├── ccrbasic3.png │ ├── ccrbasic4.png │ ├── createccr.png │ ├── createccr1.png │ ├── qcloud-vote.png │ └── vote-app-updated.png ├── 4 Wechat ├── lab.md └── resource │ ├── APIExplorer3.png │ ├── WeixinInteractionServer.png │ ├── dbcontext.png │ ├── labarch.png │ ├── mptke.png │ ├── senparcsamplebuilder.png │ ├── senparcsdk.png │ ├── tencenthub.png │ └── wechatInteraction.png ├── README.md ├── Summary.md └── overview.md /0 whydotnet/1.whydotnetcore.md: -------------------------------------------------------------------------------- 1 | # 为什么选择.NET Core 2 | 3 | 在开始这个话题之前我们来看下ASP.NET Core的性能表现: [https://github.com/aspnet/benchmarks](https://github.com/aspnet/benchmarks) 4 | ASP.NET Core的基准测试,包括(但不限于)TechEmpower Web框架基准测试中的场景 。 ASP.NET 团队的最新的结果参看[https://aka.ms/aspnet/benchmarks](https://aka.ms/aspnet/benchmarks)。 5 | 6 | * 如果你是.NET Framework开发人员 7 | 8 | .NET Core是为了重写某些.NETFramework组件而为其他人提供跨平台工作的机会。由于.NET Framework主要以托管(C#)代码为基础构建,因此这些部分不需要更改代码即可迁移到.NET Core。依赖于Windows特定组件的库必须被移除或重构以使用跨平台替代方案。这同样适用于您的应用程序。 9 | 10 | * 您的.NET应用程序可以是跨平台的 11 | 12 | 您现有的.NET Framework应用程序是可以在其他操作系统上工作。对于希望扩大类库的受众平台,或者希望在分布式应用程序的其他领域使用相同代码的开发人员来说,这是非常好的选择。即使你想在MacBook上开发.NET,而无需在MAC上安装双系统来启动到Windows。 13 | 14 | * ASP.NETCore胜过ASP.NET框架 15 | 16 | ASP.NET Core和ASP.NET之间的性能差异是几个数量级。大部分的ASP.NET被传统的System.Web库所限制。.NET Framework支持旧版本的ASP.NET项目,而且这个约束限制了ASP.NET的发展。微软决定重写整个架构。这意味着打破变化,但结果是值得的。 17 | 18 | * .NETCore是创新的焦点 19 | 20 | 向后兼容性是一把双刃剑。这意味着您的应用程序可以继续得到新版本框架的支持,确保在新版本框架中所做的更改不会破坏现有的应用程序。 21 | 22 | 所有的努力避免变化都限制了框架的创新。框架的变化需要彻底的理由(通常来自客户),详尽的测试以及来自多个层次产品组的批准。 23 | 24 | 使用.NET Core,团队可以更容易专注的在.net core上工作。比如核心类库(如System.Collections)的更改仍然需要与.NET Framework相同的活力,但是ASP.NET Core或Entity Framework Core可以更轻松地进行实质性更改,而不受向后兼容性的限制。这允许更大的创新。 25 | 26 | .NET Framework作为一个整体产品发布,但是Core被分解成多个部分。现在开发人员可以选择使用哪个版本的库,只要它在.NET标准库之内,.NET Core团队就可以用较少的难度进行创新。这就是为什么在将来你只能看到错误修复的.NET Framwork, 也就是说不会有.NET Framewok 5.0,其实.NET Framewok 5.0就是.NET Core 1.0了; .net core将获得所有新功能。 27 | 28 | * 发布周期更快 29 | 30 | 如果您曾在框架中遇到错误,并将其报告给Microsoft,则您将知道发布修复需要多长时间。这个框架有很长的发布周期,通常至少要测量一年,而且在这些周期中还有很小的窗口用于特性工作。每个代码更改都可能会导致框架中其他位置出现意外的问题。为了给每个团队足够的时间来测试框架,有很多时候代码更改是受限制的或者严格审查的。如果您在.NET中发现了一个错误,最好找到一个解决方法,而不是等待更新。 31 | 32 | .NET Core遵循更快的发布步调。开发人员可以使用夜间构建来尽早测试。不属于.NET标准库的库可以按自己的步调发布。因为所有东西都是开源的,如果微软没有足够快的响应,任何开发者都可以提出修补。如果解决方法不被接受,讨论就会公开进行,所有人都可以看到为什么做出这个决定 33 | 34 | * 如果你是.NET新手 35 | 36 | 在Windows平台上,.NET Framework没有太多的竞争。微软可以对从操作系统内核层到高级.NET库的所有内容进行更改。通过将.NET引入其他平台,比如Linux,竞争环境发生了变化。.NET现在必须与其他所有的开发框架竞争。这里有一些东西,促使.NET分开。 37 | 38 | * C#是一个了不起的语言 39 | 40 | .NET的旗舰语言C#具有许多独特的功能,例如LINQ和await/async,这使得它强大且易于使用。C#也在不断创新。C#团队公开设计语言,因为他们希望任何人提出建议或参与讨论。编译器(Roslyn)完全是模块化和可扩展的。 41 | 42 | * ASP.NET Core性能与顶级Web平台相当 43 | 44 | 如果您正在编写Web应用程序或服务,那么ASP.NET Core是一个很好的搭建平台。它具有出色的性能和低内存占用。许多功能可以使您的应用程序更容易开发和维护 45 | ASP.NET是2002年发布的第一个.NET Framework版本,并不断发展。尽管ASP.NET取得了成功,但在ASP.NET团队中却感觉到他们正在失去开发人员,因为ASP.NET的性能没有竞争力,只能在Windows平台上运行。 46 | 一家名为TechEmpower的公司每隔几个月就会运行一次Web应用程序平台的基准测试,并提供一个分为几类的排名。基准测试在Linux上运行,仅包含Windows平台。对于ASP.NET团队来说,这很麻烦。许多平台都用于编写跨平台的Web应用程序,并且其性能数据令人印象深刻。此外,一些Java框架发布了天文数字,例如每秒570万个明文请求,或者490万个。 47 | 在TechEmpower基准测试的第十一轮中,Mono平台上的ASP.NET MVC被纳入测试。结果不好。Mono上的ASP.NET每秒只有2000个明文请求。Mono不是由Microsoft创建的,是开源社区实现,它不会像普通的.NET Framework那样得到相同数量的性能调整。为了获得更公平的比较,ASP.NET团队决定在与TechEmpower相同的硬件上运行.NET 4.6的基准测试。结果是每秒约50,000个请求。仍然没有接近NodeJS(每秒320,000个请求),或TechEmpower列表上的其他任何顶级框架。 48 | 可怜的低分并不意外。如前所述,ASP.NET知道改变现状只能通过重写整个架构来清除障碍。这正是发生的事情。 49 | ASP.NET团队着手构建ASP.NET Core,几个月后,该团队庆祝asp.net core每秒超过100万个请求。最新asp.net core 性能已经跨入顶级序列,我们来看最新一期的TechEmpower基准测试[第十七轮测试](https://www.techempower.com/benchmarks/#section=data-r17&hw=ph&test=plaintext), 50 | 17轮的测试使用的是ASP.NET Core 2.1 51 | 52 | ![techempower17](./resource/techpower17.png) 53 | 54 | * .NET Core不是从头开始的 55 | 56 | .NET在2000年就已经出现了。.NET Framework代码在过去几年中已经得到了巩固,开发人员也从中受益。已经被移植到.NET Core的大部分.NET Framework代码都没有改变。这使得.NET Core在构建应用程序的可靠框架方面领先一步。.NET Core也完全由Microsoft支持。这降低了为您的应用程序使用.NET Core的风险。 57 | 2016年,微软收购了Xamarin并发布了.NET Core 1.0。Xamarin构建于开源的Mono之上,之前Mono已经移植了.NET框架的大部分内容来运行在基于Linux / Unix的操作系统上。.NET Core也受益于Mono 十几年的跨平台经验。 58 | 59 | * .NET Core的关键功能 60 | 61 | .NET Core借鉴了.NET Framework的最佳实践,并将软件工程的最新进展结合在一起。这些是.NET Core的一些显着特征。 62 | 同一个库可以在后台服务“本地”或云中运行,也可以在手机,平板电脑或桌面上运行的客户端应用程序中运行。与其为iOS,Android和Windows构建单独的应用程序,您可以构建一个适用于所有平台的应用程序。.NET Core是小型和完美的容器,可以轻松扩展并缩短开发时间。 63 | .NET Core和.NET Standard Library建立了一个通用平台。过去,当新版本的操作系统或新设备出现时,开发人员有责任重新构建新平台的应用程序或库,并分发更新。使用.NET Core,不需要重建和重新分配。只要新的平台支持你所有的依赖库,它就支持你的应用程序。 64 | 65 | * 在任何平台上简单部署 66 | 67 | Microsoft产品往往具有复杂的安装过程。COM组件,注册表项,特殊文件夹,GAC - 都是为了利用Windows的特性而设计的。.NET Framework依赖于这些构造,这使得它不适合其他操作系统。 68 | 在发布依赖于.NET Framework的应用程序时,安装程序必须足够聪明才能检测是否安装了正确的.NET Framework版本,并为用户提供正确的方法。大多数现代Windows版本都包含.NET Framework。这使得某些应用程序更容易安装,但是如果应用程序使用默认情况下未安装的功能(如ASP.NET与IIS或WCF组件的集成),则可能会导致复杂的问题。 69 | 另一个复杂的问题来自补丁。包括错误修复或安全更新的修补程序可以通过Windows更新或通过Microsoft下载中心分发给客户。您测试应用程序的.NET Framework可能与客户使用的补丁程序不同。当您假定.NET Framework对于所有客户都是一样的时候,通常很难确定在应用程序中导致奇怪行为的原因。 70 | .NET Core的模块化设计意味着您只包含所需的依赖关系。所有这些依赖关系与您的应用程序进入相同的文件夹。部署应用程序与复制文件夹一样简单。这种方法的另一个优点是可以有多个版本并行运行。这个策略对于使所有平台的部署体验保持一致至关重要。 71 | 72 | * 云和容器 73 | 74 | 云系统中,用更少的硬件为更高密度的用户提供服务是非常重要的。应用程序的占位面积越小,密度越高。虚拟机已经在云端普遍存在多年,但是它们有几个问题: 75 | - 大小 - 一个典型的虚拟机文件是千兆字节,如果不是几十千兆字节。这使得它们跨网络传输非常耗时,并且对磁盘空间有很大的要求。 76 | - 启动时间 - 启动虚拟机意味着启动操作系统。对于Windows来说,这是一个挑战,因为启动新机器需要花费时间。这可以使处理突发交通困难。 77 | - 内存 - 虚拟机需要将整个操作系统与应用程序一起加载到内存中。这意味着很多主机的内存被浪费了。 78 | - 不一致性 - 相同的虚拟机可以复制到多个主机,主机必须提供相同的虚拟化硬件,这可能依赖于物理硬件。无法保证虚拟机在任何给定的主机上运行相同的操作。 79 | 80 | 容器通过虚拟化操作系统来解决虚拟机的问题。容器只包含应用程序及其依赖项。文件大小要小很多倍,启动时间以秒为单位,只有应用程序加载到内存中,容器保证在任何主机上工作。 81 | 82 | 内置于Windows的.NET Framework现在也可以容器上运行,但是镜像文件特别大。鉴于容器的明显优势,.NET Core的设计决定之一就是使其成为模块化。这意味着你的.NET Core应用程序可以被“发布”,使得它和它的所有依赖关系在一个地方,这很容易放入容器。 83 | -------------------------------------------------------------------------------- /0 whydotnet/2.dotnetabout.md: -------------------------------------------------------------------------------- 1 | # .NET Core入门 2 | 3 | 可在 Windows、Linux 和 macOS 上安装 .NET Core。 你可在最喜欢的文本编辑器中编写代码并生成跨平台的库和应用程序。 4 | 5 | ## 创建应用程序 6 | 7 | 首先,在计算机上下载并安装 [.NET Core SDK](https://www.microsoft.com/net/download/)。 8 | 9 | 然后,打开某一终端,如 PowerShell、命令提示符或 Bash。 键入以下 `dotnet` 命令以创建并运行 C# 应用程序。 10 | 11 | ```console 12 | dotnet new console --output sample1 13 | dotnet run --project sample1 14 | ``` 15 | 16 | 您应看到以下输出: 17 | 18 | ```console 19 | Hello World! 20 | ``` 21 | 22 | 祝贺你! 现已创建了一个简单的 .NET Core 应用程序。 此外,还可以使用 Visual Studio Code、Visual Studio 2017或 Visual Studio for Mac(仅限 macOS)来创建 .NET Core 应用程序。 23 | 24 | ## 工具箱 25 | 26 | ![工具箱架构](resource/toolarch.png) 27 | 28 | 这些工具的分层非常简单。 在底部,我们将 共享 SDK 组件作为基础。共享 SDK 组件是一组负责编译代码、发布代码、打包 NuGet 包等操作的目标和关联任务。 其他所有高级工具(如 Visual Studio 或 Visual Studio Code)依靠 共享 SDK 组件来生成项目、还原依赖项以及完成其他操作。 现在所有工具集使用共享 SDK 组件及其目标,包括 CLI。 29 | 30 | ### CLI 命令 31 | 32 | .NET Core 命令行接口 (CLI) 工具是用于开发 .NET 应用程序的新型跨平台工具链。 CLI 是更高级别的工具(如集成开发环境 (IDE)、编辑器和生成协调程序)可以驻留的基础。 CLI 核心命令如下: 33 | 34 | * `new` 35 | * `restore` 36 | * `run` 37 | * `build` 38 | * `publish` 39 | * `test` 40 | * `pack` 41 | 42 | 这些命令的作用(新建项目、生成项目、发布项目、打包项目等等)。 可以使用 `dotnet --help` 查看相应命令的帮助屏幕,也可以参阅此网站上的文档来熟悉所有更改。 43 | CLI 采用可使你为项目指定其他工具的扩展性模型。 44 | 45 | ## 命令结构 46 | 47 | CLI 命令结构包含[驱动程序(“dotnet”)](#driver)、[命令(或“谓词”)](#command-verb),或可能的命令[参数](#arguments)和[选项](#options)。 在大部分 CLI 操作中可看到此模式,例如创建新控制台应用并从命令行运行该应用,因为从名为 *my_app* 的目录中执行时,显示以下命令: 48 | 49 | ```console 50 | dotnet new console 51 | dotnet build --output /build_output 52 | dotnet /build_output/my_app.dll 53 | ``` 54 | 55 | --- 56 | 57 | ### 驱动程序 58 | 59 | 驱动程序名为 [dotnet](dotnet.md),并具有两项职责,即运行[依赖于框架的应用](../deploying/index.md)或执行命令。 唯一一次在不使用命令的情况下使用 `dotnet` 是在将其用于启动应用程序时。 60 | 61 | 若要运行依赖于框架的应用,请在驱动程序后指定应用,例如,`dotnet /path/to/my_app.dll`。 从应用的 DLL 驻留的文件夹执行命令时,只需执行 `dotnet my_app.dll` 即可。 62 | 63 | 为驱动程序提供命令时,`dotnet.exe` 启动 CLI 命令执行过程。 首先,驱动程序确定要使用的 SDK 版本。 如果在命令选项中未指定版本,则驱动程序使用可用的最新版本。 若要指定某个版本,而不是最新安装的版本,请使用 `--fx-version ` 选项(请参阅 [dotnet 命令](dotnet.md) 引用)。 确定 SDK 版本后,驱动程序执行命令。 64 | 65 | ### 命令(“谓词”) 66 | 67 | 命令(或“谓词”)仅仅是执行操作的命令。 例如,`dotnet build` 生成代码。 `dotnet publish` 发布代码。 使用 `dotnet {verb}` 约定将命令作为控制台应用程序实现。 68 | 69 | ### 自变量 70 | 71 | 在命令行上传递的参数是被调用的命令的参数。 例如,执行 `dotnet publish my_app.csproj` 时,`my_app.csproj` 参数指示要发布的项目,并被传递到 `publish` 命令。 72 | 73 | ### 选项 74 | 75 | 在命令行上传递的选项是被调用的命令的选项。 例如,执行 `dotnet publish --output /build_output` 时,`--output` 选项及其值被传递到 `publish` 命令。 76 | 77 | ## 请参阅 78 | 79 | * [dotnet/CLI GitHub 存储库](https://github.com/dotnet/cli/) 80 | * [.NET Core 安装指南](https://aka.ms/dotnetcoregs) -------------------------------------------------------------------------------- /0 whydotnet/3.net-standard.md: -------------------------------------------------------------------------------- 1 | # .NET Standard 2 | 3 | [.NET Standard](https://github.com/dotnet/standard) 是一套正式的 .NET API 规范,有望在所有 .NET 实现中推出。 推出 .NET Standard 的背后动机是要提高 .NET 生态系统中的一致性。 [ECMA 335](https://github.com/dotnet/coreclr/blob/master/Documentation/project-docs/dotnet-standards.md) 持续为 .NET 实现行为建立统一性,但适用于 .NET 库实现的 .NET 基类库 (BCL) 没有类似的规范。 4 | 5 | .NET Standard 是一种正式规范,它定义了一组版本化 API。这些 API 必须可用于符合相应 Standard 版本要求的 .NET 实现。 .NET Standard 面向库开发者。 定目标到 .NET Standard 版本的库可用于任意 .NET Framework、.NET Core 或支持 Standard 版本的 Xamarin 实现。 6 | 7 | .NET Standard 的最新版本是 2.0。 .NET Core 2.1 SDK 及已安装 .NET Core 工作负载的 Visual Studio 2017 版本 15.8。 8 | 9 | 10 | .NET Standard 可实现以下重要情境: 11 | 12 | - 为要实现的所有 .NET 实现定义一组统一的、与工作负荷无关的 BCL API。 13 | - 使开发人员能够通过同一组 API 生成可在各种 .NET 实现中使用的可移植库。 14 | - 减少甚至消除由于 .NET API 方面的原因而对共享源代码进行的条件性编译(仅适用于 OS API)。 15 | 16 | 各种 .NET 实现以特定版本的 .NET Standard 为目标。 每个 .NET 实现版本都会公布它所支持的最高 .NET Standard 版本,这种声明意味着它也支持以前的版本。 例如,.NET Framework 4.6 实现 .NET Standard 1.3。也就是说,它会公开在 .NET Standard 版本 1.0 到 1.3 中定义的所有 API。 同样,.NET Framework 4.6.1 实现 .NET Standard 1.4,而 .NET Core 1.0 则实现 .NET Standard 1.6。 17 | 18 | ## .NET 实现支持 19 | 20 | 下表列出了支持每个 .NET Standard 版本的最低平台版本。 21 | | .NET Standard | [1.0] | [1.1] | [1.2] | [1.3] | [1.4] | [1.5] | [1.6] | [2.0] | 22 | |----------------------------|-------|--------|-------|-------|-------|------------|------------|------------| 23 | | .NET Core | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 | 2.0 | 24 | | .NET Framework 1| 4.5 | 4.5 | 4.5.1 | 4.6 | 4.6.1 | 4.6.1 | 4.6.1 | 4.6.1 | 25 | | Mono | 4.6 | 4.6 | 4.6 | 4.6 | 4.6 | 4.6 | 4.6 | 5.4 | 26 | | Xamarin.iOS | 10.0 | 10.0 | 10.0 | 10.0 | 10.0 | 10.0 | 10.0 | 10.14 | 27 | | Xamarin.Mac | 3.0 | 3.0 | 3.0 | 3.0 | 3.0 | 3.0 | 3.0 | 3.8 | 28 | | Xamarin.Android | 7.0 | 7.0 | 7.0 | 7.0 | 7.0 | 7.0 | 7.0 | 8.0 | 29 | | 通用 Windows 平台 | 10.0 | 10.0 | 10.0 | 10.0 | 10.0 | 10.0.16299 | 10.0.16299 | 10.0.16299 | 30 | | Windows | 8.0 | 8.0 | 8.1 | | | | | | 31 | | Windows Phone | 8.1 | 8.1 | 8.1 | | | | | | 32 | | Windows Phone Silverlight | 8.0 | | | | | | | | 33 | | Unity | 2018.1| 2018.1 | 2018.1| 2018.1| 2018.1| 2018.1 | 2018.1 | 2018.1 | 34 | 35 | 1 针对 .NET framework 列出的版本适用于 .NET Core SDK 2.0 和更高版本的工具。旧版本对 .NET Standard 1.5 及更高版本使用了不同映射。如果无法升级到 Visual Studio 2017,可[下载适用于 Visual Studio 2015 的 .NET Core 工具](https://github.com/dotnet/core/blob/master/release-notes/download-archive.md)。 36 | 37 | - 列表示 .NET Standard 版本。 每个标题单元格都是一个文档链接,其中介绍了相应版本的 .NET Standard 中新增了哪些 API。 38 | - 行表示不同的 .NET 实现。 39 | - 各单元格中的版本号指示要定向到此 .NET Standard 版本所需的最低实现版本。 40 | - 有关交互式表的信息,请参阅 [.NET Standard 版本](http://immo.landwerth.net/netstandard-versions/#)。 41 | 42 | [1.0]: https://github.com/dotnet/standard/blob/master/docs/versions/netstandard1.0.md 43 | [1.1]: https://github.com/dotnet/standard/blob/master/docs/versions/netstandard1.1.md 44 | [1.2]: https://github.com/dotnet/standard/blob/master/docs/versions/netstandard1.2.md 45 | [1.3]: https://github.com/dotnet/standard/blob/master/docs/versions/netstandard1.3.md 46 | [1.4]: https://github.com/dotnet/standard/blob/master/docs/versions/netstandard1.4.md 47 | [1.5]: https://github.com/dotnet/standard/blob/master/docs/versions/netstandard1.5.md 48 | [1.6]: https://github.com/dotnet/standard/blob/master/docs/versions/netstandard1.6.md 49 | [2.0]: https://github.com/dotnet/standard/blob/master/docs/versions/netstandard2.0.md 50 | 51 | 若要查找可以定位的 .NET Standard 最高版本,请按照以下步骤操作: 52 | 53 | 1. 查找要运行的 .NET 实现所在的行。 54 | 2. 在这一行中从右向左查找可以定位的 .NET Standard 版本所在的列。 55 | 3. 列标题指明了目标平台支持的 .NET Standard 版本(也支持所有更低的 .NET Standard 版本)。 56 | 4. 对要定位的每个平台重复执行此过程。 如果有多个目标平台,应选择它们都支持的最高版本。 例如,如果要在 .NET Framework 4.5 和 .NET Core 1.0 上运行,可以使用的最高 .NET Standard 版本是 .NET Standard 1.1。 57 | 58 | ### 要定位哪个 .NET Standard 版本 59 | 60 | 选择 .NET Standard 版本时,应权衡以下因素: 61 | 62 | - 版本越高,可使用的 API 就越多。 63 | - 版本越低,可实现它的平台就越多。 64 | 65 | 一般来说,建议尽可能定位*最低*版本 .NET Standard。 因此,在找到可以定位的最高版本 .NET Standard 后,请按照以下步骤操作: 66 | 67 | 1. 定位前一更低版本的 .NET Standard,然后生成项目。 68 | 2. 如果成功生成项目,请重复执行第 1 步。 否则,重新定位到后一较高版本,这就是应该使用的版本。 69 | 70 | 但是,定位更低版本的 .NET Standard 会引入许多支持依赖项。 如果项目定位 .NET Standard 1.x,我们建议还定位 .NET Standard 2.0。 这简化了在 .NET Standard 2.0 兼容框架上运行的库的用户的依赖项关系图,并减少了下载所需的包数。 71 | 72 | ### .NET Standard 版本控制规则 73 | 74 | 版本控制规则主要有两个: 75 | 76 | - 累加性:.NET Standard 版本在逻辑上形成同心圆。也就是说,较高的版本包含较低版本的所有 API。 版本之间没有重大更改。 77 | - 不可变:一旦发布,.NET Standard 版本就会冻结起来。 新 API 首先会在特定的 .NET 实现(如 .NET Core)中可用。 如果 .NET Standard 评审委员会认为新 API 应可用于所有 .NET 实现,则会将它们添加到新的 .NET Standard 版本中。 78 | 79 | ## 规范 80 | 81 | .NET Standard 规范是一组标准化的 API。 此规范由 .NET 实现者(具体而言,由 Microsoft(包括 .NET Framework、NET Core 和 Mono)和 Unity)进行维护。 在通过 [GitHub](https://github.com/dotnet/standard) 建立新 .NET Standard 版本的过程中,采用公众反馈流程。 82 | 83 | ### 正式项目 84 | 85 | 正式规范是一组用于定义标准中包含的 API 的 .cs 文件。 [dotnet/standard 存储库](https://github.com/dotnet/standard)中的 [Ref 目录](https://github.com/dotnet/standard/tree/master/netstandard/ref)定义了 .NET Standard API。 86 | 87 | [NETStandard.Library](https://www.nuget.org/packages/NETStandard.Library) 元包([源代码](https://github.com/dotnet/standard/blob/master/netstandard/pkg/NETStandard.Library.dependencies.props))描述用于部分定义一个或多个 .NET Standard 版本的库集。 88 | 89 | 给定的组件(如 `System.Runtime`)描述: 90 | 91 | - .NET Standard 的一部分(即其范围)。 92 | - .NET Standard 在此范围内的多个版本。 93 | 94 | 标准库提供派生项目以方便读取,并实现某些开发人员方案(例如,使用编译器)。 95 | 96 | - [Markdown 中的 API 列表](https://github.com/dotnet/standard/tree/master/docs/versions) 97 | - 引用程序集,以 NuGet 包的形式分发,由 [NETStandard.Library](https://www.nuget.org/packages/NETStandard.Library/) 元包引用。 98 | 99 | ### 包表示形式 100 | 101 | .NET Standard 引用程序集的主要分发载体是NuGet 包。 实现会以适用于每个 .NET 实现的各种方式提供。 102 | 103 | NuGet 包面向一个或多个[框架](frameworks.md)。 .NET Standard 包定位“.NET Standard”框架。 可以使用 `netstandard` 精简 TFM(例如 `netstandard1.4`)来设定 .NET Standard 框架作为目标。 如果构建的库将用于在多个运行时上运行,就应将此框架作为目标。 对于最广泛的 API 集,将 `netstandard2.0` 设定为目标,因为 .NET Standard 2.0 的可用 API 数量比 .NET Standard 1.6 的两倍还多。 104 | 105 | [`NETStandard.Library`](https://www.nuget.org/packages/NETStandard.Library/) 元包引用定义 .NET Standard 的一整套 NuGet 包。 要指定 `netstandard` 作为目标,最常见的方法是引用此元包。 它描述并提供了对大约 40 个 .NET 库及定义 .Net Standard 的相关 API 的访问权限。 可以引用以 `netstandard` 为目标的其他包来使用其他 API。 106 | 107 | ### 版本管理 108 | 109 | 规范并不是单一的,而是一组版本不断线性递增的 API。 该标准的第一个版本建立了一组基准 API。 后续版本将添加 API,并继承以前的版本定义的 API。 在从标准中移除 API 方面,并没有成文的规定。 110 | 111 | .NET Standard 并不特定于任何一种 .NET 实现,也不与其中任一运行时的版本控制方案匹配。 112 | 113 | 添加到任何实现(例如 .NET Framework、.NET Core 和 Mono)的 API 可被视为适合添加到规范中的候选项,尤其是本质上非常重要的 API。 [.NET Standard 的新版本](https://github.com/dotnet/standard/blob/master/docs/versions.md)根据 .NET 实现版本进行创建,以便可以定位 .NET Standard PCL 中的新 API。 114 | 115 | .NET Standard 版本控制对于库的使用至关重要。 在 .NET Standard 版本既定的情况下,可以使用定位相同或更低版本的库。 下面的做法介绍了使用 .NET Standard PCL(专用于 .NET Standard 定位)的工作流。 116 | 117 | - 选择要用于 PCL 的 .NET Standard 版本。 118 | - 使用依赖相同或更低 .NET Standard 版本的库。 119 | - 如果发现依赖更高 .NET Standard 版本的库,要么需要采用相同的版本,要么不要使用此库。 120 | 121 | ## 定位 .NET Standard 122 | 123 | 可以结合使用 `netstandard` 框架和 NETStandard.Library 元包来构建.NET Standard 库。 124 | 125 | ## .NET Framework 兼容性模式 126 | 127 | 从 .NET Standard 2.0 开始,引入了 .NET Framework 兼容性模式。 此兼容性模式允许 .NET Standard 项目引用 .NET Framework 库,就像其针对 .NET Standard 编译一样。 引用 .NET Framework 库并不适用于所有项目,,例如使用 Windows Presentation Foundation (WPF) API 的库。 128 | 129 | 有关详细信息,请参阅 [.NET Framework兼容性模式](https://docs.microsoft.com/zh-cn/dotnet/core/porting/third-party-deps#net-framework-compatibility-mode)。 130 | 131 | ## .NET Standard 库和 Visual Studio 132 | 133 | 要在 Visual Studio 中生成 .NET Standard 库,请确保 Windows 上已安装 [Visual Studio 2017 版本 15.3](https://visualstudio.microsoft.com/downloads/?utm_medium=microsoft&utm_source=docs.microsoft.com&utm_campaign=button+cta&utm_content=download+vs2017) 或更高版本,或 macOS 上已安装 [Visual Studio for Mac 版本 7.1](https://visualstudio.microsoft.com/vs/visual-studio-mac/) 或更高版本。 134 | 135 | 如果项目中只需使用 .NET Standard 2.0 库,也可在 Visual Studio 2015 中执行此操作。 但是需要安装 NuGet client 3.6 或更高版本。 可从 [NuGet 下载](https://www.nuget.org/downloads)页面下载适用于 Visual Studio 2015 的 NuGet 客户端。 136 | 137 | ### .NET Standard 库的工具支持 138 | 139 | 随着 .NET Core 2.0 和 .NET Standard 2.0 发布,Visual Studio 2017 和 [.NET Core 命令行接口 (CLI)](../../core/tools/index.md) 均包含创建 .NET Standard 库所需的工具支持。 140 | 141 | 如果安装含 .NET Core 跨平台开发工作负荷的 Visual Studio,可以使用项目模板创建 .NET Standard 2.0 库项目,如下图所示: 142 | 143 | ![添加新的 .NET Standard 库项目](./resource/std-project-cs.png) 144 | 145 | 如果使用的是 .NET Core CLI,可以运行下面的 [dotnet new](../../core/tools/dotnet-new.md) 命令,以创建定目标到 .NET Standard 2.0 的类库项目: 146 | 147 | ``` 148 | dotnet new classlib 149 | ``` 150 | 151 | ## 请参阅 152 | 153 | - [.NET Standard 简介](https://blogs.msdn.microsoft.com/dotnet/2016/09/26/introducing-net-standard/) -------------------------------------------------------------------------------- /0 whydotnet/4.tencentcloudsdk.md: -------------------------------------------------------------------------------- 1 | # 腾讯云开发者工具套件( SDK )3.0 2 | 3 | 腾讯云 API 全新升级 3.0 ,该版本进行了性能优化且全地域部署、支持就近和按地域接入、访问时延下降显著,接口描述更加详细、错误码描述更加全面、SDK增加接口级注释,让您更加方便快捷的使用腾讯云产品。 4 | 5 | 腾讯云开发者工具套件( SDK )3.0 ,SDK 3.0 是云 API 3.0 平台的配套工具。后续所有的云服务产品都会接入进来。新版 SDK 实现了统一化,具有各个语言版本的 SDK 使用方法相同,接口调用方式相同,统一的错误码和返回包格式这些优点。 6 | 7 | 为方便 .NET 开发者调试和接入腾讯云产品 API ,这里向您介绍适用于 .NET 的腾讯云开发工具包,开源地址是 https://github.com/TencentCloud/tencentcloud-sdk-dotnet ,对应的Nuget 包:https://www.nuget.org/packages/TencentCloudSDK/ 8 | 9 | ![腾讯云开发者套件3.0 Sdk](./resource/tencentcloudsdk.png) 10 | 微软发布了.NET 代码库指南https://docs.microsoft.com/zh-cn/dotnet/standard/library-guidance/ ,指导你为.NET创建高质量代码库。该指南包含我们已确定的适用于大多数公共.NET库的 最佳实践。希望帮助.NET开发人员构建具有以下方面的优秀库: 11 | - 包容性:优秀的.NET库致力于支持众多平台和应用程序。 12 | - 稳定性:优秀的.NET 系统在具有众多库的应用程序中运行的 .NET 生态系统中共存。 13 | - 设计为可改进:.NET 库要随着时间的推移进行改进和演变,同时支持现有用户。 14 | - 可调试:.NET库要使用最新的工具,为用户打造卓越的调试体验。 15 | - 受信任:.NE 库通过安全最佳做法发布到 NuGet,备受开发人员的信赖。 16 | 17 | TencentCloudSDK遵循.NET 代码库指南,结合国内实践设定支持.NETStandard 2.0 和.NETFramewrok 4.5 作为主要的运行平台。以便更轻松地构建.NET库,包括跨平台支持,.NET Standard以及与NuGet的紧密集成。 18 | 19 | 我们后面的动手实验中将使用腾讯云开发者工具套件(SDK) 3.0 使用腾讯云的产品。 -------------------------------------------------------------------------------- /0 whydotnet/resource/std-project-cs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geffzhang/QcloudNetCore/63708d1415c7093ab30cede0d01cbfe25784b4bb/0 whydotnet/resource/std-project-cs.png -------------------------------------------------------------------------------- /0 whydotnet/resource/techpower17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geffzhang/QcloudNetCore/63708d1415c7093ab30cede0d01cbfe25784b4bb/0 whydotnet/resource/techpower17.png -------------------------------------------------------------------------------- /0 whydotnet/resource/tencentcloudsdk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geffzhang/QcloudNetCore/63708d1415c7093ab30cede0d01cbfe25784b4bb/0 whydotnet/resource/tencentcloudsdk.png -------------------------------------------------------------------------------- /0 whydotnet/resource/toolarch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geffzhang/QcloudNetCore/63708d1415c7093ab30cede0d01cbfe25784b4bb/0 whydotnet/resource/toolarch.png -------------------------------------------------------------------------------- /1 docker/1.dotnetdockerbasic.md: -------------------------------------------------------------------------------- 1 | ## .NET Core:入门的最简单方法 2 | 3 | 在创建 Docker 映像之前,需要容器化应用程序。 可在 Linux、MacOS 或 Windows 上创建该映像。 完成该操作最快、最简单的方法是使用 .NET Core。 4 | 5 | 6 | 7 | ## 第一个 .NET Core Docker 应用 8 | 9 | ### 系统必备 10 | 11 | 完成本教程: 12 | 13 | #### .NET Core 2.1 SDK 14 | 15 | * 安装 [.NET Core SDK 2.1](https://www.microsoft.com/net/core)。 16 | 17 | 有关支持 .NET Core 2.1 的操作系统、不支持的 OS 版本和生命周期策略链接的完整列表,请参阅 [.NET Core 2.1 - 支持的 OS 版本](https://github.com/dotnet/core/blob/master/release-notes/2.1/2.1-supported-os.md)。 18 | 19 | * 安装常用的代码编辑器(如果尚未安装)。 20 | 21 | > [!TIP] 22 | > 需要安装代码编辑器? 试用 [Visual Studio](https://visualstudio.com/downloads)! 23 | 24 | #### 安装 Docker 客户端 25 | 26 | 安装 [Docker 17.06](https://docs.docker.com/release-notes/docker-ce/) 或更高版本的 Docker 客户端。 27 | 28 | 可在以下位置安装 Docker 客户端: 29 | 30 | * Linux 分布 31 | 32 | * [CentOS](https://www.docker.com/docker-centos-distribution) 33 | 34 | * [Debian](https://www.docker.com/docker-debian) 35 | 36 | * [Fedora](https://www.docker.com/docker-fedora) 37 | 38 | * [Ubuntu](https://www.docker.com/docker-ubuntu) 39 | 40 | * [macOS](https://docs.docker.com/docker-for-mac/) 41 | 42 | * [Windows](https://docs.docker.com/docker-for-windows/)。 43 | 44 | ### 创建 .NET Core 2.1 控制台应用进行 Docker 化 45 | 46 | 打开命令提示符,创建一个名为“Hello”的文件夹。 导航到创建的文件夹,并键入以下内容: 47 | 48 | ```console 49 | dotnet new console 50 | dotnet run 51 | ``` 52 | 53 | 让我们进行快速演练: 54 | 55 | 1. `$ dotnet new console` 56 | 57 | [`dotnet new`](../tools/dotnet-new.md) 会创建一个最新的 `Hello.csproj` 项目文件,其中包含生成控制台应用所必需的依赖项。 它还将创建 `Program.cs`,这是包含应用程序的入口点的基本文件。 58 | 59 | `Hello.csproj`: 60 | 61 | 项目文件指定还原依赖项和生成程序所需的一切。 62 | 63 | * `OutputType` 标记指定我们要生成的可执行文件,即控制台应用程序。 64 | * `TargetFramework` 标记指定要定位的 .NET 实现代码。 在高级方案中,可以指定多个目标框架,并在单个操作中生成到指定框架。 在本教程中,针对 .NET Core 2.0 进行生成。 65 | 66 | `Program.cs`: 67 | 68 | 程序通过 `using System` 启动。 此语句的意思是“将 `System` 命名空间中的所有内容都纳入此文件的作用域”。 `System` 命名空间包括基本结构,如 `string` 或数值类型。 69 | 70 | 接着定义一个名为 `Hello` 的命名空间。 可以将命名空间更改为任何喜欢的名称。 在该命名空间中定义了一个名为 `Program` 的类,其中 `Main` 方法将字符串数组作为其参数。 此数组包含在调用编译的程序时所传递的参数列表。 在我们的示例中,该程序只会在控制台中写入 “Hello World!”。 71 | 72 | 2. `$ dotnet build` 73 | 74 | 在 .NET Core 2.1 中,dotnet new 运行 dotnet build 命令生成项目及其所有依赖项。 通过 [NuGet](https://www.nuget.org/)(.NET 包管理器)调用还原依赖项树。 75 | NuGet 执行下列任务: 76 | * 分析 Hello.csproj 文件 77 | * 下载文件依赖项(或从计算机缓存中获取) 78 | * 写入 obj/project.assets.json 文件 79 | 80 | project.assets.json 文件是一组完整的 NuGet 依赖项关系图、绑定解决方法及其他应用元数据。 此必需文件由其他工具(如dotnet run)用于正确处理源代码。 81 | 82 | 3. `$ dotnet run` 83 | 84 | dotnet run 调用 dotnet build来确认生成成功,然后调用 `dotnet ` 来运行应用程序。 85 | 86 | ```console 87 | $ dotnet run 88 | 89 | Hello World! 90 | ``` 91 | 92 | ## 使 .NET Core 应用程序 Docker 化 93 | 94 | Hello .NET Core 控制台应用已成功在本地运行。 现在,可进一步在 Docker 中生成和运行应用。 95 | 96 | ### 第一个 Dockerfile 97 | 98 | 打开文本编辑器并开始操作! 仍从生成了应用的 Hello 目录中进行操作。 99 | 100 | 为 Linux 或 [Windows 容器](https://docs.microsoft.com/virtualization/windowscontainers/about/) 向新文件添加以下 Docker 指令。 完成后,将其保存在 Hello 目录的根目录中作为 Dockerfile,并且不使用扩展名(可能需要将文件类型设置为 `All types (*.*)` 或类似的类型)。 101 | 102 | ```Dockerfile 103 | FROM microsoft/dotnet:2.1-sdk 104 | WORKDIR /app 105 | 106 | # copy csproj and restore as distinct layers 107 | COPY *.csproj ./ 108 | RUN dotnet restore 109 | 110 | # copy and build everything else 111 | COPY . ./ 112 | RUN dotnet publish -c Release -o out 113 | ENTRYPOINT ["dotnet", "out/Hello.dll"] 114 | ``` 115 | 116 | Dockerfile 包含按顺序运行的 Docker build 指令。 117 | 118 | 第一个指令必须为 [FROM](https://docs.docker.com/engine/reference/builder/#from)。 此指令用于初始化新的生成阶段,并为剩余指令设置基础映像。 多拱形标记根据 Docker for Windows [容器模式](https://docs.docker.com/docker-for-windows/#switch-between-windows-and-linux-containers) 请求 Windows 或 Linux 容器。 本示例的基础映像是 microsoft/dotnet 存储库中的 2.1-sdk 映像, 119 | 120 | ```Dockerfile 121 | FROM microsoft/dotnet:2.1-sdk 122 | ``` 123 | 124 | [WORKDIR](https://docs.docker.com/engine/reference/builder/#workdir) 指令为剩余的任意 RUN、CMD、ENTRYPOINT、COPY 和 ADD Dockerfile 指令设置工作目录。 如果不存在,则会创建该目录。 在本例中,WORKDIR 设置为应用目录。 125 | 126 | ```Dockerfile 127 | WORKDIR /app 128 | ``` 129 | 130 | [COPY](https://docs.docker.com/engine/reference/builder/#copy) 指令从源路径复制新文件或目录,并将它们添加到目标容器文件系统。 使用此指令中,可将 C# 项目文件复制到容器。 131 | 132 | ```Dockerfile 133 | COPY *.csproj ./ 134 | ``` 135 | 136 | [RUN](https://docs.docker.com/engine/reference/builder/#run) 指令在当前映像之上的一个新层中执行任何命令,并提交结果。 最终提交的映像用于 Dockerfile 中的后续步骤。 本例运行 dotnet restore 来获取 C# 项目文件所需的依赖项。 137 | 138 | ```Dockerfile 139 | RUN dotnet restore 140 | ``` 141 | 142 | 此 COPY 指令将剩余文件复制到新[层](https://docs.docker.com/engine/userguide/storagedriver/imagesandcontainers/#images-and-layers)中的容器。 143 | 144 | ```Dockerfile 145 | COPY . ./ 146 | ``` 147 | 148 | 本例使用 RUN 指令发布应用。 [dotnet publish](../tools/dotnet-publish.md) 命令用于编译应用程序、读取项目文件中指定的所有依赖项并将生成的文件集发布到目录。 此处使用 Release 配置和到默认目录的输出来发布应用。 149 | 150 | ```Dockerfile 151 | RUN dotnet publish -c Release -o out 152 | ``` 153 | 154 | [ENTRYPOINT](https://docs.docker.com/engine/reference/builder/#entrypoint) 指令支持以可执行文件的形式运行容器。 155 | 156 | ```Dockerfile 157 | ENTRYPOINT ["dotnet", "out/Hello.dll"] 158 | ``` 159 | 160 | 现在,生成的 Dockerfile 可: 161 | 162 | * 将应用复制到映像 163 | * 作为应用对映像的依赖项 164 | * 生成作为可执行文件运行的应用 165 | 166 | ### 生成并运行 Hello .NET Core 2.1 应用 167 | 168 | #### 重要的 Docker 命令 169 | 170 | 以下 Docker 命令非常重要: 171 | 172 | * [docker build](https://docs.docker.com/engine/reference/commandline/build/) 173 | * [docker run](https://docs.docker.com/engine/reference/commandline/run/) 174 | * [docker ps](https://docs.docker.com/engine/reference/commandline/ps/) 175 | * [docker stop](https://docs.docker.com/engine/reference/commandline/stop/) 176 | * [docker rm](https://docs.docker.com/engine/reference/commandline/rm/) 177 | * [docker rmi](https://docs.docker.com/engine/reference/commandline/rmi/) 178 | * [docker image](https://docs.docker.com/engine/reference/commandline/image/) 179 | 180 | #### 生成和运行 181 | 182 | 已编写 dockerfile;现在 Docker 可生成应用,然后运行容器。 183 | 184 | ```console 185 | docker build -t dotnetapp-dev . 186 | docker run --rm dotnetapp-dev Hello from Docker 187 | ``` 188 | 189 | `docker build` 命令的输出应类似于以下控制台输出: 190 | 191 | ```console 192 | Sending build context to Docker daemon 72.7kB 193 | Step 1/7 : FROM microsoft/dotnet:2.0-sdk 194 | ---> d84f64b126a6 195 | Step 2/7 : WORKDIR /app 196 | ---> Using cache 197 | ---> 9af1fbdc7972 198 | Step 3/7 : COPY *.csproj ./ 199 | ---> Using cache 200 | ---> 86c8c332d4b3 201 | Step 4/7 : RUN dotnet restore 202 | ---> Using cache 203 | ---> 86fcd7dd0ea4 204 | Step 5/7 : COPY . ./ 205 | ---> Using cache 206 | ---> 6faf0a53607f 207 | Step 6/7 : RUN dotnet publish -c Release -o out 208 | ---> Using cache 209 | ---> f972328318c8 210 | Step 7/7 : ENTRYPOINT dotnet out/Hello.dll 211 | ---> Using cache 212 | ---> 53c337887e18 213 | Successfully built 53c337887e18 214 | Successfully tagged dotnetapp-dev:latest 215 | ``` 216 | 217 | 可在输出中看到,Docker 引擎使用 Dockerfile 生成容器。 218 | 219 | `docker run` 命令的输出应类似于以下控制台输出: 220 | 221 | ```console 222 | Hello World! 223 | ``` 224 | 225 | 祝贺你! 你刚才已: 226 | > [!div class="checklist"] 227 | > * 创建本地 .NET Core 应用 228 | > * 创建 Dockerfile 以生成第一个容器 229 | > * 生成并运行已 Docker 化的应用 230 | 231 | -------------------------------------------------------------------------------- /1 docker/2.netdocker.md: -------------------------------------------------------------------------------- 1 | # .NET 和 Docker 简介 2 | 3 | 本文提供了如何在 Docker 上使用 .NET 的简介和概念背景。 4 | 5 | ## Docker:打包应用程序以在任何位置部署和运行 6 | 7 | Docker 是一个开放平台,使开发人员和管理员可以在称为[容器](https://www.docker.com/what-container)的松散隔离的环境中构建[映像](https://docs.docker.com/glossary/?term=image)、交付和运行分布式应用程序。 此方法可以在开发、QA 和生产环境之间进行高效的应用程序生命周期管理。 8 | 9 | [Docker 平台](https://docs.docker.com/engine/docker-overview/#the-docker-platform)使用 [Docker 引擎](https://docs.docker.com/engine/docker-overview/#docker-engine)快速构建应用程序,并将其打包为使用以 [Dockerfile](https://docs.docker.com/glossary/?term=Dockerfile) 格式编写的文件创建的 [Docker 映像](https://docs.docker.com/glossary/?term=image),然后在[分层容器](https://docs.docker.com/engine/userguide/storagedriver/imagesandcontainers/#container-and-layers)中部署和运行。 10 | 11 | 你可以创建自己的[分层映像](https://docs.docker.com/engine/userguide/storagedriver/imagesandcontainers/#images-and-layers)作为 dockerfiles,或使用[注册表](https://docs.docker.com/glossary/?term=registry)中的现有映像,例如 [Docker 中心](https://docs.docker.com/glossary/?term=Docker%20Hub)。 12 | 13 | 使用 Docker 时,开发人员会创建一个应用或服务,并将它及其依赖项打包到一个容器映像中。 映像是应用或服务及其配置和依赖项的静态表示形式。 14 | 15 | 若要运行应用或服务,应用的映像会实例化,以创建一个在 Docker 主机上运行的容器。 最初,会在开发环境或 PC 中测试容器。 16 | 17 | 开发人员应将映像存储在注册表中,该注册表充当映像库,并且在部署到生产业务流程协调程序时需要用到该注册表。 Docker 通过 Docker Hub维护一个公共注册表;其他供应商为不同映像集合提供注册表,包括 腾讯云容器注册表。 或者,企业可本地拥有一个专用注册表,用于其 Docker 映像。 18 | ![docker基本概念和术语](./resource/dockerbasic.png) 19 | 20 | 通过将映射存储到注册表中,可存储静态和不可变的应用程序,包括其在框架级别的所有依赖项。 然后可将这些映像部署到多种环境中,并进行版本控制,从而提供一致的部署单元 21 | 无论是托管在本地还是托管在云中,在下列情况下都建议使用私有映像注册表: 22 | - 由于保密性,映像不能被公开分享。 23 | - 希望映像和所选部署环境之间的网络延迟保持在最低水平。 例如,如果生产环境是腾讯 云,为实现最低的网络延迟,需要将映像存储在 [腾讯云 容器注册表](https://cloud.tencent.com/document/product/457/9118)中。 同样,如果生产环境是在本地,则需要在同一本地网络中使用本地的 Docker 信任的注册表。 24 | 25 | 26 | ### 获取 .NET Docker 映像 27 | 28 | 由 Microsoft 创建和优化官方 .NET Docker 映像。 这些映像在 Docker 中心的 Microsoft 存储库中公开提供。 每个存储库可以包含多个映像,具体取决于 .NET 和 OS 版本。 大多数映像存储库提供广泛的标记,以帮助选择特定的框架版本和 OS(Linux 发行版或 Windows 版本)。 29 | 30 | ## 基于方案的指南 31 | 32 | Microsoft 对 .NET 存储库的打算是要有细化和集中存储库,表示特定方案或工作负载。 33 | 34 | `microsoft/aspnetcore` 映像针对 Docker 上的 ASP.NET Core 应用进行了优化,因此容器可以更快启动。 35 | 36 | .NET Core 映像 (`microsoft/dotnet`) 适用于基于 .NET Core 的控制台应用。 例如,批处理、Azure WebJobs 和其他控制台方案应该使用优化的 .NET Core 映像。 37 | 38 | 使用 Docker 和 .NET 应用程序最显而易见的水平方案是用于生产部署和托管。 事实证明,生产只是一种方案,其他方案同样有用。 这些方案不是特定于 .NET,但应该适用于大多数开发人员平台。 39 | 40 | * **低摩擦安装** — 你可以尝试使用 .NET,无需本地安装。 只下载 Docker 映像,其中包含 .NET。 41 | 42 | * **在容器中开发**你可以在一致的环境中开发,使开发和生产环境类似(可避免一些问题,例如开发人员计算机上的全局状态)。 通过 Visual Studio Tools for Docker,你甚至可以直接从 Visual Studio 启动容器。 43 | 44 | * **容器中测试** — 你可以在容器中测试,减少由于环境配置不当或上次测试遗留的其他更改而导致的故障。 45 | 46 | * **在容器中生成** — 你可以在容器中生成代码,消除为多个环境正确配置共享生成计算机的需要,而是转向“BYOC”(自带容器)方法。 47 | 48 | * **在所有环境中部署** — 可以通过你的所有环境部署映像。 这种方法减少了配置差异导致的故障,通常通过外部配置(例如,注入的环境变量)改变映像行为。 49 | 50 | 51 | ### 常见的 Docker 开发方案 52 | 53 | #### .NET Core 54 | 55 | **.NET Core 资源** 56 | 57 | 选择适合你感兴趣方案的 .NET Core 示例。 所有示例说明都介绍了如何从 Windows、Linux 或 macOS 主机定位 Windows 或 Linux Docker 映像。 58 | 59 | 这些示例使用 .NET Core 2.0。 它们会在适用时使用 Docker [多阶段生成](https://github.com/dotnet/announcements/issues/18)和[多拱形标记](https://github.com/dotnet/announcements/issues/14)。 60 | 61 | * [DockerHub 上的 .NET Core 映像](https://hub.docker.com/r/microsoft/dotnet/) 62 | 63 | * [使 .NET Core 应用程序 Docker 化](https://docs.docker.com/engine/examples/dotnetcore/) 64 | 65 | * 此 .NET Core Docker 示例演示如何[在 .NET Core 开发过程中使用 Docker](https://github.com/dotnet/dotnet-docker-samples/tree/master/dotnetapp-dev)。 此示例适用于 Linux 和 Windows 容器。 66 | 67 | * 此 .NET Core Docker 示例演示了[生成 .NET Core 应用程序的 Docker 映像以用于生产](https://github.com/dotnet/dotnet-docker-samples/tree/master/dotnetapp-prod)的最佳实践模式。 此示例适用于 Linux 和 Windows 容器。 68 | 69 | * 此 [.NET Core Docker 示例](https://github.com/dotnet/dotnet-docker-samples/tree/master/dotnetapp-selfcontained)演示了生成[独立式 .NET Core 应用程序](../deploying/index.md)的 Docker 映像的最佳实践模式。 用于最小的生产容器,而不会受益于[在容器之间共享基础映像](https://docs.docker.com/engine/userguide/storagedriver/imagesandcontainers/)。 但是,可以共享较低的 Docker 层。 70 | 71 | #### ASP.NET Core 72 | 73 | * [此 ASP.NET Core Docker 示例](https://github.com/dotnet/dotnet-docker-samples/tree/master/aspnetapp)演示了生成 ASP.NET Core 应用程序的 Docker 映像以用于生产的最佳实践模式。 此示例适用于 Linux 和 Windows 容器。 74 | 75 | * [DockerHub 上的 ASP.NET Core 映像](https://hub.docker.com/r/microsoft/aspnetcore-build/) 76 | 77 | * [GitHub 上的 ASP.NET Core 映像](https://github.com/aspnet/aspnet-docker) 78 | 79 | -------------------------------------------------------------------------------- /1 docker/3.buildingnetdockerimages.md: -------------------------------------------------------------------------------- 1 | # 为 .NET Core 应用程序生成 Docker 映像 2 | 3 | 首先,我们探讨 Microsoft 维护和提供的各种不同的 Docker 映像,及其使用情况。 然后讲解了如何生成和 Docker 化 ASP.NET Core 应用。 4 | 5 | 6 | ## Docker 映像优化 7 | 8 | 为开发人员生成 Docker 映像时,侧重于以下三种主要方案: 9 | 10 | * 用于开发 .NET Core 应用的映像 11 | * 用于生成 .NET Core 应用的映像 12 | * 用于运行 .NET Core 应用的映像 13 | 14 | 为什么是三个映像? 15 | 因为在开发、生成和运行容器化应用程序时,具有不同的优先级。 16 | 17 | * **开发:** 优先级注重循环访问更改的速度以及调试更改的能力。 与更改代码并且快速查看相比,映像的大小是否不是那么重要? 18 | 19 | * **生成:** 此映像包含编译应用所需的所有内容,其中包括编译器和任何其他用于优化二进制文件的依赖项。 可使用生成映像创建置于生产映像中的资产。 生成映像用于持续集成或用于生成环境中。 此方法允许生成代理在生成映像实例中编译和生成应用程序(包括所有必需的依赖项)。 生成代理只需要了解如何运行此 Docker 映像即可。 20 | 21 | * **生产:** 部署和启动映像的速度可以有多快? 此映像很小,因此从 Docker 注册表到 Docker 主机的网络性能得到了优化。 已准备运行内容,以此实现从 Docker 运行到处理结果的最快时间。 Docker 模型中不需要动态代码编译。 放置在此映像中的内容将限制为运行应用程序所需的二进制文件和内容。 22 | 23 | 例如,`dotnet publish` 输出包含: 24 | 25 | * 已编译的二进制文件 26 | * .js 和 .css 文件 27 | 28 | 29 | 在生产映像中包括 `dotnet publish` 命令输出的原因是使生产映像保持最小大小。 30 | 31 | 某些 .NET Core 映像共享不同标记之间的层,因此下载最新标记是一个相对轻量的过程。 如果计算机上已有较早版本,此体系结构会降低所需的磁盘空间。 32 | 33 | 当多个应用程序在同一计算机上使用公共映像时,在公共映像之间共享内存。 映像必须相同才可共享。 34 | 35 | ## Docker 映像变体 36 | 37 | 为了实现上述目标,我们在 [`microsoft/dotnet`](https://hub.docker.com/r/microsoft/dotnet/) 下提供了映像变体。 38 | 39 | * `microsoft/dotnet:-sdk`(`microsoft/dotnet:2.1-sdk`) 此映像包含带有 .NET Core 和命令行工具 (CLI) 的 .NET Core SDK。 此映像将映射到**开发方案**。 可使用此映像进行本地开发、调试和单元测试。 此映像还可用于**生成**方案。 使用 `microsoft/dotnet:sdk` 始终都提供最新版本。 40 | 41 | > [!TIP] 42 | > 如果不确定自己的需求,需使用 `microsoft/dotnet:-sdk` 映像。 作为“实际”映像,它旨在用作一次性容器(装载源代码并启动容器以启动应用)以及生成其他映像的基础映像。 43 | 44 | * `microsoft/dotnet:-runtime`:此映像包含 .NET Core(运行时和库),并且针对在生产环境中运行 .NET Core 应用进行了优化。 45 | 46 | ## 备用映像 47 | 48 | 除了开发、生成和生产的优化方案外,我们还提供了其他映像: 49 | 50 | * `microsoft/dotnet:-runtime-deps`:runtime-deps 映像包括具有 .NET Core 所需的所有本机依赖项的操作系统。 此映像适用于独立应用程序 51 | 52 | 每个变体的最新版本: 53 | 54 | * `microsoft/dotnet` 或 `microsoft/dotnet:latest`(SDK 映像的别名) 55 | * `microsoft/dotnet:sdk` 56 | * `microsoft/dotnet:runtime` 57 | * `microsoft/dotnet:runtime-deps` 58 | 59 | ## 要了解的示例 60 | 61 | * [此 ASP.NET Core Docker 示例](https://github.com/dotnet/dotnet-docker/tree/master/samples/aspnetapp)演示了生成 ASP.NET Core 应用程序的 Docker 映像以用于生产的最佳实践模式。 此示例适用于 Linux 和 Windows 容器。 62 | 63 | * 此 .NET Core Docker 示例演示了[生成 .NET Core 应用程序的 Docker 映像以用于生产](https://github.com/dotnet/dotnet-docker/tree/master/samples/dotnetapp)的最佳实践模式。 64 | 65 | ## 转发请求方案和原始 IP 地址 66 | 67 | 代理服务器、负载均衡器和其他网络设备通常会在请求到达容器化应用之前隐藏有关请求的信息: 68 | 69 | * 当通过 HTTP 代理 HTTPS 请求时,原方案 (HTTPS) 将丢失,并且必须在标头中转接。 70 | * 由于应用收到来自代理的请求,而不是 Internet 或公司网络上请求的真实源,因此原始客户端 IP 地址也必须在标头中转接。 71 | 72 | 此信息在请求处理中可能很重要,例如在重定向、身份验证、链接生成、策略评估和客户端地理位置中。 73 | 74 | 要将方案和原始 IP 地址转发到 ASP.NET Core 容器化应用,请使用 Forwarded Headers 中间件。 有关详细信息,请参阅[配置 ASP.NET Core 以使用代理服务器和负载均衡器](https://docs.microsoft.com/zh-cn/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-2.1)。 75 | 76 | ## 第一个 ASP.NET Core Docker 应用 77 | 78 | 本教程对要 Docker 化的应用使用 ASP.NET Core Docker 示例应用程序。 此 ASP.NET Core Docker 示例应用程序演示了生成 ASP.NET Core 应用程序的 Docker 映像以用于生产的最佳做法模式。 此示例适用于 Linux 和 Windows 容器。 79 | 80 | 该示例 Dockerfile 基于 ASP.NET Core 运行时 Docker 基础映像创建 ASP.NET Core 应用程序 Docker 映像。 81 | 82 | 它使用 [Docker 多阶段生成功能](https://docs.docker.com/engine/userguide/eng-image/multistage-build/)完成以下操作: 83 | 84 | * 基于较大的 ASP.NET Core 生成 Docker 基础映像在容器中生成示例 85 | * 基于较小的 ASP.NET Core Docker 运行时基础映像将最终生成结果复制到 Docker 映像 86 | 87 | > [!NOTE] 88 | > 生成映像包含生成应用程序所需的工具,而运行时映像不包括这些工具。 89 | 90 | ### 系统必备 91 | 92 | 要进行生成并运行,请安装以下各项: 93 | 94 | #### .NET Core 2.1 SDK 95 | 96 | * 安装 [.NET Core SDK 2.1](https://www.microsoft.com/net/core)。 97 | 98 | * 安装常用的代码编辑器(如果尚未安装)。 99 | 100 | > [!TIP] 101 | > 需要安装代码编辑器? 试用 [Visual Studio](https://visualstudio.com/downloads)! 102 | 103 | #### 安装 Docker 客户端 104 | 105 | 安装 [Docker 18.03](https://docs.docker.com/release-notes/docker-ce/) 或更高版本的 Docker 客户端。 106 | 107 | 可在以下位置安装 Docker 客户端: 108 | 109 | * Linux 分布 110 | 111 | * [CentOS](https://docs.docker.com/install/linux/docker-ce/centos/) 112 | 113 | * [Debian](https://docs.docker.com/install/linux/docker-ce/debian/) 114 | 115 | * [Fedora](https://docs.docker.com/install/linux/docker-ce/fedora/) 116 | 117 | * [Ubuntu](https://docs.docker.com/install/linux/docker-ce/ubuntu/) 118 | 119 | * [macOS](https://docs.docker.com/docker-for-mac/install/) 120 | 121 | * [Windows](https://docs.docker.com/docker-for-windows/install/)。 122 | 123 | #### 为示例存储库安装 Git 124 | 125 | * 如果要克隆存储库,请安装 [git](https://git-scm.com/download)。 126 | 127 | ### 获取示例应用程序 128 | 129 | 获取该示例的最简单方法是使用以下指令克隆包含 git 的 [.NET Core Docker 存储库](https://github.com/dotnet/dotnet-docker): 130 | 131 | ```console 132 | git clone https://github.com/dotnet/dotnet-docker 133 | ``` 134 | 135 | 也可以从 .NET Core Docker 存储库中下载 zip 格式的存储库(其大小较小)。 136 | 137 | ### 在本地运行 ASP.NET 应用 138 | 139 | 对于引用点,在容器化应用程序之前,请先在本地运行应用程序。 140 | 141 | 可使用以下命令,通过 .NET Core 2.1 SDK 在本地生成和运行应用程序(这些指令假定使用存储库的根目录): 142 | 143 | ```console 144 | cd dotnet-docker 145 | cd samples 146 | cd aspnetapp // solution scope where the dockerfile is located 147 | cd aspnetapp // project scope 148 | 149 | dotnet run 150 | ``` 151 | 152 | 应用程序启动后,在 Web 浏览器中访问 **http://localhost:5000**。 153 | 154 | ### 使用 Docker for Linux 容器生成和运行示例 155 | 156 | 可使用以下命令,通过 Linux 容器在 Docker 中生成和运行示例(这些指令假定使用存储库的根目录): 157 | 158 | ```console 159 | cd dotnet-docker 160 | cd samples 161 | cd aspnetapp // solution scope where the dockerfile is located 162 | 163 | docker build -t aspnetapp . 164 | docker run -it --rm -p 5000:80 --name aspnetcore_sample aspnetapp 165 | ``` 166 | 167 | > [!NOTE] 168 | > `docker run` 的“-p”参数将本地计算机上的端口 5000 映射到容器中的端口 80(该端口映射形式为 `host:container`)。 有关详细信息,请参阅命令行参数中的 [docker run](https://docs.docker.com/engine/reference/commandline/exec/) 引用。 169 | 170 | 应用程序启动后,在 Web 浏览器中访问 **http://localhost:5000**。 171 | 172 | ### 使用 Docker for Windows 容器生成和运行示例 173 | 174 | 可使用以下命令,通过 Windows 容器在 Docker 中生成和运行示例(这些指令假定使用存储库的根目录): 175 | 176 | ```console 177 | cd dotnet-docker 178 | cd samples 179 | cd aspnetapp // solution scope where the dockerfile is located 180 | 181 | docker build -t aspnetapp . 182 | docker run -it --rm --name aspnetcore_sample aspnetapp 183 | ``` 184 | 185 | > [!IMPORTANT] 186 | > 使用 Windows 容器时,必须直接在浏览器中转到容器 IP 地址(而不是 `http://localhost`)。 可通过以下步骤获取容器的 IP 地址: 187 | 188 | * 打开另一个命令提示符。 189 | * 运行 `docker ps`,查看正在运行的容器。 其中应包含“Aspnetcore_sample”。 190 | * 运行 `docker exec aspnetcore_sample ipconfig`。 191 | * 将容器 IP 地址复制并粘贴到浏览器中(例如,172.29.245.43)。 192 | 193 | > [!NOTE] 194 | > Docker exec 支持通过名称或哈希标识容器。 示例中使用了名称 (aspnetcore_sample)。 195 | 196 | 197 | > [!NOTE] 198 | > Docker exec 在正在运行的容器中运行新命令。 有关详细信息,请参阅命令行参数中的 [docker exec 引用](https://docs.docker.com/engine/reference/commandline/exec/)。 199 | 200 | 可使用 dotnet publish 命令生成已准备好在本地部署到生产环境的应用程序。 201 | 202 | ```console 203 | dotnet publish -c Release -o published 204 | ``` 205 | 206 | > [!NOTE] 207 | > -c Release 参数用于在发布模式(默认为调试模式)下生成应用程序。 有关详细信息,请参阅命令行参数中的 dotnet run 引用。 208 | 209 | 可使用以下命令在 Windows 中运行应用程序。 210 | 211 | ```console 212 | dotnet published\aspnetapp.dll 213 | ``` 214 | 215 | 可使用以下命令在 Linux 或 macOS 中运行应用程序。 216 | 217 | ```bash 218 | dotnet published/aspnetapp.dll 219 | ``` 220 | 221 | ### 此示例中使用的 Docker 映像 222 | 223 | 此示例的 dockerfile 中使用了以下 Docker 映像。 224 | 225 | * `microsoft/dotnet:2.1-sdk` 226 | * `microsoft/dotnet:2.1-aspnetcore-runtime` 227 | 228 | 祝贺你! 你刚才已: 229 | > [!div class="checklist"] 230 | > * 了解 Microsoft .NET Core Docker 映像 231 | > * 获取要 Docker 化的 ASP.NET Core 示例应用 232 | > * 在本地运行 ASP.NET 示例应用 233 | > * 使用 Docker for Linux 容器生成和运行示例 234 | > * 使用 Docker for Windows 容器生成和运行示例 235 | 236 | > [!NOTE] 237 | > 如果你没有 腾讯云账号,请[立即注册](https://cloud.tencent.com/act/free?from=10107 )获取一个包含 7 款热门产品和 42 款长期免费云产品服务的任意组合。 -------------------------------------------------------------------------------- /1 docker/4.visualstudiotoolsfordocker.md: -------------------------------------------------------------------------------- 1 | # 使用 ASP.NET Core 的 Visual Studio Tools for Docker 2 | 3 | 使用 Visual Studio Code 和 Docker CLI 时,Visual Studio Tools for Docker 开发工作流是类似于工作流。 实际上,它基于相同的 Docker CLI,但它是更轻松地开始,可以简化此过程中,并提供了提高工作效率生成、 运行和组合任务。 执行和调试简单的操作,例如通过容器F5并Ctrl+F5。 通过可选容器业务流程支持,除了能够运行和调试单个容器,可运行和调试容器Visual Studio 2017 支持生成、调试和运行面向 .NET Core 的容器化 ASP.NET Core 应用。 Windows 和 Linux 容器均受支持。 4 | 5 | [查看或下载示例代码](https://github.com/aspnet/Docs/tree/master/aspnetcore/host-and-deploy/docker/visual-studio-tools-for-docker/samples)([如何下载](xref:index#how-to-download-a-sample)) 6 | 7 | ## 系统必备 8 | 9 | * [Docker for Windows](https://docs.docker.com/docker-for-windows/install/) 10 | * 具有“.NET Core 跨平台开发”工作负载的 [Visual Studio 2017](https://www.visualstudio.com/) 11 | 12 | ## 安装和设置 13 | 14 | 要安装 Docker,请先查看[用于 Windows 的 Docker:安装须知](https://docs.docker.com/docker-for-windows/install/#what-to-know-before-you-install)了解相关信息。 然后安装[用于 Windows 的 Docker](https://docs.docker.com/docker-for-windows/install/)。 15 | 16 | Docker for Windows 中的[共享驱动器](https://docs.docker.com/docker-for-windows/#shared-drives)必须配置为支持卷映射和调试。 右键单击系统托盘中的 Docker 图标,单击“设置”,然后选择“共享驱动器”。 选择 Docker 存储文件的驱动器。 单击“应用”。 17 | 18 | ![为容器选择本地驱动器 C 作为共享驱动器的对话框](./resource/settings-shared-drives-win.png) 19 | 20 | > [!TIP] 21 | > 未配置共享驱动器时,Visual Studio 2017 15.6 及更高版本会发出提示。 22 | 23 | ## 向 Docker 容器添加项目 24 | 25 | 若要容器化 ASP.NET Core 项目,项目必须面向 .NET Core。 同时支持 Linux 和 Windows 容器。 26 | 27 | 向项目添加 Docker 支持后,可选择 Windows 或 Linux 容器。 Docker 主机必须运行类型相同的容器。 要更改正在运行的 Docker 实例中的容器类型,请右键单击系统托盘中的 Docker 图标,再选择“切换到 Windows 容器...”或“切换到 Linux 容器...”。 28 | 29 | ### 新应用 30 | 31 | 使用“ASP.NET Core Web 应用”项目模板新建应用时,请选中“启用 Docker 支持”复选框: 32 | 33 | ![“启用 Docker 支持”复选框](visual-studio-tools-for-docker/_static/enable-docker-support-check-box.png) 34 | 35 | 如果目标框架是 .NET Core,可通过 OS 下拉列表选择容器类型。 36 | 37 | ### 现有应用 38 | 39 | 对于面向 .NET Core 的 ASP.NET Core 项目,可通过两个选项使用工具添加 Docker 支持。 在 Visual Studio 中打开项目,然后选择以下选项之一: 40 | 41 | * 从“项目”菜单中选择“Docker 支持”。 42 | * 右键单击“解决方案资源管理器”中的项目,然后选择“添加” > “Docker 支持”。 43 | 44 | Visual Studio Tools for Docker 不支持向面向.NET Framework 的现有 ASP.NET Core 项目添加 Docker。 45 | 46 | ## Dockerfile 概述 47 | 48 | Dockerfile,用作创建最终 Docker 映像的方案,添加到项目根目录。 请参阅 [Dockerfile 引用](https://docs.docker.com/engine/reference/builder/),了解其中的命令。 此特定 Dockerfile 使用[多阶段生成](https://docs.docker.com/engine/userguide/eng-image/multistage-build/),该生成包含四个不同的命名生成阶段: 49 | 50 | ::: moniker range=">= aspnetcore-2.1" 51 | 52 | [!code-dockerfile[](visual-studio-tools-for-docker/samples/2.1/HelloDockerTools/Dockerfile.original?highlight=1,6,14,17)] 53 | 54 | 前面的 Dockerfile 基于 [microsoft/dotnet](https://hub.docker.com/r/microsoft/dotnet/) 映像。 此基础映像包括 ASP.NET Core 运行时和 NuGet 包。 对该包进行了实时 (JIT) 编译,以提高启动性能。 55 | 56 | 如果选中了新建项目对话框的“为 HTTPS 配置”复选框,则 Dockerfile 公开两个端口。 一个端口用于 HTTP 流量;另一个端口用于 HTTPS。 如果未选中该复选框,则为 HTTP 流量公开单个端口 (80)。 57 | 58 | FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base 59 | WORKDIR /app 60 | EXPOSE 59518 61 | EXPOSE 44364 62 | 63 | FROM microsoft/dotnet:2.1-sdk AS build 64 | WORKDIR /src 65 | COPY HelloDockerTools/HelloDockerTools.csproj HelloDockerTools/ 66 | RUN dotnet restore HelloDockerTools/HelloDockerTools.csproj 67 | COPY . . 68 | WORKDIR /src/HelloDockerTools 69 | RUN dotnet build HelloDockerTools.csproj -c Release -o /app 70 | 71 | FROM build AS publish 72 | RUN dotnet publish HelloDockerTools.csproj -c Release -o /app 73 | 74 | FROM base AS final 75 | WORKDIR /app 76 | COPY --from=publish /app . 77 | ENTRYPOINT ["dotnet", "HelloDockerTools.dll"] 78 | 79 | 前面的 Dockerfile 基于 [microsoft/aspnetcore](https://hub.docker.com/r/microsoft/aspnetcore/) 映像。 此基础映像包括 ASP.NET Core NuGet 包,对该包进行了实时编译 (JIT),以提高启动性能。 80 | 81 | 82 | ## 调试 83 | 84 | 在工具栏的调试下拉列表中选择“Docker”,然后开始调试应用。 “输出”窗口的“Docker”视图显示发生的以下操作: 85 | 86 | 87 | * 已获取 microsoft/dotnet 运行时映像的 2.1-aspnetcore-runtime 标记(如果缓存中尚不存在)。 该映像可安装 ASP.NET Core 和.NET Core 运行时及其关联的库。 在生产环境中针对运行 ASP.NET Core 应用对其进行了优化。 88 | * `ASPNETCORE_ENVIRONMENT` 环境变量设置为容器内的 `Development`。 89 | * 公开了两个动态分配的端口:分别用于 HTTP 和 HTTPS。 可以使用 `docker ps` 命令查询分配给本地主机的端口。 90 | * 应用已复制到容器。 91 | * 默认浏览器使用动态分配端口启动,带有附加到容器的调试程序。 92 | 93 | 最终得到的应用的 Docker 映像标记为“开发”。 该映像基于 microsoft/dotnet 基础映像的 2.1-aspnetcore-runtime 标记。 在“包管理器控制台”(PMC) 窗口中运行 `docker images` 命令。 显示了计算机上的映像: 94 | 95 | ```console 96 | REPOSITORY TAG IMAGE ID CREATED SIZE 97 | hellodockertools dev d72ce0f1dfe7 30 seconds ago 255MB 98 | microsoft/dotnet 2.1-aspnetcore-runtime fcc3887985bb 6 days ago 255MB 99 | ``` 100 | 101 | 102 | * 已获取 microsoft/aspnetcore 运行时映像(如果缓存中尚不存在)。 103 | * `ASPNETCORE_ENVIRONMENT` 环境变量设置为容器内的 `Development`。 104 | * 端口 80 公开,并映射到 localhost 的动态分配端口。 该端口由 Docker 主机确定,并且可以使用 `docker ps` 进行查询。 105 | * 应用已复制到容器。 106 | * 默认浏览器使用动态分配端口启动,带有附加到容器的调试程序。 107 | 108 | 最终得到的应用的 Docker 映像标记为“开发”。 该映像基于 microsoft/aspnetcore 基础映像。 在“包管理器控制台”(PMC) 窗口中运行 `docker images` 命令。 显示了计算机上的映像: 109 | 110 | ```console 111 | REPOSITORY TAG IMAGE ID CREATED SIZE 112 | hellodockertools dev 5fafe5d1ad5b 4 minutes ago 347MB 113 | microsoft/aspnetcore 2.0 c69d39472da9 13 days ago 347MB 114 | ``` 115 | 116 | 117 | > [!NOTE] 118 | > 因为“调试”配置使用卷装载提供迭代体验,因此,开发映像中缺少应用内容。 要推送映像,请使用“发布”配置。 119 | 120 | 在 PMC 中运行 `docker ps` 命令。 请注意,应用使用容器运行: 121 | 122 | ```console 123 | CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 124 | baf9a678c88d hellodockertools:dev "C:\\remote_debugge..." 21 seconds ago Up 19 seconds 0.0.0.0:37630->80/tcp dockercompose4642749010770307127_hellodockertools_1 125 | ``` 126 | 127 | ## 编辑并继续 128 | 129 | 对静态文件和 Razor 视图的更改会自动更新,无需执行编译步骤。 进行更改,保存并在浏览器中刷新,以查看更新。 130 | 131 | 必须在容器内编译和重启 Kestrel,才能修改代码文件。 更改后,按 `CTRL+F5` 执行过程,并在容器内启动应用。 未重新生成或停止 Docker 容器。 在 PMC 中运行 `docker ps` 命令。 请注意,截至 10 分钟前,原始容器仍在运行: 132 | 133 | ```console 134 | CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 135 | baf9a678c88d hellodockertools:dev "C:\\remote_debugge..." 10 minutes ago Up 10 minutes 0.0.0.0:37630->80/tcp dockercompose4642749010770307127_hellodockertools_1 136 | ``` 137 | 138 | ## 发布 Docker 映像 139 | 140 | 完成应用的开发和调试循环后,Visual Studio Tools for Docker 可帮助创建应用的生产映像。 将配置下拉列表更改为“发布”,然后生成应用。 该工具从 Docker Hub 中获取 compile/publish 映像(如果缓存中尚不存在)。 生成了具有“latest”标签的映像,可以将其推送到专用注册表或 Docker Hub。 141 | 142 | 在 PMC 中运行 `docker images` 命令,查看映像列表。 显示了类似下面的输出: 143 | 144 | ```console 145 | REPOSITORY TAG IMAGE ID CREATED SIZE 146 | hellodockertools latest e3984a64230c About a minute ago 258MB 147 | hellodockertools dev d72ce0f1dfe7 4 minutes ago 255MB 148 | microsoft/dotnet 2.1-sdk 9e243db15f91 6 days ago 1.7GB 149 | microsoft/dotnet 2.1-aspnetcore-runtime fcc3887985bb 6 days ago 255MB 150 | ``` 151 | 152 | ```console 153 | REPOSITORY TAG IMAGE ID CREATED SIZE 154 | hellodockertools latest cd28f0d4abbd 12 seconds ago 349MB 155 | hellodockertools dev 5fafe5d1ad5b 23 minutes ago 347MB 156 | microsoft/aspnetcore-build 2.0 7fed40fbb647 13 days ago 2.02GB 157 | microsoft/aspnetcore 2.0 c69d39472da9 13 days ago 347MB 158 | ``` 159 | 160 | 自 .NET Core 2.1 起,前面的输出中列出的 `microsoft/aspnetcore-build` 和 `microsoft/aspnetcore` 映像替换为 `microsoft/dotnet` 映像。 有关详细信息,请参阅 [Docker 存储库迁移公告](https://github.com/aspnet/Announcements/issues/298)。 161 | 162 | 163 | > [!NOTE] 164 | > `docker images` 命令返回存储库名称和标记标识为 \ (上面未列出)的中间映像。 这些未命名映像由[多阶段生成](https://docs.docker.com/engine/userguide/eng-image/multistage-build/) *Dockerfile* 生成。 它们可提高生成最终映像的效率 — 发生更改时,仅重新生成必要的层。 不再需要中间映像时,请使用 [docker rmi](https://docs.docker.com/engine/reference/commandline/rmi/) 命令将其删除。 165 | 166 | 可能希望生产或发布映像的大小比开发映像小。 由于卷映射,调试程序和应用从本地计算机运行,而不在容器内运行。 最新映像已打包必要的应用代码,以在主机上运行应用。 因此,增量是应用代码的大小。 167 | 168 | ## 使用Visual Studio将ASP.NET容器部署到容器仓库 169 | 170 | 使用Visual Studio将容器化应用程序发布到[Tencent Hub容器仓库](https://cloud.tencent.com/document/product/857/17969) 171 | 172 | ### 创建ASP.NET Core Web应用程序 173 | 以下步骤将指导您创建将在本教程中使用的基本ASP.NET Core应用程序。 174 | 175 | 1. 从Visual Studio菜单中,选择“ 文件”>“新建”>“项目”。 176 | 2. 在“ 新建项目”对话框的“ 模板”部分下,选择“ Visual C#> Web”。 177 | 3. 选择ASP.NET Core Web Application。 178 | 4. 为新应用程序命名(或采用默认值),然后选择“ 确定”。 179 | 5. 选择Web应用程序。 180 | 6. 选中Enable Docker Support复选框。 181 | 7. 选择所需的容器类型(Windows或Linux),然后单击“ 确定”。 182 | 183 | ![用visual studio创建容器化asp.net core 应用](./resource/createdockerappwithvs2017.png) 184 | 185 | ## 2. 将容器发布到腾讯云容器仓库 186 | 1. 在Solution Explorer中右键单击您的项目,然后选择Publish。 187 | 188 | 2. 在发布目标对话框中,选择“ 容器仓库”选项卡。 189 | 190 | 3. 选择Custom,然后单击Publish。 191 | 192 | 4. 在“容器仓库”中填写所需的值。 193 | 194 | ![发布到腾讯云容器仓库](./resource/publishdockertotencentyun0.png) 195 | 196 | 这里我们使用的是腾讯云的私有容器仓库 https://hub.tencentyun.com/geffzhang/ geffzhang 是我创建的命名空间。镜像仓库用于存放Docker镜像,Docker镜像用于部署容器服务,每个镜像有特定的唯一标识(镜像的Registry地址+镜像名称+镜像Tag)。具体参考文档[镜像仓库基本教程](https://cloud.tencent.com/document/product/857/18201) 197 | 198 | 5. 单击发布,就可以把镜像发布到腾讯云容器仓库 199 | ![发布镜像到腾讯云容器仓库](./resource/publishdockertotencentyun0.png) 200 | 201 | 202 | 您现在可以将容器从注册表中拉到任何能够运行Docker镜像的主机. 下面是我发布到腾讯云的镜像: 203 | ![腾讯云的镜像](./resource/dockerregisterontencentyun.png) -------------------------------------------------------------------------------- /1 docker/resource/createdockerappwithvs2017.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geffzhang/QcloudNetCore/63708d1415c7093ab30cede0d01cbfe25784b4bb/1 docker/resource/createdockerappwithvs2017.png -------------------------------------------------------------------------------- /1 docker/resource/dockerbasic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geffzhang/QcloudNetCore/63708d1415c7093ab30cede0d01cbfe25784b4bb/1 docker/resource/dockerbasic.png -------------------------------------------------------------------------------- /1 docker/resource/dockerregisterontencentyun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geffzhang/QcloudNetCore/63708d1415c7093ab30cede0d01cbfe25784b4bb/1 docker/resource/dockerregisterontencentyun.png -------------------------------------------------------------------------------- /1 docker/resource/publishdockertotencentyun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geffzhang/QcloudNetCore/63708d1415c7093ab30cede0d01cbfe25784b4bb/1 docker/resource/publishdockertotencentyun.png -------------------------------------------------------------------------------- /1 docker/resource/publishdockertotencentyun0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geffzhang/QcloudNetCore/63708d1415c7093ab30cede0d01cbfe25784b4bb/1 docker/resource/publishdockertotencentyun0.png -------------------------------------------------------------------------------- /1 docker/resource/settings-shared-drives-win.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geffzhang/QcloudNetCore/63708d1415c7093ab30cede0d01cbfe25784b4bb/1 docker/resource/settings-shared-drives-win.png -------------------------------------------------------------------------------- /2 microservices/1.microserviceandcontainer.md: -------------------------------------------------------------------------------- 1 | # 容器与微服务 2 | 当前在讨论容器和云原生应用话题时,微服务也成为一个热门的讨论点。在很多人看来微服务和容器是密不可分的。 3 | 4 | ## 微服务概述 5 | 微服务(microservice)的核心理念是将大的单体应用(monolithic application)拆散,形成多个相对较小的单体应用。这些单体应用可以独立进行开发、测试和部署,通过对这些单体应用的编排和组合最终提供完整的服务。微服务将传统的应用架构化整为零,目的是提高应用开发和交付的效率。在传统的单体应用时代,虽然有模块的概念,但是在构建时,众多的模块往往会被构建成一个单一的、庞大的部署包。单体应用的更新往往会导致整个系统的所有服务中断。而在微服务的场景中,所有的功能都是由一个或多个服务提供的,当某个微服务进行更新和维护时,只会影响该服务涉及到的业务,其他模块可以正常对外提供服务。微服务之间相对独立,它们各自可以有各自的开发周期,相互之间不会有过强的捆绑关系,这样有助于加快系统整体迭代更新的节奏。从团队组织上来说,微服务的划分颗粒度较细,可以形成更有针对性的权责关系。 6 | 7 | 8 | 9 | ## 微服务与容器 10 | 目前常见的一种错误认识是”要使用微服务架构就要使用容器”,或者”使用容器就必须实现微服务架构“。其实微服务和容器之间并没有很强的捆绑关系。微服务和具体的语言和技术也没有直接的绑定关系。要实现微服务,不一定要使用容器,但是容器和微服务是天生一对。应用的微服务化,除了技术层面,还需要从开发运营团队的文化,组织架构着手。从技术层面看,容器具备在大规模云环境中快速部署复杂应用的能力,十分适合应用在微服务架构的场景中使用容器。反过来看,容器在未来成为云上主流应用运行环境后,传统的大型单体应用运行在容器中并不是一个很好的选择。未来的应用架构必须做出调整,让未来的应用更适合在容器内运行,在云上运行,甚至最终变成云原生应用(cloud native application)。微服务和容器是两个相辅相成的概念,它们的最终目的都是一致的,那就是提高应用开发、测试和部署的效率,让IT变得更敏捷。 11 | 关于微服务的细节这里不再展开,推荐参考 http://www.csharpkit.com/microservice.html 。 -------------------------------------------------------------------------------- /2 microservices/2.microservicecontainer.md: -------------------------------------------------------------------------------- 1 | # 微服务容器化 2 | 微服务落实到实处,其实就是应用。一个微服务可以用任何编程语言实现,但是不管它是用那种编程语言实现,最终都还是需要一个运行环境,如一个操作系统,一个web服务器、一个脚本解释器或者类似CLR的虚拟机。微服务享用容器和容器云提供的种种便利的前提条件就是,微服务需要被容器化。关于应用的容器化,虽然可以手工实现微服务的容器化,但是这样做是低效和不现实的。在企业大规模使用容器场景中,企业必须建立一套微服务及应用容器化的自动化流程。通过自动化流程来规范应用容器化的过程以及提高应用容器化流程的效率和质量。 3 | 4 | ## 基于现有的构建系统容器化微服务 5 | 6 | 实现微服务应用容器化的自动化有多种途径。比如通过编写Dockerfile将一个.NET Core应用程序进行容器化。编写Dockerfile,其实就已经将应用容器化的过程进行了固化,Visual Studio 和Visual Studio Code都对我们的.NET Core应用程序容器化提供了非常好的支持。对于已经有构建自动化系统的用户,下一步 往往是对其自动化构建系统改造,在构建出原有构建支付件后再接着触发一次Docker构建,产生相应的微服务应用的容器镜像,并将镜像发布至相应的镜像仓库备用。例如,如果用户的团队现在已经在用Jenkins进行代码的持续集成和部署,就可以在现有的基础上修改Jenkins的配置,让Jenkins构建及发布应用的镜像。 -------------------------------------------------------------------------------- /2 microservices/3.deployservice.md: -------------------------------------------------------------------------------- 1 | 2 | # 服务部署 3 | 关于微服务的部署,要着眼于两个层面:单个微服务的部署和微服务集群的部署。在微服务架构中,完整的系统是由多个微服务的组合构成的。这意味着完成一次完整的系统部署,涉及多个微服务的部署。一般而言,每个微服务提供不同的功能,完成不同的任务。因此不同的微服务的部署配置不尽相同。因为服务部署的复杂性,部署应该自动化。在完成单个微服务部署的基础上,还需要进一步考虑如何高效的完成多个微服务的部署,使一个个单独的微服务有机地构成一个完整的系统并对外提供服务。 4 | 5 | ## 单个微服务的部署 6 | 在腾讯云的容器服务中,用户通过服务(由多个相同配置的容器和访问这些容器的规则所组成)作为容器部署定义描述对象,定义部署的容器行为特性。通过服务,用户可以定义单个微服务的部署要求,如微服务的镜像,启动命令,系统环境变量、资源配额、数据持久化、健康检查、实例数量、所运行的目标计算节点等。举一个常见的例子,每个微服务对资源的需求往往是不尽相同的。有的微服务属于联机事务处理型的应用,对内存的消耗会比较大,有的可能属于联机事务分析型的应用,对CPU的消耗比较大。在部署微服务时,应该根据当前微服务的特性,部署到合适的集群节点上。 7 | 8 | ## 多个微服务的部署 9 | 服务可以满足单个微服务的部署需求。对于多个微服务的部署,腾讯云容器服务支持通过应用的方式对服务进行分组管理,极大的简化了服务管理的复杂度。同时,通过应用模板来保存服务的部署信息,通过配置来管理服务在不同环境下的差异化信息,实现在不同环境下通过应用模板+配置快速的部署服务。 -------------------------------------------------------------------------------- /2 microservices/4.servicediscovery.md: -------------------------------------------------------------------------------- 1 | # 服务发现 2 | 在微服务架构中的微服务并不是孤立的个体,服务之间是相互依赖的。A服务可能会调用B和C服务的接口,C服务又可能依赖于D服务。在传统的服务依赖模型中,各个服务的调用地址,如域名、IP和饥饿端口在服务部署前就已经明确了。一般远程被调用的服务的调用地址会被写入调用方的配置文件中。和传统的模型不同,在云的环境中,所有的资源都是按需创建的,服务的域名、IP和端口在服务创建时才会被分配,因此依赖信息不能事先写入配置文件中。这意味着应用要以一种全新的方式获取所依赖的服务的调用信息。 3 | kubernetes有一个重要的组件Service。一个Service具有一个相对恒定的IP地址,能为后端的一组Pod容器分发流量。 4 | 5 | ## 通过Service进行服务发现 6 | Kubernetes 支持两种方式的来发现服务 ,环境变量和 DNS 7 | 8 | + 环境变量 9 | 当 Pod 运行在 Node 上,kubelet 会为每个活跃的 Service 添加一组环境变量。 它同时支持 Docker links兼容 变量(查看 makeLinkVariables)、简单的 {SVCNAME}_SERVICE_HOST 和 {SVCNAME}_SERVICE_PORT 变量,这里 Service 的名称需大写,横线被转换成下划线。 10 | 举个例子,一个名称为 "redis-master" 的 Service 暴露了 TCP 端口 6379,同时给它分配了 Cluster IP 地址 10.0.0.11,这个 Service 生成了如下环境变量: 11 | REDIS_MASTER_SERVICE_HOST=10.0.0.11 12 | REDIS_MASTER_SERVICE_PORT=6379 13 | REDIS_MASTER_PORT=tcp://10.0.0.11:6379 14 | REDIS_MASTER_PORT_6379_TCP=tcp://10.0.0.11:6379 15 | REDIS_MASTER_PORT_6379_TCP_PROTO=tcp 16 | REDIS_MASTER_PORT_6379_TCP_PORT=6379 17 | REDIS_MASTER_PORT_6379_TCP_ADDR=10.0.0.11 18 | 这意味着需要有顺序的要求 —— Pod 想要访问的任何 Service 必须在 Pod 自己之前被创建,否则这些环境变量就不会被赋值。DNS 并没有这个限制。 19 | 20 | + DNS 21 | 一个可选(尽管强烈推荐)集群插件 是 DNS 服务器。 DNS 服务器监视着创建新 Service 的 Kubernetes API,从而为每一个 Service 创建一组 DNS 记录。 如果整个集群的 DNS 一直被启用,那么所有的 Pod 应该能够自动对 Service 进行名称解析。 22 | 例如,有一个名称为 "my-service" 的 Service,它在 Kubernetes 集群中名为 "my-ns" 的 Namespace 中,为 "my-service.my-ns" 创建了一条 DNS 记录。 在名称为 "my-ns" 的 Namespace 中的 Pod 应该能够简单地通过名称查询找到 "my-service"。 在另一个 Namespace 中的 Pod 必须限定名称为 "my-service.my-ns"。 这些名称查询的结果是 Cluster IP。 23 | Kubernetes 也支持对端口名称的 DNS SRV(Service)记录。 如果名称为 "my-service.my-ns" 的 Service 有一个名为 "http" 的 TCP 端口,可以对 "_http._tcp.my-service.my-ns" 执行 DNS SRV 查询,得到 "http" 的端口号。 24 | Kubernetes DNS 服务器是唯一的一种能够访问 ExternalName 类型的 Service 的方式。 -------------------------------------------------------------------------------- /2 microservices/5.servicehealth.md: -------------------------------------------------------------------------------- 1 | # 健康检查 2 | 以为每个微服务必须为它自身的状态负责,所以每个微服务都应提供一个健康检查的接口。通过调用这个健康检查接口,外界可以判断这个服务的当前状态。一般情况下,并不是容器启动后容器中的应用就马上就绪了,应用一般还有一个启动或者初始化的过程。因此,必须有一种手段让平台检查微服务应用的就绪状态。 3 | 4 | ## 健康检查类别 5 | 健康检查分为两大类别:容器存活检查和容器就绪检查。 6 | + 容器存活检查:该检查方式用于检测容器是否存活,类似于我们执行 ps 命令检查进程是否存在。如果容器的存活检查失败,集群会对该容器执行重启操作;若容器的存活检查成功则不执行任何操作。 7 | 8 | + 容器就绪检查:该检查方式用于检测容器是否准备好开始处理用户请求。一些程序的启动时间可能很长,比如要加载磁盘数据或者要依赖外部的某个模块启动完成才能提供服务。这时候程序进程在,但是并不能对外提供服务。这种场景下该检查方式就非常有用。如果容器的就绪检查失败,集群会屏蔽请求访问该容器;若检查成功,则会开放对该容器的访问。 9 | 10 | ## 健康检查方式 11 | 12 | TCP 端口探测 13 | 14 | TCP 端口探测的原理如下: 15 | 对于提供 TCP 通信服务的容器,集群周期性地对该容器建立 TCP 连接,如果连接成功,则证明探测成功,否则探测失败。选择 TCP 端口探测方式,必须指定容器监听的端口。比如我们有一个 redis 容器,它的服务端口是 6379,我们对该容器配置了 TCP 端口探测,指定探测端口为 6379,那么集群会周期性地对该容器的 6379 端口发起 TCP 连接,如果连接成功则证明检查成功,否则检查失败。 16 | 17 | HTTP 请求探测 18 | 19 | HTTP 请求探测针对的是提供 HTTP/HTTPS 服务的容器,集群周期性地对该容器发起 HTTP/HTTPS GET 请求,如果 HTTP/HTTPS response 返回码属于 200~399 范围,则证明探测成功,否则探测失败。使用 HTTP 请求探测必须指定容器监听的端口和 HTTP/HTTPS 的请求路径。 20 | 例如:提供 HTTP 服务的容器,服务端口为 80,HTTP 检查路径为 /health-check,那么集群会周期性地对容器发起如下请求:GET http://containerIP:80/health-check。 21 | 执行命令检查 22 | 执行命令检查是一种强大的检查方式,该方式要求用户指定一个容器内的可执行命令,集群会周期性地在容器内执行该命令,如果命令的返回结果是 0 则检查成功,否则检查失败。 23 | 对于上面提到的 TCP 端口探测和 HTTP 请求探测,都可以通过执行命令检查的方式来替代: 24 | + 对于 TCP 端口探测,我们可以写一个程序来对容器的端口进行 connect,如果 connect 成功,脚本返回 0,否则返回 -1。 25 | + 对于 HTTP 请求探测,我们可以写一个脚本来对容器进行 wget 26 | wget http://127.0.0.1:80/health-check 27 | 并检查 response 的返回码,如果返回码在 200~399 的范围,脚本返回 0,否则返回 -1。 -------------------------------------------------------------------------------- /2 microservices/6.serviceupdate.md: -------------------------------------------------------------------------------- 1 | # 更新发布 2 | 将单体应用转化成一组微服务的一个优点是,每个微服务都可以有自己的生命周期。每个微服务开发团队可以有自己相对独立的版本节奏,各个团队可以根据自己的节奏发布版本。这也意味着应用的更新发布会变得更加频繁。微服务架构从架构上减少了系统整体服务停机的风险。每个微服务更新时,系统只有部分相关功能受影响。 3 | 4 | ## 滚动更新 5 | 对于单个微服务而言,Kubernetes提供了滚动更新(rolling update)的机制,保证在服务更新过程中服务不受影响。 6 | 7 | ## 发布回滚 8 | 不一定每一次的发布都是顺利的,如果发布失败或者发布异常,必须有一套机制让用户可以快速回滚操作。发布的回滚是一项很实用的功能。 9 | 10 | ## 灰度发布 11 | 灰度发布是当前非常流行的一种发布方式。用户在发布一个新版本应用服务时,并不完全替换所有老版本的应用服务实例,而是替换一定的比例。这样避免因为新版本存在的缺陷而导致所有的用户都受到影响。 12 | 13 | -------------------------------------------------------------------------------- /2 microservices/7.servicegov.md: -------------------------------------------------------------------------------- 1 | # 服务治理 2 | 大家对微服务的一个很大的关注点就是在于微服务的治理。用户希望能够清晰地掌握微服务的性能、调用分析以及依赖关系等数据。这些数据的获取一般有两种方式:一种是通过设置API网关进行微服务访问的转发,实现对调用的度量统计、流量控制和安全管控;另外一种方式是借助于微服务框架,在应用服务的代码或运行环境中加入探针,进行度量收集和行为控制。这两种方式前者是非入侵性的,后者则是入侵性的。 3 | 4 | ## API 网关 5 | 目前市场上有不少API网关的选择,有开源的,也有商用的。这里推荐一个开源的.NET Core的API Gateway Ocelot。Ocelot 是.NET 开源社区的一个API GateWay开发框架,方便根据自己的需求定制一款API网关,进行容器化部署。详细信息参考https://docs.microsoft.com/zh-cn/dotnet/standard/microservices-architecture/multi-container-microservice-net-applications/implement-api-gateways-with-ocelot#using-kubernetes-ingress-plus-ocelot-api-gateways 6 | 7 | ## 微服务框架 8 | 微服务框架和应用的耦合比较紧密,往往和开发平台有较强的相关性。就.NET平台而言,微软的[Service Fabric](https://github.com/Microsoft/service-fabric) 的微服务框架是当前比较流行的微服务框架之一。这里还是要推荐一款由我们的社区开发的微服务框架[Surging](https://github.com/dotnetcore/surging),Surging 是一个分布式微服务框架,提供高性能 RPC 远程服务调用,采用 Zookeeper、Consul 为服务注册中心,集成了哈希、随机、轮询、压力最小优先作为负载均衡的算法,集成 Netty 框架,使用异步传输。在Surging作者的范亮先生的博客中有大量文章介绍 Surging 的各子系统细节和用例,本文不做赘述。 9 | 最后还要为我们正在开发的微服务框架[TarsNET](https://github.com/TarsNET )做下广告,虽然目前C#版本我们正在开发中,Tars 作为一款微服务在腾讯QQ运行10多年经过海量互联网流量考验的微服务框架是值得我们期待的。 10 | -------------------------------------------------------------------------------- /3 tke/0.tkeabout.md: -------------------------------------------------------------------------------- 1 | # 腾讯云容器服务 (TKE) 2 | 3 | 可以使用 腾讯云容器服务(Tencent Kubernetes Engine) 在 腾讯云 中轻松地部署托管的 Kubernetes 群集。 TKE 通过将大量管理工作量交给腾讯云,来降低管理 Kubernetes 所产生的复杂性和操作开销。 作为一个托管 Kubernetes 腾讯云可以自动处理运行状况监视和维护等关键任务。 Kubernetes 主节点由 腾讯云 管理。 你只管理和维护代理节点。 作为托管型 Kubernetes 服务,TKE 是免费的 - 你只需支付群集中的代理节点费,不需支付主节点的费用。 4 | 5 | 可以在 腾讯云 门户中使用 Kubernetes CLI 或模板驱动型部署选项 来创建 TKE 群集。当你部署 TKE 群集时,系统会为你部署和配置 Kubernetes 主节点和所有节点。 另外,也可在部署过程中配置其他功能,例如高级网络、监视。 6 | 7 | 若要开始,请[通过 腾讯云 门户](https://console.cloud.tencent.com/ccsl)或者[通过 kubectl](https://cloud.tencent.com/document/product/457/14208) 完成 TKE 快速入门。 8 | 9 | ## 监控告警 10 | 11 | 为腾讯云容器服务提供良好的监控环境是保证容器服务的高可靠性、高可用性和高性能的重要部分。用户可以方便地为不同资源收集不同维度的监控数据,这能方便掌握资源的使用状况,轻松定位故障。 12 | 13 | ### 访问管理 14 | 15 | 访问管理( CAM,Cloud Access Management )是腾讯云提供的一套 Web 服务,它主要用于帮助客户安全管理腾讯云账户下的资源的访问权限。通过 CAM,您可以创建、管理和销毁用户( 组 ),并通过身份管理和策略管理控制哪些人可以使用哪些腾讯云资源 16 | 17 | 若要确保 TKE 群集的安全性,请参阅[ 访问管理](https://cloud.tencent.com/document/product/457/11542)。 18 | 19 | 20 | 21 | ## 群集和节点 22 | 23 | TKE 节点在 腾讯云 虚拟机上运行。 可以将存储连接到节点和 Pod、升级群集配置 。 24 | 25 | ### 群集节点和 Pod 缩放 26 | 27 | 如果对资源的需求发生变化,用于运行服务的群集节点或 Pod 的数目就会自动增大或减小。 可以使用水平的 Pod 自动缩放程序或群集自动缩放程序。 服务自动扩缩容功能(又称 HPA)可以根据实例(pod)CPU 利用率等指标自动扩展,缩减服务的实例数量。这种缩放方法可以让 TKE 群集自动针对需求进行调整,只运行所需的资源。 28 | 29 | 有关详细信息,请参阅[服务自动扩缩容](https://cloud.tencent.com/document/product/457/14209)。 30 | 31 | ### 群集节点升级 32 | 33 | 腾讯云容器服务提供多个 Kubernetes 版本。 新版本在 TKE 中可用以后,即可使用 提交工单给腾讯云来 升级群集。 在升级过程中,节点会被仔细封锁和排除以尽量减少对正在运行的应用程序造成中断。 34 | 35 | 有关升级步骤,请参阅[升级腾讯云容器服务 (TKE) 群集](https://cloud.tencent.com/document/product/457/19508)。 36 | 37 | 38 | ### 存储卷支持 39 | 40 | 若要支持应用程序工作负荷,可以为持久保存的数据装载存储卷。 静态和动态卷都可以使用。 根据要共享存储的已连接 Pod 的数目,可以使用 腾讯云 磁盘支持的存储进行单个 Pod 的访问,也可以使用 腾讯云 文件支持的存储进行多个并发 Pod 的访问。 41 | 42 | 43 | 44 | ## 虚拟网络和入口 45 | 46 | TKE 群集可以部署到现有的虚拟网络中。 在此配置中,群集中的每个 Pod 在虚拟网络中分配有一个 IP 地址,并可直接与群集中的其他 Pod 以及虚拟网络中的其他节点通信。 Pod 也可通过 ExpressRoute 或站点到站点 (S2S) VPN 连接与对等互连虚拟网络中的其他服务和本地网络建立连接。 47 | 48 | ### 使用 HTTP 应用程序路由的入口 49 | 50 | 可以通过 HTTP 应用程序路由加载项轻松地访问部署到 TKE 群集的应用程序。 启用后,HTTP 应用程序路由解决方案可以在 TKE 群集中配置入口控制器。 部署应用程序后,会自动配置可以公开访问的 DNS 名称。 HTTP 应用程序路由会配置一个 DNS 区域并将其与 TKE 群集集成。 然后,你可以照常部署 Kubernetes 入口资源。 51 | 52 | 53 | ## Docker 映像支持和专用容器仓库 54 | 55 | TKE 支持 Docker 映像格式。 若要对 Docker 映像进行专用存储,可以将 TKE 与 TKE 容器仓库 (ACR) 集成。 56 | 57 | 若要创建专用映像存储,请参阅 [腾讯云 Tencent Hub](https://cloud.tencent.com/document/product/857/17969)。 58 | 59 | -------------------------------------------------------------------------------- /3 tke/1.tkeprepareapp.md: -------------------------------------------------------------------------------- 1 | # 准备用于腾讯云容器服务 (TKE) 的应用程序 2 | 3 | 我们将准备一个要在 Kubernetes 中使用的多容器应用程序。 现有的开发工具(例如 Docker Compose)用于在本地生成和测试应用程序。 学习如何: 4 | 5 | > [!div class="checklist"] 6 | > * 克隆 GitHub 中的示例应用程序源 7 | > * 根据示例应用程序源创建容器映像 8 | > * 在本地 Docker 环境中测试多容器应用程序 9 | 10 | 完成后,以下应用程序会在本地开发环境中运行: 11 | 12 | ![腾讯云 上的 Kubernetes 群集映像](./resource/qcloud-vote.png) 13 | 14 | 在后续教程中,此容器映像会上传到 腾讯云 容器仓库,然后部署到 腾讯云容器服务 群集中。 15 | 16 | ## 开始之前 17 | 18 | 本教程假定你基本了解核心 Docker 概念,如容器、容器映像和 `docker` 命令。 有关容器的入门基础知识,请参阅 [Docker 入门](https://docs.docker.com/get-started/)。 19 | 20 | 若要完成本教程,需要运行 Linux 容器的本地 Docker 开发环境。 Docker 提供的包可在 [Mac][docker-for-mac]、[Windows][docker-for-windows] 或 [Linux][docker-for-linux] 系统上配置 Docker。 21 | 22 | 23 | ## 获取应用程序代码 24 | 25 | 本教程使用的示例应用程序是一个基本的投票应用。 该应用程序由前端 Web 组件和后端 Redis 实例组成。 Web 组件打包到自定义容器映像中。 Redis 实例使用 Docker 中心提供的未修改的映像。 26 | 27 | 使用 [git][] 可将示例应用程序克隆到开发环境: 28 | 29 | ```console 30 | git clone https://github.com/geffzhang/qcloud-voting-app-redis.git 31 | ``` 32 | 33 | 将目录更改为克隆的目录,以供使用。 34 | 35 | ```console 36 | cd qcloud-voting-app-redis 37 | ``` 38 | 39 | 目录内包含应用程序源代码、预创建的 Docker Compose 文件和 Kubernetes 清单文件。 整套教程都会使用这些文件。 40 | 41 | ## 创建容器映像 42 | 43 | 使用 [Docker Compose][docker-compose],可自动生成容器映像和部署多容器应用程序。 44 | 45 | 使用示例 `docker-compose.yaml` 文件创建容器映像、下载 Redis 映像和启动应用程序: 46 | 47 | ```console 48 | docker-compose up -d 49 | ``` 50 | 51 | 完成后,使用 [docker images][docker-images] 命令查看创建的映像。 已下载或创建三个映像。 *qcloud-vote-front* 映像包含前端应用程序,并以 `nginx-flask` 映像为依据。 `redis` 映像用于启动 Redis 实例。 52 | 53 | ``` 54 | $ docker images 55 | 56 | REPOSITORY TAG IMAGE ID CREATED SIZE 57 | qcloud-vote-front latest 9cc914e25834 40 seconds ago 694MB 58 | redis latest a1b99da73d05 7 days ago 106MB 59 | tiangolo/uwsgi-nginx-flask flask 788ca94b2313 9 months ago 694MB 60 | ``` 61 | 62 | 运行 [docker ps][docker-ps] 命令,查看正在运行的容器: 63 | 64 | ``` 65 | $ docker ps 66 | 67 | CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 68 | c812cebbd367 redis "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 0.0.0.0:6379->6379/tcp qcloud-vote-back 69 | 65d68346d448 qcloud-vote-front "/entrypoint.sh /sta…" 2 minutes ago Up 2 minutes 443/tcp, 0.0.0.0:8080->80/tcp qcloud-vote-front 70 | 6b48f598e3f8 webapplication1:dev "tail -f /dev/null" 7 hours ago Up 7 hours 44331/tcp, 55480/tcp, 0.0.0.0:55480->80/tcp, 0.0.0.0:44331->443/tcp awesome_wilson 71 | ``` 72 | 73 | ## 在本地测试应用程序 74 | 75 | 若要查看正在运行的应用程序,请在本地 Web 浏览器中输入 http://localhost:8080。 示例应用程序会加载,如以下示例所示: 76 | 77 | ![腾讯云 上的 Kubernetes 群集映像](./resource/qcloud-vote.png) 78 | 79 | ## 清理资源 80 | 81 | 现已验证应用程序的功能,可停止并删除正在运行的容器。 请勿删除容器映像 - 在下一教程中,会将 *qcloud-vote-front* 映像上传到 腾讯云容器仓库实例。 82 | 83 | 使用 [docker-compose down][docker-compose-down] 命令停止并删除容器实例和资源: 84 | 85 | ```console 86 | docker-compose down 87 | ``` 88 | 89 | 删除本地应用程序以后,你就有了一个包含 腾讯云 投票应用程序的 Docker 映像 *qcloud-front-front*,可以在下一教程中使用。 90 | 91 | ## 后续步骤 92 | 93 | 本教程测试了应用程序并针对应用程序创建了容器映像。 你已了解如何: 94 | 95 | > [!div class="checklist"] 96 | > * 克隆 GitHub 中的示例应用程序源 97 | > * 根据示例应用程序源创建容器映像 98 | > * 在本地 Docker 环境中测试多容器应用程序 99 | 100 | 请转到下一教程,了解如何在 腾讯云 容器仓库中存取容器映像。 101 | 102 | 103 | 104 | [docker-compose]: https://docs.docker.com/compose/ 105 | [docker-for-linux]: https://docs.docker.com/engine/installation/#supported-platforms 106 | [docker-for-mac]: https://docs.docker.com/docker-for-mac/ 107 | [docker-for-windows]: https://docs.docker.com/docker-for-windows/ 108 | [docker-get-started]: https://docs.docker.com/get-started/ 109 | [docker-images]: https://docs.docker.com/engine/reference/commandline/images/ 110 | [docker-ps]: https://docs.docker.com/engine/reference/commandline/ps/ 111 | [docker-compose-down]: https://docs.docker.com/compose/reference/down 112 | [git]: https://git-scm.com/downloads 113 | 114 | -------------------------------------------------------------------------------- /3 tke/2.tkeprepareccr.md: -------------------------------------------------------------------------------- 1 | # 部署和使用腾讯云容器仓库 2 | 3 | 腾讯云 容器仓库 是用于 Docker 容器映像的基于腾讯云 的专用仓库。 可以通过专用容器仓库 安全地生成和部署应用程序和自定义代码。 介绍如何部署 Tencent Hub 实例并向其推送容器映像。 学习如何: 4 | 5 | > [!div class="checklist"] 6 | > * 创建 腾讯云 容器仓库 (Tencent hub) 实例 7 | > * 标记 Tencent Hub 的容器映像 8 | > * 向 Tencent Hub 上传映像 9 | > * 查看仓库中的映像 10 | 11 | 在后续教程中,此 Tencent Hub 实例将与 TKE 中的 Kubernetes 群集集成,而应用程序则通过映像进行部署。 12 | 13 | ## 开始之前 14 | 15 | 在上一教程中,已经为一个 腾讯云投票 应用程序示例创建了容器映像。 如果尚未创建 腾讯云投票 应用映像,请返回到上个教程学习。 16 | 17 | 本教程参考的是腾讯云的官方文档 [Tencent Hub新手入门](https://cloud.tencent.com/document/product/857/17143)。 18 | 19 | 20 | ## 创建腾讯云 容器仓库 21 | 22 | ![创建仓库](./resource/createccr.png) 23 | 填写仓库信息。根据业务填写相关信息,所有者可选择自己的账号或者所在的组织。仓库类型可选择 public 共有型或者 private 私有型。填写后单击【完成】。 24 | 25 | ![新建仓库](./resource/createccr1.png) 26 | 27 | 首次使用镜像仓库的用户,需要先开通镜像仓库。 28 | 29 | - 命名空间:命名空间是您创建的私人镜像地址的前缀。 30 | - 用户名:默认是当前用户的账号,是您登录到腾讯云docker镜像仓库的身份。 31 | - 密码:是您登录到腾讯云Tencent Hub镜像仓库的凭证。 32 | 33 | 34 | ## 登录到容器仓库 35 | 36 | 若要使用 Tencent Hub 实例,必须先登录。 使用 docker 的命令[docker-login]并提供一个唯一名称,该名称是在上一步提供给容器仓库的。 37 | 38 | ```docker cli 39 | docker login --username=[username] hub.tencentyun.com 40 | ``` 41 | 42 | 完成后,该命令会返回“登录成功”消息。 43 | 44 | ## 标记容器映像 45 | 46 | 若要查看当前的本地映像的列表,请使用 [docker images][docker-images] 命令: 47 | 48 | ``` 49 | $ docker images 50 | 51 | REPOSITORY TAG IMAGE ID CREATED SIZE 52 | qcloud-vote-front latest f4ac531bb890 About an hour ago 946MB 53 | redis latest 415381a6cb81 6 days ago 94.9MB 54 | tiangolo/uwsgi-nginx-flask python3.6 70971ba9bd6c 3 weeks ago 945MB 55 | ``` 56 | 57 | 若要将 *qcloud-vote-front* 容器映像与 TencentHub 配合使用,需使用注册表的登录服务器地址对映像进行标记。qcloud-vote-front 就是我再Tencent Hub上创建的一个项目仓库,在将容器映像推送到容器仓库时,使用此标记进行路由。 58 | 59 | 60 | 61 | ```console 62 | docker tag qcloud-vote-front hub.tencentyun.com/geffzhang/qcloud-vote-front:v1 63 | ``` 64 | 65 | 若要验证是否已应用标记,请再次运行 [docker images][docker-images]。 系统会使用 Tencent Hub 实例地址和版本号对映像进行标记。 66 | 67 | ``` 68 | $ docker images 69 | 70 | REPOSITORY TAG IMAGE ID CREATED SIZE 71 | hub.tencentyun.com/geffzhang/qcloud-vote-front v1 f4ac531bb890 About an hour ago 946MB 72 | qcloud-vote-front latest f4ac531bb890 About an hour ago 946MB 73 | redis latest 415381a6cb81 6 days ago 94.9MB 74 | tiangolo/uwsgi-nginx-flask python3.6 70971ba9bd6c 3 weeks ago 945MB 75 | ``` 76 | 77 | ## 将映像推送到容器仓库 78 | 79 | 现在可以将 *qcloud-vote-front* 映像推送到 Tencent hub 实例。 使用 [docker push][docker-push] 并提供你自己的适用于映像名称的 *hub.tencentyun.com/geffzhang/qcloud-vote-front* 地址,如下所示: 80 | 81 | ```console 82 | docker push hub.tencentyun.com/geffzhang/qcloud-vote-front:v1 83 | ``` 84 | 85 | 可能需要数分钟才能将映像推送到 Tencent Hub 86 | 87 | 88 | 89 | 90 | [docker-login]: https://docs.docker.com/engine/reference/commandline/login/ 91 | [docker-images]: https://docs.docker.com/engine/reference/commandline/images/ 92 | [docker-push]: https://docs.docker.com/engine/reference/commandline/push/ 93 | -------------------------------------------------------------------------------- /3 tke/3.tkedeploycluster.md: -------------------------------------------------------------------------------- 1 | # 部署腾讯容器服务 (TKE) 群集 2 | 3 | Kubernetes 为容器化应用程序提供一个分布式平台。 使用 TKE 可以快速预配生产就绪的 Kubernetes 群集。 本节在 TKE 中部署了 Kubernetes 群集。 学习如何: 4 | 5 | > [!div class="checklist"] 6 | > * 创建用于资源交互的服务主体 7 | > * 部署一个 Kubernetes TKE 群集 8 | > * 安装 Kubernetes CLI (kubectl) 9 | > * 配置 kubectl,以便连接到 TKE 群集 10 | 11 | 在后续教程中,腾讯云投票应用程序将部署到群集,并进行缩放和更新。 12 | 13 | ## 开始之前 14 | 15 | 在以前的教程中,已创建容器映像并上传到 腾讯云 Tencent Hub 容器仓库。 如果尚未完成这些步骤,并且想要逐一完成,请返回到 上节创建容器映像 16 | 17 | 18 | ## 创建 Kubernetes 群集 19 | 20 | 创建集群 21 | 1. 登录 [腾讯云容器服务控制台](https://console.cloud.tencent.com/ccs) 。 22 | 2. 单击左侧导航栏中的 集群,单击集群列表页的 【新建】。 23 | 24 | ![创建集群](./resource/ccrbasic1.png) 25 | 26 | 3. 设置集群的基本信息。 27 | 28 | + 集群名称:要创建的集群的名称。不超过60个字符。 29 | + 计费模式:提供包年包月和按量计费两种计费模式,详细对比请查看 [计费模式说明](https://cloud.tencent.com/doc/product/213/2180)。 30 | + 所在地域:建议您根据所在地理位置选择靠近的地域。可降低访问延迟,提高下载速度。 31 | + 可用区:同地域内,内网互通;不同地域,内网不通。需要多个内网通信的用户须选择相同的地域。 32 | + 节点网络:为集群内主机分配在节点网络地址范围内的 IP 地址。参阅 [容器及节点网络设置](https://cloud.tencent.com/doc/product/457/9083)。 33 | + 容器网络:为集群内容器分配在容器网络地址范围内的 IP 地址。参阅 [容器及节点网络设置](https://cloud.tencent.com/doc/product/457/9083)。 34 | + 集群描述:创建集群的相关信息。该信息将显示在 集群信息 页面。 35 | 36 | ![设置集群基本信息](./resource/ccrbasic2.png) 37 | 38 | 4. 选择机型 (支持系统盘为云盘的所有机型)。 39 | 40 | + 系列:提供 系列 1 和 系列 2 。详细对比参看 [实例类型概述](https://cloud.tencent.com/doc/product/213/7153#.E5.8F.AF.E7.94.A8.E5.AE.9E.E4.BE.8B.E7.B1.BB.E5.9E.8B2) 。 41 | + 机型:机型选择方案参看 [确定云服务器配置方案](https://cloud.tencent.com/doc/product/213/2764#.E7.A1.AE.E5.AE.9A.E4.BA.91.E6.9C.8D.E5.8A.A1.E5.99.A8.E9.85.8D.E7.BD.AE.E6.96.B9.E6.A1.88)。 42 | 43 | ![设置集群基本信息](./resource/ccrbasic3.png) 44 | 45 | 5. 填写云主机配置。 46 | 47 | + 系统盘:固定为 50G 。 48 | + 数据盘:步长 10G ,最高为 4000G 。 49 | + 公网宽带:提供两种计费模式,详细对比参看 购买网络带宽。 50 | + 带宽:勾选 免费分配公网 IP ,系统将免费分配公网 IP ,若不需要,请选择带宽值为 0 。 51 | + 登录方式:提供三种对应登录方式。 52 | i. 设置密码:请根据提示设置对应密码。 53 | ii.立即关联密钥:密钥对是通过一种算法生成的一对参数,是一种比常规密码更安全的登录云服务器的方式。详细参阅 SSH 密钥 。 54 | iii.自动生成密码:自动生成的密码将通过站内信发送给您。 55 | + 安全组:安全组具有防火墙的功能,用于设置云主机 CVM 的网络访问控制。参阅 容器服务安全组设置 。 56 | + 云主机数量:选择服务器数量。 57 | ![设置集群基本信息](./resource/ccrbasic4.png) 58 | 59 | 6. 创建完成的集群将出现在集群列表中。 60 | 61 | ## 使用 kubectl 连接到群集 62 | 63 | 通过 Kubernetes 命令行工具 kubectl 从本地客户端机器连接到 TKE 集群. 详细安装过程参考 [Installing and Setting up kubectl](https://kubernetes.io/docs/user-guide/prereqs/)。 64 | 65 | 我们主要使用Windows 10 操作系统上来完成操作。下载kubectl 工具保存到我们的工作区,比如我的工作区是D:\workshop\Software\k8s。 66 | https://storage.googleapis.com/kubernetes-release/release/v1.8.13/bin/windows/amd64/kubectl.exe 67 | 68 | 获取集群账号密码以及证书信息 69 | 1. 登录 [容器服务控制台 > 集群](https://console.cloud.tencent.com/ccs),单击需要连接的集群 ID/名称,查看集群详情。 70 | 71 | 2. 在集群信息页,单击【显示凭证】,查看用户名、密码和证书信息。 72 | 73 | 3. 复制或下载证书文件到本地。 74 | 75 | 4. 获取访问入口。 开启公网访问地址后可参考 76 | 77 | 通过证书信息使用 kubectl 操作集群,修改 kubectl 配置文件,长期有效。该方法适用于长期通过 kubectl 操作集群, 一次配置,只要文件不修改就长期有效。 78 | 设置 kubectl 配置,修改以下命令中的密码、证书信息。 79 | 80 | ``` 81 | kubectl config set-credentials default-admin --username=admin --password=xxxxxxxxxxx 记得把这里的用户名和密码换成集群的用户名和密码 82 | ``` 83 | kubectl 把配置信息存放在C:\Users\geffzhang\.kube\ 下,记得把证书放到这个目录下 84 | 继续运行以下命令 85 | ``` 86 | kubectl config set-cluster default-cluster --server=https://cls-386w5vjo.ccs.tencent-cloud.com --certificate-authority=C:\Users\geffzhang\.kube\cluster-ca.crt 87 | kubectl config set-context default-system --cluster=default-cluster --user=default-admin 88 | kubectl config use-context default-system 89 | ``` 90 | 配置完成,直接使用 kubectl 命令: 91 | 92 | $ kubectl get nodes 93 | 94 | ``` 95 | NAME STATUS ROLES AGE VERSION 96 | 192.168.0.11 Ready 3d v1.10.5-qcloud-rev1 97 | 192.168.0.12 Ready 12d v1.10.5-qcloud-rev1 98 | 192.168.0.8 Ready 12d v1.10.5-qcloud-rev1 99 | ``` 100 | 101 | ## 后续步骤 102 | 103 | 本教程在 TKE 中部署了一个 Kubernetes 群集并将 `kubectl` 配置为连接到该群集。 你已了解如何: 104 | 105 | 106 | 请继续学习下一教程,了解如何将应用程序部署到群集。 107 | 108 | 109 | [kubectl]: https://kubernetes.io/docs/user-guide/kubectl/ 110 | [kubectl-get]: https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#get 111 | -------------------------------------------------------------------------------- /3 tke/4.tkedeployapplication.md: -------------------------------------------------------------------------------- 1 | # 在腾讯云容器服务 (TKE) 中运行应用程序 2 | 3 | Kubernetes 为容器化应用程序提供一个分布式平台。 你生成自己的应用程序和服务并将其部署到 Kubernetes 群集中,让群集管理可用性和连接性。 本节将把示例应用程序会部署到 Kubernetes 群集中。 学习如何: 4 | 5 | > [!div class="checklist"] 6 | > * 更新 Kubernetes 清单文件 7 | > * 在 Kubernetes 中运行应用程序 8 | > * 测试应用程序 9 | 10 | 在后续教程中,此应用程序将进行横向扩展和更新。 11 | 12 | 本教程假定你基本了解 Kubernetes 概念。有关 Kubernetes 的详细信息,请参阅 [Kubernetes 文档][kubernetes-documentation]。 13 | 14 | ## 开始之前 15 | 16 | 在前面的教程中,我们已将应用程度打包到容器映像中,将此映像上传到 Tencent Hub的容器仓库中,并创建了 Kubernetes 群集。 17 | 18 | 必须先预创建 `qcloud-vote-all-in-one-redis.yaml` Kubernetes 清单文件,然后才能完成本教程。 此文件是在上一教程中与应用程序源代码一同下载。 验证是否已克隆代码库,并且是否已将目录更改为克隆的代码库。 如果尚未完成这些步骤,并且想要逐一完成,请返回到 创建容器映像 。 19 | 20 | ## 更新清单文件 21 | 22 | 在这些教程中,请使用 Tencent Hub 容器仓库 实例来存储示例应用程序的容器映像。 若要部署此应用程序,必须更新 Kubernetes 清单文件中的映像名称,使之包括 Tencent Hub 登录服务器名称。 23 | 24 | 25 | ``` 26 | 27 | 在第一个教程中克隆的 git 存储库中的示例清单文件使用仓库名称为 *hub.tencentyun.com/geffzhang*。 使用 `vi` 之类的文本编辑器打开该清单文件: 28 | 29 | ```console 30 | vi qcloud-vote-all-in-one-redis.yaml 31 | ``` 32 | 33 | 将 *hub.tencentyun.com/geffzhang* 替换为 Tencent Hub 项目名称。 映像名称位于清单文件的第 45-60 行, 同时注意imagePullSecrets 的*name:tencenthubkey* 就是Tencent Hub的镜像私有仓库的变量,是必须设置的。 以下示例展示了默认映像名称: 34 | 35 | ```yaml 36 | containers: 37 | - name: qcloud-vote-front 38 | image: hub.tencentyun.com/geffzhang/qcloud-vote-front:v1 39 | ports: 40 | - containerPort: 80 41 | resources: 42 | requests: 43 | cpu: 250m 44 | limits: 45 | cpu: 500m 46 | env: 47 | - name: REDIS 48 | value: "qcloud-vote-back" 49 | imagePullSecrets: 50 | - name: qcloudregistrykey 51 | - name: tencenthubkey 52 | ``` 53 | 54 | 提供自己的 Tencent Hub的项目仓库名称,使清单文件如以下示例所示: 55 | 56 | ```yaml 57 | containers: 58 | - name: qcloud-vote-front 59 | image: hub.tencentyun.com/geffzhang/qcloud-vote-front:v1 60 | ``` 61 | 62 | 保存并关闭该文件。 63 | 64 | ## 部署应用程序 65 | 66 | 若要部署应用程序,请使用 [kubectl apply][kubectl-apply] 命令。 此命令分析清单文件并创建定义的 Kubernetes 对象。 指定示例清单文件,如以下示例所示: 67 | 68 | ```console 69 | kubectl apply -f qcloud-vote-all-in-one-redis.yaml 70 | ``` 71 | 72 | Kubernetes 对象在群集中创建,如以下示例所示: 73 | 74 | ``` 75 | $ kubectl apply -f qcloud-vote-all-in-one-redis.yaml 76 | 77 | deployment.apps "qcloud-vote-back" created 78 | service "qcloud-vote-back" created 79 | deployment.apps "qcloud-vote-front" created 80 | service "qcloud-vote-front" created 81 | ``` 82 | 83 | ## 测试应用程序 84 | 85 | 创建向 Internet 公开应用程序的 [Kubernetes 服务][kubernetes-service]。 此过程可能需要几分钟。 若要监视进度,请将 [kubectl get service][kubectl-get] 命令与 `--watch` 参数配合使用: 86 | 87 | ```console 88 | kubectl get service qcloud-vote-front --watch 89 | ``` 90 | 91 | 以下示例显示现在已分配一个公共 IP 地址: 92 | 93 | ``` 94 | NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE 95 | qcloud-vote-front LoadBalancer 172.16.255.183 193.112.254.239 80:32093/TCP 2m 96 | ``` 97 | 98 | 若要查看正在操作的应用程序,请打开 Web 浏览器并转到外部 IP 地址。 99 | 100 | ![腾讯云 上的 Kubernetes 群集映像](./resource/qcloud-vote.png) 101 | 102 | 如果应用程序未加载,可能是因为容器仓库存在授权问题。 若要查看容器的状态,请使用 `kubectl get pods` 命令。 103 | 104 | ## 后续步骤 105 | 106 | 在本教程中,已将 腾讯云投票应用程序部署到 TKE 中的 Kubernetes 群集。 你已了解如何: 107 | 108 | > [!div class="checklist"] 109 | > * 更新 Kubernetes 清单文件 110 | > * 在 Kubernetes 中运行应用程序 111 | > * 测试应用程序 112 | 113 | 114 | 115 | [kubectl-apply]: https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#apply 116 | [kubectl-create]: https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#create 117 | [kubectl-get]: https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#get 118 | [kubernetes-documentation]: https://kubernetes.io/docs/home/ 119 | [kubernetes-service]: https://kubernetes.io/docs/concepts/services-networking/service/ -------------------------------------------------------------------------------- /3 tke/5.tkekubernetesscale.md: -------------------------------------------------------------------------------- 1 | # 在腾讯云容器服务 (TKE) 中缩放应用程序 2 | 3 | 如果已按照教程执行,则在 TKE 中已有可正常工作的 Kubernetes 群集,并且已部署了 腾讯云 投票应用。 在本节会在应用中扩大 Pod 并尝试 Pod 自动缩放。 学习如何: 4 | 5 | > [!div class="checklist"] 6 | > * 缩放 Kubernetes 节点 7 | > * 手动缩放运行应用程序的 Kubernetes Pod 8 | > * 配置运行应用前端的自动缩放 Pod 9 | 10 | 在后续教程中,腾讯云 投票应用程序将更新为新版本。 11 | 12 | ## 开始之前 13 | 14 | 在前面的教程中,我们已将应用程度打包到容器映像中,将此映像上传到 Tencent Hub的 容器仓库中,并创建了 Kubernetes 群集。 应用程序随后在 Kubernetes 群集上运行。 如果尚未完成这些步骤,并且想要逐一完成,请返回到 创建容器映像。 15 | 16 | ## 手动缩放 Pod 17 | 18 | 在前述教程中部署 腾讯云 投票前端和 Redis 实例时,创建了单个副本。 若要查看群集中 Pod 的数目和状态,请使用 [kubectl get][kubectl-get] 命令,如下所示: 19 | 20 | ```console 21 | kubectl get pods 22 | ``` 23 | 24 | 以下示例输出显示一个前端 Pod 和一个后端 Pod: 25 | 26 | ``` 27 | NAME READY STATUS RESTARTS AGE 28 | qcloud-vote-back-b68b85dbf-cn9lz 1/1 Running 0 6m 29 | qcloud-vote-front-76fccf8655-5t9vh 1/1 Running 0 6m 30 | ``` 31 | 32 | 若要手动更改 *qcloud-vote-front* 部署中的 Pod 数,请使用 [kubectl scale][kubectl-scale] 命令。 以下示例将前端 Pod 数增加到 *3*: 33 | 34 | ```console 35 | kubectl scale --replicas=3 deployment/qcloud-vote-front 36 | ``` 37 | 38 | 再次运行 [kubectl get pods][kubectl-get],验证 Kubernetes 是否创建其他 Pod。 一分钟左右之后,其他 Pod 会在群集中提供: 39 | 40 | ```console 41 | $ kubectl get pods 42 | 43 | NAME READY STATUS RESTARTS AGE 44 | qcloud-vote-back-b68b85dbf-cn9lz 1/1 Running 0 16m 45 | qcloud-vote-front-76fccf8655-5qrvt 1/1 Running 0 1m 46 | qcloud-vote-front-76fccf8655-5t9vh 1/1 Running 0 16m 47 | qcloud-vote-front-76fccf8655-qwkss 1/1 Running 0 1m 48 | ``` 49 | 50 | ## 自动缩放 Pod 51 | 52 | Kubernetes 支持[水平 Pod 自动缩放][kubernetes-hpa]以根据 CPU 利用率或其他选择指标调整部署中的 Pod 数。 [指标服务器][metrics-server]用来将资源利用率提供给 Kubernetes,可自动部署在 TKE 群集 1.10 及更高版本中。 53 | 54 | 如果 TKE 群集的版本低于 *1.10*,请安装指标服务器,否则请跳过此步骤。 若要查看这些 YAML 定义的内容,请参阅[适用于 Kuberenetes 1.8+ 的指标服务器][metrics-server-github]。 55 | 56 | 若要使用自动缩放程序,Pod 必须定义了 CPU 请求和限制。 在 `qcloud-vote-front` 部署中,前端容器请求 0.25 个 CPU,限制为 0.5 个 CPU。 设置与下面类似: 57 | 58 | ```yaml 59 | resources: 60 | requests: 61 | cpu: 250m 62 | limits: 63 | cpu: 500m 64 | ``` 65 | 66 | 下面的示例使用 [kubectl autoscale][kubectl-autoscale] 命令自动缩放 *qcloud-vote-front* 部署中的 Pod 数。 如果 CPU 利用率超过 50%,则自动缩放程序会将 Pod 增加到最多 5 个实例: 67 | 68 | ```console 69 | kubectl autoscale deployment qcloud-vote-front --cpu-percent=50 --min=2 --max=5 70 | ``` 71 | 72 | 若要查看自动缩放程序的状态,请使用 `kubectl get hpa` 命令,如下所示: 73 | 74 | ``` 75 | $ kubectl get hpa 76 | 77 | NNAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE 78 | qcloud-vote-front Deployment/qcloud-vote-front /50% 2 5 0 5s 79 | ``` 80 | 81 | 在 腾讯云 投票应用处于最小负荷状态几分钟之后,Pod 副本数会自动减少到 2 个。 也可再次使用 `kubectl get pods` 来查看不需要的 Pod 是否已删除。 82 | 83 | ## 后续步骤 84 | 85 | 在本教程中,在 Kubernetes 群集中使用了不同的缩放功能。 你已了解如何: 86 | 87 | > [!div class="checklist"] 88 | > * 缩放 Kubernetes 节点 89 | > * 手动缩放运行应用程序的 Kubernetes Pod 90 | > * 配置运行应用前端的自动缩放 Pod 91 | 92 | 继续学习下一教程,了解如何在 Kubernetes 中更新应用程序。 93 | 94 | 95 | [kubectl-autoscale]: https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#autoscale 96 | [kubectl-get]: https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#get 97 | [kubectl-scale]: https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#scale 98 | [kubernetes-hpa]: https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/ 99 | [metrics-server-github]: https://github.com/kubernetes-incubator/metrics-server/tree/master/deploy/1.8%2B 100 | [metrics-server]: https://kubernetes.io/docs/tasks/debug-application-cluster/core-metrics-pipeline/ -------------------------------------------------------------------------------- /3 tke/6.tkeappupdate.md: -------------------------------------------------------------------------------- 1 | # 在腾讯云容器服务 (TKE) 中更新应用程序 2 | 3 | 在 Kubernetes 中部署应用程序后,可以指定新的容器映像或映像版本,从而更新应用程序。 这样做时,更新会进行暂存,因此只有一部分部署会同时更新。 借助这种暂存更新,可以让应用程序在更新期间继续运行。 如果发生部署故障,还可以利用它的回滚机制。 4 | 5 | 在本教程,我们便完成了对 腾讯云投票 应用示例的更新。 学习如何: 6 | 7 | > [!div class="checklist"] 8 | > * 更新前端应用程序代码 9 | > * 创建更新的容器映像 10 | > * 向 Tencent Hub容器仓库推送容器映像 11 | > * 部署更新的容器映像 12 | 13 | ## 开始之前 14 | 15 | 在前面的教程中,已将应用程度打包到容器映像中,将该映像上传到 Tencent Hub 容器仓库,并创建了 Kubernetes 群集。 应用程序随后在 Kubernetes 群集上运行。 16 | 17 | 还克隆了应用程序存储库,其中包括应用程序源代码和本教程中使用的预创建的 Docker Compose 文件。 验证是否已克隆存储库,并且是否已将目录更改为克隆的目录。 如果尚未完成这些步骤,并且想要逐一完成,请返回到 创建容器映像。 18 | 19 | 20 | ## 更新应用程序 21 | 22 | 让我们更改示例应用程序,然后更新已部署到 TKE 群集的版本。 示例应用程序源代码位于 *qcloud-vote* 目录中。 使用编辑器(例如 `vi`)打开 *config_file.cfg* 文件: 23 | 24 | ```console 25 | vi qcloud-vote/qcloud-vote/config_file.cfg 26 | ``` 27 | 28 | 将 *VOTE1VALUE* 和 *VOTE2VALUE* 的值更改为不同的颜色。 以下示例显示更新的颜色值: 29 | 30 | ``` 31 | # UI Configurations 32 | TITLE = 'Qcloud Voting App' 33 | VOTE1VALUE = 'Cats' 34 | VOTE2VALUE = 'Dogs' 35 | SHOWHOST = 'false' 36 | ``` 37 | 38 | 保存并关闭该文件。 39 | 40 | ## 更新容器映像 41 | 42 | 若要重新创建前端映像并测试更新的应用程序,请使用 [docker-compose][docker-compose]。 `--build` 参数用于指示 Docker Compose 重新创建应用程序映像: 43 | 44 | ```console 45 | docker-compose up --build -d 46 | ``` 47 | 48 | ## 在本地测试应用程序 49 | 50 | 若要验证已更新的容器映像是否显示所做的更改,请打开一个本地 Web 浏览器并访问 http://localhost:8080。 51 | 52 | ![腾讯云 上的 Kubernetes 群集映像](resource/vote-app-updated.png) 53 | 54 | 在 *config_file.cfg* 文件中提供的已更新颜色值显示在正运行的应用程序上。 55 | 56 | ## 标记并推送映像 57 | 58 | 59 | 使用 [docker tag][docker-tag] 标记映像。 将 `hub.tencentyun.com/geffzhang/qcloud-vote-front` 替换为 Tencent Hub 项目名称,并将映像版本更新为 *:v2*,如下所示: 60 | 61 | ```console 62 | docker tag qcloud-vote-front hub.tencentyun.com/geffzhang/qcloud-vote-front:v2 63 | ``` 64 | 65 | 现在,请使用 [docker push][docker-push] 将映像上传到注册表。 将 `hub.tencentyun.com/geffzhang/qcloud-vote-front` 替换为 Tencent Hub 项目名称。 66 | 67 | ```console 68 | docker push hub.tencentyun.com/geffzhang/qcloud-vote-front:v2 69 | ``` 70 | 71 | ## 部署更新的应用程序 72 | 73 | 为了确保最长运行时间,必须运行应用程序 Pod 的多个实例。 使用 [kubectl get pods][kubectl-get] 命令验证运行的前端实例的数目: 74 | 75 | ``` 76 | $ kubectl get pods 77 | 78 | NNAME READY STATUS RESTARTS AGE 79 | qcloud-vote-back-b68b85dbf-cn9lz 1/1 Running 0 44m 80 | qcloud-vote-front-76fccf8655-5qrvt 1/1 Running 0 29m 81 | qcloud-vote-front-76fccf8655-5t9vh 1/1 Running 0 44m 82 | ``` 83 | 84 | 如果没有多个前端 Pod,请缩放 *qcloud-vote-front* 部署,如下所示: 85 | 86 | ```console 87 | kubectl scale --replicas=2 deployment/qcloud-vote-front 88 | ``` 89 | 90 | 若要更新应用程序,请使用 [kubectl set][kubectl-set] 命令。 使用Tencent Hub项目名称更新 `hub.tencentyun.com/geffzhang/qcloud-vote-front`,并指定 *v2* 应用程序版本: 91 | 92 | ```console 93 | kubectl set image deployment/qcloud-vote-front qcloud-vote-front=hub.tencentyun.com/geffzhang/qcloud-vote-front:v2 94 | ``` 95 | 96 | 若要监视部署,请使用 [kubectl get pod][kubectl-get] 命令。 部署更新的应用程序时,Pod 终止运行并通过新容器映像重新创建。 97 | 98 | ```console 99 | kubectl get pods 100 | ``` 101 | 102 | 以下示例输出显示,在部署进行时,Pod 正在终止,新实例正在运行: 103 | 104 | ``` 105 | $ kubectl get pods 106 | 107 | NAME READY STATUS RESTARTS AGE 108 | NAME READY STATUS RESTARTS AGE 109 | qcloud-vote-back-b68b85dbf-cn9lz 1/1 Running 0 44m 110 | qcloud-vote-front-76fccf8655-5qrvt 1/1 Running 0 29m 111 | qcloud-vote-front-76fccf8655-5t9vh 1/1 Running 0 44m 112 | ``` 113 | 114 | ## 测试更新的应用程序 115 | 116 | 若要查看更新的应用程序,请先获取 `qcloud-vote-front` 服务的外部 IP 地址: 117 | 118 | ```console 119 | kubectl get service qcloud-vote-front 120 | ``` 121 | 122 | 现在,请打开本地 Web 浏览器并访问该 IP 地址。 123 | 124 | ![腾讯云 上的 Kubernetes 群集映像](resource/vote-app-updated.png) 125 | 126 | ## 后续步骤 127 | 128 | 在本教程中,更新了应用程序并向 Kubernetes 群集推出了此更新。 你已了解如何: 129 | 130 | > [!div class="checklist"] 131 | > * 更新前端应用程序代码 132 | > * 创建更新的容器映像 133 | > * 向Tencent Hub 容器仓库推送容器映像 134 | > * 部署更新的容器映像 135 | 136 | 137 | 138 | [docker-compose]: https://docs.docker.com/compose/ 139 | [docker-push]: https://docs.docker.com/engine/reference/commandline/push/ 140 | [docker-tag]: https://docs.docker.com/engine/reference/commandline/tag/ 141 | [kubectl-get]: https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#get 142 | [kubectl-set]: https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#set 143 | -------------------------------------------------------------------------------- /3 tke/resource/ccrbasic1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geffzhang/QcloudNetCore/63708d1415c7093ab30cede0d01cbfe25784b4bb/3 tke/resource/ccrbasic1.png -------------------------------------------------------------------------------- /3 tke/resource/ccrbasic2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geffzhang/QcloudNetCore/63708d1415c7093ab30cede0d01cbfe25784b4bb/3 tke/resource/ccrbasic2.png -------------------------------------------------------------------------------- /3 tke/resource/ccrbasic3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geffzhang/QcloudNetCore/63708d1415c7093ab30cede0d01cbfe25784b4bb/3 tke/resource/ccrbasic3.png -------------------------------------------------------------------------------- /3 tke/resource/ccrbasic4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geffzhang/QcloudNetCore/63708d1415c7093ab30cede0d01cbfe25784b4bb/3 tke/resource/ccrbasic4.png -------------------------------------------------------------------------------- /3 tke/resource/createccr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geffzhang/QcloudNetCore/63708d1415c7093ab30cede0d01cbfe25784b4bb/3 tke/resource/createccr.png -------------------------------------------------------------------------------- /3 tke/resource/createccr1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geffzhang/QcloudNetCore/63708d1415c7093ab30cede0d01cbfe25784b4bb/3 tke/resource/createccr1.png -------------------------------------------------------------------------------- /3 tke/resource/qcloud-vote.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geffzhang/QcloudNetCore/63708d1415c7093ab30cede0d01cbfe25784b4bb/3 tke/resource/qcloud-vote.png -------------------------------------------------------------------------------- /3 tke/resource/vote-app-updated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geffzhang/QcloudNetCore/63708d1415c7093ab30cede0d01cbfe25784b4bb/3 tke/resource/vote-app-updated.png -------------------------------------------------------------------------------- /4 Wechat/lab.md: -------------------------------------------------------------------------------- 1 | ## 一、实验概述 2 | 将通过实战“微信公众号”开发,教你如何借助腾讯云的SDK让公众号更智能,以及借助腾讯云的容器服务,解决用户开发、测试及运维过程的环境一致性问题,帮助用户降低成本,提高效率。 3 | 4 | ## 二、准备工作 5 | 1、 已申请公众号账号或个人微信公众平台接口测试帐号 6 | 2、 已注册腾讯云账号 7 | ![镜像仓库![项目仓库3](./resource/dd.png)](./resource/dd.png)、 购买一个Mysql 服务 和一个 Redis服务 8 | 4、 开通Tencent Hub 服务 9 | 5、 开通腾讯云容器服务 10 | 6、 下载微信公众号Demo代码 https://github.com/geffzhang/TencentCloudMPSample 11 | 12 | ## 三、实验架构 13 | ![架构图](./resource/labarch.png) 14 | 15 | + 使用腾讯云容器服务TKE 来托管我们的公众号服务 16 | + 公众号服务使用了腾讯云的4 个PasS服务:机器翻译、智能语音、MySQL以及Redis 服务 17 | + 公众号使用的机器翻译和智能语音服务进行单独的封装成2个微服务 18 | 19 | ## 四、任务一:使用 Senparc.Weixin 接入微信公众号开发 20 | 21 | ### 微信公众号SDK Senparc.Weixin.MP 22 | Senparc.Weixin SDK 是由盛派网络(Senparc)团队自主研发的针对微信各模块的开发套件(C# SDK),已全面支持微信公众号、小程序、微信支付、企业号、开放平台、JSSDK、摇一摇周边等模块。快使用 Senparc.Weixin SDK 轻松打造微信各平台的扩展应用吧。 23 | 有详细的文档:https://sdk.weixin.senparc.com/Document ,还有客服支持以及QQ/微信支持群。 24 | ![盛派微信SDK](./resource/senparcsdk.png) 25 | Github开源代码:[https://github.com/JeffreySu/WeiXinMPSDK](https://github.com/JeffreySu/WeiXinMPSDK) 26 | 27 | ### 申请微信公众号授权 28 | 先申请微信公众号的授权,找到或配置几个关键的信息(开发者ID、开发者密码、IP白名单、令牌和消息加解密密钥等) 29 | 30 | 开发者ID:固定的; 31 | 开发者密码:自己扫一下就可以看到; 32 | IP白名单:设置自己配置服务器的地址; 33 | 服务器地址(URL):稍后详解; 34 | 令牌:随便写,按规则; 35 | 消息加解密密钥:随便写,或者随机生成; 36 | 37 | 在微信公众平台认证之前,我们可以先申请一个测试的公众号来进行测试,这对开发人员来说还是有很大好处的。(https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login ) 38 | 39 | 40 | ### 配置服务器地址(URL) 41 | 服务器地址(URL)应该怎么配置呢?它对应的ASP.NET Core控制器应该是怎么样子的呢? 42 | 43 | 首先我们创建一个ASP.NET Core的项目,启用docker支持。添加Nuget 包 Senparc.Weixin.MP.MVC。 44 | 45 | 在这里我们要引用.NET社区使用最广泛的微信开发SDK Senparc.Weixin。 这个SDK 也是一位MVP 领导的开源项目,他的公司叫做盛派网络。盛派网络团队最近开发了一个微信 Sample 项目生成器:WeChatSampleBuilder,帮助大家自动生成你所需的项目代码,包括任意选择.NET版本、所需使用到的微信模块、分布式缓存,等等。 46 | 我们就借助WeChatSampleBuilder 来生成微信公众号代码,我们需要启用Redis 缓存。 47 | 48 | 生成的示例代码中,我们把微信处理消息的代码拷到我们的项目中。 49 | ![生成代码](./resource/senparcsamplebuilder.png) 50 | 51 | ### 请求处理 52 | 在上面的处理请求信息的代码中,我自定义了一个类 CustomMessageHandler 来处理消息。 53 | CustomMessageHandler 类继承了 MessageHandler 类,然后重写了 DefaultResponseMessage() 方法,返回固定的文本值。base.CreateResponseMessage() 方法可以返回多种不同类型的结果值,如: 54 | 55 | ResponseMessageText - 对应文本消息 56 | ResponseMessageNews - 对应图文消息 57 | ResponseMessageMusic - 对应音乐消息 58 | ResponseMessageXXX - 其他类型以此类推 59 | 60 | 上述方法只是一种默认的消息处理,我们也可以专门针对不同的请求类型做出不同的回应,比如重写 OnTextRequest(),其它重载需要自己观察基类成员: 61 | 62 | 因为在继承 MessageHandler 类的同时,我创建了一个 CustomMessageContext 自定义消息上下文的类,该类内容如下,并没有包含其它方法,直接继承 MessageContext 即可: 63 | 64 | ### 记录交互请求 65 | 使用EF Core + Mysql记录交互请求。 66 | 1.Nuget 添加Microsoft.EntityFrameworkCore 与Pomelo.EntityFrameworkCore.MySql包. 67 | 68 | 2.添加实体 WeixinInteraction.cs 69 | 70 | ``` 71 | public class WeixinInteraction 72 | { 73 | [Key] 74 | public int Id { get; set; } 75 | 76 | public string Request { get; set; } 77 | 78 | public string Response { get; set; } 79 | } 80 | ``` 81 | 82 | 3.添加TencentCloudDbContext.cs继承EF的DBContext类。 83 | 84 | ``` 85 | namespace TencentCloudMPSample.EFCore 86 | { 87 | public class TencentCloudDbContext : DbContext 88 | { 89 | public TencentCloudDbContext(DbContextOptions options):base(options) 90 | { 91 | } 92 | 93 | public DbSet WeixinInteractions { get; set; } 94 | 95 | protected override void OnModelCreating(ModelBuilder modelBuilder) 96 | { 97 | base.OnModelCreating(modelBuilder); 98 | } 99 | } 100 | } 101 | ``` 102 | 103 | 4.添加数据库操作类WeixinInteractionServer.cs 104 | ``` 105 | namespace TencentCloudMPSample.EFCore.Servers 106 | { 107 | public class WeixinInteractionServer 108 | { 109 | private TencentCloudDbContext _dbContext; 110 | 111 | public WeixinInteractionServer(TencentCloudDbContext dbContext) 112 | { 113 | _dbContext = dbContext; 114 | } 115 | 116 | public async Task AddInteraction(string request,string response) 117 | { 118 | await _dbContext.WeixinInteractions.AddAsync(new WeixinInteraction { Request = request, Response = response }); 119 | await _dbContext.SaveChangesAsync(); 120 | } 121 | 122 | public async Task> GetWeixinInteractions() 123 | { 124 | var list = await _dbContext.WeixinInteractions.ToListAsync(); 125 | return list; 126 | } 127 | 128 | } 129 | } 130 | ``` 131 | 5.配置mysql连接字符串 132 | 133 | ``` 134 | "ConnectionStrings": { 135 | "Mysql": "server=192.168.0.4;uid=root;pwd=pwd@2018;port=3306;pooling=true;CharSet=utf8mb4;database=TencentCloudMP;sslmode=none;" 136 | }, 137 | ``` 138 | 139 | 6.StartUp类中注入DbContext和WeixinInteractionServer 140 | ``` 141 | services.AddDbContext(option => option.UseMySql(Configuration.GetConnectionString("Mysql"))); 142 | services.AddScoped(); 143 | services.AddHttpContextAccessor(); 144 | ``` 145 | 7.使用命令Add-Migration Init 和Update-Database迁移数据库 146 | 147 | 8.在WeixinController注入并使用WeixinInteractionServer记录交互信息。 148 | 149 | ## 五、任务二:处理公众号文本信息 150 | 151 | ### 机器翻译 152 | 腾讯机器翻译(Tencent Machine Translation)结合了神经机器翻译和统计机器翻译的优点,从大规模双语语料库自动学习翻译知识,实现从源语言文本到目标语言文本的自动翻译,目前可支持中英双语互译。  153 | 腾讯机器翻译有哪样的功能?  154 | 1.中英文本互译,中英翻译API,提供中文到英文、英文到中文的文本内容翻译,您只需要通过调用API,发送需要翻译的内容,即可获得翻译结果。翻译内容经过大数据语料库、多种解码算法、翻译引擎深度优化,在不同翻译使用场景中都有深厚积累,翻译结果专业评价处于行业领先水平。结合统计机器翻译和神经网络机器翻译优点,完美融合,并持续技术升级,保证业界领先的翻译体验。  155 | 2.腾讯机器翻译可以自动识别文本语种,自动识别语种API,您只需要通过调用API,发送待翻译的文本内容,无需额外输入语言种类和做判断实现,即可自动获得语言种类,轻量高效,使面向客户的服务体验更佳。  156 | 157 | 腾讯云机器翻译有哪些优势?  158 | 1.多引擎融合,翻译引擎深度优化,集成翻译记忆技术,融合统计及神经网络等多种解 159 | 码算法,翻译技术积累深厚。  160 | 2.大数据支持,亿级大数据资源支持,融合领域自适应技术,可满足您多领域、多场景 161 | 翻译需求。  162 | 3.灵活定制扩展,提供翻译词典、翻译模板等扩展定制,可针对不同人群满足您的定制 163 | 化服务需求。 164 | 3. 实时准确效果,翻译请求响应实时,译文结果精准流畅,满足您高质量的翻译水准要求。  165 | 166 | 腾讯机器翻译有哪些场景是我们所需要用到的? 167 | 168 | 像文档资料翻译,对于合同、文件、资料、论文、邮件等文档类内容均可快速翻译; 169 | 文章资讯阅读,适合于快速获取国外资讯、文章阅读或将自有内容快速发布外文版本; 170 | 外文网站翻译,外文网站直接翻译可以有效提升访问效率。 171 | 外语学习查询,基于权威词典数据库,针对小学、初中、高中、大学、出国等多阶段英语学习均有帮助; 172 | 口语对话辅助,针对日常口语对话句型长期训练, 173 | 可用于对外实时交流、社交沟通等情境中;境外旅游服务,境外旅游时的吃饭点餐、酒店住宿、购物支付、交通出行、景点浏览都可使用的机器翻译服务。  174 | 175 | 我们在公众号里使用的功能 文本中英文互译:用户发送翻译消息,通过腾讯云的翻译API进行翻译 ,翻译完成发到微信公众号。 176 | 177 | ### 使用TencentCloudSDK编写机器翻译服务 178 | 新建asp.net core WebApi项目,添加Docker支持,安装TencentCloudSDK 179 | 180 | 使用nuget命令Install-Package TencentCloudSDK -Version 3.0.6 181 | 182 | 推荐使用[API3.0 Explorer](https://console.cloud.tencent.com/api/explorer?Product=tmt&Version=2018-03-21&Action=LanguageDetect) 辅助编写代码 183 | 184 | ![API Explorer ](./resource/apiexplorer3.png) 185 | 使用依赖注入,将机器翻译Client注入。 186 | 187 | 188 | 添加MachineTranslationController.cs,注入Client 189 | 190 | 191 | 编写相关业务代码。 192 | 193 | ### 公众号后端请求机器翻译服务 194 | 公众号后端添加MachineTranslationServer.cs 195 | 使用HttpClient访问机器翻译服务。服务通过服务名称调用,如下图的machine-translation 196 | 添加文本翻译请求方法 197 | 198 | 在CustomMessageHandler的OnTextRequest中调用翻译服务 199 | ``` 200 | /// 201 | /// 处理文字请求 202 | /// 203 | /// 204 | public override IResponseMessageBase OnTextRequest(RequestMessageText requestMessage) 205 | { 206 | var defaultResponseMessage = base.CreateResponseMessage(); 207 | var mtServer = new MachineTranslationServe(); 208 | var tranText = mtServer.TextTranslate(requestMessage.Content).ConfigureAwait(false).GetAwaiter().GetResult(); 209 | defaultResponseMessage.Content = tranText; 210 | return defaultResponseMessage; 211 | } 212 | ``` 213 | 214 | 215 | ## 六、任务三:处理公众号语音信息 216 | 智能语音服务 217 | 218 | 智能语音服务(Artificial Audio Intelligence)满足语音识别、语音合成、声纹识别等语音处理需求。智能语音服务拥有强大的垂直领域定制化服务,打造专业高效的语音大脑,为企业提供全方位的智能语音解决方案。 219 | 腾讯语音识别(Automatic Speech Recognition, ASR) 为开发者提供语音转文字服务的最佳体验。一句话识别(SentenceRecognition)可对60秒之内的短音频流进行识别。 220 | 221 | 语音识别 222 | 智能语音服务具有语音转文字,根据关键词列表搜索语音偏移量,情绪识别,静音监测等功能;提供声学和语言模型定制化服务。 223 | 224 | 语音合成 225 | 智能语音服务可以将文本转成自然清晰的语音,支持多种音色选择、语速选择,并支持中文、英文和中英文混读等。 226 | 227 | 语音翻译 API 是基于云的自动翻译服务,开发人员可利用此服务,向其应用程序或服务添加端到端实时语音翻译。 https://cloud.tencent.com/document/api/441/19453 228 | 229 | 语音中英文互译:用户语音转成文本,通过文本翻译发到微信公众号。 230 | 231 | ### 使用TencentCloudSDK编写智能语音服务 232 | 新建asp.net core WebApi项目,添加Docker支持,安装TencentCloudSDK 233 | 234 | 操作与机器翻译服务基本一致。 235 | 将注入的机器翻译Client改成智能语音服务Cleint 236 | 237 | ### 公众号后端请求智能语音服务 238 | 公众号后端添加IntelligentVoiceServer.cs 239 | 使用HttpClient访问智能语音服务。服务通过服务名称调用,如下图的 intelligent-voice 240 | 添加一句话识别请求方法 241 | 242 | 在CustomMessageHandler的OnVoiceRequest中调用一句话识别服务 243 | ``` 244 | /// 处理语音请求 245 | /// 246 | /// 247 | /// 248 | public override IResponseMessageBase OnVoiceRequest(RequestMessageVoice requestMessage) 249 | { 250 | var responseMessage = CreateResponseMessage(); 251 | var path = MediaApi.Get(appId, requestMessage.MediaId, $"{Server.AppDomainAppPath}App_Data/Audio/"); 252 | var outPutPath = $"{path.Substring(0, path.Length - 4)}.mp3"; 253 | var success = FFmpegUtil.Arm2Mp3Async(path, outPutPath).ConfigureAwait(false).GetAwaiter().GetResult(); 254 | if (success) 255 | { 256 | var intelligentVoiceServer = new IntelligentVoiceServer(); 257 | var text = intelligentVoiceServer.Voice2Text(outPutPath).ConfigureAwait(false).GetAwaiter().GetResult(); 258 | responseMessage.Content = text; 259 | File.Delete(path); 260 | File.Delete(outPutPath); 261 | } 262 | else 263 | { 264 | File.Delete(path); 265 | responseMessage.Content = "转换失败"; 266 | } 267 | return responseMessage; 268 | } 269 | ``` 270 | 由于公众号音频文件个是为amr,所以需要使用FFmpeg工具将 amr转码成MP3格式。 271 | 这里使用Xabe.FFmpeg的nuget包,非商业项目可以使用。 272 | 273 | 274 | ##七、任务四:部署到容器服务 275 | 打包容器镜像并推送至腾讯云容器服务,首先在Tencent Hub上建立一个组织和项目仓库。 276 | 277 | 1.登陆腾讯云容器服务 278 | ``` 279 | Windows下使用命令 280 | docker login --username=[username] hub.tencentyun.com 281 | ``` 282 | 输入密码后验证成功则可以推送镜像到腾讯云容器服务 283 | 284 | 2.打包镜像 285 | 编写项目中的DockerFile 286 | 使用docker build -t [name] . 命令打包镜像 287 | 288 | 3.给镜像打标签 289 | 290 | ``` 291 | 使用命令 292 | docker tag [镜像ID] hub.tencentyun.com/[组织名称]/[项目仓库]: [tag] 293 | ``` 294 | 给打包好的镜像打上腾讯云的标签。 295 | 296 | 4.推送镜像至容器服务 297 | ``` 298 | 使用命令 299 | docker push hub.tencentyun.com/[组织名称]/[项目仓库]: [tag] 300 | ``` 301 | 将打好标签的镜像推送至容器服务。 302 | 303 | 5.查看镜像仓库中的镜像 304 | 305 | 登陆腾讯云进入Tencent Hub,选择项目仓库查看镜像 306 | ![镜像仓库](./resource/tencenthub.png) 307 | 308 | 新建集群 309 | 若已有集群可以忽略此步 310 | 1.进入腾讯云容器服务,点击集群,新建。 311 | 312 | 2.根据步骤配置集群。 313 | ![微信公众号集群](./resource/mptke.png) -------------------------------------------------------------------------------- /4 Wechat/resource/APIExplorer3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geffzhang/QcloudNetCore/63708d1415c7093ab30cede0d01cbfe25784b4bb/4 Wechat/resource/APIExplorer3.png -------------------------------------------------------------------------------- /4 Wechat/resource/WeixinInteractionServer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geffzhang/QcloudNetCore/63708d1415c7093ab30cede0d01cbfe25784b4bb/4 Wechat/resource/WeixinInteractionServer.png -------------------------------------------------------------------------------- /4 Wechat/resource/dbcontext.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geffzhang/QcloudNetCore/63708d1415c7093ab30cede0d01cbfe25784b4bb/4 Wechat/resource/dbcontext.png -------------------------------------------------------------------------------- /4 Wechat/resource/labarch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geffzhang/QcloudNetCore/63708d1415c7093ab30cede0d01cbfe25784b4bb/4 Wechat/resource/labarch.png -------------------------------------------------------------------------------- /4 Wechat/resource/mptke.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geffzhang/QcloudNetCore/63708d1415c7093ab30cede0d01cbfe25784b4bb/4 Wechat/resource/mptke.png -------------------------------------------------------------------------------- /4 Wechat/resource/senparcsamplebuilder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geffzhang/QcloudNetCore/63708d1415c7093ab30cede0d01cbfe25784b4bb/4 Wechat/resource/senparcsamplebuilder.png -------------------------------------------------------------------------------- /4 Wechat/resource/senparcsdk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geffzhang/QcloudNetCore/63708d1415c7093ab30cede0d01cbfe25784b4bb/4 Wechat/resource/senparcsdk.png -------------------------------------------------------------------------------- /4 Wechat/resource/tencenthub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geffzhang/QcloudNetCore/63708d1415c7093ab30cede0d01cbfe25784b4bb/4 Wechat/resource/tencenthub.png -------------------------------------------------------------------------------- /4 Wechat/resource/wechatInteraction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geffzhang/QcloudNetCore/63708d1415c7093ab30cede0d01cbfe25784b4bb/4 Wechat/resource/wechatInteraction.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # QcloudNetCore 2 | 腾讯云课程- .NET 微服务实战 — 微信公众号开发 3 | 4 | ## [课程概要](./overview.md) 5 | ## .NET 基础 6 | ### [为什么选择.NET Core](./0 whydotnet/1.whydotnetcore.md) 7 | ### [.NET Core入门](./0 whydotnet/2.dotnetabout.md) 8 | ### [.NET Standard](./0 whydotnet/3.net-standard.md) 9 | ### [腾讯云开发者工具套件(c# SDK)3.0](./0 whydotnet/4.tencentcloudsdk.md) 10 | ## .NET 和 Docker 11 | ### [.NET Core:入门的最简单方法](./1 docker/1.dotnetdockerbasic.md) 12 | ### [.NET 和 Docker 简介](./1 docker/2.netdocker.md) 13 | ### [为 .NET Core 应用程序生成 Docker 映像](./1 docker/3.buildingnetdockerinages.md) 14 | ### [使用 ASP.NET Core 的 Visual Studio Tools for Docker](./1 docker/4.visualstudiotoolsfordocker.md) 15 | 16 | ## 应用容器化 17 | ### [容器与微服务](./2 microservices/1.microserviceandcontainer.md) 18 | ### [微服务容器化](./2 microservices/2.microservicecontainer.md) 19 | ### [服务部署](./2 microservices/3.deployservice.md) 20 | ### [服务发现](./2 microservices/4.servicediscovery.md) 21 | ### [健康检查](./2 microservices/5.servicehealth.md) 22 | ### [更新发布](./2 microservices/6.serviceupdate.md) 23 | ### [服务治理](./2 microservices/7.servicegov.md) 24 | 25 | ## 腾讯容器服务TKE 26 | ### [腾讯云容器服务 (TKE)](./3 tke/0.tkeabout.md) 27 | ### [准备用于腾讯云容器服务 (TKE) 的应用程序](./3 tke/1.tkeprepareapp.md) 28 | ### [部署和使用腾讯云容器仓库](./3 tke/2.tkeprepareccr.md) 29 | ### [部署腾讯容器服务 (TKE) 群集](./3 tke/3.tkedeploycluster.md) 30 | ### [在腾讯云容器服务 (TKE) 中运行应用程序](./3 tke/4.tkedeployapplication.md) 31 | ### [在腾讯云容器服务 (TKE) 中缩放应用程序](./3 tke/5.tkekubernetesscale.md) 32 | ### [在腾讯云容器服务 (TKE) 中更新应用程序](./3 tke/6.tkeappupdate.md) 33 | 34 | ## 实验手册 35 | 36 | ### [微信公众号开发手册](./4 Wechat/lab.md) 37 | 38 | ## [总结](./Summary.md) -------------------------------------------------------------------------------- /Summary.md: -------------------------------------------------------------------------------- 1 | ## 总结 2 | 3 | 感谢你看完了这一系列围绕几个开源项目 tencentcloud-sdk-dotnet、WeiXinMPSDK结合腾讯云开发一个中英文翻译 微信公众号 的应用,使用微服务的架构进行开发,充分利用腾讯云的容器服务和.NET Core让我们开发微服务变得很简单 !如果这个系列视频有点(或者没有)用处,我很乐于倾听您的想法,请您通过微信公众号dotnet跨平台给我留言。 4 | 5 | 如果要深入学习,以下这些方式可供参考: 6 | 7 | + ASP.NET Core 文档 官方的 ASP.NET Core 文档位于 https://docs.asp.net ,其中包含了一些有关这些主题的,深入详尽的教程。本人强烈推荐。 8 | + 如果你更喜欢通过视频学习,在http://video.jessetalk.cn/ 上就有很多非常精彩。 涵盖了ASP.NET ,微服务以及kubernetes 的视频教程 9 | + MVP苏震巍主讲的:微信公众号SDK Senparc.Weixin.MP 开发视频 https://study.163.com/course/introduction.htm?courseId=1004873017 10 | + 我的网站 https://www.csharpkit.com 上有大量整理自我的公众号”dotnet跨平台”的文章的整理。每天我都会通过公众号”dotnet跨平台” 推送最新的文章,欢迎你关注 11 | -------------------------------------------------------------------------------- /overview.md: -------------------------------------------------------------------------------- 1 | 本课程《.NET 微服务实战 — 微信公众号开发》主要面对的是有C# 基础的.NET 开发人员, 通过本课程可以学习到如何借助腾讯云服务使用.NET Core开发一个微服务应用。 2 | 3 | 从未来的发展方向来看,容器引擎将会越来越成为主流,哪怕不是弹性架构,托管到应用容器也将是一种趋势——因为更低的开发运维和托管成本以及对服务器的资源的优化配置。 4 | 5 | 云计算的一大特性就是将服务构建在云上,供多种设备同时无缝调用。但事实上,云服务在发展的过程中还没能实现共融共通的理想——比如,各家的云服务是相对割裂的,开发者基于阿里云服务构建的软件拿到腾讯云也许就不能用了,阿里云的应用迁移到腾讯云可能就存在问题了;在任务执行层面,为防止互相干扰,云服务厂商在同一台服务器上执行多个任务时也会将它们隔离进行。很明显,这样的实际情况和云服务的初始理念相去甚远。而利用容器技术,软件可以快速在各类云服务和基础设施上转换。而且,当割裂问题被解决之后,软件也有望在瞬间获取大量的计算能力。 6 | 7 | 而Docker,就是容器引擎中的佼佼者,并且已经得到了广泛的实践和应用。有了Docker之后,软件的开发工作将会变得更加容易,但是在国内,开发者普遍迁移到云端基本上也都是只用到了虚拟机等基础设施。 8 | 9 | 通过本课程带领大家对.NET Core结合容器的开发微服务有全新的认识: 10 | 11 | + 使用Docker很简单,小公司也可以用; 12 | + 带你体验云端容器服务,能够掌握容器服务和以及对容器服务可控; 13 | + 加深对容器服务的认知,充分认识到它的好处; 14 | + 通过容器化方式更好对现有系统的架构进行微服务化改造; 15 | + 体验到Docker 可以给现有的开发带来什么改变; 16 | 17 | 本课程从微信公众号这一个大家非常熟悉的主题,通过动手实验的方式进行学习,采用微服务方式开发 微信公众号 的练习 。这是个很棒的体验微服务开发练习,麻雀小,五脏俱全,它将涉及 .NET Core的各个组件,而且涵盖了很多概念,它们可以直接应用于规模更大的应用程序。同时,你将构建一个微信公众号的后台消息处理,允许用户通过微信公众号进行交互,语音发送到公众号可以,翻译语音。腾讯云AI服务 帮助用户实现直接使用语音与虚拟机器人对话,大大提升了用户体验。通过腾讯云的容器服务来部署我们的应用,让我们开发部署我们的应用更加得心应手。 18 | 19 | 具体来说,你将创建的是: 20 | + 一个 web 应用程序,我们使用ASP.NET Core来开发微信公众号。 21 | + 一个用于存储公众号交互信息的数据库,使用 MySQL数据库引擎和一个被称为 Entity Framework Core 的ORM 进行创建。用户交互的所有信息记录到数据库。 22 | + 让用户通过她们的微信和微信公众号进行交互,主要完成下列功能: 23 | 机器翻译:文本中英文互译:用户发送翻译消息,通过腾讯云的翻译API进行翻译 。 24 | 智能语音服务:语音中英文互译:用户语音转成文本,,通过文本转语音发到微信公众号。 25 | 26 | 我们采用微服务架构进行开发,部署到腾讯云的容器服务中运行。这个课程主要演示.NET Core应用的微服务。 27 | 28 | 本课程涉及到的主要开源项目: 29 | + .NET Core :https://github.com/dotnet 30 | + tencentcloud-sdk-dotnet :https://github.com/TencentCloud/tencentcloud-sdk-dotnet 31 | + WeiXinMPSDK: https://github.com/JeffreySu/WeiXinMPSDK 32 | --------------------------------------------------------------------------------