函数计算 custom runtime 使用集锦

本文涉及的产品
Serverless 应用引擎 SAE,800核*时 1600GiB*时
函数计算FC,每月15万CU 3个月
简介: 函数计算 custom runtime 使用集锦

前言

该文章过期

直接参考官方文档, 比如 go

函数计算目前原生支持的开发语言有 nodejs, python, java, php 和 c#, 在实现这些开发语言 runtime 的时候, 函数计算开发团队花了很大的精力去让各自语言的传统应用能够简单快速迁移到函数计算平台:

如上述所列的各自语言的传统应用迁移到函数计算的迁移方案, 虽然已经足够简单, 但是还是需要去理解一下函数计算的接口以及各自语言在函数计算环境中运行起来的原理, 比如 python, 用户需要理解 WSGI 协议, 然后才编写一个符合要求的入口函数。 为了彻底解放生产力, Custom Runtime 应运而生, Custom Runitme 可以解决以下两个重要需求:

  • 可以随心所欲持定制个性化语言执行环境(例如 golang、lua、ruby)以及各种语言的小版本(例如python3.7、Nodejs12)等,打造属于自己的自定义runtime
  • 现有的 web 应用或基于传统开发 web 项目基本不用做任何改造,即可将项目一键迁移到函数计算平台

用户要实现一个最简单的 Custom runtime,只要符合以下两条:

  • 创建一个http server,监听在固定端口(端口可以读取环境变量 FC_SERVER_PORT,默认为 9000)
  • http server 需要在 15s 内完成启动

接下来, 我们梳理一下基于 Custom Runtime 一键迁移迁移案例。

custom 实现注意细节:

  • Custom Runtime 启动的服务一定监听 0.0.0.0:9000 或者 *:9000 端口,不用使用127.0.0.1:9000, 会导致请求超时。
    {"ErrorCode":"FunctionNotStarted","ErrorMessage":"The CA's http server cannot be started:ContainerStartDuration:25000000000. Ping CA failed due to: dial tcp 21.0.5.7:9000: getsockopt: connection refused Logs : 2019-11-29T09:53:30.859837462Z Listening on port 9000rn"}
  • Custom Runtime 的 bootstrap 一定需要添加 #!/bin/bash,不然会遇见如下错误
    {"ErrorCode":"CAExited","ErrorMessage":"The CA process either cannot be started or exited:ContainerStartDuration:25037266905. CA process cannot be started or exited already: rpc error: code = 106 desc = ContainerStartDuration:25000000000. Ping CA failed due to: dial tcp 21.0.7.2:9000: i/o timeout Logs : 2019-11-29T07:27:50.759658265Z panic: standard_init_linux.go:178: exec user process caused "exec format error"

使用 windows 一些文本编辑器要注意文件格式, 比如:

image

  • bootstrap 一定需要可执行权限
  • bootstrap 代码一定要执行到 http server 启动成功的逻辑, 不能被前面的逻辑阻塞, 比如启动server之前, 尝试连接一个不可达的数据库,造成启动时间 timeout
  • http server 的实现 connection keep alive, request timeout 至少10分钟以上

案例

java

Serverless 实战 —— 快速搭建 SpringBoot 应用
Serverless 实战 —— 移植 spring-petclinic 到函数计算
轻松搭建基于 SpringBoot + Vue 的 Web 商城应用

python

import tornado.ioloop
import tornado.web
import os

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        rid = self.request.headers.get('x-fc-request-id',None)
        print("FC Invoke Start RequestId: " + str(rid));
        
        # your logic
        self.write("GET: Hello world")
            
        print("FC Invoke End RequestId: " + str(rid));
     
    def post(self):
        rid = self.request.headers.get('x-fc-request-id',None)
        print("FC Invoke Start RequestId: " + str(rid));
        
        # your logic
        self.write("GET: Hello world")
        
        print("FC Invoke End RequestId: " + str(rid));

def make_app():
    return tornado.web.Application([
        (r"/.*", MainHandler),
    ])
 
if __name__ == "__main__":
    app = make_app()
    port = os.environ.get("FC_SERVER_PORT", "9000")
    app.listen(int(port))
    tornado.ioloop.IOLoop.current().start()

本地安装第三方包 tornado

然后编写一个具有可执行权限的名字为bootstrap (注:#!/bin/bash注释是必需的)文件启动上面代码的 http server:

#!/bin/bash
python server.py

go

基于custom runtime 打造 golang runtime

nodejs

'use strict';

var express = require('express');
var app = express();

var crypto = require('crypto');

app.post(/.*/, function (req, res) {
      var rid = req.headers["x-fc-request-id"];
      console.log(`FC Invoke Start RequestId: ${rid}`);
      
      // your logic, for example, get hash
      var secret = 'abcdefg';
      var hash = crypto.createHmac('sha256', secret)
          .update('I love cupcakes')
          .digest('hex');

      // c0fa1bc00531bd78ef38c628449c5102aeabd49b5dc3a2a516ea6ea959d6658e
      console.log(hash);

      res.send(hash);

      console.log(`FC Invoke End RequestId: ${rid}`);
});

var port = process.env.FC_SERVER_PORT || 9000

app.listen(port, function () {
      console.log("FunctionCompute custom-nodejs runtime inited.");
});

app.timeout = 0; // never timeout
app.keepAliveTimeout = 0; // keepalive, never timeout

本地安装第三方包 express

然后编写一个具有可执行权限的名字为bootstrap (注:#!/bin/bash注释是必需的)文件启动上面代码的 http server:

#!/bin/bash
node server.js

php

<?php

define('FC_LOG_TAIL_START_PREFIX', 'FC Invoke Start RequestId: '); // Start of log tail mark

define('FC_LOG_TAIL_END_PREFIX', 'FC Invoke End RequestId: '); // End of log tail mark


$http = new swoole_http_server("0.0.0.0", 9000);

$options = [
    'worker_num' => 3,
];

$http->set($options);

$http->on("start", function ($server) {
    echo "FC customruntime Swoole http server is started at http://0.0.0.0:9000" . PHP_EOL;
});

$http->on('shutdown', function ($server){
    echo "FC customrutime Swoole http server shutdown" . PHP_EOL;
});

$http->on("request", function ($request, $response) {
    $rid = $request->header["x-fc-request-id"];
    echo FC_LOG_TAIL_START_PREFIX . $rid . PHP_EOL;
    $response->header("Content-Type", "text/plain");
    $response->end("Hello World");
    echo FC_LOG_TAIL_END_PREFIX . $rid . PHP_EOL;
});

$http->start();

基于custom runtime + nginx + php-fpm 运行 wordpress
customruntime-php

.NETCORE CSharp

.Net Core 2.1 MVC Web应用迁移到函数计算 custom runtime

教程同样适用于 .netcore 3.0

相关实践学习
【文生图】一键部署Stable Diffusion基于函数计算
本实验教你如何在函数计算FC上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。函数计算提供一定的免费额度供用户使用。本实验答疑钉钉群:29290019867
建立 Serverless 思维
本课程包括: Serverless 应用引擎的概念, 为开发者带来的实际价值, 以及让您了解常见的 Serverless 架构模式
目录
相关文章
|
2月前
|
缓存 运维 Serverless
函数计算产品使用问题之如何在Custom Runtime中引用层中的依赖
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
3月前
|
存储 Java Serverless
函数计算产品使用问题之Custom Runtime函数的详细配置包括哪些
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
|
3月前
|
运维 Serverless API
函数计算产品使用问题之如何使用PHP Runtime非内置扩展
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
|
4月前
|
弹性计算 Java Serverless
Serverless 应用引擎操作报错合集之在执行环境 custom pre-deploy 时,命令 "go mod tidy" 失败了,是什么导致的
Serverless 应用引擎(SAE)是阿里云提供的Serverless PaaS平台,支持Spring Cloud、Dubbo、HSF等主流微服务框架,简化应用的部署、运维和弹性伸缩。在使用SAE过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
407 0
|
5月前
|
运维 Java Serverless
Serverless 应用引擎产品使用之阿里函数计算中云函数怎么防止恶意刷流量的请求,例如:openresty的runtime如何解决
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
139 0
|
5月前
|
运维 Java 物联网
Serverless 应用引擎产品使用之阿里函数计算中使用custom container,如何解决
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
|
运维 Kubernetes Cloud Native
serverless 学习 | QCon2022-深圳: Serverless 高密度部署与 Web-interoperable Runtime 在字节跳动的实践
serverless 学习 | QCon2022-深圳: Serverless 高密度部署与 Web-interoperable Runtime 在字节跳动的实践
677 0
serverless 学习 | QCon2022-深圳: Serverless 高密度部署与 Web-interoperable Runtime 在字节跳动的实践
|
Java Serverless
FC Java runtime 找不到函数入口问题
在函数计算中使用Java编程时,需要定义一个函数作为入口函数。由于Java有包的概念,因此执行方法和其他语言有所不同,需要带有包信息。在入口函数需要配置包信息
625 0
FC Java runtime 找不到函数入口问题
|
1月前
|
人工智能 自然语言处理 Serverless
阿里云函数计算 x NVIDIA 加速企业 AI 应用落地
阿里云函数计算与 NVIDIA TensorRT/TensorRT-LLM 展开合作,通过结合阿里云的无缝计算体验和 NVIDIA 的高性能推理库,开发者能够以更低的成本、更高的效率完成复杂的 AI 任务,加速技术落地和应用创新。
107 14
|
2月前
|
机器学习/深度学习 机器人 Serverless
FaaS 的应用场景
FaaS 的应用场景

相关产品

  • 函数计算