近期手上的一個基于Function Grap(類AWS的Lambda)小項目的改造引發的思考

函數式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.pswp.cn/news/907593.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/907593.shtml
英文地址,請注明出處:http://en.pswp.cn/news/907593.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

什么是 SQL 注入?如何防范?

什么是 SQL 注入?如何防范? 1. SQL 注入概述 1.1 基本定義 SQL 注入(SQL Injection)是一種通過將惡意SQL 語句插入到應用程序的輸入參數中,從而欺騙服務器執行非預期SQL命令的攻擊技術。攻擊者可以利用此漏洞繞過認證、竊取數據甚至破壞數據庫。 關鍵結論:SQL 注入是O…

高德地圖應用OceanBase單元化構建下一代在線地圖服務

IEEE International Conference on Data Engineering (ICDE) 是數據庫和數據工程領域的頂級學術會議之一(與SIGMOD、VLDB并成為數據庫三大頂會),自1984年首次舉辦以來,每年舉辦一次。ICDE涵蓋廣泛的主題,包括數據庫系統…

Vue3中Element-Plus中el-input及el-select 邊框樣式

如果不需要顯示下邊框&#xff0c;純無邊框直接將 【border-bottom: 1px solid #C0C4CC; 】注掉或去掉即可。 正常引用組件使用即可&#xff0c;無須自定義樣式&#xff0c;最終效果CSS樣式。 <style scoped> /* 輸入框的樣式 */ :deep(.el-input__wrapper) { box-sha…

如何做好一份技術文檔:從信息孤島到知識圖譜的進階之路

如何做好一份技術文檔&#xff1a;從信息孤島到知識圖譜的進階之路 在軟件開發的漫長征程中&#xff0c;技術文檔如同隱藏在代碼叢林中的路標&#xff0c;不僅指引著開發團隊的前行方向&#xff0c;更在產品迭代的歲月里構筑起知識傳承的橋梁。一份優質的技術文檔&#xff0c;既…

Docker Compose使用自定義用戶名密碼啟動Redis

通常我們使用下面的命令來啟動 redis 容器&#xff0c;此時連接 Redis 的時候是不需要用戶認證的 sudo docker run -d --name my-redis -p 6379:6379 redis此時我們可以使用 redis-server --requirepass "mypassword" 來指定默認用戶&#xff08;default&#xff09…

1.什么是node.js、npm、vue

一、Node.js 是什么&#xff1f; &#x1f63a; 定義&#xff1a; Node.js 是一個基于 Chrome V8 引擎的 JavaScript 運行時環境&#xff0c;讓你可以在瀏覽器之外運行 JavaScript 代碼&#xff0c;主要用于服務端開發。 &#x1f63a;從計算機底層說&#xff1a;什么是“運…

如何在 Vue.js 中集成 Three.js —— 創建一個旋轉的 3D 立方體

在這篇文章中&#xff0c;我將向大家展示如何將 Three.js 與 Vue.js 結合&#xff0c;創建一個簡單的 3D 場景&#xff0c;并展示一個旋轉的立方體。通過這個簡單的示例&#xff0c;你將學習到如何在 Vue 項目中集成 Three.js&#xff0c;以及如何創建動態的 3D 內容。 1. 安裝…

DeepSeek?R1-0528 重磅升級:螞蟻百寶箱免費、無限量調用

DeepSeek?R1-0528 重磅升級&#xff1a;螞蟻百寶箱免費、無限量調用 端午假期前一天&#xff0c;DeepSeek?R1 更新到了 0528 版本&#xff01; 官方說明&#xff1a;0528 版本在深度思考與推理能力方面顯著增強——在數學、編程與通用邏輯等多項基準測評中&#xff0c;表現已…

RS232轉Profinet網關在檢漏儀與西門子PLC里的應用

RS232轉Profinet網關在檢漏儀與西門子PLC里的應用 在工業自動化和控制領域&#xff0c;設備間的高效通信至關重要。RS232轉Profinet網關作為一種關鍵的轉換工具&#xff0c;能夠將傳統的RS232接口設備接入現代化的Profinet網絡&#xff0c;從而實現數據的無縫傳輸和設備的遠程…

jenkins-jenkins簡介

一、簡介 jenkins是一個可擴展的持續集成引擎。持續集成&#xff0c;也就是通常所說的CI&#xff08;Continues Integration&#xff09;&#xff0c;可以說是現代軟件技術開發的基礎。持續集成是一種軟件開發實踐&#xff0c; 即團隊開發成員經常集成他們的工作&#xff0c;通…

vue發版html 生成打包到docker鏡像進行發版

將Vue項目打包成Docker鏡像部署主要分為以下幾個步驟&#xff1a; 1. Vue項目打包? 執行npm run build生成dist文件夾&#xff0c;包含靜態資源文件 注意檢查index.html中資源引用路徑是否正確&#xff08;避免絕對路徑問題&#xff09; 2. 編寫Dockerfile Copy Code FROM…

掃地機器人苦尋新引擎,大疆們卻已攻入腹地

原創 科技新知 前沿科技組 作者丨江籬 編輯丨櫻木、九黎 競爭激烈的掃地機器人賽道&#xff0c;迎來了新玩家。 據近日相關報道&#xff0c;大疆掃地機器人產品已開始量產&#xff0c;預計將于6月份發布。消息稱大疆研發掃地機器人已超過四年&#xff0c;即將上市的產品是掃…

【C++】22. 紅黑樹封裝實現Mymap和Myset

上一章節我們實現了紅黑樹&#xff0c;這一章節我們就用紅黑樹封裝來實現一個我們自己的map和set 1. 源碼及框架分析 SGI-STL 3.0版本的源代碼中&#xff0c;map和set的實現主要分布在若干頭文件中&#xff0c;這些頭文件構成了這兩個容器的完整實現架構&#xff1a; 核心頭文…

02_redis分布式鎖原理

文章目錄 一、redis如何實現分布式鎖1. 使用 SETNX 命令2. 設置過期時間3. 釋放鎖4. 注意事項5. 示例代碼二、Java中分布式鎖如何設置超時時間1. Redis分布式鎖2. 基于Zookeeper的分布式鎖3. 基于數據庫的分布式鎖注意事項一、redis如何實現分布式鎖 Redis 實現分布式鎖是一種…

酷派Cool20/20S/30/40手機安裝Play商店-谷歌三件套-GMS方法

酷派Cool系列主打低端市場&#xff0c;系統無任何GMS程序&#xff0c;也不支持直接開啟或者安裝谷歌服務等功能&#xff0c;對于國內部分經常使用谷歌服務商店的小伙伴非常不友好。涉及機型有酷派Cool20/Cool20S /30/40/50/60等旗下多個設備。好在這些機型運行的系統都是安卓11…

技術為器,服務為本:AI時代的客服價值重構

在智能化浪潮中&#xff0c;大語言模型的出現為客戶服務行業注入了全新動能。然而技術創新的價值不在于技術本身&#xff0c;而在于其賦能服務的深度與廣度。AI對于我們來說&#xff0c;如同發動機之于汽車&#xff0c;重要的不是引擎參數&#xff0c;而是整車帶給用戶的駕駛體…

技術創新如何賦能音視頻直播行業?

在全球音視頻直播行業的快速發展中&#xff0c;技術的持續創新始終是推動行業進步的核心動力。作為大牛直播SDK的開發者&#xff0c;我很榮幸能分享我們公司如何從產品的維度出發&#xff0c;精準把握市場需求&#xff0c;并不斷推動產品的發展&#xff0c;以滿足不斷變化的行業…

Linux線程池(下)(34)

文章目錄 前言一、v3版本二、單例模式概念特點簡單實現 三、其余問題STL線程安全問題智能指針線程安全問題其他鎖的概念 總結 前言 加油&#xff01;&#xff01;&#xff01; 一、v3版本 「優化版」&#xff1a;從任務隊列入手&#xff0c;引入 「生產者消費者模型」&#xff…

Netty 實戰篇:Netty RPC 框架整合 Spring Boot,邁向工程化

本文將基于前面構建的 RPC 能力&#xff0c;嘗試將其與 Spring Boot 整合&#xff0c;借助注解、自動掃描、依賴注入等機制&#xff0c;打造“開箱即用”的 Netty RPC 框架&#xff0c;提升開發效率與工程規范。 一、為什么要整合 Spring Boot&#xff1f; 手動 new 實例、寫注…

Axure中繼器學習筆記

一、中繼器概述 中繼器(Axure Repeater)是Axure中的高級組件&#xff0c;功能類似于數據集成器&#xff0c;主要用于&#xff1a; 數據存儲與管理 數據的增刪改查操作 數據的分頁與展示控制 二、中繼器基本使用流程 數據存儲&#xff1a;將數據儲存在中繼器組件中 數據展…