玩转AIGC训练营:课时4:函数的开发与配置
函数的开发与配置
内容介绍
一、课程概述
二、基本概念
三、开发流程
四、操作演示
五、课程总结
一、课程概述
本节课介绍函数计算的开发与配置,通过今天的学习,希望可以基于函数计算开发自己的应用。
本节课主要分为三个部分,基本概念中介绍了函数计算最核心的概念包括服务、函数、触发器,版本联名以及相关的配置。开发流程介绍了基于函数计算开发的完整开发部署的流程,操作演示会带着大家在控制台进行操作,搭建一个基于函数计算的应用,并且进行更新和迭代。
二、基本概念
1、服务
(1)基本介绍
服务是函数计算资源管理的单位,同一个服务下有很多函数,这些函数共享服务的网络配置、权限配置、存储配置、日志配置。服务可以对应成一个微服务的概念,这个微服务下面由很多函数共同组成,这些函数具有相同的访问权限,网络配置,日志也会进入到相同的 Log Store 中去,但是这些函数本身的配置可以各不相同。
比如同一个服务下面有的函数内存是3G,有的函数内存是512M,有的函数用Python写。应用比较复杂,同一个应用可以对应多个服务,这是没有强制的绑定关系的。
(2)服务配置
接下来就介绍服务的几个核心配置。
①日志配置 Log Config
设置日志服务的日志项目和日志仓库,用于存储和分析函数运行的日志。
开发者的代码在函数计算平台运行,如何查看函数运行产生的日志。比如在 ECS 上或者是在传统的服务器上开发日志都会打到统一的文件里面,通过日志收集工具收集到用户自己的 elastic search中,并且通过这种可视化工具来查看日志或者指标,但是函数计算里面运行代码的机器是由函数计算动态分配的,开发者无法自己收集日志了,函数计算需要帮助开发者投递日志,日志配置就是起到这个作用。
设置日志服务的 project,函数计算会将函数运行中产生的日志投递到开发者的 Log Store 中。但是为了成功投递日志,单单配置 Log Store 还不够,函数计算是没有权限向开发者的 Log Store 里面投递日志的,还需要开发者的授予函数计算向指定的 Log Store 写数据的权限。有了这个权限以后,函数计算就可以名正言顺的向开发者投递日志的。
在这里总结一下日志配置,就是为了让用户有地方配置 Log Store 和 project,允许函数计算向其中去投递函数日志,然后用户可以在 Log Store 中进行进一步的分析。
②文件存储配置 NASConfig
配置 NAS,让函数访问 NAS 文件系统时如同访问本地文件系统一样。
函数计算的每个函数都是独立的,都在不同的执行环境里运行。可以把执行环境理解成是一个容器。如果用户有一些公共文件,希望通过函数共享的话,在传统 Solo 化的开发方式中就是将公共文件放到磁盘里面,各个函数都在磁盘里面的同一个位置读,但是函数计算的机器是函数计算动态分配的,同一个函数的不同实例可能不在同一个主机上面。开发者也没有办法相信这些文件存入磁盘,因为这个机器也是函数计算的。
为解决这个问题函数计算推出了挂载 master 的功能,在服务中挂载了 master 后,函数就可以像访问本地文件系统一样访问 master 上的文件。然后用户是可以在 master 控制台上去对文件进行操作。
③网络配置
网络配置顾名思义就是设置网络的访问能力,函数的网络访问能力主要有两种:一个是函数是否可以访问,有的不需要访问公网,以免产生一些预期之外的公网流量费用。函数计算设置了一个布尔型的开关,默认是开启的,如果不需要访问公网就可以关闭开关。
另一个是函数是否可以访问指定VPC,VPC 是专有网络。专有网络中的数据比较机密是不能通过公共网络访问的,如果需要函数访问 VPC 的资源,比如希望函数来访问 VPC 中的 RDS,那就需要授予函数计算访问指定 VPC 的能力。原理是用户授权赋予弹性网卡 INI访问VPC,函数计算将 INI 插入到 XC 中执行用户函数的机器上,从而就可以使函数访问 VPC 中的资源。
④权限
函数计算是云原生的架构,和云上很多服务都会产生交互,阿里云有非常严格的权限限制,函数计算是没有能力访问开发者的其他云资源的。当开发者需要函数计算访问其他云服务的时候,就像显示的授予函数计算权限。权限主要有两个应用场景,一个是授予函数计算访问其他服务的权限,比如刚才提到的授权函数计算访问开发者的日志服务,授权函数创建 INI;另一个是授权函数可以访问开发者的云资源,第一个是授予函数计算,第二个是授权函数。
举个例子是函数代码中需要访问 OSS 获取对象,当然可以把 AK 写在函数代码里面或者是通过环境变量传入 AK。因为 AK 非常机密所以并不想暴露,开发者可以配置服务中的 role,role 具有访问 OSS 的权限。在函数执行的过程当中,函数计算是会生成一个临时 AK,也可以一起将这个 AK 存储到函数的上下文 contest中,这就是函数代码执行当中的一个输入参数叫 contest,开发者在代码中就可以来使用contest 键和credential 键还有 token,然后来建立一个 OSS Client,这个client就可以访问 OSS 中的资源了。这一页主要是介绍了服务的主要配置,包括日志配置、权限,NAS 还有网络配置。这些配置是服务当中所有函数共享的。
2、函数
接下来看函数和函数配置。在函数计算中函数是核心概念,函数是管理和运行的基本单元,函数通常由一系列的配置和一个可运行的代码包组成。函数的配展如图所示:
Runtime 是函数运行时的环境类型,函数计算目前支持Python,Java,PHP 等开发环境,同时也支持用户来定义这个运行环境。空Code 是函数代码包,函数计算的后端是指认代码包的,各个开发工具会自动帮助打包,比如可以在控制台上编写代码,控制台会将代码自动打包,并且创建函数或者更新函数。也可以在本地编写函数或者调试函数,通过部署工具部署函数计算。
代码包中主要是有代码以及代码所需要的第三方依赖,比如代码当中用到了一些第三方的库,也需要将第三方的库和代码一同打到这个代码包里面。Handler 是入口函数,在代码中写了非常多的函数。虽然有十个函数,但是入口就是这一个,handler就是告诉函数计算入口函数的位置;Timeout是函数的超时时间,如果函数计算执行超过了这个时间函数就会被强制停止执行;
Memory Size是为函数分配的执行环境的内存,目前的取值范围是128M到3G,如果函数耗用的内存超过了分配的内存就会 OM 掉。接下来是 Initializer 叫做初始化函数,之前介绍函数计算执行环境的时候有讲到,函数计算会为函数分配执行环境,第一次分配的时候会有冷启动,当前这个请求执行完成后,函数计算不会立即释放,如果在一段时间内有新的请求来的时候,可以复用这个执行环境。Initializer 的逻辑就是在第一次分配环境中来执行的,并且保证同一个执行环境执行且执行一次。
第一次的时候函数计算会为这些请求来分配实例,然后这实例会立即被释放掉,第二个请求和第三个解决都可以复用这个实例,Initializer 就是第一次创建这个实例之后,立刻就执行了证明和逻辑,去找初始化函数。
其实这个特性同一执行环境中执行自身的特性,就可以将一些建立链接,加载音乐这些耗时的操作放到 Initializer 里面来执行。
3、触发器
上节课是介绍了函数计算支持的丰富的世界元类型,在事件驱动的计算模型中,事件源是事件的生产者,函数是事件的处理者,触发器提供了一种集中统一的方式来管理不同的事件源。当事件发生时,如果满足触发器定义的规则,事件源会自动触发,自动调用这个触发器所对应的函数。典型的使用场景包括对上传的 OSS 当中的对象进行处理,比如图像处理,音视频转码,OSS 的包解压,然后也包括对 SLS 中的日志进行清洗与处理,转存等等。
4、版本
前面介绍了服务,函数和触发器,开发者就可以基于函数计算把应用搭建起来,但是又有了新的问题,开发者有了新需求,需要更新代码。如果要保证线上应用不受影响,在写更新代码的时候,更新的是线上应用的版本。为了解决这个问题,函数计算就引入了版本和别名,别名是版本相当于服务的快照,包括服务的配置,服务内所有的函数的代码及函数的配置。
在开发和测试完成后就可以发布一个版本单调递增,版本发布后已发布的版本不能更改,可以继续在 latest 版本上开发测试,不会影响已发布的版本。调用函数的时候,只需要指定版本就可以调用指定函数了。版本名称是函数计算指定的,而且是单调递增的,每次发布一个版本都会有一个新的版本名称,每次发布版本之后,要在客户端指定对应哪个版本。
就客户端是否还需要不断的来更改代码来指向最新的版本这个问题,引入了别名的概念,别名就是指向特定服务版本的指针,它本身下面是没有任何资源的,它是一个指针。
客户端只需要指定别名就可以保证最新的代码或者回归到某一个版本的代码,别名只有指挥发布的功能,10%的流量指向最新的版本,90%的流量指向老版本,这是可以的。只需要将别名指向以前的版本就可以迅速完成回滚。版本和别名解决了,函数不断更新迭代的问题让函数在开发的同时不会影响线上正在应用的服务。
三、开发流程
这是一个完整的开发流程,如图所示,开发者需要先创建服务,设置日志、权限这些配置,然后创建函数。当前版本是 Latest 版本,在 Latest 版本下编写代码开发函数,测试通过后可以发布版本。
第一次发布的版本是版本一,创建别名指向版本一就可以对外提供服务了。客户端调用函数的日志会记录在开发者配置的Log Store 里,函数计算提供完备的监控图表,应用上线后发布者可以通过监控图表和日志来查看应用的健康状况。
开发者有新的需求的时候,可以继续在 Latest 版本来更新代码开发函数,测试通过后就可以发布版本。这个时候线上的版本是刚才的版本编码,测试的版本 Latest 版本就是当前版本,当前版本是通过后就发布一个新的版本即版本二。
如果有现场业务进行灰度发布,先切换线上别名 10%的流量到版本二,接下来的请求10%会落到新的版本上,90%会落到老的版本上,这样就可以实现灰度发布,观察一段时间以后没有问题就可以切换百分之百的流量到版本二。
四、操作演示
最后通过一个事例来为大家演示应用完整的开发流程。
打开函数极端的控制台,然后创建一个服务开始,在这里新建服务 Demo Service。这里有一个绑定日志,指的就是正常情况下可以配置自己的 Log Project 和 Log store,但是往往第一次的时候不知道怎么配置,所以函数计算这里默认创建了一个 Project,然后创建一个 Log Store,这个服务下面的所有日志都会打到这个 project 中,选择绑定日志,就是函数计算自动的帮助创建一个 project,并且将 project 设置为service对应下的 Loft Fik。
在创建这个 Service 的时候,它就只指定了 Loft Fik 的,可以在这其中对它进行更多的配置,可以点击修改。
这就是函数计算控制台默认帮助创建的,这个默认配置是允许访问公网,然后是不允许访问 VPC。如果是访问 VPC 的话就把允许访问 VPC 资源键打开,选择一下要访问的 VPC 的信息。
创建好服务之后继续来创建一个函数,选择这个服务,再点新建函数,这里有三个事件函数,HTTP 函数和函数模板,HTTP 函数是函数的入参就是 HTTP request 的返回值,APP的response可以直接做应用的 solo,事件函数是函数的入参是用户可以指定的一个入参,它不是request,不是指定什么就是什么,返回值也是指定什么就是什么,就是像平时写的函数一样。模板是提供的一些比较常用的模板,以 hello word 函数为例,也是可以切换到其他服务的。
函数名称设置成 hello word,环境也是知识的运行环境,函数入口就是函数计算从哪里开始执行这一代码呢?函数的执行内存超时时间,单实例并发度发布是这样。
函数计算是在实例里面执行,这个实例默认情况下是同时只能执行一个请求的。如果有更多请求的话则会调度更多的实例来进行更多的请求,但是有的时候是 L密集型这些场景一个实例执行一个请求就会浪费,所以用户可以选择一个实例,同时可以并发多少请求是可指定的。
函数创建完成后会有一个默认的代码,左边是文件数,右边是代码其实就是一个Hello word。Callback 是在 js 里面,主动掉了 callback 之后函数计算就认为这个函数已经执行完成了,就可以将这个实例来进行冻结,等待接受下一次请求。
这就可以看到当前的结果以及一些日志,也可以在刚才配置的 Log Store 中。简单查询就是 request ID,可以把它的日志展示出来。高级查询就是把查询的页面展示出来,可以查到这个 Log Store 下所有的日志。
现在认为假如代码就在 Latest 当前版本上面已经开发完成了,就可以上线了,第一次上线的就是 hello world 这么一个应用,上线要发布一个版本,在其下创建一个别名,版本是服务级别的,发布了这个版本之后,这个服务下面所有的函数都会跟着发一个版本。要发布一个版本 hello word First Version。这个版本的ID是版本1,它的描述中刚才写的,对此可以先来试一下是否可以触发指定版本的函数,再把函数选择版本1。在发布的版本之后,代码是不能编辑的,只有 Latest版本可以编写。这个代码是可以被执行的。然后发布就行了。
接下来创建一个别名,指向刚才发布的这个版本,新建编名线上版本的主版本和灰度版本,主版本就是百分百流量都在这里,灰度版本就是切多少流量到其他版本上,所以就只有主版本,百分之百的流量都到版本上进行确定。
接下来就可以通过别人来访问用户,可以通过别人来访问开发的应用了。然后就需要开发,就是产品经理有了新的需求要开发迭代,就在 Latest 版本上面开发。最新的版本都要改成new world,就应该换一个版本2。这里不需要新建一个别名了,只要将刚才的别名指向版本2就可以。
版本全部进行比较危险,所以把新版本灰度50%的流量,其实只有10%就可以只是怕演示的过程中不容易将流量打到新的版本上,所以是一个比较明显的50%。现在的请求应该是有一半的概率触发版本1,一半的概率来执行版本2的,就是一半的概率是输出hello word,一半的概率输出 new word。
选择别名之后是看不到代码的,别名下是没有任何资源的,它只是一个指针但是可以来执行它。然后指向了版本二,执行了版本二的代码,大概是一个50%的比例,所以在这里搭建了一个简单的应用,就是hello word 的应用,并且模拟了这个应用的更新迭代以及新版本的发布和上线,在有新的版本发布的时候只需要在函数计算这里发布版本,并且将别名指向最新的版本,就可以完成一次应用的升级了。
代码如下:
'use strict';
/*
To
enable the initializer feature
(https://help.aliyun.com/document_detail/156876.html) please implement the initializer function as below: exports.initializer=(context,callback)=>{
console.log('initializing');
callback(null,'');};*/
exports.handler=(event,context,callback)=> {
console.log('hello world');
callback(null, "hello world');
}
五、课程总结
今天介绍了函数计算的基本配置,包括服务和服务配置,函数和函数配置,触发器,版本和版本配置还有别名,并且带领大家一同搭建了一个简易的函数计算应用,课程进行到这里。