如何使用AWS Lambda构建一个云端工具(超详细)

首发地址(欢迎大家访问):如何使用AWS Lambda构建一个云端工具(超详细)


1 前言

1.1 无服务器架构

无服务器架构(Serverless Computing)是一种云计算服务模型,它允许开发者构建和运行应用程序而无需直接管理底层服务器或基础设施。开发者无需显式地管理服务器。也就是不再需要担心服务器的配置、扩展或维护。相反,云服务提供商会为替你处理这些底层基础设施,你只需专注于编写代码。

Gartner最近的一份报告表明,到2020年,全球将有20%的企业部署无服务器架构。

这说明无服务器架构不只是一个流行语,而是一种众所周知的云计算趋势,并且已经在软件世界掀起一场革命。大型厂商(如亚马逊)已经在无服务器架构领域重资投入,追赶革命的浪潮1

无服务器架构主要的两种类型

FaaS(Functions as a Service)

  • 将代码拆分成一个个独立的函数。
  • 每个函数都是一个无状态的、短暂的执行单元。
  • 函数只在有请求时才被触发执行,执行完毕后即被销毁。
  • 典型应用场景: API网关后端、数据处理、事件驱动架构。

BaaS(Backend as a Service)

  • 提供一组预构建的后端服务,如数据库、身份验证、推送通知等。
  • 开发者可以通过 API 调用这些服务,而无需自己搭建后端。
  • 典型应用场景: 移动应用后端、Web应用后端。

无服务器架构的优势

成本效益高

  • 按需付费,只为使用的资源付费。
  • 自动扩展,根据负载动态调整资源。

开发效率高

  • 无需管理服务器,专注于业务逻辑。
  • 快速部署和迭代。

高可用性

  • 云服务提供商负责基础设施的可靠性。

弹性扩展

  • 自动应对流量峰值。

无服务器架构的高效、高可用特性属实很吸引我,我一直想弄一个在线的 Python 工具集;当然现在也都只是个想法,大概就是用 Python 写一些NLP工具、随机接口(随机 图片、随机一言等)或者其他任何相关的工具;

之前一直在苦恼没有硬件资源的支持,但如果用无服务器架构来实践的话,应该会有不错的效果;

1.2 本文目标

本文的目标比较简单,就是利用无服务器架构写一个随机图片的接口以及一个jieba分词的接口;

能够在客户端调用,目标效果如下:

image-20241025001048029

2 关于Amazon Lambda

2.1 简介

Amazon Lambda是亚马逊云科技提供的核心服务之一,也是典型的无服务器架构服务;使用 Lambda,基本就可以只管我们的代码了;Lambda 管理提供内存、CPU、网络和其他资源均衡的计算机群,以运行代码。

而且Amazon Lambda是有免费额度的,对于我个人或者说我这小流量网站来讲,免费额度就很吸引人;

所以本文的主要目标就需要结合它来实现了;

详细的介绍及特性描述参考官方文档:什么是 Amazon Lambda?

除了Amazon Lambda,亚马逊云科技还提供了很多其他的免费云产品,了解详情可以访问:亚马逊云科技

1729825727.png

2.2 定价

Amazon Lambda是通过运行时间和请求数量来计费的,同时亚马逊云科技提供了一定的免费使用额度;

image-20241024144338126

免费额度包括:每月 1000000 次免费请求和每月 40 万 GB-秒或 320 万秒的计算时间;

这个 GB-秒 其实就是计算时间和内存结合的度量单位,假设你分配了 1 GB 内存给你的Lambda函数,然后这个函数运行了 1 秒,那么你运行一次,就花了 1 GB-秒;

那么这个 320 万秒的时间,也就是你函数最长的运行时间,假如你函数分配的内存是 100 MB ,那么你运行 320 万秒其实才花 31 万多 GB-秒;即使没超过40 万 GB-秒,也超出了免费套餐;

但是这个额度,对于个人或者小需求的用户来讲,已经非常的宽裕了;

你也可以通过Amazon Lambda 定价计算器估算你的需求:

image-20241024144732000

计算的项目是很详细的:

image-20241024144747804

3 逻辑梳理

3.1 关键概念

在使用之前需要了解一些关键的概念,不然的话,后面的东西可能也是云里雾里的;

官方文档:了解关键的 Lambda 概念

简单总结一下:

  1. 函数(Function):Lambda 函数是用户上传的业务逻辑代码,可响应触发器执行,代码文件被称为部署程序包。

  2. 触发器(Trigger):触发器是 Lambda 执行的起点,定义 Lambda 被调用的事件源。事件源可以是 HTTP 请求(通过 API Gateway)、S3 存储事件、DynamoDB 数据变化等。

  3. 事件(Event):触发 Lambda 的具体数据。Lambda 在被调用时会获取事件数据,并将其作为输入传递给函数。

  4. 执行环境(Execution Environment):Lambda 的隔离运行环境,包含 OS、运行时、层等组件。每次触发,Lambda 会为每个函数实例创建隔离环境。

  5. 部署程序包(Deployment Package):用户上传的代码及其依赖项,以 ZIP 文件或容器镜像格式存储在 Lambda。

  6. 运行时(Runtime):Lambda 支持的编程语言环境(如 Python、Node.js),提供函数代码执行所需的语言依赖及生命周期管理。

  7. 层(Layer):用于将共享的代码库或依赖分离出来,以便不同 Lambda 函数共用。

  8. 并发(Concurrency):每个函数的并发执行次数。Lambda 自动扩展并发处理请求,但可以为函数设定最大并发数。

  9. Qualifier:Lambda 函数的版本或别名,可在部署过程中创建,以支持不同的代码版本管理。

  10. 目标位置(Destination):Lambda 可以将执行的结果或错误消息发送到目标服务,如 SNS、SQS 或 EventBridge。

3.2 逻辑流程

以下是 Amazon Lambda 的逻辑架构图,展示了 Lambda 的执行流程,包含触发器、事件、执行环境及目标位置等关键组件:

1729828106.png

  1. 触发阶段

    • 触发器引发事件(如 HTTP 请求、S3 文件更新),触发器向 Lambda 提供事件数据作为输入。
  2. 执行环境准备

    • Lambda 会为函数创建一个隔离的执行环境,包括初始化层、运行时及共享资源(如第三方依赖)。
  3. 代码部署和执行

    • Lambda 部署程序包进入执行环境,运行时加载程序包中的代码并开始执行。
    • 函数代码通过层加载共用依赖,并通过运行时执行代码逻辑。
  4. 并发和伸缩管理

    • Lambda 会自动扩展处理多个并发请求,同时通过并发限制管理资源使用。
  5. 返回结果至目标位置

    • Lambda 执行结束后,返回结果或错误信息,并将结果发送至指定的目标位置(如 SNS、SQS)。
  6. 版本控制

    • Lambda 允许创建不同版本或别名(Qualifier),支持多版本的分发和管理,方便代码变更追踪和灰度发布。

3.3 本文案例流程架构

通过上面的梳理,我们基本确定,要使用Amazon Lambda的话,一定需要一个触发器来触发对应的函数;

我们本次的目标是弄一个API的服务,所以我们需要使用亚马逊云科技的另外一个服务 Amazon API Gateway来作为触发器

  • Amazon API Gateway 简介

Amazon API Gateway 是一项亚马逊云科技服务,用于创建、发布、维护、监控和保护任意规模的 REST、HTTP 和 WebSocket API。API 开发人员可以创建能够访问 Amazon 或其他 Web 服务以及存储在 Amazon 云中的数据的 API。

Amazon API Gateway也是可以免费试用的:

image-20241025120126445

我这里不做它过多的介绍,后续有机会的话,可以再详细的研究一下,可以查看官方文档了解更多;

它在这个案例中主要的作用就是来触发函数并提供 api 接口,由 Lambda 提供主要计算逻辑;

那么我们案例的流程架构如下:

1729824582.png

4 开始实践

4.1 前置条件

  • 你需要有一个亚马逊云科技的账户,如果没有注册的话,可以进入 亚马逊云科技 官网了解更多免费服务并注册;

4.2 创建一个 Lambda 函数

进入控制台后,选择Lambda服务

image-20241024144210971

点击创建按钮

image-20241024144944738

选择从头开始创作;

配置函数名称、运行时环境、主要架构;

image-20241024150102927

这里有个默认执行角色的配置项;

可以先不做修改,后面有机会再来琢磨这个权限的使用方法;

image-20241024150556821

其他设置,这里也先不用改,默认配置就行;

这些配置项大致功能和用途介绍:

  1. 启用代码签名信息

    • 功能:启用代码签名后,Lambda 函数的代码必须通过由受信任的实体进行签名。这确保了代码的来源已被验证,并且在签名后未被篡改。
    • 用途:确保安全性,防止恶意代码被部署在 Lambda 中。通过这种方式,你可以设置代码必须由可信任开发人员或构建管道进行签名,符合公司安全策略或合规要求。
  2. 启用函数 URL 信息

    • 功能:启用函数 URL 后,你将为 Lambda 函数分配一个 HTTP(S) 终端节点。这意味着你可以直接通过此 URL 发起 HTTP 请求调用 Lambda 函数。
    • 用途:为 Lambda 函数创建公共或受限制的 API 接口,无需使用 API Gateway。适合轻量级的 HTTP 请求场景,如直接通过浏览器或第三方应用程序访问 Lambda。
  3. 启用标签信息

    • 功能:标签是键值对形式的标记,用于标识和组织亚马逊云科技资源。每个 Lambda 函数可以关联多个标签,帮助你管理和分类资源。
    • 用途:便于成本跟踪、资源管理和权限控制。你可以通过标签筛选资源、查看某类资源的成本,以及在基于属性的访问控制策略中使用标签来定义权限。
  4. 启用 VPC 信息

    • 功能:启用后,Lambda 函数将连接到你的 VPC(Virtual Private Cloud,虚拟私有云)。这允许 Lambda 函数在调用时访问 VPC 内的私有资源,例如数据库或内部服务。
    • 用途:当 Lambda 需要访问受保护的资源(例如,RDS、ElastiCache)时,通过将其连接到 VPC,可以确保这些资源不会暴露在公共互联网上,增强了安全性和网络隔离性。

image-20241024150251739

配置好后点击创建,然后就进来了:
image-20241024150715312

直接运行测试一下示例代码;

运行成功,说明函数没问题了;

image-20241024180725965

4.3 配置API Gateway

前面流程架构里面已经说了需要配置 API Gateway 结合使用了;

所以我们先走通流程;

点击配置,选择触发器,然后添加触发器;

image-20241024180909578

选择API Gateway

image-20241024180930800

选择创建新的 API,创建一个HTTP API;配置好其他的参数;打开安全性和CORS;

image-20241024181017753

然后直接点击节点 URL 测试;

image-20241024181054674

测试效果如下,现在基本流程就通了;

image-20241024181110780

4.4 Lambda 获取 API Gateway传递的事件参数

Amazon API Gateway 会使用包含 HTTP 请求的 JSON 表示形式的事件同步调用函数。对于自定义集成,该事件为请求的正文。对于代理集成,该事件具有已确定的结构。

我们用的是代理集成,所以要确认一下 Amazon Lambda 获取 event的方式;

代理集成,API Gateway 传递过来的事件并不是直接由请求组成的正文,而是这样的:

{"resource": "/","path": "/","httpMethod": "GET","requestContext": {"resourcePath": "/","httpMethod": "GET","path": "/Prod/",...},"headers": {"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9","accept-encoding": "gzip, deflate, br","Host": "70ixmpl4fl.execute-api.us-east-2.amazonaws.com","User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36","X-Amzn-Trace-Id": "Root=1-5e66d96f-7491f09xmpl79d18acf3d050",...},"multiValueHeaders": {"accept": ["text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"],"accept-encoding": ["gzip, deflate, br"],...},"queryStringParameters": null,"multiValueQueryStringParameters": null,"pathParameters": null,"stageVariables": null,"body": null,"isBase64Encoded": false}

你也可以通过下面的代码来查看返回的事件

import jsondef lambda_handler(event, context):# TODO implementreturn {'statusCode': 200,'body': json.dumps(event, indent=4, default=str)}

综合来看,就是如果使用代理集成,我们的 Lambda 函数中需要通过 queryStringParameters 或其他参数来获取客户端传递过来的具体的参数值;

4.5 写一个简单的计算器

那我们进一步实践一下,写一个简单的计算器,代码如下:

import jsondef lambda_handler(event, context):# 从查询字符串参数中解析输入事件以获取数字和运算符try:num1 = float(event['queryStringParameters']['num1'])num2 = float(event['queryStringParameters']['num2'])operator = event['queryStringParameters']['operator']# 根据运算符执行运算if operator == 'add':result = num1 + num2elif operator == 'subtract':result = num1 - num2elif operator == 'multiply':result = num1 * num2elif operator == 'divide':# 检查除数是否为0if num2 == 0:return {'statusCode': 400,'body': json.dumps({'error': 'Cannot divide by zero'})}result = num1 / num2else:return {'statusCode': 400,'body': json.dumps({'error': 'Invalid operator'})}# 返回结果return {'statusCode': 200,'body': json.dumps({'result': result}, indent=4)}except (ValueError, TypeError, KeyError) as e:# 如果输入不是有效的数字或运算符,返回错误信息return {'statusCode': 400,'body': json.dumps({'error': 'Invalid input'}, indent=4)}

在代码中粘贴上面的代码;然后 deploy 部署一下;

image-20241024181200873

等待部署完了之后,还是上面配置的 Gateway 的那个url;

进入 Postman 测试一下,测试结果如下:

image-20241024181408413

浏览器测试也可以,可以发现接口完全没问题

image-20241024181458566

4.6 写一个随机图片接口

再简单扩展一下,这里就自定义一个列表,写入几个图片url;

进阶的可以结合Amazon S3等产品使用;

这里先简单实现:

import json
import randomdef lambda_handler(event, context):# 定义图片URL列表image_urls = ["https://s2.loli.net/2024/10/24/rQT7SwhpzM8BWiX.jpg","https://s2.loli.net/2024/10/24/qnzo8eZuXs73gAd.jpg","https://s2.loli.net/2024/10/24/TIPSGQNxv4tC6Bq.jpg","https://s2.loli.net/2024/10/24/VgqiAGTW2rULuek.jpg","https://s2.loli.net/2024/09/12/7Ev1936CLn2toRq.jpg"]# 从列表中随机选择一个URLrandom_image_url = random.choice(image_urls)# 返回随机选择的图片URLreturn {'statusCode': 200,'body': json.dumps({'imageUrl': random_image_url}, indent=4)}

浏览器测试一下,完全没问题

image-20241024183010714

4.7 实现一个 jieba 分词工具

来,再扩展一下,直接 jieba

先不考虑 API Gateway 传递 event 参数,所以直接获取 text 参数:

import json
import jiebadef lambda_handler(event, context):# 从事件对象中获取文本text = event.get('text', '')# 使用 jieba 进行分词words = jieba.cut(text)# 将分词结果转换为列表words_list = list(words)# 返回分词结果return {'statusCode': 200,'body': json.dumps({'words': words_list}, indent=4, ensure_ascii=False)}

直接测试下先,然后就报错了

image-20241024225553188

这就说明默认的运行环境中是没有第三方库的;

4.8 解决没第三方库的问题(上传本地代码)

我目前了解的有两种办法

4.8.1 将依赖的库一起打包

在本地新建一个目录,然后里面新建一个Lambda函数文件,也就是lambda_function.py

在文件里面写上刚才的jieba分词代码;

然后pip3 install --target=.\ jieba把 jieba 依赖下载到和代码同一目录下:

image-20241024232315249

目录结构如下:

image-20241024232404271

然后把它们一起打一个 zip 包,结构如图:

image-20241024232449763

回到 Amazon 控制台,上传代码:

image-20241024232537752

image-20241024232607266

上传后的函数目录结构如下,和本地目录一致:

image-20241024232707525

然后在测试中配置好事件参数后运行;

image-20241024232837019

ok,失败了!

看下报错:Task timed out after 3.04 seconds

还好,问题不大,就是因为 jieba 需要的资源稍微有点大,改下资源分配就行;

image-20241024232850228

进入配置菜单,在常规配置中配置;可以看到默认分配 128 MB的空间,超时是 3s ,所以错误也正常:

image-20241024232936433

点击编辑,按照你的需求改一下:

image-20241024232948677

回去再测试一下,大功告成:

image-20241024233044471

可以查看运行结果,效果不错:

image-20241024233106726

4.8.2 Amazon Lambda层

这里就需要引入Lambda层的概念;

Amazon Lambda 层 是 Amazon Lambda 中的一种机制,旨在让开发者能够重用代码库、依赖项、或常用资源,以便在多个 Lambda 函数之间共享这些资源,而无需将其打包到每个函数代码中。

层的概念

层的核心思想是将某些通用的库、依赖项、配置文件等打包成一个独立的(Layer),然后将该层与多个 Lambda 函数关联,减少冗余,提高管理和维护的效率。可以包含库(如第三方依赖包)、自定义运行时、共享的配置文件,甚至是自定义代码片段。

  • Lambda 层的优势
  1. 减少代码重复:多个 Lambda 函数可以引用同一个层,因此无需在每个函数代码包中重复添加相同的依赖库或资源。
  2. 简化管理:通过集中管理常用的依赖库,开发者只需更新层,而不需要分别更新每个 Lambda 函数中的依赖。
  3. 加速部署:Lambda 函数代码包不再需要包含依赖库,从而减小代码包的体积,减少上传和部署时间。
  4. 版本控制:每个层都可以有多个版本,Lambda 函数可以选择使用特定版本的层,从而支持依赖库的版本管理。

Lambda 层的原理

Lambda 层的原理是通过将一些资源与 Lambda 函数的执行环境隔离开来,当 Lambda 函数执行时,Lambda 会将所需的层加载到函数的运行时环境中,从而使函数能够访问层中的资源。

  • 运行时整合:Lambda 函数执行时,会自动将关联的层中的文件加载到 /opt 目录中,供 Lambda 函数调用。

    • 层中的内容会根据类型放置在 /opt/ 下的特定路径中,例如:

      库文件:Python 库或 Node.js 模块会被放置在 /opt/python/opt/nodejs

      二进制文件:如果层中包含某些可执行文件或二进制库,这些也会被放在 /opt 目录下的某些子目录中。

  • 多层支持:一个 Lambda 函数最多可以引用 5 个层,会按顺序将这些层加载,层之间的文件可能会覆盖,后加载的层会覆盖先加载的层的文件。

  • 跨账户共享:层可以在亚马逊云科技账户内或跨账户共享,这样一个账户的用户可以创建和维护层,其他账户的用户也能使用这些层。

使用 Lambda 层的步骤

  1. 创建层:将依赖包或代码打包为 .zip 文件,并将其上传作为一个 Lambda 层。
  2. 配置函数使用层:在 Lambda 函数的设置中,选择将该层添加到函数中。可以选择层的版本。
  3. 在函数中引用层的资源:例如,使用 Python 时,层中的依赖库会放在 /opt/python 目录中,所以你可以像平常一样 import 这些库。

层的使用场景

  1. 第三方库管理:假如多个 Lambda 函数都需要用到同样的第三方依赖库(例如 requestsnumpy),可以把这些库打包成一个层,让所有函数都可以复用它,而不必每次都在函数代码中包含这些库。
  2. 自定义运行时:如果您想在 Amazon Lambda 中使用官方不支持的编程语言(如 Rust 或 Erlang),可以创建一个自定义运行时,并将其作为一个层进行上传,供 Lambda 函数使用。
  3. 共享工具集:如果多个 Lambda 函数需要使用相同的工具或二进制文件,例如加密工具、数据库连接工具等,可以将这些工具打包成层。

层的限制

  1. 大小限制:每个层的最大大小为 250 MB(压缩后的大小)。
  2. 层的数量:每个 Lambda 函数最多可以关联 5 个层,因此层的数量需要合理规划。
  3. 跨区域不可用:层是区域特定的,不能跨区域使用(但可以通过跨区域复制层来实现相同层在不同区域的使用)。

所以我们需要创建层;

首先先把依赖打包一下:pip3 install --target=.\python jieba

在本地把依赖安装到 python 目录下;

image-20241024235756032

然后打个 zip 压缩包;

这里注意一下目录结构和名称(目录不规范的时候,会报错)

当向函数添加层时,Lambda 会将层内容加载到该执行环境的 /opt 目录中。对于每个 Lambda 运行时系统,PATH 变量都包括 /opt 目录中的特定文件夹路径。为确保 PATH 变量能够获取层内容,层 .zip 文件应在以下文件夹路径中具有依赖项:

image-20241025132812302

构建 python.zip 存档的文件夹架构:

layer_content.zip
└ python└ lib└ python3.11└ site-packages└ requests└ <other_dependencies> (i.e. dependencies of the requests package)...

也就是你依赖得放到 python 目录下

image-20241024235735297

进入控制台,点击创建层:

image-20241024233457557

配置好层名称及其他关键参数并上传 zip 压缩包:

image-20241025000052274

回到 Lambda 函数,划到代码最下面,点击添加层;

image-20241024234032416

选择自定义层,然后选择创建的层和版本;

image-20241025000153822

回到代码上方的示意图,可以看到函数下已经有了一个 layer 了;

image-20241024234133446

此时的代码结构也只有一个主要的 python 代码文件了:

image-20241024234148489

进入测试,运行成功:

image-20241025000305065

4.9 制作 jieba 分词 API

上面仅仅实现了在 Lambda 中运行,但是还没做成 API;

要结合 API Gateway 就需要改一下代码,保证从 API Gateway 传递过来的 event json 中获取到参数:

import json
import jiebadef lambda_handler(event, context):# 从事件对象中获取查询字符串参数query_params = event.get('queryStringParameters', {})# 从查询参数中获取'text'字段的值text = query_params.get('text', '')# 使用 jieba 进行分词words = jieba.cut(text)# 将分词结果转换为列表words_list = list(words)# 返回分词结果return {'statusCode': 200,'body': json.dumps({'words': words_list}, indent=4, ensure_ascii=False)}

接着怎么结合 API Gateway 就不多说了,前面章节说了;

测试一下,大功告成:

image-20241025001048029

5 总结与扩展

5.1 待探索

这次仅仅是打通了一下基本流程,还有很多东西都需要琢磨;

包括和其他亚马逊云科技的服务集成、Amazon API Gateway的详细使用方法、Amazon Lambda的进阶使用方法(权限、事件和触发器、函数代码和性能优化、监控和日志、自动化或半自动化部署等);

要研究的比较透彻的话,还需要投入很多,但是一边学一边实践的话,应该还是很快的;

5.2 一个无敌的 python 库

这里推荐一个开源的 pythonpython-lambda,我还没正式研究过,就大致看了一下,用了它应该是事半功倍的!

地址:python-lambda

python-lambda 是一个开源库,旨在简化 AWS Lambda 函数的创建和管理。提供了一系列工具和功能,帮助开发者更轻松地构建无服务器应用程序。以下是该库的一些关键特性和功能的详细介绍:

  • 主要特性

    1. 简化的函数定义

      • python-lambda 提供了一种简化的方式来定义 Lambda 函数,允许开发者用更少的代码来创建和部署函数。
    2. 集成的本地开发环境

      • 提供了本地开发和测试的支持,允许开发者在本地运行和调试 Lambda 函数,而无需频繁部署到 AWS。
    3. 自动化部署

      • 支持将 Lambda 函数及其相关资源自动部署到 AWS。开发者只需简单的命令即可完成整个部署过程。
    4. 支持 API Gateway

      • 可以轻松创建和管理与 AWS API Gateway 的集成,使得 Lambda 函数能够通过 HTTP 请求触发。
    5. 环境变量管理

      • 支持管理 Lambda 函数的环境变量,确保敏感信息和配置信息的安全存储。
    6. 多种事件源支持

      • 能够处理多种事件源,如 S3、DynamoDB、SNS 等,开发者可以轻松地将函数与这些服务集成。
    7. 灵活的依赖管理

      • 支持自定义依赖项的管理,开发者可以在项目中轻松集成第三方库。

5.3 总结

本文基本上完成了从理论到实践,涵盖了无服务器架构的基础知识、Amazon LambdaAPI Gateway 的配置与使用,以及如何构建具体的无服务器应用程序。但是要正式投入相关的研发,还需要研究的东西还有很多。如果你有什么好的想法和点子,欢迎一起讨论!

最后还是得说下亚马逊云科技提供的免费云产品真的很不错,很适合开发者去学习!


  1. 看完这篇你就知道什么是无服务器架构了 ↩︎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/477455.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络爬虫总结与未来方向

通过深入学习和实际操作&#xff0c;网络爬虫技术从基础到进阶得以系统掌握。本节将全面总结关键内容&#xff0c;并结合前沿技术趋势与最新资料&#xff0c;为开发者提供实用性强的深度思考和方案建议。 1. 网络爬虫技术发展趋势 1.1 趋势一&#xff1a;高性能分布式爬虫 随…

实验十三 生态安全评价

1 背景及目的 生态安全是生态系统完整性和健康性的整体反映&#xff0c;完整健康的生态系统具有调节气候净化污染、涵养水源、保持水土、防风固沙、减轻灾害、保护生物多样性等功能。维护生态安全对于人类生产、生活、健康及可持续发展至关重要。随着城市化进程的不断推进&…

archlinux安装waydroid

目录 参考资料 注意 第一步切换wayland 第二步安装binder核心模组 注意 开始安装 AUR安裝Waydroid 启动waydroid 设置网络&#xff08;正常的可以不看&#xff09; 注册谷歌设备 安装Arm转译器 重启即可 其他 参考资料 https://ivonblog.com/posts/archlinux-way…

鸿蒙NEXT开发案例:随机数生成

【引言】 本项目是一个简单的随机数生成器应用&#xff0c;用户可以通过设置随机数的范围和个数&#xff0c;并选择是否允许生成重复的随机数&#xff0c;来生成所需的随机数列表。生成的结果可以通过点击“复制”按钮复制到剪贴板。 【环境准备】 • 操作系统&#xff1a;W…

【Android】Service使用方法:本地服务 / 可通信服务 / 前台服务 / 远程服务(AIDL)

1 本地Service 这是最普通、最常用的后台服务Service。 1.1 使用步骤 步骤1&#xff1a;新建子类继承Service类&#xff1a;需重写父类的onCreate()、onStartCommand()、onDestroy()和onBind()方法步骤2&#xff1a;构建用于启动Service的Intent对象步骤3&#xff1a;调用st…

【LeetCode热题100】队列+宽搜

这篇博客是关于队列宽搜的几道题&#xff0c;主要包括N叉树的层序遍历、二叉树的锯齿形层序遍历、二叉树最大宽度、在每个数行中找最大值。 class Solution { public:vector<vector<int>> levelOrder(Node* root) {vector<vector<int>> ret;if(!root) …

双因子认证:统一运维平台安全管理策略

01双因子认证概述 双因子认证&#xff08;Two-Factor Authentication&#xff0c;简称2FA&#xff09;是一种身份验证机制&#xff0c;它要求用户提供两种不同类型的证据来证明自己的身份。这通常包括用户所知道的&#xff08;如密码&#xff09;、用户所拥有的&#xff08;如…

Apple Vision Pro开发002-新建项目配置

一、新建项目 可以选择默认的&#xff0c;也可以选择Universal 3D 二、切换打包平台 注意选择Target SDK为Devices SDk&#xff0c;这种适配打包到真机调试 三、升级新的Input系统 打开ProjectSettings&#xff0c;替换完毕之后引擎会重启 四、导入PolySpatial 修改上图红…

瑞佑液晶控制芯片RA6807系列介绍 (三)软件代码详解 Part.10(让PNG图片动起来)完结篇

RA6807是RA8876M的缩小版&#xff0c;具备RA8876M的所有功能&#xff0c;只将MCU控制接口进行缩减&#xff0c;仅保留SPI-3和I2C接口&#xff0c;其它功能基本相同。 该芯片最大可控制854x600的分辨率&#xff0c;内建64Mbits显存&#xff0c;多个图层&#xff0c;使用起来相当…

机器人SLAM建图与自主导航:从基础到实践

前言 这篇文章我开始和大家一起探讨机器人SLAM建图与自主导航 &#xff0c;在前面的内容中&#xff0c;我们介绍了差速轮式机器人的概念及应用&#xff0c;谈到了使用Gazebo平台搭建仿真环境的教程&#xff0c;主要是利用gmapping slam算法&#xff0c;生成一张二维的仿真环境…

一篇保姆式centos/ubuntu安装docker

前言&#xff1a; 本章节分别演示centos虚拟机&#xff0c;ubuntu虚拟机进行安装docker。 上一篇介绍&#xff1a;docker一键部署springboot项目 一&#xff1a;centos 1.卸载旧版本 yum remove docker docker-client docker-client-latest docker-common docker-latest doc…

Robot | 用 RDK 做一个小型机器人(更新中)

目录 前言架构图开发过程摄像头模型转换准备校准数据使用 hb_mapper makertbin 工具转换模型 底版开发 结语 前言 最近想开发一个小型机器人&#xff0c;碰巧看到了 RDK x5 发布了&#xff0c;参数对于我来说非常合适&#xff0c;就买了一块回来玩。 外设也是非常丰富&#xf…

如何在 UniApp 中实现 iOS 版本更新检测

随着移动应用的不断发展&#xff0c;保持应用程序的更新是必不可少的&#xff0c;这样用户才能获得更好的体验。本文将帮助你在 UniApp 中实现 iOS 版的版本更新检测和提示&#xff0c;适合刚入行的小白。我们将分步骤进行说明&#xff0c;每一步所需的代码及其解释都会一一列出…

软件工程导论 选填题知识点总结

一 原型化方法是一种动态定义需求的方法&#xff0c;提供完整定义的需求不是原型化方法的特征&#xff0c;其特征包括尽快建立初步需求、简化项目管理以及加强用户参与和决策。 软件危机的表现包括用户对已完成的软件系统不满意的现象经常发生、软件产品的质量往往靠不住、软件…

软件测试面试之常规问题

1.描述一下测试过程 类似题目:测试的生命周期 思路:这是一个“范围”很大的题目&#xff0c;而且回答时间一般在3分钟之内&#xff0c;不可能非常详细的描述整个过程&#xff0c;因此答题的思路要从整体结构入手&#xff0c;不要过细。为了保证答案的准确性&#xff0c;可以引…

Linux|内存级文件原理

目录 进程与文件 Linux下的文件系统 文件操作&#xff0c;及文件流 C语言函数 文件流 文件描述符 系统调用操作 系统调用参数 重定向与文件描述符 输出重定向 输入重定向 文件内容属性 Linux下一切皆文件 进程与文件 当我们对文件进行操作时&#xff0c;文件必须…

洛谷 P1722 矩阵 II C语言 记忆化搜索

题目&#xff1a; https://www.luogu.com.cn/problem/P1722 我们按照案例画一下 我们会发现&#xff0c;会出现重复的子结构。 代码如下&#xff1a; #include<iostream> using namespace std; int mem[300][300]; int n; int f[305][305]; int dfs(int x,int red,…

RTSP播放器EasyPlayer.js播放器分辨率高的视频在设置container的宽高较小时,会出现锯齿状的画面效果

流媒体播放器的核心技术及发展趋势展现了其在未来数字生活中的无限潜力。随着技术的不断进步和市场的持续发展&#xff0c;流媒体播放器将在内容创新、用户体验优化以及跨平台互通等方面取得新的突破。对于从业者而言&#xff0c;把握这些趋势并积极应对挑战将是实现成功的关键…

半导体、晶体管、集成电路、芯片、CPU、单片机、单片机最小系统、单片机开发板-概念串联辨析

下面概念定义从小到大串联&#xff1a; 半导体&#xff08;semiconductor&#xff09;&#xff1a; 是一类常温下导电性能介于导体与绝缘体之间的材料&#xff0c;这种材料的导电性可以随着外部环境比如电压、温度、光照的变换而改变&#xff0c;导电特性区别于导体、超导体、…

WebStorm 2024.3/IntelliJ IDEA 2024.3出现elementUI提示未知 HTML 标记、组件引用爆红等问题处理

WebStorm 2024.3/IntelliJ IDEA 2024.3出现elementUI提示未知 HTML 标记、组件引用爆红等问题处理 1. 标题识别elementUI组件爆红 这个原因是&#xff1a; 在官网说明里&#xff0c;才版本2024.1开始&#xff0c;默认启用的 Vue Language Server&#xff0c;但是在 Vue 2 项目…