近期手上的一个基于Function Grap(类AWS的Lambda)小项目的改造引发的思考

article/2025/7/5 11:10:13

函数式Function是云计算里最近几年流行起来的新的架构和模式,因为它不依赖云主机,非常轻量,按需使用,甚至是免费使用,特别适合哪种数据同步,数据转发,本身不需要保存数据的业务场景,或者通过一个输入转换或者变化,处理以后流转到下一个输出。

我们刚好有这样的业务,云云对接,把一个储能云的数据,经过接口查询以后,转换后保存到我们的私有云平台上(内部是微软提供的IoT平台底座)。

但是在实际开发中发现了有两个痛点,
 触发方式,云厂商一般会提供2个方式,
1.基于事件的调用,比如Python语言的固定式的函数,比如

def handler(event, context)

,函数名和内存占用,网络设置等配置,这里有一个重要的设置就是触发器,

一般最常用的是定时触发器:

当你编写好以后,在云平台上直接点击运行测试,云平台会调用你的这个handler,你也可以通过参数event, context 获取运行时的一些数据。如果是简单任务,只需要在这里调用你的业务代码就开发完成。

一切都很自然,这里的定时器,相当于linux里的cronjob, 最后运行的python ss.py 这样的方式会导致每次启动都会把代码重新执行一遍,但是如果你的业务要求严格的话,希望这个程序运行了以后一直不退出,在程序内部运行Schedule,这样的好处会节省调用方的资源,比如代码需要访问MQ,每隔3分钟程序重新执行的时候,会频繁得创建TCP连接。会给MQ broker的连接创造一定的压力,我刚好遇到了对方投诉我们占用了他们的连接资源。所以我需要改造程序,让程序一直不退出的方式,复用创建好的连接。一共经历了3次优化

  1. 修改代码,创建一个全局的Connection对象,然后在handler里直接写while True的方式执行,发现云平台给的handler函数,有个限制,如果超时没有返回,平台强制终止程序,可以在日志里查看到,程序超时被终止。这条路走不通
  2. 不改架构使用异步,handler里启动一个线程,在线程里while True,后来发现执行一段时间后,效果并不好。
通过Schedule包,顺便说一下,Python竟然没有一个特别强大的定时器,非常不好用,想这样, import schedule
schedule.every(3).minutes.do(job1)需要设置好了以后,还需要 if __name __ =="__main__":         schedule.run_pending()为了防止程序退出还有在主线程里写上while True: time.sleep(5)
 
或者类似这样的代码
import time
import threadingdef background_task():print("后台任务开始")time.sleep(5)  # 模拟长时间任务print("后台任务完成")def handler(event, context):print("收到请求")def delayed_run():time.sleep(0.1)background_task()thread = threading.Thread(target=delayed_run)thread.start()# 主线程故意睡一会儿,防止函数提前退出time.sleep(6)return {"statusCode": 200, "body": "已尝试启动后台任务"}
这样恶心的代码,非常的不优雅。

3. 改动架构,使用彻底异步

  1. 使用redis的发布订阅模式(或者其他MQ),把启动和执行分开。在执行同步的代码里,handler里把连接建立好,就等待redis的消息通知,代码如下:
  2. def handler(event, context):
  3.     localtime = time.asctime(time.localtime(time.time()))
  4.     print(f"execution at {localtime}.")
  5.     startConn()
  6.     start_redis_listener()
  7.     print("??",client)
  8.     return {"statusCode": 200, "isBase64Encoded": False, "headers": {"Content-Type": "application/json;charset=UTF-8"},
  9.             "body": "sucess"}

  10. 这样非常优雅,如下:
  11. def sync_data():
  12.     print("开始执行耗时的数据同步任务...")    
  13.     print(client)  
  14.     try:
  15.         while True:
  16.             time.sleep(5)
  17.             print("开始处理站点列表")
  18.             for conf in configLs:
  19.                 print(f"开始处理站点: {conf.station_name} 数据")
  20.                 site = AccessSite(conf)
  21.                 site.publish_mqtt()
  22.                 # msg = msg + f"{conf.station_name}"
  23.                 print("成功处理站点数据至能源平台!")
  24.     except Exception as e:
  25.         print("同步出错:", str(e))
  26. # Redis 订阅客户端
  27. def start_redis_listener():
  28.    
  29.     pubsub = redisClient.pubsub()
  30.     pubsub.subscribe(["stored_energy_sync_channel"])
  31.     print("等待 Redis 消息...")
  32.     for message in pubsub.listen():
  33.         if message['type'] == 'message':
  34.             print(f"收到消息: {message['data'].decode()}")
  35.             if message['data'].decode() == "start_sync":
  36.                 sync_data()

至于程序何时启动,只需要在另外一个FG里,通过调用redis的pub接口,把这个sync_data()给启动。

非常的完美,容易维护。而第二个版本,使用线程和使用定时器都无法取得满意的效果。

注意这里的redis还可以替换成Kafka, RocketMQ,或者其他通知SMN, SQS。
2. 还有一个方式是基于http或者https的方式启动任务,方式大同小异,都是一次执行完成以后,需要再次触发才能继续执行。如下图:


http://www.hkcw.cn/article/TuqPlSQpkq.shtml

相关文章

C++ - 模板(一) #泛型编程 #函数模板 #类模板

文章目录 前言 一、泛型编程 二、函数模板 1、函数模板的概念 2、函数模板的格式 3、函数模板的原理 4、函数模板的实例化 1、隐式实例化: 2、显式实例化: 5、模板参数的匹配原则 三、类模板 1、类模板的定义格式 2、类模板的实例化 总结 …

智能制造全场景数字化解决方案

制造企业数字化转型面临的挑战 数智化转型已成为中国制造业高质量发展的关键战略。面对全球制造业格局调整,如何快速构建覆盖全业务流程的可视化应用,通过数据驱动的方式为企业经营管理、预警监测、质量管控、决策支持提供全面支撑,是企业面…

Vue-收集表单信息

收集表单信息 Input label for 和 input id 关联, 点击账号标签 也能聚焦 input 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><title>表单数据</title><!-- 引入Vue --><scrip…

篮球分组问题讨论

1 问题概述 问题&#xff1a;有5支球队在同一块场地上进行单循环赛,共要进行10场比赛。下表是一个赛程安排&#xff0c;有些队觉得不公平。研究以下问题 A B C D E 每两场比赛间相隔场次数 A X 1 9 3 6 1, 2, 2 B 1 X 2 5 8 0, 2, 2 C 9 2 X 7 10 4…

成都鼎讯--通信干扰设备功能全解析

在现代电子战与通信对抗领域&#xff0c;一款高性能的通信干扰设备是掌握电磁频谱主动权的关键。本文将深入解析一款先进的通信干扰设备&#xff0c;其凭借多频段覆盖、多通道并行、多样化调制方式及灵活供电等特性&#xff0c;成为部队、科研院所等机构在电磁对抗训练与研究中…

vscode中让文件夹一直保持展开不折叠

vscode中让文件夹一直保持展开不折叠 问题 很多小伙伴使用vscode发现空文件夹会折叠显示, 让人看起来非常难受, 如下图 解决办法 首先打开设置->setting, 搜索compact Folders, 去掉勾选即可, 如下图所示 效果如下 看起来非常爽 ! ! !

中国城市间地理距离矩阵(2024)

1825 中国城市间地理距离矩阵(2024) 数据简介 中国城市间地理距离矩阵数据集&#xff0c;通过审图号GS(2024)0650的中国城市地图在Albers投影坐标系中进行计算得出矩阵表格&#xff0c;单位为KM&#xff0c;方便大家研究使用。 中国城市地理距离矩阵数据通过计算城市中心距离…

Linux中的shell脚本

什么是shell脚本 shell脚本是文本的一种shell脚本是可以运行的文本shell脚本的内容是由逻辑和数据组成shell脚本是解释型语言 用file命令可以查看文件是否是一个脚本文件 file filename 脚本书写规范 注释 单行注释 使用#号来进行单行注释 多行注释 使用 : " 注释内容…

20250530-C#知识:抽象类、抽象方法、接口

C#知识&#xff1a;抽象类、抽象方法、接口 在开发过程中接口一般用得较多&#xff0c;程序框架往往定义一堆接口规范&#xff0c;然后程序员自己写逻辑来实现接口功能。掌握接口的知识还是很有必要的。 1、抽象类 用abstract关键字修饰的类不能用来实例化对象可以包含抽象方法…

韩国首尔一地铁车厢内遭纵火 乘客被紧急疏散

当地时间5月31日8时47分左右,韩国首尔地铁5号线一辆列车车厢内起火,乘客随后被紧急疏散。据初步调查,火灾原因为有人纵火,嫌疑人已被抓获。目前暂无人员伤亡报告。受火灾事件影响,该地铁线路部分区段一度暂停运行,首尔市交通部门10时13分通报,事故处理已经完毕,暂停运行…

跨平台浏览器集成库JxBrowser 支持 Chrome 扩展程序,高效赋能 Java 桌面应用

JxBrowser 是 TeamDev 开发的跨平台库&#xff0c;用于在 Java 应用程序中集成 Chromium 浏览器。它支持 HTML5、CSS3、JavaScript 等&#xff0c;具备硬件加速渲染、双向 Java 与 JavaScript 连接、丰富的事件监听等功能&#xff0c;能处理网页保存、打印等操作&#xff0c;助…

聊聊网络变压器的浪涌等级标准是怎样划分的呢?

Hqst盈盛&#xff08;华强盛&#xff09;电子导读&#xff1a;聊聊网络变压器的浪涌等级标准是怎样划分的呢&#xff1f; 在和做防雷产品的客户的深度沟通网络变压器产品选型中发现&#xff1a;客户对网络变压器的浪涌等级划分也很希望有更深的了解&#xff0c;今天就这个问题和…

探索Air780EPM:N种GPIO控制LED的创新应用!

通过创新思维与实用技巧&#xff0c;本文将带你了解Air780EPM如何通过GPIO实现LED控制的N种可能&#xff0c;从简单到复杂&#xff0c;激发项目灵感。 一、GPIO直接驱动LED 1.1 适用场景 低功耗场景&#xff1a;LED电流 ≤ 5mA&#xff08;普通GPIO的驱动能力限制&#xff09;…

JS 事件循环详解

JS 事件循环详解 文章目录 JS 事件循环详解一、JS 的单线程模型与异步机制二、事件循环的核心组件1. 执行栈&#xff08;Call Stack&#xff09;2. 任务队列&#xff08;Task Queue&#xff09;3. Web APIs 三、事件循环的执行流程四、任务类型详解1. 宏任务&#xff08;Macrot…

堆遇到的stl与理论基础

目录 二叉完全搜索树是堆吗:并不是,堆比两孩子都大 1. 二叉完全搜索树的特点 2. 堆的特点 3. 两者的主要区别 4. 结论 c有swap吗 堆的向上调整和向下调整是什么 1. 堆的定义 2. 向上调整&#xff08;Heapify Up&#xff09; 操作步骤 示例&#xff08;最大堆&#x…

年度工作汇报工作总结PPT模版分享

年度工作汇报工作总结PPT模版分享&#xff1a;工作总结汇报类PPT模版https://pan.quark.cn/s/774660cc70e8

一文学会c++中的内存管理知识点

文章目录 c/c内存管理c语言动态内存管理c动态内存管理new/delete自定义类型妙用operator new和operator delete malloc/new&#xff0c;free/delete区别 c/c内存管理 int globalVar 1;static int staticGlobalVar 1;void Test(){static int staticVar 1;int localVar 1;in…

ZC-OFDM雷达通信一体化减小PAPR——直接限幅法

文章目录 前言一、直接限幅法技术1、简介2、原理 二、MATLAB 仿真1、核心代码2、仿真结果 三、资源自取 前言 在 OFDM 雷达通信一体化系统中&#xff0c;信号的传输由多个子载波协同完成&#xff0c;多个载波信号相互叠加形成最终的发射信号。此叠加过程可能导致信号峰值显著高…

【二维数组】

二维数组 需要掌握的知识二维数组与内存二维数组语法Arrays类的常用方法介绍如何实现冒泡排序 需要掌握的知识 二维数组与内存 二维数组语法 //数据类型【】【】数组; //或者 //数据类型 数组名【】【】&#xff1b; //二维数组初始化操作 int [][] scorenew int[][]{{90,85,92…

小黑大语言模型通过设计demo进行应用探索:langchain中chain的简单理解demo

chain简介 LangChain 中的 Chain 模块‌在开发大型语言模型&#xff08;LLM&#xff09;驱动的应用程序中起着至关重要的作用。Chain是串联LLM能力与实际业务的关键桥梁&#xff0c;通过将多个工具和模块按逻辑串联起来&#xff0c;实现复杂任务的多步骤流程编排。 案例 通过…