Aller au contenu principal
Version: 3.0.0

Deploy to Alibaba Cloud Function Compute

Alibaba Cloud Serverless is one of the first teams in China to provide serverless computing services. It relies on Alibaba Cloud's powerful cloud infrastructure service capabilities to continuously achieve technological breakthroughs. At present, Taobao, Alipay, DingTalk, AutoNavi, etc. have applied Serverless to production business. Serverless products on the cloud have been successfully implemented in tens of thousands of companies such as Pumpkin Movie, NetEase Cloud Music, iQiyi Sports, and Lilith.

Alibaba Cloud Serverless includes many products, such as Function Compute FC, Lightweight Application Engine SAE, etc. This article mainly uses its Function Compute part.

The following are common methods of using, testing, and deploying function triggers.

Deployment type

Alibaba Cloud has many types of function computing deployments, including the following types according to the different containers they run.

NameFunctional limitationsDescriptionDeployment Media
Built-in runtimeStreaming requests and responses are not supported; requests and responses that are too large are not supported.Only function interfaces can be deployed, no custom ports are required, zip packages are built for platform deploymentzip package deployment
Custom RuntimeYou can deploy standard applications, start port 9000, use the system image provided by the platform, and build a zip package for platform deploymentzip package deployment
Custom ContainerYou can deploy standard applications, start port 9000, control all environmental dependencies yourself, and build a Dockerfile for platform deploymentDockerfile deployment

There are three ways to create functions on the platform.

Pure function development (built-in runtime)

Below we will use the "built-in runtime deployment" pure function as an example.

Trigger code

Publish a function that does not contain a trigger. This is the simplest type. You can manually trigger parameters directly through event, or you can bind other triggers on the platform.

Bind event triggers via the @ServerlessTrigger decorator directly in code.

import { Provide, Inject, ServerlessTrigger, ServerlessTriggerType } from '@midwayjs/core';
import { Context } from '@midwayjs/faas';

@Provide()
export class HelloAliyunService {
@Inject()
ctx: Context;

@ServerlessTrigger(ServerlessTriggerType.EVENT)
async handleEvent(event: any) {
return event;
}
}
info

More configurations of triggers are platform-related and will be written in s.yaml, such as the time interval of scheduled tasks, etc. For more details, please see the deployment paragraph below.

Type definition

The definition of FC will be exported by the adapter. In order for the definition of ctx.originContext to remain correct, it needs to be added to src/interface.ts.

// src/interface.ts
import type {} from '@midwayjs/fc-starter';

Additionally, definitions for various Event types are provided.

//Event type
import type {
OSSEvent,
MNSEvent,
SLSEEvent,
CDNEvent,
TimerEvent,
APIGatewayEvent,
TableStoreEvent,
} from '@midwayjs/fc-starter';
// InitializeContext type
import type { InitializeContext } from '@midwayjs/fc-starter';

Local development

HTTP triggers and API Gateway types can be developed locally through local npm run dev and development methods similar to traditional applications. Other types of triggers cannot be developed locally using dev and can only be tested by running npm run test.

Local testing

Similar to traditional application testing, use the createFunctionApp method to create a function app and use the close method to close it.

import { Application, Context, Framework } from '@midwayjs/faas';
import { mockContext } from '@midwayjs/fc-starter';
import { createFunctionApp } from '@midwayjs/mock';

describe('test/hello_aliyun.test.ts', () => {

it('should get result from event trigger', async () => {

// create app
const app: Application = await createFunctionApp<Framework>(join(__dirname, '../'), {
initContext: mockContext(),
});

// ...

await close(app);
});
});

The mockContext method is used to simulate a FC Context data structure. You can customize a similar structure or modify some data.

import { Application, Context, Framework } from '@midwayjs/faas';
import { mockContext } from '@midwayjs/fc-starter';
import { createFunctionApp } from '@midwayjs/mock';

describe('test/hello_aliyun.test.ts', () => {

it('should get result from event trigger', async () => {

// create app
const app: Application = await createFunctionApp<Framework>(join(__dirname, '../'), {
initContext: Object.assign(mockContext(), {
function: {
name: '***',
handler: '***'
}
}),
});

// ...

await close(app);
});
});

Different triggers have different testing methods. Some common triggers are listed below.

Obtain the class instance through getServerlessInstance, directly call the instance method, and pass in the parameters for testing.

import { HelloAliyunService } from '../src/function/hello_aliyun';

describe('test/hello_aliyun.test.ts', () => {

it('should get result from event trigger', async () => {
// ...
const instance = await app.getServerlessInstance<HelloAliyunService>(HelloAliyunService);
expect(await instance.handleEvent('hello world')).toEqual('hello world');
// ...
});
});

Pure function deployment (built-in runtime)

The following will briefly describe how to use Serverless Devs to deploy to Alibaba Cloud functions.

1. Confirm the launcher

In the provider section of f.yml in the project root directory, make sure the starter is @midwayjs/fc-starter.

provider:
name: aliyun
starter: '@midwayjs/fc-starter'

2. Install Serverless Devs tools

aliyun uses Serverless Devs tool for function deployment.

You can install it globally.

$ npm install @serverless-devs/s -g

Refer to the Key Configuration document for configuration.

3. Write a Serverless Devs description file

Create a s.yaml in the root directory and add the following content.

edition: 1.0.0
name: "midwayApp" # project name
access: "default" # Secret key alias

vars:
service:
name: fc-build-demo
description: 'demo for fc-deploy component'
services:
project-0981cd9b07:
component: devsapp/fc
props:
region: cn-hangzhou
service: ${vars.service}
function:
name: hello # function name
handler: helloHttpService.handleHTTPEvent
codeUri: '.'
initializer: helloHttpService.initializer
customDomains:
- domainName: auto
protocol: HTTP
routeConfigs:
- path: /*
serviceName: ${vars.service.name}
functionName: helloHttpService-handleHTTPEvent
triggers:
- name: http
type: http
config:
methods:
-GET
authType: anonymous

Every time you add a function, you need to adjust the s.yaml file. For this reason, Midway provides a @midwayjs/serverless-yaml-generator tool to write the decorator function information into s.yaml.

{
"scripts": {
+ "generate": "serverless-yaml-generator",
},
"devDependencies": {
+ "@midwayjs/serverless-yaml-generator": "^1.0.0",
},
}

By executing the following command, you can fill existing function information into s.yaml and generate an entry file to facilitate troubleshooting.

$ npm run generate

The tool will look for the configuration in s.yaml using the function name as the key.

    1. If there is a function, it will cover specific fields, such as handler, http trigger methods
    1. If the function does not exist, a new function will be added
    1. The tool will not write the http routing method. To simplify subsequent updates, you can provide a /* route (as an example)

We recommend that users only define the basic function name, function handler, and basic trigger information (such as the path and method of the http trigger) in the decorator, and write the rest in yaml.

The complete configuration of s.yaml is more complicated. For details, please refer to Description File Specification.

4. Write a deployment script

Since deployment has multiple steps such as building and copying, we can write a deployment script to unify this process.

For example, create a new deploy.sh file in the project root directory with the following content.

#!/bin/bash

set -e

# Build product directory
export BUILD_DIST=$PWD/.serverless
#Build start time in milliseconds
export BUILD_START_TIME=$(date +%s%3N)

echo "Building Midway Serverless Application"

#Print the current directory cwd
echo "Current Working Directory: $PWD"
#Print result directory BUILD_DIST
echo "Build Directory: $BUILD_DIST"

#Install current project dependencies
npm i

# Execute build
./node_modules/.bin/tsc || return 1
# Generate entry file
./node_modules/.bin/serverless-yaml-generator || return 1

# If the .serverless folder exists, delete it and recreate it
if [ -d "$BUILD_DIST" ]; then
rm -rf $BUILD_DIST
fi

mkdir $BUILD_DIST

# Copy dist, *.json, *.yml to the .serverless directory
cp -r dist $BUILD_DIST
cp *.yaml $BUILD_DIST 2>/dev/null || :
cp *.json $BUILD_DIST 2>/dev/null || :
# Move the entry file to the .serverless directory
mv *.js $BUILD_DIST 2>/dev/null || :

# Enter the .serverless directory
cd $BUILD_DIST
# Install online dependencies
npm install --production

echo "Build success"

# Deploy in the .serverless directory
s deploy

You can put this deploy.sh file in the deploy command of package.json, and execute npm run deploy for subsequent deployment.

{
"scripts": {
"deploy": "sh deploy.sh"
}
}
astuce
    1. deploy.sh is only tested on mac, other platforms can be adjusted by yourself.
    1. The script content can be adjusted according to business logic, such as copied files, etc.

Custom runtime deployment

1. Create a project

Custom runtimes can be deployed using standard projects. Since port 9000 needs to be provided, the Midway koa/express/express project needs to be created.

For initialization projects, please refer to Creating the first application.

2. Adjust the port

In order to avoid affecting local development, we only add ports at the entrance bootstrap.js.

const { Bootstrap } = require('@midwayjs/bootstrap');

// Explicitly introduce user code as a component
Bootstrap.configure({
globalConfig: {
koa: {
port: 9000,
}
}
}).run()

For different framework modification ports, please refer to:

3. Platform deployment configuration

    1. Select the running environment, such as Node.js 18
    1. Select the code upload method, for example, you can upload a zip package locally
    1. The startup command specifies node bootstrap.js
    1. Listening port 9000

After the configuration is completed, upload the compressed package to complete the deployment.