Author: Liu Yu (flower name: Jiang Yu)
The author said: The application development under the serverless architecture is quite different from the application development of the traditional architecture. For example, the natural distributed architecture will make many frameworks lose a certain degree of "convenience", and the stateless characteristics make a lot of" Operations that seem normal under traditional architecture "become unusually risky.
Therefore, in this article, I will introduce some common application development considerations under the serverless architecture, and share some personal practical experience. If you encounter problems in the serverless development process, you may wish to read it below.
7 things to know about app development
How to upload files
In traditional web frameworks, uploading files is very simple and convenient, such as Python's Flask framework:
f = request.files['file']
f.save('my_file_path')
However, under the Serverless architecture, files cannot be uploaded directly for the following reasons:
- API gateway triggers of some cloud platforms will convert binary files into strings; it is inconvenient to obtain and store them directly;
- In addition, the data packets passed between the API gateway and the FaaS platform are limited in size, and many platforms are limited to 6M;
- Most FaaS platforms are stateless, and even if they are stored in the current instance, files will be lost when the instance is released;
Therefore, the upload scheme commonly used in traditional frameworks is not suitable for direct use in serverless architecture. If you want to upload files in a serverless architecture, you can try the following two methods:
- One is to upload after BASE64 and persist it to object storage or NAS. This approach may affect the size limit of the data packets passed between the API gateway and the FaaS platform. Therefore, this upload method is usually used for uploading. Business scenarios for small files such as avatars;
- The second upload method is to upload through a platform such as object storage, because it is risky for the client to directly upload files to object storage through the key and other information. Therefore, it is usually the case that the client initiates an upload request, and Function Compute performs a pre-signature operation based on the request content, and returns the pre-signature address to the client. The client then uses the specified method to upload. Please wait to update the upload result, as shown in the following figure:
File reading and writing and persistence methods
During the execution of the application, it may involve the read and write operations of files, or the persistence of some files. In the traditional cloud host mode, it is usually possible to read and write files directly, or to persist files in a directory, but this is not the case in the serverless architecture.
Since the FaaS platform is stateless and will be destroyed after use, if the file needs to be persisted and cannot be directly persisted in the instance, you can choose to persist it to other services, such as object storage, NAS, etc.
At the same time, if the NAS is not configured, the FaaS platform usually has writable permissions in the /tmp directory, so some temporary files can be cached in the /tmp folder.
Use some features of web frameworks sparingly
Function Compute (FC) is a request-level isolation, so it can be considered that the request is over, and the instance may enter a "silent" state. In function computing, API gateway triggers are usually called synchronously (taking Alibaba Cloud Function Compute as an example, they are usually triggered asynchronously only in several cases, such as timing triggers, OSS event triggers, MNS topic triggers, and IoT triggers. ) , which means that when the API Gateway returns the result to the client, the entire function will go into a "silent" state, or be destroyed, instead of continuing to execute the asynchronous method.
Therefore, it is usually difficult for frameworks such as Tornado to play their asynchronous role in a Serverless architecture. Of course, if users need asynchronous capabilities, they can refer to the asynchronous methods provided by cloud vendors. Taking Alibaba Cloud Function Compute as an example, Alibaba Cloud Function Compute provides users with an asynchronous calling capability. When an asynchronous call of a function is triggered, the function The calculation will put the trigger event into the internal queue and return the request ID, but the specific calling situation and function execution status will not be returned. If the user wants to obtain the result of an asynchronous call, he can do so by configuring the asynchronous call target, as shown in the figure:
Under the serverless architecture, once the application completes the current request, it will enter a "silent" state, and the instance will even be destroyed, so some frameworks with their own scheduled tasks cannot perform the scheduled tasks normally. Because function computations are usually triggered by events, they are not automatically timed to start. For example, a timed task is set in the Egg project, but in the actual function calculation, if the function is not triggered by a trigger, the function will not be triggered, and the function will not be automatically started from the inside to execute the timed task, so At this time, you can use the timing triggers provided by various cloud vendors for their FaaS platforms, and trigger the specified method through the timing trigger to replace the timing task.
Pay attention to the application composition structure
Under the serverless architecture, static resources should be provided with external services under the support of object storage and CDN; otherwise, all resources are in functions and exposed through function computing, which will not only reduce the concurrency of the real business logic of functions, but also will result in more costs. Especially when migrating some existing programs to the serverless architecture, such as Wordpress, etc., it is necessary to pay attention to the separation of static resources and business logic, otherwise in the case of high concurrency, performance and cost will be strictly tested .
In many cloud vendors, the charging standard for functions is based on the running time and configured memory, as well as the traffic generated. If the memory setting of a function is not reasonable, it will cause the cost to double. Therefore, we must not only ensure that the memory settings are reasonable, but also ensure the reliability of the business logic structure.
Taking Alibaba Cloud Function Compute as an example, when an application has two external interfaces, the memory consumption of one interface is below 128MB, and the memory consumption of the other interface is stable at around 3000MB. These two interfaces are triggered 10,000 times a day on average, and the time consumption is both 100ms. If two interfaces are written into one function, then this function may need to set the memory at 3072MB. At the same time, when the user requests an interface with less memory consumption, it may be difficult to obtain better performance in the case of cold start; however, If the two interfaces are written to two functions respectively, then the memory of the two functions can be set to 128MB and 3072MB respectively:
From the above table, we can clearly see that when the business is split reasonably and appropriately, the cost will be saved to a certain extent. In the above example, the cost will be saved by nearly 50%!
Traditional Framework Migration Schemes and Strategies
The scope of Serverless is getting wider and wider, and it is essentially more of a design concept, a new programming paradigm. Under this new architecture, or a new programming paradigm, it is better to use a new idea to do serverless applications. However, there are very few native serverless development frameworks. Taking web frameworks as an example, the current mainstream web frameworks "do not support serverless mode deployment". So how to deploy the traditional framework to the serverless architecture in a simpler, faster and more scientific way is a question worth exploring. Let me share the migration ideas with the case:
- Traditional framework migration case
The request integration solution is actually to pass the real API gateway request directly to the FaaS platform without adding any conversion logic in the middle. Taking the HTTP function of Alibaba Cloud Function Computing as an example, when developers want to deploy traditional frameworks (such as Django, Flask, Express, Next.js, etc.) to the Alibaba Cloud Function Computing platform, and experience the pay-as-you-go brought by Serverless , elastic scaling and other convenient advantages.
Thanks to the HTTP functions and HTTP triggers of Alibaba Cloud Function Compute, developers can not only deploy the framework to Alibaba Cloud Function Compute quickly and easily, but also maintain the same experience as traditional development. Taking Python's Bottle framework as an example, when we develop a Bottle project:
# index.pyp
import bottle
@bottle.route('/hello/<name>')
def index(name):
return "Hello world"
if __name__ == '__main__':
bottle.run(host='localhost', port=8080, debug=True)
You can debug directly locally. When you want to deploy the project to Alibaba Cloud Function Compute, you only need to add a default_app object:
app=bottle.default_app()
Whole project:
# index.py
import bottle
@bottle.route('/hello/<name>')
def index(name):
return "Hello world"
app = bottle.default_app()
if __name__ == '__main__':
bottle.run(host='localhost', port=8080, debug=True)
At this point, when creating a function on the Alibaba Cloud function computing platform, set the function entry to: index.app. In addition to Bottle, the operation methods of other web frameworks are similar, and then take Flask as an example:
# index.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, World!'
if __name__ == '__main__':
app.run(
host="0.0.0.0",
port=int("8001")
)
When configuring the function, write the entry function as: index.app to ensure that the Flask project runs on the function computing platform.
Of course, in addition to using the existing language Runtime, you can also consider using Custom Runtime and Custom Container to achieve, for example, after a Web project is completed, you can write a Bootstrap file (just write some startup commands in the Bootstrap file), For example, I want to start an Express project. After I prepare my Express project, I can directly pass Bootstrap to:
#!/usr/bin/env bash
export PORT=9000
npm run star
- Quick migration/deployment via developer tools
If the traditional framework is supported by developer tools, the case project can be created directly through the commands of Serverless Devs. Currently Serverless Devs already supports the following frameworks:
For details, please refer to: https://github.com/devsapp/start-web-framework
Take the Express project as an example, you can execute it in the command line tool:
s init start-express
You can initialize the project:
_____
| ___|
| |____ ___ __ _ __ ___ ___ ___
| __\ / / '_ | '__/ _ / __/ __|
| |___> <| |_) | | | __/__ __ \
____/_/_\ .__/|_| ___||___/___/
| |
|_|
? please select credential alias default
Welcome to the start-express application
This application requires to open these services:
FC : https://fc.console.aliyun.com/
Express development docs: https://www.expressjs.com.cn/4x/api.html
* 额外说明:s.yaml中声明了actions:
部署前执行:npm install --production
如果遇到npm命令找不到等问题,可以适当进行手动项目构建,并根据需要取消actions内容
* 项目初始化完成,您可以直接进入项目目录下,并使用 s deploy 进行项目部署
🏄 Thanks for using Serverless-Devs
👉 You could [cd /Users/jiangyu/Desktop/fc-custom-lua-event/image-prediction-app/start-express] and enjoy your serverless journey!
🧭️ If you need help for this example, you can use [s -h] after you enter folder.
💞 Document ❤ Star:https://github.com/Serverless-Devs/Serverless-Devs
Once done, you can go into the project and deploy:
$ s deploy
framework:
region: cn-beijing
service:
name: web-framework
function:
name: express
runtime: custom
handler: index.handler
memorySize: 128
timeout: 60
url:
system_url: https://1583208943291465.cn-beijing.fc.aliyuncs.com/2016-08-15/proxy/web-framework/express/
custom_domain:
-
domain: http://express.web-framework.1583208943291465.cn-beijing.fc.devsapp.net
triggers:
-
type: http
name: httpTrigger
At this point, you can open the page through the browser:
At this point, you can refer to Bootstrap and s.yaml provided in the case, and deploy/migrate your own project to Alibaba Cloud Serverless architecture. where Bootstrap is:
#!/bin/bash
node index.js
其中 s.yaml 为:
# ------------------------------------
# 欢迎您使用阿里云函数计算 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 # 命令行YAML规范版本,遵循语义化版本(Semantic Versioning)规范
name: framework # 项目名称
access: "default" # 秘钥别名
services:
framework: # 业务名称/模块名称
component: fc # 组件名称
actions:
pre-deploy: # 在deploy之前运行
- run: npm install --production # 要运行的命令行
path: ./code # 命令行运行的路径
props: # 组件的属性值
region: cn-beijing
service:
name: web-framework
description: 'Serverless Devs Web Framework Service'
function:
name: express
description: 'Serverless Devs Web Framework Express Function'
codeUri: './code'
runtime: custom
timeout: 60
caPort: 9000
triggers:
- name: httpTrigger
type: http
config:
authType: anonymous
methods:
- GET
customDomains:
- domainName: auto
protocol: HTTP
routeConfigs:
- path: '/*'
observability
The observability of serverless applications is a concern of many users. Observability is a measure of judging the internal state of the system through external performance. In application development, observability helps to judge the internal health of the system. When there is a problem with the system, it helps to locate, troubleshoot, and analyze the problem; when the system runs smoothly, it helps to assess risks and predict possible problems.
In serverless application development, if it is observed that the concurrency of functions continues to increase, it is likely that the hard work of the business promotion team has led to the rapid expansion of the business scale. In order to avoid triggering flow control by reaching the concurrency limit, developers need to increase the concurrency in advance. , Taking Alibaba Cloud Function Compute as an example, Alibaba Cloud Function Compute provides multiple dimensions at the observability level, including Logging, Metrics, and Tracing.
As shown in the figure, in the console monitoring center, you can view the overall metrics, service-level metrics, and metrics for each function. In addition, you can also see the request record of the current function:
According to different request records, we can view the details of the function:
In addition to viewing the function log and other information in the monitoring center of the console, you can also see the function's detailed log information on the function details page:
And Tracing related information:
Of course, observation-related operations can also be performed through Serverless Devs developer tools and function computing components. Let's take a look at how it is done.
- Metrics view through tools
For details, please refer to:
https://github.com/devsapp/fc/blob/main/docs/zh/command/metrics.md
- When there is a resource description file (Yaml), you can directly execute s metrics to view the indicator information of the function;
- In pure command line form (when there is no resource description Yaml file), you need to specify the region where the service is located, the service name, function name, etc., such as sclifcmetrics--regionch-hangzhou--service-namemyService--function-namemyFunction;
An example of the execution result of the above command is as follows:
[2021-06-07T12:20:06.661] [INFO ] [FC-METRICS] - 请用浏览器访问Uri地址进行查看: http://localhost:3000
At this point, open the address through the browser, and you can see the function indicator information:
PS You need to enable the request level indicator to view the function indicator information, otherwise the chart will not display the data.
About how to enable request-level metrics:
1. https://fcnext.console.aliyun.com/
2. In services and functions-find your own region-corresponding service name-click Configure in the operation bar to open the request level indicator
- Logs viewing through tools
For details, please refer to:
https://github.com/devsapp/fc/blob/main/docs/zh/command/logs.md
- When there is a resource description file (Yaml), you can directly execute s logs to query the log of online functions;
- In pure command line form (when there is no resource description Yaml file), you need to specify the region where the service is located, the service name, function name, etc., such as s cli fc logs --region cn-hangzhou --service-name fc-deploy-service -- function-name http-trigger-py36
Example of the execution result of the above command:
FunctionCompute python3 runtime inited.
FC Invoke Start RequestId: 84d6ae81-02ff-4011-b3ca-45e65b210cc3
FC Invoke End RequestId: 84d6ae81-02ff-4011-b3ca-45e65b210cc3
FC Invoke Start RequestId: de4812be-9137-4a33-9869-370cb61ac427
FC Invoke End RequestId: de4812be-9137-4a33-9869-370cb61ac427
If you need to query logs in tail mode, you can add the --tail parameter, such as s logs --tail;
Query logs of a specified time period by adding --start-time and --end-time parameters (for example, s logs -s 2021-11-04T15:40:00 -e 2021-11-04T15:45:00)
How to debug your app
In the process of application development, or when the application development is completed, but the execution result does not meet expectations, certain debugging work is usually performed. However, under the serverless architecture, debugging is often limited by great environmental factors. It may happen that the developed applications can run in a relatively healthy and expected manner locally, but on the FaaS platform, there will be Some unpredictable problems; or in some special environments, there is no way to simulate the online environment locally, making it difficult to develop and debug projects.
Serverless application debugging is regarded as the biggest pain point and challenge in the implementation of serverless, but various cloud vendors have not given up their continuous and in-depth exploration in the debugging direction. Taking Alibaba Cloud Function Compute as an example, various debugging solutions such as online debugging and local debugging are currently provided. For some specific operations, please refer to the Serverless official account article: <Hard-core debugging practice | Hands-on guide to implement Serverless breakpoint debugging>, which will not be repeated here.
Epilogue
The above are some of my experience sharing in serverless application development. Forrester once proposed: The rise of serverless architecture makes FaaS (Function As A Service) a new way to provide cloud computing capabilities after IaaS, PaaS, and SaaS. In the future, a large number of core applications of mainstream enterprises will migrate from the original mainframe architecture to the serverless architecture.
The serverless architecture is at the right time, and it has already opened the road to large-scale implementation from concept to practice, as predicted in the Gartner report: by 2025, half of the world's enterprises will adopt FaaS deployment;
Serverless can not only make developers no longer need to manage servers, no longer need to estimate resources and consider expansion; take advantage of cost reduction, efficiency improvement, and pay-as-you-go, it allows you to enter a state of only concentrating on business logic, thereby Comprehensively improve the R&D efficiency in the work.
Well, today is World Book Day, thank you for listening (reading), I hope my sharing can help you.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。