.NET Core 编写 Azure Function 并连接 GitHub 持续部署


点击上方蓝字关注“汪宇杰博客”

640?wx_fmt=png

导语

Azure Function 是一个事件驱动型无服务器计算平台,可以解决复杂的业务流程问题,更加高效地进行开发。在本地构建和调试,而无需额外的设置,在云中大规模部署和操作,并使用触发器和绑定集成服务。对我来说,Function 能帮助我快速开发一些简单的API,我只需要编写业务代码,而无需构建完整的应用框架等基础代码。本文将会讲解如何使用.NET Core,C#语言,开发一个简单的 http 触发的 Function 应用,并完成 GitHub 的持续部署配置。

需求

我需要一个 API,用于返回客户端 IP 以及 User-Agent 字符串。但是我不想为了做这么一件简单的事,而创建一个完整的 ASP.NET Core Web API 项目。我只关心我要进行的业务逻辑,不想编写和管理配置文件、依赖注入、Controller、验证等基础代码。

准备开发环境

我们需要以下开发条件:

  • 卖血买到的 Azure 订阅

  • 丐版 Visual Studio 2019 Community 或豪版 Enterprise

  • Azure development workload

  • 免费开源的 .NET Core 2.1 / 2.2 SDK

640?wx_fmt=png

创建 Function 应用

在 VS2019 里,选择 Azure 分类下的 Azure Function,新建一个工程。如:Edi.AzureFunctions

640?wx_fmt=png

默认的.NET Core版本为2.1,我们可以手工改成2.2。编辑 Edi.AzureFunctions.csproj文件,将 TargetFramework 改成 netcoreapp2.2

同样,也可以将 Microsoft.NET.Sdk.Functions 升级到最新版。

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>

    <TargetFramework>netcoreapp2.2</TargetFramework>

    <AzureFunctionsVersion>v2</AzureFunctionsVersion>

  </PropertyGroup>

  <ItemGroup>

    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="1.0.29" />

  </ItemGroup>

  <ItemGroup>

    <None Update="host.json">

      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>

    </None>

    <None Update="local.settings.json">

      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>

      <CopyToPublishDirectory>Never</CopyToPublishDirectory>

    </None>

  </ItemGroup>

</Project>

将默认类改名为 ClientInfoFuncion,完成我们的业务代码:取客户端IP及User-Agent

public static class ClientInfoFuncion

{

[FunctionName("IP")]

    public static IActionResult GetClientIp(

        [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,

        ILogger log)

    {

        log.LogInformation("Requesting client IP.");

        var ip = req.HttpContext.Connection.RemoteIpAddress.ToString();

        return ip != null

            ? (ActionResult)new OkObjectResult($"{ip}")

            : new BadRequestObjectResult("ip is null");

    }


[FunctionName("UserAgent")]

    public static IActionResult GetClientUserAgent(

        [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,

        ILogger log)

    {

        log.LogInformation("Requesting client User-Agent.");

        var ua = req.Headers["User-Agent"].ToString();

        return ua != null

            ? (ActionResult)new OkObjectResult($"{ua}")

            : new BadRequestObjectResult("user-agent is null");

    }

}

可以发现,Azure Function 的代码非常类似 ASP.NET Core MVC / Web API,返回类型正是 Microsoft.AspNetCore.Mvc.IActionResult,然而我们无需关心如何构建一个完整的ASP.NET Core Web API工程,也无需知道 Controller 的存在,只要编写业务逻辑即可。

FunctionName 可以理解为 ASP.NET Core 中的 Route,也就是最终用户调用 API 的 endpoint 地址。

[FunctionName("IP")] 也就最终对应:

https://你的function地址/api/IP

HttpTrigger 是 Azure Function 的一种触发器,表示通过HTTP请求,触发你写的业务逻辑。此处我允许匿名访问,并限定为 get / post 两种HTTP Verb。

ILogger 接口中的日志最终会输出到 Azure Function 的后台,用于调试。

按 F5 启动本地调试。会看见一个很炫酷的命令行窗口,里面启动的是本地的 Azure Function 模拟器。

640?wx_fmt=png

模拟器准备完成后,控制台会输出两个绿色的URL地址,用于本地测试。

640?wx_fmt=png

复制URL到浏览器,完成测试。

640?wx_fmt=png

从 VS 创建和部署 Azure Function

 Edi.AzureFunctions 点击右键,选择 Publish

点击 Start,选择 Azure Functions Consumption Plan,然后选择 Create New。如果你已经在 Azure 上创建过一个 Function 应用,则可选择 Select Existing。关于如何从 Azure portal 创建一个 Function 应用,在稍后讨论。

640?wx_fmt=png

根据需要填写参数

640?wx_fmt=png

最后点击 Publish 完成发布

640?wx_fmt=png

如果发布成功,你可以在 Azure portal 里找到这个 Function 应用,并能看见其 URL

640?wx_fmt=png

尝试在浏览器中访问两个API,分别是:

https://你的function名称.azurewebsites.net/api/ip

https://你的function名称.azurewebsites.net/api/useragent

640?wx_fmt=png

你也可以在 Functions 下进入具体的 HttpTrigger,并在 Azure Portal 里完成测试。这会输出更详细的日志信息。

640?wx_fmt=png

在 Azure Portal 创建 Function

刚才的例子里,我们通过 VS2019 一条龙开发和部署了一个Azure Function,而在实际应用中,通常不会这样操作。因为 Azure Portal 给我们提供了更细致的参数选项,以便根据自己的需求调整。要从 Azure Portal 创建一个空的Function 应用也十分简单,点击 Function App / Add 

640?wx_fmt=png

输入 App name,它将作为该function默认域名使用。

其他参数根据自己需要设置。我建议大家重用既有的 App Service Plan,这样可以省钱。

Runtime Stack 选择 .NET Core

640?wx_fmt=png

从 GitHub 仓库持续部署

我在之前的博客文章中介绍过了 Azure DevOps 的CI/CD流程,非常强大。但是本文给大家介绍一个更简单,但是略为基础的发布方式。

实际上 Function 的本质是对 App Service 的进一步包装,所以包括部署在内的大部分 App Service 的功能这里也能用。在 Platform features 里进入 Deployment Center

640?wx_fmt=png

代码来源选择 GitHub

640?wx_fmt=png

选择 Kudu 编译

640?wx_fmt=png

我已将本文的代码上传到 https://github.com/EdiWang/Edi.AzureFunctions

在 Azure 里选择对应的仓库以及分支,并完成配置。

640?wx_fmt=png

完成配置后,会立即触发一次部署,可以看到详细日志。

640?wx_fmt=png

部署成功后,刷新左边的 Functions 就能看见我们的两个 API 了

640?wx_fmt=png

如果你是个土豪,有自己的域名和证书,也可以绑定自定义域名。就像我这样:

640?wx_fmt=png640?wx_fmt=png

最后,就能优雅的通过自己的域名访问 Function 了!

640?wx_fmt=png640?wx_fmt=gif

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

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

相关文章

Codeforces Round #766 (Div. 2) D. Not Adding 数学gcd

传送门 文章目录目录题意&#xff1a;思路&#xff1a;目录 题意&#xff1a; 给你一个长度为nnn的数组&#xff0c;你每次可以选择其中的两个数&#xff0c;如果他们的gcdgcdgcd在数组中没有出现那么就可以加在数组后面构成一个新的数组&#xff0c;问数组最长是多少。 2≤n…

「数据ETL」从数据民工到数据白领蜕变之旅(五)-使用dotNET脚本实现SSIS无限扩展...

在前面一文中&#xff0c;正式引出了SSIS专业数据ETL工具&#xff0c;笔者仅能作引路作用&#xff0c;未能使用文章的方式给大家写出更多的入门级的文章&#xff0c;希望读者们可以自行根据分享的学习资源自行完成入门及进阶的学习。同时也想给大家分享到SSIS的能力边界性&…

P3067 [USACO12OPEN]Balanced Cow Subsets G 折半搜索

传送门 文章目录目录题意&#xff1a;思路&#xff1a;目录 题意&#xff1a; 给你nnn个数&#xff0c;从中任意选出一组数&#xff0c;使这些数能分成和相等的两组&#xff0c;问有多少种选数方案。 2≤n≤20,1≤ai≤1e92\le n\le 20,1\le a_i\le 1e92≤n≤20,1≤ai​≤1e9 …

poj 2191 Mersenne Composite Numbers

思路 用pollard_rho miller_rabin来拆分数字&#xff0c;如果得到的质因子大于等于2的话就按照格式输出&#xff0c;否则就不是我们想要的梅森素数。 代码 /*Author : lifehappy */ // #pragma GCC optimize(2) // #pragma GCC optimize(3) // #include <bits/stdc.h>…

数据结构为什么那么难?

来源 | 异步 | 文末赠书2017年8月&#xff0c;本着让更多的人轻松学习算法的初心&#xff0c;我写作了第一本书《趣学算法》&#xff0c;该书在出版后受到广大读者一致好评&#xff0c;在一年内重印了10次&#xff0c;并输出了繁体版的版权。一位读者对我说&#xff0c;读这本书…

书籍推荐:《C#7.0本质论》

在dotNet平台中有多种开发语言可以使用&#xff0c;C#无疑是其中应用得最为广泛的。学习一门编程语言最好的方式就是找一本好书系统地学习&#xff0c;我读过的关于C#的书籍中&#xff0c;我认为下面三本最为经典&#xff1a;《C#本质论》&#xff1a;入门类&#xff0c;目前最…

乌龟棋(dp)

乌龟棋 思路 最优值问题&#xff0c;显然可以通过dpdpdp解决&#xff0c;我们定义dp[i][j][k][l]dp[i][j][k][l]dp[i][j][k][l]表示到达1i∗2∗j3∗k4∗l1 i * 2 * j 3 * k 4 * l1i∗2∗j3∗k4∗l这个点之前已经走过的价值最大的值(i,j,k,li, j, k, li,j,k,l分别是走一步&…

CF 1631 D. Range and Partition 尺取 + 前缀和

传送门 文章目录目录&#xff1a;题意&#xff1a;思路&#xff1a;目录&#xff1a; 题意&#xff1a; 给你一个长度为nnn的数组aaa以及kkk&#xff0c;让你选择一个值域[x,y][x,y][x,y]&#xff0c;满足能将该数组分成连续的kkk段并且每段中值域在[x,y][x,y][x,y]内的个数严…

gRPC的简单使用

前言八月初的时候&#xff0c;在公司内部做了一个主题为《gRPC的简单使用》的分享&#xff0c;其实就是和小伙伴们扯扯淡&#xff0c;现在抽空回忆一下&#xff0c;也算是一个小小的总结吧。现在市面上耳熟能详的RPC框架也很多&#xff0c;下面列举几个遇到比较多的。谷歌的gRP…

P6282 [USACO20OPEN] Cereal S 思维

传送门 文章目录目录&#xff1a;题意&#xff1a;思路&#xff1a;目录&#xff1a; 题意&#xff1a; 你有nnn头奶牛&#xff0c;mmm中不同种类的麦片&#xff0c;每个麦片只有一箱&#xff0c;给你每个奶牛第一和第二喜欢的麦片&#xff0c;奶牛会先看第一喜欢的是否有&am…

HDU 4417 Super Mario(莫队 + 树状数组 + 离散化)

Super Mario 思路 区间查找问题&#xff0c;容易想到离线莫队&#xff0c;确实这题就是莫队&#xff0c;接下来我们考虑如何维护区间高度值问题。 既然是离线嘛&#xff0c;我们容易想到离散化和他挂钩&#xff0c;想想这题是否需要离散化&#xff0c;高度的最大值是1000000…

生命周期结束,Spring Boot 1.x退役

一年前 Spring 官方宣布 Spring Boot 1.x 生命周期将于今年 8 月 1 日结束&#xff0c;如今时间已到&#xff0c;在发布 Spring Boot 1.5.22 的同时&#xff0c;Spring 确认将不再为 1.x 系列发布维护版本。官方希望用户尽快迁移到 Spring Boot 2.x 上&#xff0c;为此还制作了…

P3085 [USACO13OPEN]Yin and Yang G 点分治

文章目录题意&#xff1a;思路&#xff1a;传送门 题意&#xff1a; 给你一颗nnn个点的树&#xff0c;每条边为黑色或者白色&#xff0c;问满足以下条件的路径条数&#xff1a;路径上存在一个不是端点的点&#xff0c;使得两端点到该点的两条路径上两种颜色的边数相等。 1≤n…

G. Xor-MST(异或最小生成树)

G. Xor-MST 思路 异或最小生成树&#xff0c;这里采用了一种分治的方法来贪心求解最值&#xff1a; 首先我们对所有的点权值从小到大排个序&#xff0c;从高位开始在中间找到一个这个位置上的0&#xff0c;10&#xff0c;10&#xff0c;1分界点分成两个集合&#xff0c;然后…

CF 1638 E. Colorful Operations set 区间平推

文章目录题意&#xff1a;思路&#xff1a;传送门 题意&#xff1a; 给你一个数组aaa&#xff0c;初始价值全为000&#xff0c;颜色全为111&#xff0c;让后让你实现以下三个操作&#xff1a; 将[l,r][l,r][l,r]区间内的颜色都染成ccc。将所有颜色为ccc的位置价值都加上xxx。…

B Graph(异或最小生成树)

Graph 思路 图是联通的&#xff0c;并且加边的时候要保证环一定是异或值为0&#xff0c;所以我们可以保证从一个点到另一个点的路径异或值是不变的&#xff0c;这个时候就简单了&#xff0c;不就是一个异或最小生成树了嘛。 我们只要预处理一下&#xff0c;任选一个点作为根…

Apollo 配置中心:分布式部署

Apollo&#xff08;阿波罗&#xff09;是携程框架部门研发的分布式配置中心&#xff0c;能够集中化管理应用不同环境、不同集群的配置&#xff0c;配置修改后能够实时推送到应用端&#xff0c;并且具备规范的权限、流程治理等特性&#xff0c;适用于微服务配置管理场景。服务端…

CF 1637 D. Yet Another Minimization Problem dp + 思维

文章目录题意&#xff1a;思路&#xff1a;传送门 题意&#xff1a; 给你两个长度为nnn的数组a,ba,ba,b&#xff0c;每次交换可以选择一个iii&#xff0c;交换ai,bia_i,b_iai​,bi​&#xff0c;最小化∑i1n∑ji1n(aiaj)2∑i1n∑ji1n(bibj)2\sum_{i1}^n \sum_{ji1}^n(a_ia_j)…

各种逆元推导

逆元 求解一&#xff08;费马小定理&#xff09; ppp是一个质数&#xff0c;并且a%p̸0a \% p \not 0a%p​0&#xff0c;则有ap−1≡1(modp)a ^ {p - 1} \equiv 1 \pmod pap−1≡1(modp)&#xff0c;ap−2≡a−1a ^ {p - 2} \equiv a ^ {-1}ap−2≡a−1&#xff0c;即可得到…

使用Redis实现最近N条数据的决策

前言很多时候&#xff0c;我们会根据用户最近一段时间的行为&#xff0c;做出一些相应的策略&#xff0c;从而改变系统的运动轨迹。举个简单的例子来说明一下&#xff1a;假设A公司现在有两个合作伙伴(B和C)&#xff0c;B和C都是提供天气数据的&#xff0c;现在A公司做了一个聚…