使用 HTTPS 代理在本地测试 AWS Lambdas

news2024/11/27 4:23:50

​       欢迎来到雲闪世界。AWS Lambda 通常是在云中部署和执行代码的最简单方法之一,尤其是在使用sam CLI部署代码时。无服务器资源定义的简单性加上在本地打包资源并确保它们在 AWS 上运行的能力,提供了美妙的开发体验。

但有时,当构建和打包步骤增加到十分钟、十五分钟或(哇)更多分钟时,这个漂亮的流程可能会变成一个可怕的部署过程。在一些地方,sam build/sam deploy范式会崩溃并开始导致部署时间失控:

  • 部署中的 Lambda 数量变得很大(例如超过六个)

  • 您的部分或全部 Lambda 需要安装大量资源和/或 Lambda 包大小较大(增加了构建时间和sam将代码放到 S3 上的时间)

  • 您正在同时对两个 Lambda 进行协调更改(在测试之前,需要在 AWS 中更新多个堆栈)

  • 多个人同时在同一个 Lambda 堆栈上进行开发

  • 你的网速很慢(再次延长将 Lambda 包放入 S3 的时间)

由于sam将所有资源部署在 CFT 中,因此您无法有选择地选择要逐步更新哪些资源。其影响是,您需要为要在云中测试的每个部署构建并将所有代码上传到 AWS。当您将代码推送到 AWS 后才意识到您拼错了一个字符串并且需要重新部署整个堆栈时,这种情况会变得特别烦人。

添加图片注释,不超过 140 字(可选)

​ 是的,sam确实提供了一种在本地调用 lambda 的方法,但当您想要测试 Lambda 之间的协调更改时,这无济于事。使用sam您无法在本地部署两个 lambda并在它们之间路由流量(据我所知)。当然,可能有更好的方法来构建和部署您的代码以防止单片部署问题,但总会有权衡。单个 Lambda 中应该包含多少功能代码?如何选择何时将函数分离到不同的堆栈中?如何围绕堆栈组织存储库?

如果您的打包和部署步骤很长,但又想加快构建和测试 Lambda 所需的时间,该怎么办?或者,如果您有来自不同堆栈的 lambda 相互调用,而您想同时在本地测试它们,该怎么办?

使用代理重新路由流量

使用代理重新路由流量的基本原理是,我们希望捕获发往 AWS 的传输中请求,然后将其发送回本地计算机,而不是允许其进入云端。这个过程通常称为中间人 (MITM)。这个名字因被广泛用于黑客攻击而声名狼藉,但它在帮助减少测试 Lambda 所需的时间方面具有实际用途。

添加图片注释,不超过 140 字(可选)

​这里的关键是,我们只想将预配置的端点重新路由回我们的本地机器。例如,如果我们部署一个有五个 Lambda 的堆栈,并且我们只对其中一个 Lambda 进行更改,那么其他四个 Lambda 的流量应该继续流向 AWS。

捕获流向 AWS 的流量

当您使用boto3或其他 AWS 程序包调用 AWS Lambda 时,您只是通过 HTTPS 调用 API;AWS 程序包会为您处理身份验证、端点创建和序列化。由于所有这些流量都是通过 HTTPS 发送的,因此您可以通过代理查看计算机的所有 HTTPS 传出流量!

如果您使用的是 Mac,则可以在系统偏好设置下更新 HTTPS 代理设置,然后network > advanced > proxies。在这里,我已为端口 9090 打开了本地代理。

添加图片注释,不超过 140 字(可选)

如果您下载Proxyman之类的工具,然后从本地机器调用 lambdas,您就可以自己看到流经流量的流量。

添加图片注释,不超过 140 字(可选)

Proxyman 中显示的对 AWS 的 HTTPS 请求的屏幕截图(图片来自作者)

匹配来自端点的流量以在本地重新路由它们

现在 HTTPS 流量正在通过我们的代理,我们有能力对其进行操纵。这是通过中间人程序完成的。此 MITM 将读取通过代理的所有事件,并可选择对它们应用某些操作。这是在本地测试我们的 Lambda 的关键。

我正在使用mitmproxy,这是一个功能非常强大的工具,它允许将脚本逻辑应用于通过代理的任何记录(又称流)。mitmproxy cli 接受一个 python 文件作为参数,它将 HTTPS 事件提供给 python 脚本以采取行动。这是一个脚本示例

此代码可以通过以下命令运行(注意 - 9090 是我的 HTTPS 代理正在运行的端口):

import json
import time


from mitmproxy import http


class MatchedFlow(object):
    def __init__(self, from_route, to_route):
        self.from_route = from_route
        self.to_route = to_route

    def matches(self, route_url: str) -> bool:
        if self.from_route in route_url:
            return True
        return False

    def replace_url(self, flow: http.HTTPFlow) -> None:
        env_url = flow.request.url.replace(self.from_route, '')
        replacement_route = self.to_route + env_url[env_url.index('/'):]
        flow.request.url = replacement_route


class FlowMatcher(object):
    """Matches specific flows (URLs) that are being sent to AWS and routes them to internally
    running services
    """
    def __init__(self, match_flows):
        self.route_confs = None
        self.match_flows = match_flows

    def match_update_url(self, flow: http.HTTPFlow) -> None:
        """Matches a request against the set of configuraitons provided to see if the request
        should be rerouted.
        :param flow: A mitmproxy http flow object containing the full request details
        :return: None
        """
        for match_flow in self.match_flows:
            if match_flow.matches(flow.request.pretty_url):
                match_flow.replace_url(flow)
                break

mf1 = MatchedFlow(from_route='https://google.com', to_route='https://bing.com')
mf2 = MatchedFlow(from_route='https://reddit.com', to_route='https://medium.com')
matched_flows = [mf1, mf2]
FM = FlowMatcher(matched_flows)


def request(flow: http.HTTPFlow) -> None:
    FM.match_update_url(flow)

此代码可以通过以下命令运行(注意 - 9090 是我的 HTTPS 代理正在运行的端口):

mitmdump -p 9090 重新路由流量.py

重新路由 Lambda 流量

您可能已经在上面的屏幕截图中注意到,向 AWS 发出的所有请求都遵循相同的命名约定;区域、lambda 版本日期和 lambda 函数名称被连接在一起以构建端点。当您运行时,sam local start-lambda …本地也会发生类似的过程!AWS 在您的计算机上创建一个映射到特定端口的本地端点。您甚至可以像这样指定该端口:

sam local start-lambda -p 54321 --template /path/to/template.yaml

您的 Lambda 将在本地运行,您可以看到本地端点:

添加图片注释,不超过 140 字(可选)

到目前为止,我们已经学习了如何通过中间人捕获和重新路由流量,以及如何在本地启动 lambda 并选择其运行的端口。剩下要做的唯一一件事就是构建一个映射,从 AWS 中的端点指向运行此 Lambda 的本地端口。这可能会让你感到棘手。在本地启动 lambda 时,你只能使用资源名称sam调用 lambda ,但正如我们上面看到的,Lambda URL 包含函数名称。

添加图片注释,不超过 140 字(可选)

CFT Lambda 定义(作者提供图片)

我总是为我的 Lambda 使用标准化的命名约定,我的团队也非常严格地遵循它,如上所示,命名约定是“ {StackName}-{ResourceName}-{Env} ”。这样,在将流量路由到本地运行的 Lambda 时,我只需从函数名称中剥离堆栈名称和环境即可。这允许中间人脚本使用此基本逻辑替换流!

reroute_flow = { 
    'from_route':'my-stack-MyLambda1-dev',
    'to_route':'MyLambda1' 
} 
mf = MatchedFlow(**reroute_flow)
FM = FlowMatcher([mf])

瞧!一旦插入中间人脚本,我们现在就可以将流量路由到本地 Lambda。我们甚至可以定义多个重新路由,以便在本地版本的 Lambda 之间路由流量!

reroute_flow1 = { 
    'from_route':'my-stack-MyLambda1-dev', 
    'to_route': 'MyLambda1' 
} 
reroute_flow2 = { 
    'from_route':'my-stack-MySecondLambda-dev', 
    'to_route': 'MySecondLambda' 
} 
mf1 = MatchedFlow(**reroute_flow1) 
mf2 = MatchedFlow(**reroute_flow2) 
FM = FlowMatcher([mf1, mf2])

LocaLambda — 一个简化事情的 CLI

为了在本地测试 Lambda,有很多事情要做:设置 HTTPS 代理、定义匹配规则、在本地提供 Lambda 等。LocaLambda (简称lola)是一个轻量级 CLI,可以简化此过程。Lola 提供三种功能:

  • 设置:设置所需的资源和配置文件,以使lola运行,这是安装lola后的一次性活动

  • 构建:lola将构建lola.yaml文件中定义的特定资源。它通过使用仅包含指定资源的精简版本复制实际的 template.yaml 文件来实现此目的

  • 服务:lola针对配置文件中定义的每个 Lambda运行sam local start-lambda... ,并跟踪所使用的特定端口。然后,它将自动启动您的本地 HTTPS 代理服务器并执行中间人脚本。应该注意的是,中间人运行的可执行文件与lola 不同。为了告诉中间人要应用什么匹配逻辑,它会序列化本地部署资源的映射并将它们放在 Redis 上(您也必须在本地运行它)。

LocaLambda 设置

LocaLambda 可在pypi上使用,可以通过以下方式安装:

pip 安装 localambda

首次安装时,LocaLambda 需要设置一些特定于您计算机的资源和配置文件。您可以让 LocaLambda 指导您完成一次性设置:

lola——设置

输出结果是一个.lolarc位于您的主目录中的资源文件和一个lola位于您选择的位置的新目录。您需要lola.yaml在目录中创建一个文件(例如下面的文件),该文件将告诉 LocaLambda 要构建和提供哪些资源。此文件也可以在 GitHub 存储库的示例lola部分中找到。

repo_home: "/your/path/to/base/git/directory"

region: us-east-1

stacks:
  - MyLambdaFunctionTest:            # This item is the minimum configurations for a resource
      location: deployable_lambda
      stack_name: my-lambda-stack
      resources:
        - MyLambdaFunction           # CFT Resource Name
  - MySecondLambda:
      location: deployable_lambda
      stack_name: my-second-lambda-stack
      template: template.yml         # Specify your own template name, default is template.yaml 
      region: us-east-1              # Optionally override the default region
      resources:
        - MySecondLambdaFunction     # CFT Resource Name

这些配置中的很多都是基于我们的使用情况,您的需求可能会略有不同。由于我对 Lambdas 使用了标准化的命名约定,因此我只需要告诉lola三件事:

  1. template.yaml 文件的位置:这是repo_home 和location的组合, 或者可以提供完全限定的位置。这应该是代码和模板所在的目录。

  2. 堆栈名称:lola需要删除发往 AWS 的 HTTPS 请求中的堆栈名称和环境名称,以便找到特定的资源名称。环境将是静态的 (dev),因此目前是硬编码的。

  3. 资源:CFT template.yaml 文件中应部署或提供的资源名称列表。如果您的 CFT 中有十个 lambda,则可以选择一个、两个或更多个进行构建和测试,而不必构建和部署所有十个。

奔跑的萝拉

LocaLambda 主要做两件事:构建资源并在本地提供服务。您可以单独使用lola构建和提供 lambda ,也可以同时进行这两项操作。构建只需要-b在提供服务需要的地方添加标志-s。要构建和服务,您可以运行:

lola-bs

当使用示例配置文件运行此命令时,您将获得以下输出:

添加图片注释,不超过 140 字(可选)

LocaLambda 构建并提供输出(作者提供的图片)

LocaLambda 将按顺序执行几个步骤,如果您仅构建或部署,则可以跳过其中一些步骤:

  1. (构建)为lola.yaml配置中的每个堆栈创建精简版部署模板,只有选定的资源才会包含在构建中,而不是整个堆栈

  2. (构建)sam build ...为每个精简的模板运行

  3. (服务)对于lola.yaml中定义的每个堆栈,运行 sam local start-lambda ..

  4. (服务)对于lola.yaml中定义的每个堆栈,将中间人的匹配逻辑序列化并将它们放在 Redis 上

  5. (服务)启动中间人,从 Redis 读取配置并开始匹配 HTTPS 事件

关闭 SSL 验证

由于我们正在捕获 HTTPS 流量并将其重新路由到其他主机,因此我们将不可避免地遇到 SSL 证书问题,因为您的本地计算机无法拥有涵盖 AWS 域的证书。为了解决这个问题,AWS Lambda 背后的开发人员提供了一种关闭 SSL 验证的巧妙方法。设置 Lambda 客户端时,只需将 verify 标志设置为False,如 boto3 所示:

导入 boto3 lambda_client = boto3.client('lambda',verify = False)

实际上,您不想硬编码此值,因为在所有其他环境中,您都希望让 lambda 客户端验证证书。这里的一个建议是只使用环境变量(例如 local、dev、staging、prod 等),并且仅在本地部署时将其设置为验证。

测试以确保事件被拦截和重新路由

现在一切都已设置完毕并开始运行,我们可以测试流量是否正确路由到本地 Lambda。当lola为您的本地资源提供服务时,可以在 shell 中运行以下脚本。

import json
import boto3

lambda_client = boto3.client('lambda', verify=False)

user_address = lambda_client.invoke(
    FunctionName='my-lambda-stack-MyLambdaFunction-dev',
    InvocationType='RequestResponse',
    Payload=json.dumps({'some': 'input'})

我在后台进行了设置,以便此 Lambda 部署在本地,并调用部署在 AWS 中的另一个 lambda。您可以在此处看到,流量被路由到本地提供的第一个 Lambda,而不是 AWS!

LocaLambda 重新路由事件输出(作者提供图片)

结束语

LocaLambda 可以成为您工具箱中一款出色的字符串工具,可加快您的开发过程,但它绝不是万灵药。它比localstack更轻量,但如果只需要一两分钟即可构建并将代码推送到 AWS,它可能仍然有点太重了。它有几个地方有改进的空间(并且始终欢迎反馈/ PR):

  • 允许函数名称到资源映射的自定义匹配逻辑

  • 处理层集成,包括本地层和从 AWS 导入的层

  • 管理 ssh 隧道;许多需要访问私有网络中数据库的 lambda 也部署在私有网络中,或者至少部署在可以访问数据库的安全组中。能够快速测试需要数据库访问的 lambda,而无需手动配置隧道,这将是一个巨大的进步。

  • 能够使用 repo 中的模板的不同结构进行部署(例如 template.yaml 不在 repo 根目录、多个模板、嵌入式模板等)

  • 允许动态链接和取消链接不同的lola.yaml配置文件,以避免需要更新单个配置

总而言之,这是一个巧妙而有趣的小工具,可以满足我们团队不时遇到的利基用例的需求。我希望你也可以从这个项目中获得一些价值!

感谢关注雲闪世界。(Aws解决方案架构师vs开发人员&GCP解决方案架构师vs开发人员)

订阅频道(https://t.me/awsgoogvps_Host)

TG交流群(t.me/awsgoogvpsHost)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

torch.roll()函数使用方法

官方文档在这里,说的比较清楚,但是举的例子不是很直观。我们再详细解释一下: torch.roll(input, shifts, dimsNone) → Tensor input:输入的tensorshifts:滚动的方向和长度,若为正,则向索引大…

Web 服务基础介绍

目录 1.1 互联网发展历程回顾 1.2 Web 服务介绍 1.2.1 Apache 经典的 Web 服务端 1.2.1.1 Apache prefork 模型 1.2.1.2 Apache worker 模型 1.2.1.3 Apache event模型 1.2.2 Nginx-高性能的 Web 服务端 1.2.3 用户访问体验和性能 1.2.3.1 用户访问体验统计 1.2.3.2 …

数字孪生技术框架:从数据到决策的桥梁

随着科技的飞速发展,数字孪生技术作为一种创新的信息化手段,正逐步渗透到各个行业领域,成为推动数字化转型的重要力量。数字孪生技术框架,作为支撑这一技术体系的核心架构,以其独特的层级结构,实现了从数据…

Matlab进阶绘图第66期—特征渲染的滑珠气泡图

特征渲染的滑珠气泡图是在滑珠散点图的基础上,添加散点大小与颜色参数,通过散点的尺寸与颜色表示两个额外的特征。 由于Matlab中没有现成的函数绘制特征渲染的滑珠气泡图,因此需要大家自行解决。 本文利用自己制作的BubbleScatter工具&…

奥威BI数据可视化展示:如何充分发挥数据价值

奥威BI数据可视化展示:如何充分发挥数据价值 在大数据时代,数据已成为企业最宝贵的资产之一。然而,仅仅拥有海量数据并不足以带来竞争优势,关键在于如何有效地挖掘、分析和展示这些数据,从而转化为有价值的洞察和决策…

更改Docker默认存储位置

Docker镜像和容器等数据默认保存在目录/var/lib/docker目录下,我们可以更改Docker 的默认存储位置,比如改到数据盘。需注决,变更存储位置时,原来的镜像和容器有可能丢失。 1、确认docker默认存放目录 [rootkfk12 ~]# docker inf…

算法的学习笔记—链表中环的入口结点(牛客JZ23)

😀前言 在链表的操作中,环形链表是一个常见且需要特别处理的结构。当我们遇到一个包含环的链表时,如何找到环的入口结点是一个经典的问题。本文将详细介绍使用双指针技术来解决这一问题,并提供一个基于 Java 的实现代码。 &#x…

搭建内网开发环境(五)|基于nexus搭建npm私服

引言 在前面一篇教程中,通过 nexus 搭建了 maven 的私服,并通过脚本将本地的依赖文件批量上传到私服中,本文介绍通过 nexus 搭建 npm 私服,同样也通过脚本将本地依赖文件同步到私服中。 搭建内网开发环境(一&#xff…

目标检测 | yolov6 原理和介绍

前言:目标检测 | yolov5 原理和介绍 后续: 1.简介 YOLOv6是由美团视觉智能部研发的一款目标检测框架,专注于工业应用,致力于提供极致的检测精度和推理效率。相较于YOLOv4和YOLOv5,YOLOv6在网络结构方面进行了深入优化…

动手学深度学习(pytorch)学习记录12-激活函数[学习记录]

激活函数 激活函数(activation function)通过计算加权和并加上偏置来确定神经元是否应该被激活, 它们将输入信号转换为输出的可微运算。 import torch import matplotlib.pyplot as plt 简单定义一个画图的函数 def graph_drawing(x_,y_…

Robotics: Aerial Robotics 部分笔记——Week3(2)规划部分

3.2 轨迹不同于路径,需要是光滑的,考虑无人机动力学约束三阶导控制jerk,四阶导控制snap如果轨迹要满足某个特点,如:最短时间、最短路径,此时最优控制思路会被引入,变分法等算法可用以求解,选择…

2024最新版本Python安装及开发环境配置(vscodepython)

python安装 去Python官网下载最新版本: 接下来请一步步按照图片操作: 这样子就安装完成了 测试Python安装是否成功 先打开终端 右键Windows徽标,点击终端 然后输入python,如果如下图所示,就说明安装成功&#xff0…

【深度学习实战】利用Linear Regression预测房价

本文参考了李沐老师的b站深度学习课程 课程链接,使用了线性回归模型,特别适合深度学习初学者。通过阅读本文,你将学会如何用PyTorch训练模型,并掌握一些实用的训练技巧。希望这些内容能对你的深度学习学习有所帮助。 安装pytorch …

【书生大模型实战营(暑假场)】基础任务四 XTuner微调个人小助手认知

基础任务四 XTuner微调个人小助手认知 任务文档视频XTuner微调前置基础 文章目录 基础任务四 XTuner微调个人小助手认知0 认识微调0.1 Fine-tune 的两种范式0.2 常见微调技术 1 微调工具 XTuner1.1 认识高效微调框架 XTuner1.2 XTuner 具有出色的优化效果1.3 XTuner 零显存浪费…

【已成功EI检索】第五届新材料与清洁能源国际学术会议(ICAMCE 2024)

重要信息 会议官网:2024.icceam.com 接受/拒稿通知:投稿后1周内 收录检索:EI, Scopus 会议召开视频 见刊封面 EI检索页面 Scopus 检索页面 相关会议 第六届新材料与清洁能源国际学术会议(ICAMCE 2025) 大会官网&…

【Android】不同系统版本获取设备MAC地址

【Android】不同系统版本获取设备MAC地址 尝试实现 尝试 在开发过程中,想要获取MAC地址,最开始想到的就是WifiManager,但结果始终返回02:00:00:00:00:00,由于用得是wifi ,考虑是不是因为用得网线的原因,但…

【海思SS626 | VB】关于 视频缓存池 的理解

😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀 🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C、数据结构、音视频🍭 🤣本文内容🤣&a…

【C#】explicit、implicit与operator

字面解释 explicit:清楚明白的;易于理解的;(说话)清晰的,明确的;直言的;坦率的;直截了当的;不隐晦的;不含糊的。 implicit:含蓄的;不直接言明的;成为一部分的;内含的;完全的;无疑问的。 operator:操作人员;技工;电话员;接线员;…

OSL 冠名赞助Web3峰会 “FORESIGHT2024”圆满收官

OSL 望为香港数字资产市场发展建设添砖加瓦 (香港,2024 年 8 月 13 日)- 8 月 11 日至 12 日, 由 香港唯一专注数字资产的上市公司 OSL 集团(863.HK)冠名赞助,Foresight News、 Foresight Ventu…

C++ 11相关新特性(lambda表达式与function包装器)

目录 lambda表达式 引入 lambda表达式介绍 lambda表达式捕捉列表的传递形式 lambda表达式的原理 包装器 包装器的基本使用 包装器与重载函数 包装器的使用 绑定 C 11 新特性 lambda表达式 引入 在C 98中,对于sort函数来说,如果需要根据不同的比较方式实现…