依赖项的处理与层的创建与注册
依赖项的处理与层的创建与注册
- 依赖项的处理与层的创建与注册
- 新问题
- 什么是
layer
? layer
的创建与注册- 与函数同时创建和绑定
- 单独上传
layer
再绑定函数(推荐)
- 真正的运行时依赖
- 注册包的约定
- 与平台强关联的运行时
- 1. 云端安装依赖
- 2. 本地构建
Amazon Linux 2
容器环境 - 3. 利用 CI 构建并进行上传和部署
- 镜像部署
- Next Chapter
- 完整示例及文章仓库地址
新问题
在一个 nodejs
函数里,我们往往会去安装和使用各种各样的依赖包,来辅助我们项目的开发。
这些依赖以及对应的版本都被注册在了 package.json
里 (由 npm init
创建)。在安装依赖之后,它们会被存放在当前项目的 node_modules
目录里。而 sls deploy
默认也会把 node_modules
里所有文件,打包压缩后,和代码一起上传到云上。这点很好理解,没有依赖项,函数压根跑不起来。
但是当我们 node_modules
依赖足够大,足够深之后,整个 node_modules
就会变成一个黑洞。随随便便就有 1GB/2GB
甚至更多,这时候去进行 sls deploy
就会变成一种折磨,因为要压缩 node_modules
,这个行为耗时太长了,即使压缩好了,上传到 S3
对象存储也要花费很久的时间。
如何解决? 这时候就需要让我们的 layer
(层)出场了。
什么是 layer
?
layer
你可以理解成,预先放置在我们 Lambda
函数容器中的文件包,你可以在里面放一些代码,库,数据文件,配置文件甚至是一些自定义语言运行时。比如我在使用的时候,往往会把 运行时
依赖的包,打成 zip
上传上去,又或者有些爬虫函数,需要使用 chromium
来模仿用户的行为,那么这种case
则需要在 layer
里面直接内置一个 headless chromium
。
这些文件最终都会被挂载到函数容器中的 /opt
目录。
layer
的创建与注册
这里我给出一个示例,假设运行时的依赖只有 uuid
(假设我们只依赖这一个包)
我们现在项目中安装 npm i uuid
并使用它:
// index.ts
import { v4 } from 'uuid'
v4()
// ...code...
这时候 uuid
在函数package.json
这一层的 node_modules
文件夹里,测试运行后,运转良好。
让我们在当前目录下,创建一个 layers
文件夹,然后再在里面创建一个 uuid
(名称可自定义)文件夹,创建 package.json
并写入:
{"dependencies": {"uuid": "^9.0.0"}
}
layers/uuid/package.json#dependencies
字段中的uuid
即为你主目录下安装的版本。
然后执行 npm i
/yarn
安装依赖 (不要使用pnpm
),安装完成后会出现 layers/uuid/node_modules
文件夹,接下来就可以 layer
的上传和绑定了。
与函数同时创建和绑定
我们可以复用原先部署函数的那个 serverless.yml
文件,让它不但部署函数,也同时创建 layer
并进行绑定。具体配置如下:
layers:# layer 配置uuid:# 路径path: layers/uuid# aws lambda layer 里的名称name: ${sls:stage}-uuidfunctions:api:# ...package:individually: true# 既然我们把所有运行时都打成 layer 了自然不用上传 node_modules 了patterns:- "!node_modules/**"# layer 绑定配置layers:# 绑定 UuidLambdaLayer- !Ref UuidLambdaLayerenvironment:# 环境变量,告诉函数应该从哪里找依赖NODE_PATH: "./:/opt/node_modules"
其中最重要的就是2
个layers
的配置了,其中 !Ref UuidLambdaLayer
这个其实就是引用了layers.uuid
,只不过它的命名是一种约定,即 uuid
的 u
大写加上 LambdaLayer
,于是就变成了 UuidLambdaLayer
了,命名规则为 layer
名称的 Title_Case
加 LambdaLayer
。
注意!
NODE_PATH: "./:/opt/node_modules"
这个环境变量是必不可少的,不然会导致无法从layer
中加载node_modules
相关配置的参考链接
此时使用 sls package
会在 .serverless
目录下生成 2
个 zip
:
api.zip
函数代码包uuid.zip
layer包
这2
个压缩包的名字,就是我们在 serverless.yml
注册的名字。
sls deploy
会把它们依次上传,先layer
后function
,并把layer
上传部署后的结果,注册进我们的function
,从而达成绑定的效果。
单独上传 layer
再绑定函数(推荐)
除了与函数同时创建和绑定的形式,我们还可以分步骤单独上传 layer
再绑定函数,这也是我推荐的方式。
这个就顾名思义,我们可以先上传layer
拿到结果,在把结果写到函数的 serverless.yml
中去。这样步骤方面分为了 2
步,但是好处却是显而易见的。
它适用于这样的场景,我们的 layer
包很大,且不经常更新,这种情况是没有必要每次都去打包上传 layer
的。
我们部署只需要部署我们自己的函数代码,然后告诉 AWS
应该去绑定哪个 layer
的哪个版本就行。
按照这样的思路,我们就可以把刚刚那个 serverless.yml
拆成 2
个 yml
文件:
- 单独上传
layer
配置文件 - 函数的
deploy
配置文件,加一行绑定layer
的配置即可
单独部署 layer
的配置,内容如下:
# layers/serverless.yml
layers:uuid:path: uuidname: ${sls:stage}-uuid
执行 sls deploy
后上传部署成功会显示:
layers:uuid: arn:aws-cn:lambda:cn-northwest-1:000000000000:layer:dev-uuid:2
这一个字符串就是接下来我们需要写入函数 yml
配置进行绑定的关键,当然当时没保存刷了terminal
也没关系,这个信息通过在当前目录执行 sls info
还会显示出来。
接下来我们去函数的 yml
配置去绑定 layers
:
# serverless.yml
functions:api:# ....layers:# - !Ref UuidLambdaLayer 改为- arn:aws-cn:lambda:cn-northwest-1:000000000000:layer:dev-uuid:2
这样再在函数这一层执行 sls deploy
这层绑定关系就完成了,同时上传速度也要比 与函数同时创建和绑定
快不少,因为这种方法只要上传函数的代码包,再通过调用 AWS API
告诉它们这层绑定关系即可。
真正的运行时依赖
之前有一个细节没有讲,为什么我们上传 layer
是单独建一个 layers
的目录,在里面单个单个上传,而不是把外面函数的 node_modules
整个打包上传上去呢?
其实那样也可以,但是不够完美,因为这样做会导致layer
代码包中的文件,过于冗余。
举个简单的例子,默认情况下 npm
安装包时,会把 devDependencies
和 dependencies
都安装在 node_modules
。
比如 dependencies
里就是一些 express
/lodash
啥的,devDependencies
里面就是 eslint
/sass
/webpack
这些开发时用的包,运行代码的时候用不着。
这时候,你直接打包上传 node_modules
显然是可以的,因为你所有的运行时依赖已经在里面了,不幸的是 eslint
等等许多无关紧要的包也进去了,这些加起来有可能会占用你 layer
包整体体积的一般以上甚至更多,显然这是没有必要的。
所以,你必须找到真正的运行时依赖!
注册包的约定
首先你必须在安装包时正确的注册 devDependencies
和 dependencies
。
我们把运行时用的到的放在 dependencies
里,到时候也从这里面抽出包名和版本,做成 layer
。至于devDependencies
里我们只会把那些开发时用得到的包放在里面,它们就没有必要上传了,本地运行即可。
与平台强关联的运行时
其次你必须很清楚你的运行时是 nodejs
而不是什么浏览器。
虽然说 nodejs
是跨平台的,但是我们使用的第三方库里,有时候会存在着很多和平台强关联的二进制文件。
比如有些包会在下载下来之后,调用 postinstall
脚本获取我们的系统信息(平台,cpu架构),然后根据这些信息去使用不同的二进制文件。
又或者有些包基于 C++ addons
的,安装好之后,才在我们机器上实时去编译,生成适配我们系统平台的二进制文件。
这就导致一个问题,假如你直接用 win/macos
开发,你安装的二进制包,大概率无法在 aws lambda
环境下运行,因为它的环境是 Amazon Linux 2
所以,我们应该在挑选与线上 Lambda 运行时,相似的容器中,进行开发,上传代码和层 (layer)
具体怎么做呢?这里给出三种解决方案:
1. 云端安装依赖
顾名思义,直接在云上的目标容器环境中进行安装依赖这个行为,这也是最简单的解决方案。
2. 本地构建 Amazon Linux 2
容器环境
这要求我们在 docker
容器中开发,拉下 Amazon Linux 2
的镜像,在里面开发并上传层函数和代码包。
3. 利用 CI 构建并进行上传和部署
这个思路便是,由环境相同或者相似的 CI 容器,进行上传和部署。
比如我们可以利用 Github Action
去构建和上传,大致的配置如下:
name: Layeron:workflow_dispatch:jobs:upload:name: uploadtimeout-minutes: 15strategy:fail-fast: falsematrix:# 找一个相似的镜像 osos: [ubuntu-latest]node-version: [18]runs-on: ${{ matrix.os }}steps:- name: Check out codeuses: actions/checkout@v3with:fetch-depth: 2- name: Configure AWS credentials from Test accountuses: aws-actions/configure-aws-credentials@v3with:aws-region: cn-northwest-1aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}- name: Setup Node.js environmentuses: actions/setup-node@v3with:node-version: ${{ matrix.node-version }}- name: Install Serverlessrun: yarn global add serverless- name: Install puppeteer Layerrun: yarnworking-directory: apps/aws-express-api-ts/layers/puppeteer- name: sls deployrun: yarn deployworking-directory: apps/aws-express-api-ts/layers
镜像部署
当然,假如你使用镜像去部署 lambda
,那以上这些问题都可以避免,但是代价便是冷启动时间比较长。
不过很多技术上的问题,都是可以通过付出更多金钱的方式去解决的,这点就综合考虑利弊吧。
Next Chapter
现在你已经学会了 layer
的用法和一些稀奇古怪的场景。
下一篇,《lambda nodejs 函数降低冷启动时间的最佳实践》中,将会详细介绍如何优化我们自身的代码,欢迎阅读。
完整示例及文章仓库地址
https://github.com/sonofmagic/serverless-aws-cn-guide
如果你遇到什么问题,或者发现什么勘误,欢迎提 issue
给我
相关文章:

依赖项的处理与层的创建与注册
依赖项的处理与层的创建与注册 依赖项的处理与层的创建与注册 新问题什么是 layer?layer 的创建与注册 与函数同时创建和绑定单独上传 layer 再绑定函数(推荐) 真正的运行时依赖 注册包的约定与平台强关联的运行时 1. 云端安装依赖2. 本地构建 Amazon Linux 2 容器环境3. 利用…...

Linux CentOS7 系统中添加用户
在linux centOS7系统中,添加用户是管理员的基本操作。作为学习linux系统的基本操作,对添加用户应该多方面了解。 添加用户的命令useradd,跟上用户名,就可以快速创建一个用户。添加一些选项,可以设置更人性化的用户信息…...

八、任务状态
1、任务状态简介 (1)任务状态可以简单的分为运行和非运行。 (2)非运行状态可以细分为:阻塞状态、暂停状态、就绪状态。 2、阻塞状态(Blocked) (1)举例说明:在日常生活的例子中,母亲在电脑前跟同事沟通时,如果同事一直没回复&a…...
基于python的反爬虫技术的研究设计与实现
摘 要 当下的网络是复杂的,网络上的信息非常的丰富,但也造成了大量的信息堆积,特别是大量的重复信息被反复的推送给用户。这是一个流量的时代,很多社会群体都会聚焦具备流量潜力的信息,从而发生蹭热度等行为来提升自己…...

msvcr120.dll放在哪里?怎么修复msvcr120.dll文件
当您在运行某些应用程序或游戏时遇到“msvcr120.dll缺失”错误时,这可能会影响您的使用体验。msvcr120.dll是Microsoft Visual C Redistributable的一部分,并且它提供了程序运行所需的运行时支持,今天我们来讨论一下msvcr120.dl文件缺失了要怎…...
Ubuntu搭建NFS服务
# 服务器初始化步骤 ## 查看磁盘 fdisk -l ## 格式化磁盘,后面的盘符注意对应关系 mkfs.ext4 /dev/sdc ## 新建文件夹 mkdir /mnt/nfs ## 挂载磁盘到创建的文件夹 echo "/dev/sdc /mnt/nfs ext4 defaults 0 0" >> /etc/fstab ## 重新挂载所有分区…...

PHP教学质量评估系统Dreamweaver开发mysql数据库web结构php编程计算机网页代码
一、源码特点 PHP教学质量评估系统是一套完善的web设计系统,对理解php编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。 代码 https://download.csdn.net/download/qq_41221322/88301983 论文 https://down…...
ElementUI浅尝辄止15:Table 表格
用于展示多条结构类似的数据,可对数据进行排序、筛选、对比或其他自定义操作。 Table组件比较常用,常见于数据查询,报表页面,用来展示表格数据。 1.如何使用? //当el-table元素中注入data对象数组后,在el-t…...
配置LVS_DR模式以及nginx负载均衡
一、配置LVS--DR模式: yum install ipvsadm 配置 LVS 负载均衡服务 ( 1 )手动添加 LVS 转发 1 )用户访问: www.uolookking.com-->vip 192 .168.79.110 ##> 这个是在 DNS 配置 hzitedu 域的 DNS 记录设置 w…...

虚拟数字人直播软件实现带货功能,成为新一代直播风口!
随着短视频带货市场的不断发展,虚拟数字人直播技术逐渐成为热门话题。而在现如今的市场趋势下直播带货则成为了一种火热的营销方式。那么,虚拟数字人直播软件是否可以结合起来,实现无人直播带货的效果呢?让我们来了解一下。 灰豚数…...
01背包问题暴力解法(回溯法)和经典解法
暴力解法(回溯法) import java.util.Arrays; import java.util.Scanner;public class Main {private final static int N 999;public static int SumValue 0;public static int SumWeight 0;public static int OptimalValue 0;public static int O…...

K8S的CKA考试环境和题目
CKA考试这几年来虽然版本在升级,但题目一直没有大的变化,通过K8S考试的方法就是在模拟环境上反复练习,通过练习熟悉考试环境和考试过程中可能遇到的坑。这里姚远老师详细向大家介绍一下考试的环境和题目,需要详细资料的同学请在文…...

docker清理
1. 查看docker 磁盘占用 docker system df 2. 参考: Docker磁盘占用与清理问题_docker system prune_蓝鲸123的博客-CSDN博客...
队列和栈两种数据结构的区别和Python实现
队列和栈是两种数据结构,其内部都是按照固定顺序来存放变量的,二者的区别在于对数据的存取顺序 栈是最后存入的数据最先取出,即后进先出 队列是先存入的数据最先取出,即先进先出 Python实现栈 使用append()方法存入数据,使用pop()方法读取数据 # 定义一个空列表(当做栈使…...

java 企业工程管理系统软件源码+Spring Cloud + Spring Boot +二次开发+ MybatisPlus + Redis
鸿鹄工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离构建工程项目管理系统 1. 项目背景 一、随着公司的快速发展,企业人员和经营规模不断壮大。为了提高工程管理效率、减轻劳动强度、提高信息处理速度和准确性,公司对内部工程管…...

使用Smartctl脚本输入当前所有磁盘的状态
一、安装Smartctl yum install smartmontools 二、写一个脚本输出当前所有磁盘的状态并且按名称分别写入到文件中 #!/bin/bashfor dev in $(lsblk -l | grep disk | awk {print $1}) doecho "检测磁盘 $dev"smartctl -a /dev/$dev > $dev.smartctl done 以下是这…...

数学建模之插值法
目录 1 插值法概述2 插值法原理3 拉格朗日插值4 牛顿插值5 三次Hermite插值(重点)6 三次样条插值(重点)7 各种插值法总结8 n 维数据的插值9 插值法拓展10 课后作业 1 插值法概述 数模比赛中,常常需要根据已知的函数点进…...

rhcsa学习2(vim、创建管理用户、组等)
创建、查看和编辑文本文件 重定向符号 > 进程使用称为文件描述符的编号通道来获取输入并发送输出。所有进程在开始时至少要有三个文件描述符。如果程序打开连接至其他文件的单独连接,则可能要使用更大编号的文件描述符 上述通过通道1去写入,且写入的文…...
【使用教程】Github(自用)
1.下载Git⼯具 使在windows 命令⾏下边可以输⼊这两个命令: gitssh-keygen 2.配置git信息: 在命令⾏⾥输⼊: $ git config --global user.name “你在Github上注册的账号” $ git config --global user.email 你在Github上注册的邮箱 3. c…...

typeScript学习笔记(一)
学习资源来自: 类与接口 TypeScript 入门教程 (xcatliu.com) 一.TypeScript的安装和运行 1.安装TypeScript 通过npm(Node.js包管理器)安装Visual Studio的TypeScript插件:(Visual Studio 2017和Visual Studio 2015 Update 3默认包含了Ty…...

使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...

Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
uniapp中使用aixos 报错
问题: 在uniapp中使用aixos,运行后报如下错误: AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

相关类相关的可视化图像总结
目录 一、散点图 二、气泡图 三、相关图 四、热力图 五、二维密度图 六、多模态二维密度图 七、雷达图 八、桑基图 九、总结 一、散点图 特点 通过点的位置展示两个连续变量之间的关系,可直观判断线性相关、非线性相关或无相关关系,点的分布密…...

解析“道作为序位生成器”的核心原理
解析“道作为序位生成器”的核心原理 以下完整展开道函数的零点调控机制,重点解析"道作为序位生成器"的核心原理与实现框架: 一、道函数的零点调控机制 1. 道作为序位生成器 道在认知坐标系$(x_{\text{物}}, y_{\text{意}}, z_{\text{文}}…...

【若依】框架项目部署笔记
参考【SpringBoot】【Vue】项目部署_no main manifest attribute, in springboot-0.0.1-sn-CSDN博客 多一个redis安装 准备工作: 压缩包下载:http://download.redis.io/releases 1. 上传压缩包,并进入压缩包所在目录,解压到目标…...
电脑桌面太单调,用Python写一个桌面小宠物应用。
下面是一个使用Python创建的简单桌面小宠物应用。这个小宠物会在桌面上游荡,可以响应鼠标点击,并且有简单的动画效果。 import tkinter as tk import random import time from PIL import Image, ImageTk import os import sysclass DesktopPet:def __i…...