阿里云函数计算 go环境尝鲜

831 阅读6分钟

阿里云函数计算 go环境尝鲜

最近尝试了一下阿里云函数计算的应用功能,点一下就可以启动一个完整的云上应用,感觉十分方便,也想来本地尝试一下。

这里我选择使用 go 语言的HTTP请求处理程序, 但对静态编译语言的支持不够到位,需要每次本地编译好产物上传, 然后我找到Serverless Devs, 可以使用开源的cli+yml方式进行配置上传, 不过官方文档零零散散,操作起来不连贯, 这里我来记录下本地的实验过程

注意实验过程中会开启阿里云的计费服务,如不需要在实验完成后记得及时关闭

手动流程

为了更好的理解 cli 可以帮我们解决什么问题, 我们可以先走一遍手动上传的流程, 首先编写好fc代码

这里直接使用官方的示例代码

package main

import (
    "context"
    "fmt"
    "net/http"
    "io/ioutil"

    "github.com/aliyun/fc-runtime-go-sdk/fc"
)

func HandleHttpRequest(ctx context.Context, w http.ResponseWriter, req *http.Request) error {
  body, err := ioutil.ReadAll(req.Body)
  if err != nil {
    w.WriteHeader(http.StatusBadRequest)
    w.Header().Add("Content-Type", "text/plain")
    w.Write([]byte(err.Error()))
    return nil
  }
    w.WriteHeader(http.StatusOK)
    w.Header().Add("Content-Type", "text/plain")
    w.Write([]byte(fmt.Sprintf("Hi,%s!\n", body)))
    return nil
}

func main() {
    fc.StartHttp(HandleHttpRequest)
}

代码很简单, 每次有http请求时都进入HandleHttpRequest来处理

接下来我们需要按照文档来打包和上传代码

当然上传之前我们还需要按照文档上的介绍, 在阿里云上创建函数计算的服务函数

服务最好选择一个离自己最近的区域 Xnip2022-08-27_18-48-23.jpg

创建服务时开启日志功能, 这样我们才能看到运行时打印的输出,这个功能也是阿里云通用的日志服务(sls)

创建函数 有三种方式,主要的区别是运行时环境,标准Runtime才会有fc的环境,自定义Runtime就是裸机的环境,适用于在现有框架上开发的代码,直接运行,最后是容器环境

  • 使用标准Runtime从零创建
  • 使用自定义运行时平滑迁移 Web Server
  • 使用容器镜像(面向 Kubernetes、Docker 等用户)

这里选第一个标准Runtime创建,处理Http请求,运行环境为go1,然后将二进制打包上传。 Xnip2022-08-27_18-59-28.jpg

创建完成后,我们进入函数详情,选择函数代码/测试代码中的测试函数,一切顺利的话就可以看到返回的http响应了。

这里值得说明的一点是http功能其实是通过http触发器实现的。

Xnip2022-08-27_19-06-24.jpg

我们可以直接点击测试地址在浏览器访问, 如果需要公网可访问需要分配自己的域名,这里我只是用api功能,因此默认的访问地址就可以满足测试需求了。

这样我们就完成了fc代码的部署, 但有一个讨厌的问题, 每次更新代码后都要手动打包📦和上传⏫,这实在是太繁琐😰了,下一步我们就来配置cli,通过命令行部署fc代码。

Serverless Devs 配置/命令行自动部署

Serverless Devs 是一个开源的 Serverless 开发cli工具, 使用它来向阿里云api交互可以为我们省去许多麻烦。

可以看阿里云上的文章来配置

  1. 什么是Serverless Devs
  2. 安装
  3. 配置

配置这里可以选择 RAM 访问控制, 创建一个函数计算专用的用户/用户组, 具体可以看这篇.

然后为用户组添加 fc 相关权限 fc-pev.jpg

然后是编写s.yml配置文件, 它定义fc的配置, 通过与api交互就可以完成函数组件的创建、更新等等功能,
可以在官方仓库找到完整的例子,
我这里找到一个实例代码, 并给予它进行修改

也可以在函数详情里选择 导出函数-导出配置, 将配置文件放到代码仓库里.

# ------------------------------------
#   欢迎您使用阿里云函数计算 FC 组件进行项目开发
#   组件仓库地址/帮助文档:https://github.com/devsapp/fc
#   Yaml参考文档:https://github.com/devsapp/fc/blob/jiangyu-docs/docs/zh/yaml.md
#   关于:
#      - Serverless Devs和FC组件的关系、如何声明/部署多个函数、超过50M的代码包如何部署
#      - 关于.fcignore使用方法、工具中.s目录是做什么、函数进行build操作之后如何处理build的产物
#   等问题,可以参考文档:https://github.com/devsapp/fc/blob/jiangyu-docs/docs/zh/tips.md
#   关于如何做CICD等问题,可以参考:https://github.com/Serverless-Devs/Serverless-Devs/blob/master/docs/zh/cicd.md
#   有问题快来钉钉群问一下吧:33947367
# ------------------------------------

edition: 1.0.0
name: acfun-curl
access: ${acccess_name} # 设置 RAM 访问控制 环节为 cli 设置的用户名, 可以用 `s config` 查询

vars: # 全局变量
  region: cn-shenzhen
  service:
    name: acfun-curl
    description: 'example for golang runtime'
    logConfig:
      project: aliyun-fc-cn-shenzhen-**** # 为服务开启日志功能后生成的,可以在`服务详情-日志项目`中看到
      logstore: function-log
      enableRequestMetrics: true
      enableInstanceMetrics: true
      logBeginRule: "DefaultRegex"

services:
  acfun-curl: # 业务名称/模块名称
    component: fc # 什么样的serverless组件,这里fc即可
    actions: # 自定义执行逻辑
      pre-deploy: # 在deploy之前运行
        - run: make build  # 要运行的命令行
          path: ./ # 命令行运行的路径
    props:
      region: ${vars.region}
      service: ${vars.service}
      function:
        environmentVariables:
          FC_ENV: true
        handler: main
        memorySize: 512
        runtime: go1
        timeout: 30
        name: acfun-curl-fc1
        codeUri: ./build/
      triggers:
        -
          type: http
          name: httpTrigger
          config:
            authType: anonymous
            methods:
              - GET

需要替换某些信息

  • access: 访问的用户名, 设置 RAM 访问控制环节创建的, 可以用 s config 查询
  • region: 需要和你选择的region对应, 不同的region服务是隔离的.
  • service/function name: service 名称需要替换两处, function name 需要替换一处, 注意区分
  • pre-deploy: 这里是导出的不会包含的, 可以自定deploy前要执行的命令, 利用makefile进行编译
  • environmentVariables: 自定义的环境变量,按需使用, 我在这里加了一个,可以判断是本地环境还是fc环境
  • handler: fc组件的入口, go 环境下使用 main.go 编译出的 main 文件
  • codeUri: 需要上传的文件, 这里我将编译产物放到 build 目录下, 然后直接上传目录.

其余参数保持默认即可, 如果需要自定义配置可以查看上文的官方仓库连接.

然后我们使用s deploy命令就可以部署了👏.

补充我遇到的一些问题

  • http触发器可能会超时/返回500
    • 我是由于向已有的fc组件部署(刚才我们创建的).
    • 解决需要创建新的fc组件(换个名字), 后续再用s deploy部署就ok了
  • 提示本地参数与远程参数不一致,
    • 一开始实验时我们可以无脑选使用本地. 真正应用的情况下, 可能是因为手动在网站上修改函数/服务配置, 或是本地更新了 s.yml, 这时需要确认到底是要本地的配置还是远程的配置.
  • http函数服务通过s invoke访问失败.
    • 直接通过cURL访问吧

总结

云函数计算的发展还在早期, 有些配套功能还不完善, 但如果能使用好, 对于个人开发者来说, 弹性扩容, 按使用计费, 快速部署等等都是很方便的功能, 希望以后能越发展越好.