函数计算支持HTTP触发器,配置HTTP触发器的函数可以通过gRPC请求被触发执行。此时函数可以看做一个gRPC Server,处理gRPC请求并将处理结果返回给调用端。本文介绍如何在函数计算控制台配置HTTP触发器并使用gRPC请求触发函数。
使用说明
调用方式
域名:支持使用子域名
fcapp.run
或自定义域名调用gRPC函数,不支持使用旧域名fc.aliyuncs.com
调用gRPC函数。说明如果需要使用自定义域名,自定义域名需要配置请求路径与函数的映射关系。建议您将请求的路径配置为
/*
,可以让所有gRPC请求都转发到对应的gRPC函数中,gRPC函数会将请求路由到客户端定义的gRPC方法。端口:gRPC请求端口为
8089
。
传输安全性
为保证gRPC请求的安全性,函数计算线上环境仅支持使用TLS协议的客户端。否则,请求会报错
rpc error: code = Unavailable desc = connection closed before server preface received
。自定义域名支持使用自定义HTTPS证书,gRPC服务端不需要定义TLS证书验证,函数计算网关层会进行TLS验证。
请求超时控制
gRPC请求的最长超时时间不得超过函数的执行超时时间。执行超时时间默认为60秒,最长为86400秒。
请求并发度控制
gRPC请求受函数计算并发度的控制。一个gRPC请求被视为占用一个并发度。gRPC的协议基于HTTP/2,在函数计算中,对于一个函数实例而言,分配到这个函数实例的gRPC请求会复用同一条HTTP/2连接,则这条HTTP/2连接上的并发流就等于实例的并发度。您可以设置函数的单实例并发度来控制一个实例上的并发流数量。具体操作,请参见设置实例并发度。
负载均衡
函数计算支持将gRPC请求分发到不同的实例上,自动为gRPC请求做负载均衡。
计费方式
gRPC有以下四种请求类型:
普通gRPC请求
客户端流式请求
服务端流式请求
双向流式请求
不同请求类型对应的计费方式不同,具体如下:
普通gRPC请求:计费方式与使用HTTP的计费方式完全一致。
对于并发度设置为1的函数,计费时间从gRPC连接建立开始到gRPC连接断开结束。
对于并发度大于1的函数,实例的计费时间从收到第一个gRPC连接建立开始,到最后一个gRPC连接断开结束。一个实例中多个连接同时存在期间,不会被重复计费。
如下图所示,一个函数的并发度设置为2,第一个请求到达的时间为T1,结束时间为T3,第二个请求到达时间为T2,结束时间为T4,计费时间为T4-T1,其中T2到T3这段时间只会被计费一次,不会被重复计费。
客户端流式、服务端流式和双向流式请求:实例的计费从第一个gRPC连接开始,到最后一个gRPC连接断开结束。
准备工作
准备gRPC函数代码
您可以自己编写代码,也可以在安装并配置Serverless Devs工具后执行s init fc-custom-golang-grpc
,下载一套完整的使用Golang语言,在函数计算运行gRPC服务的示例代码。完整的代码目录结构如下所示,其中./greeter_client
目录为客户端代码,./code
目录为服务端代码。
fc-custom-golang-grpc
├── build-image
│ └── Dockerfile
├── certificate
├── code
│ ├── bootstrap
│ └── main.go
├── go.mod
├── greeter_client
│ ├── main
│ └── main.go
├── Makefile
├── privatekey
├── proto
│ ├── helloworld_grpc.pb.go
│ ├── helloworld.pb.go
│ └── helloworld.proto
├── readme.md
├── s_en.yaml
└── s.yaml
准备ZIP代码包
在项目目录fc-custom-golang-grpc
,执行make deploy
,会在./code
目录下生成二进制文件bootstrap
,将其打包为bootstrap.zip
。
安装依赖
在项目目录fc-custom-golang-grpc
,执行go mod vendor
安装运行gRPC客户端需要的依赖。
使用控制台部署函数
前提条件
操作步骤
- 登录函数计算控制台,在左侧导航栏,单击服务及函数。
- 在顶部菜单栏,选择地域,然后在服务列表页面,单击目标服务。
- 在函数管理页面,单击创建函数。
在创建函数页面,选择使用自定义运行时创建方式,设置相关参数,然后单击创建。
需要设置的参数说明如下,其余参数保持默认值即可。更多参数信息,请参见创建函数。
函数名称:设置您要创建的函数名称,例如grpc-demo。
请求处理程序类型:选择处理 HTTP 请求。
运行环境:选择Debian 9。
代码上传方式:选择通过 ZIP 包上传代码。
代码包:选择并上传您已打包的
bootstrap.zip
文件。启动命令:如不填写,默认执行
./bootstrap
。监听端口:监听端口与服务端监听的端口保持一致,本文示例值为8089。
在函数详情页面,单击触发器管理页签,查看触发器的公网访问地址。
执行以下命令调用gRPC客户端,发起gRPC调用,测试函数的正确性。
go run ./greeter_client -addr grpc-demo-service-*********.cn-qingdao.fcapp.run:8089
您也可以为您创建的gRPC函数配置自定义域名,并使用自定义域名调用该函数。
使用Serverless Devs工具部署函数
前提条件
操作步骤
执行以下命令,初始化项目。
s init fc-custom-golang-grpc -d fc-custom-golang-grpc
执行以下命令,进入项目目录
fc-custom-golang-grpc
。cd fc-custom-golang-grpc
可选:编辑s.yaml文件。
示例如下:
edition: 1.0.0 name: hello-world-app # access为当前应用所需要的密钥信息 # 密钥配置可以参考:https://www.serverless-devs.com/serverless-devs/command/config # 密钥使用顺序可以参考:https://www.serverless-devs.com/serverless-devs/tool# access: "default" vars: # 全局变量 region: "cn-hangzhou" # 您要部署的函数所在的地域 service: name: "grpc-demo" # 您要部署的函数所在的服务名称 description: 'hello world by serverless devs' internetAccess: true services: helloworld: # 您自定义的业务名称或模块名称 # 如果只想针对helloworld下面的业务进行相关操作,可以在命令行中加上helloworld,例如,只对helloworld进行构建:s helloworld build # 如果不带有helloworld,而是直接执行s build,工具则会对当前Yaml下,所有和helloworld平级的业务模块(如有其他平级的模块,例如下面注释的next-function),按照一定顺序进行build操作 component: fc actions: # 自定义执行逻辑,关于actions的使用,可以参考:https://www.serverless-devs.com/serverless-devs/yaml pre-deploy: # 在deploy之前运行 - run: make build path: ./ # - component: fc build --use-docker --dockerfile ./code/Dockerfile # 要运行的组件,格式为【component: 组件名 命令 参数】(可以通过s cli registry search --type Component 获取组件列表) # - run: docker build xxx # 要执行的系统命令,类似于一种钩子的形式 # path: ./src # 执行系统命令/钩子的路径 # - plugin: myplugin # 运行的插件(可以通过s cli registry search --type Plugin获取插件列表) # args: # 插件的参数信息 # testKey: testValue # post-deploy: # 在deploy之后运行 # - component: fc versions publish # 要运行的命令行 props: region: ${vars.region} service: ${vars.service} # logConfig: # project: mypro-dev # logstore: function-log function: name: "golang-grpc" # 您要部署的函数名称 description: 'hello world by serverless devs' timeout: 30 memorySize: 512 runtime: custom codeUri: ./code instanceConcurrency: 3 caPort: 8089 triggers: - name: http2Trigger type: http config: authType: anonymous # HTTP触发器的触发方式配置,必须配置POST方式 methods: - GET - POST # customDomains: # - domainName: auto # protocol: HTTP,HTTPS # routeConfigs: # - path: /* # serviceName: "grpc-demo" # functionName: "golang-grpc" # certConfig: # certName: certtest # certificate: ./certificate # privateKey: ./privatekey
执行
s deploy -y
部署函数。执行完成后,函数将部署至函数计算。此外,函数计算会生成一个可直接访问的URL地址,您可以使用该URL地址调用函数进行测试。
执行以下命令,安装运行gRPC客户端所需的依赖。
go mod vendor
执行以下命令,调用gRPC客户端,发起gRPC调用,测试函数的正确性。
使用HTTP函数触发器的公网访问地址,示例如下:
go run ./greeter_client -addr golang-grpc-grpc-demo-torcawakky.cn-qingdao.fcapp.run:8089
更多示例
Custom Runtime | Custom Container |
无 |
常见问题
函数错误
客户端报错rpc error: code = Internal desc = server closed the stream without sending trailers
,表示函数计算服务端提前异常关闭gRPC请求。这种错误属于函数错误,例如函数超时、函数进程异常退出或函数出现内存溢出OOM错误等。您可以从函数日志中查询具体的错误原因并排查处理。更多信息,请参见查看调用日志。
gRPC请求未使用TLS协议客户端
需使用TLS协议客户端调用gRPC请求,否则会报错rpc error: code = Internal desc = server closed the stream without sending trailers
。例如,Golang语言可以使用如下示例代码:
var opts []grpc.DialOption
cred := credentials.NewTLS(&tls.Config{
InsecureSkipVerify: false,
})
opts = append(opts, grpc.WithTransportCredentials(cred))
conn, err := grpc.Dial(*addr, opts...)
InsecureSkipVerify的值可以设置为true,即跳过TLS证书验证,或者设置为false,即不跳过TLS证书验证。
更多信息
除了函数计算控制台,您还可通过SDK配置触发器。具体操作,请参见SDK参考(2021-04-16推荐)。
如需修改或删除触发器,具体操作,请参见触发器管理。