用 SPL 編寫阿里云 FC2.0 函數

前言

在數字化轉型持續加速的背景下,企業越來越多地將業務邏輯以服務化方式部署至云端。阿里云函數計算(Function Compute,簡稱FC)作為一種無服務器計算平臺,屏蔽了底層資源運維的復雜性,使開發者能夠專注于核心邏輯的開發與交付。只需上傳代碼,即可通過HTTP請求或事件驅動靈活觸發函數執行,實現彈性伸縮、按需計費的函數式計算能力。

在實際應用中,函數計算往往需要處理復雜的數據處理任務,如多源數據的匯聚、清洗與分析。然而,使用傳統Java編寫這類邏輯不僅代碼冗長、調試困難,還缺乏靈活性,微小的邏輯變更通常也需要重新構建、打包并上傳整個函數代碼包。

SPL(Structured Process Language)專注于結構化數據處理,具備簡潔的語法、豐富的計算函數,特別適合表達各類復雜的數據邏輯。更重要的是,SPL支持將數據處理邏輯以外部腳本形式運行,修改邏輯時只需替換腳本文件,無需重新構建或部署函數代碼包,即可在下一次調用時自動生效。這種“輕量級熱切換”特性,非常契合函數計算輕量、快速迭代的特性,有效提升了云端函數邏輯的可維護性與敏捷性。

此外,SPL原生支持多種數據源(如支持JDBC的數據源、NAS文件、JSON等),并具備可視化分步調試能力,是Serverless架構中應對動態數據邏輯、數據服務編排的高效利器。

本文將介紹如何結合Micronaut框架與SPL腳本,以Fat-JAR方式部署至阿里云FC2.0,構建一個通過RESTful API調用、支持邏輯熱更新的無服務器計算服務。示例將展示SPL如何訪問并分析MySQL數據庫和NAS文件系統,幫助讀者快速構建可擴展、易維護的Serverless數據服務方案。

SPL在阿里云FC中的架構圖

函數開發與部署

創建項目

使用 Micronaut CLI 快速創建 Maven 項目:

mn create-app micronaut-spl --build maven

創建完成后,可在集成開發環境(如 IntelliJ IDEA)中打開項目繼續開發。

集成SPL

添加依賴

在 pom.xml 中引入 SPL 與數據庫驅動:

<dependency><groupId>com.scudata.esproc</groupId><artifactId>esproc</artifactId><version>20250605</version>
</dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>8.3.0</version>
</dependency>

提示:中央倉庫的更新頻率有限,推薦從[SPL 下載地址]下載標準版,并通過私有Maven倉庫同步更新。

相關jar包位于安裝目錄esProc/lib/,其中兩個基礎jar包為:

· esproc-bin-xxxx.jar:SPL 引擎及 JDBC 驅動

· icu4j-60.3.jar:國際化支持庫

準備SPL配置文件

raqsoftConfig.xml 為 SPL 的核心配置文件,負責數據源定義、腳本路徑管理等。本文中RDS MySQL數據源與腳本路徑的示例配置如下:

……
<DBList encryptLevel="0"><DB name="rds_mysql"><property name="url" value="jdbc:mysql://rm-xxx.mysql.rds.aliyuncs.com:3306/spltest?useCursorFetch=true"></property><property name="driver" value="com.mysql.cj.jdbc.Driver"></property><property name="type" value="10"></property><property name="user" value="dms_user"></property><property name="password" value="password"></property><property name="batchSize" value="0"></property><property name="autoConnect" value="true"></property><property name="useSchema" value="false"></property><property name="addTilde" value="false"></property><property name="caseSentence" value="false"></property></DB>
</DBList>
<esProc>
……<splPathList><splPath>/opt</splPath></splPathList>
……
</esProc>
……

特別注意:需加上useCursorFetch=true,否則JDBC驅動可能將整個結果集加載至內存,容易在 FC 的內存限制下導致連接斷開或錯誤。

與傳統項目部署方式不同,這里我們先將raqsoftConfig.xml打成zip包(raqsoftConfig.xml.zip),以供后續作為自定義層上傳使用。

SPL 通用接口實現

使用 SPL 提供的 JDBC 接口,在 Micronaut 中構建統一的函數調用入口。通過 HTTP POST 請求傳入參數,執行指定 SPL 腳本,并將結果以 JSON 格式返回。

該接口接收兩個參數:

· splxName:腳本文件名(不帶擴展名)

· jsonParam:SPL腳本所需參數(JSON字符串)

返回值中包括狀態碼、消息提示及腳本執行結果數據。

package micronaut.spl;import io.micronaut.http.annotation.*;
import io.micronaut.http.MediaType;import java.sql.*;
import java.util.*;@Controller("/spl")
public class SPLExecutionController {@Post(uri = "/call", consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON)public Map<String, Object> execute(@Body Map<String, String> request) {Map<String, Object> response = new HashMap<>();String splxName = request.get("splxName");String jsonParam = request.get("jsonParam");if (splxName == null || splxName.isBlank()) {response.put("code", 400);response.put("message", "Missing splxName");return response;}try {Class.forName("com.esproc.jdbc.InternalDriver");try (Connection con = DriverManager.getConnection("jdbc:esproc:local://?config=/opt/raqsoftConfig.xml");CallableStatement st = con.prepareCall("call " + splxName + "(?)")) {if (jsonParam != null && !jsonParam.isEmpty()) {st.setString(1, jsonParam);} else {st.setNull(1, Types.VARCHAR);}boolean hasResult = st.execute();List<List<Object>> allResults = new ArrayList<>();while (true) {if (hasResult) {try (ResultSet rs = st.getResultSet()) {ResultSetMetaData metaData = rs.getMetaData();int columnCount = metaData.getColumnCount();List<Object> currentResult = new ArrayList<>();while (rs.next()) {if (columnCount == 1) {currentResult.add(rs.getObject(1));} else {Map<String, Object> row = new LinkedHashMap<>();for (int i = 1; i <= columnCount; i++) {row.put(metaData.getColumnLabel(i), rs.getObject(i));}currentResult.add(row);}}if (!currentResult.isEmpty()) {allResults.add(currentResult);}}}if (!st.getMoreResults() && st.getUpdateCount() == -1) {break;}hasResult = true;}if (!allResults.isEmpty()) {response.put("code", 200);response.put("message", "success");response.put("data", allResults.size() == 1 ? allResults.get(0) : allResults);} else {response.put("code", 404);response.put("message", "No result data");}}} catch (Exception e) {e.printStackTrace();response.put("code", 500);response.put("message", "Execution failed: " + e.getMessage());}return response;}
}

打包項目后,再打成zip包(micronaut-spl-0.1.jar.zip)

上傳部署Fat-JAR

在阿里云 FC 控制臺中創建函數,推薦配置如下:

· 創建方式:使用自定義運行時創建

· 運行環境:Java 21

· 上傳方式:ZIP 上傳(micronaut-spl-0.1.jar.zip)

· 啟動命令:java -jar micronaut-spl-0.1.jar

· 認證方式:無需認證(測試用)

點擊創建后,即可完成函數部署。

添加配置層

在函數詳情中點擊“編輯層”,上傳打包好的 raqsoftConfig.xml.zip,新建名為 config 的自定義層。

編寫SPL腳本

使用 MySQL 表數據計算

在阿里云 RDS 中創建 MySQL 實例及 orders 表,導入 TPC-H 示例數據(建庫建表和導入過程略)。以下腳本 rds-mysql.splx 演示如何按訂單年份與狀態分組統計訂單總額:

A
1=connect("rds_mysql")
2=A1.cursor@x("SELECT O_ORDERDATE, O_ORDERSTATUS, O_TOTALPRICE FROM ORDERS")
3=A2.groups(year(O_ORDERDATE):year,O_ORDERSTATUS:status;sum(O_TOTALPRICE):amount)

將腳本打zip包后,添加并創建自定義層(splx),即可在/opt下訪問到該腳本。

調用示例

請求行
POST https://sss-fff-xxx.cn-xxx.fcapp.run/spl/call
Content-Type: application/json
請求體
{"splxName": "rds-mysql","jsonParam": ""
}
返回
{"code": 200,"data": [{"year": 1992,"status": "F","amount": 34330674052.43},{"year": 1993,"status": "F","amount": 34340410079.03},{"year": 1994,"status": "F","amount": 34416369052.97},{"year": 1995,"status": "F","amount": 6614961429.26},{"year": 1995,"status": "O","amount": 20822054361.33},{"year": 1995,"status": "P","amount": 7109117393.01},{"year": 1996,"status": "O","amount": 34609364760.86},{"year": 1997,"status": "O","amount": 34373633413.04},{"year": 1998,"status": "O","amount": 20212721905.53}],"message": "success"
}

使用 NAS 文件系統

通過阿里云函數配置掛載 NAS 路徑(如 /mnt/nas),可在 SPL 中直接讀寫該路徑下的文件,實現持久化與共享。

以下為 w.splx(寫)和 r.splx(讀)兩個腳本,模擬數據生成與讀取處理過程。

w.splx如下:

A
1=path=json(jsonParams).path
2=connect("rds_mysql")
3=A2.cursor@x("SELECT O_ORDERDATE, O_ORDERSTATUS, O_TOTALPRICE FROM ORDERS")
4=file(path/"orders.btx").export@b(A3)
5return "btx exported."

r.splx如下:

A
1>p=json(jsonParam),path=p.path,n=p.n,m=p.m
2=file(path/"orders.btx").cursor@b()
3=A2.skip(n)
4=A2.fetch(m)
5>A2.close()
6return A4

寫腳本,通過數據庫游標讀取MySQL實例中的orders表,并寫入orders.btx文件(path可使用配置的NAS路徑,實現持久化或與其他服務共享數據)。

讀腳本,通過讀取指定路徑文件的游標,跳過前n條記錄,展示接下來的m條記錄。

也可將腳本文件本身存放在 NAS 中,配合 raqsoftConfig.xml 中增加路徑:

…
<splPathList><splPath>/opt;/mnt/nas</splPath>
</splPathList>
…

寫入調用示例

請求行

POST https://sss-fff-xxx.cn-xxx.fcapp.run/spl/call

Content-Type: application/json

請求體
POST https://sss-fff-xxx.cn-xxx.fcapp.run/spl/call
Content-Type: application/json
返回
{"splxName": "w","jsonParam": "{path:/mnt/nas/}"
}

讀取調用示例

請求行
POST https://sss-fff-xxx.cn-xxx.fcapp.run/spl/call
Content-Type: application/json
請求體
{"splxName": "r","jsonParam": "{path:/mnt/nas/,n:99,m:2}"
}
返回
{"code": 200,"data": [{"O_ORDERDATE": "1992-12-16","O_ORDERSTATUS": "F","O_TOTALPRICE": 198800.71},{"O_ORDERDATE": "1994-02-17","O_ORDERSTATUS": "F","O_TOTALPRICE": 2519.40}],"message": "success"
}

業務邏輯變更

我們將“使用 MySQL 表數據計算”的“按訂單年份與狀態分組統計訂單總額”改為“按訂單年月與狀態分組統計訂單總額”,只需要將 A3 中的 year(O_ORDERDATE):year 改為 month@y(O_ORDERDATE):YearMonth 即可。由于 SPL 支持將數據邏輯以外部腳本形式運行,此類修改無需重新構建和部署函數代碼包,只需更新腳本內容即可在下一次函數調用時自動生效。這種“輕量級熱切換”方式完美契合 Serverless 架構短生命周期、按需執行的特點,顯著提升了云端數據服務的響應速度與維護效率,尤其適合頻繁調整的數據分析類場景。

總結

借助 Micronaut 的輕量級框架特性與 SPL 的靈活腳本執行能力,我們成功構建了一個具備結構化數據處理能力的 Serverless 應用,并以 Fat-JAR 方式部署至阿里云函數計算 FC2.0。函數啟動后可通過 REST 接口按需觸發,訪問 MySQL 或 NAS 等多種數據源,執行復雜的計算邏輯。

相比傳統 Java 開發,SPL 顯著簡化了數據處理過程,使業務邏輯更清晰、更易維護。尤其在 Serverless 架構下,SPL 的“腳本熱切換”能力無需重構或重新部署函數,即可在下次調用中自動生效,極大提升了系統的靈活性和運維效率。結合 NAS 文件系統,還能實現函數之間的數據共享與持久化,滿足更多元的業務場景需求。

這種架構適用于需要快速迭代、規則頻繁調整的數據服務場景,是企業在 Serverless 架構下構建高效、可擴展數據計算服務的有力方案。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/95925.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/95925.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/95925.shtml

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

相關文章

AR 巡檢與普通巡檢有哪些區別,有哪些優勢|阿法龍XR云平臺

AR 巡檢&#xff08;增強現實巡檢&#xff09;與普通巡檢&#xff08;傳統人工巡檢&#xff09;在技術應用、效率、準確性等多個維度存在顯著差異&#xff0c;具體區別如下&#xff1a; 1. 巡檢方式更智能 普通巡檢&#xff1a;依賴人工現場觀察&#xff0c;主要通過眼看、手…

Java中的volatile關鍵字詳解

核心作用&#xff1a;解決可見性和有序性問題volatile 的主要作用可以歸結為兩點&#xff1a;1.保證變量的可見性 和 禁止指令重排序。2.它提供了一種輕量級的同步機制&#xff0c;3.但需要注意的是&#xff0c;它不能保證原子性。保證可見性&#xff1a;什么是可見性問題&…

【Linux】MySQL數據目錄遷移步驟(含流程圖踩坑經驗)

在生產環境中&#xff0c;有時候你會遇到一些看似簡單但實際上很棘手的問題。最近我就碰到了一次典型的服務器磁盤空間告急&#xff0c;最后通過遷移 MySQL 數據目錄成功解決了問題。本文記錄整個過程&#xff0c;包括我的分析思路、遷移步驟、踩坑和經驗總結&#xff0c;希望對…

數據驅動下的連鎖模式復制:技術科普與方法論深度解析

前言在連鎖經營的賽道上&#xff0c;“復制”是核心命題&#xff0c;但絕非簡單的“粘貼”。當行業進入數字化深水區&#xff0c;數據驅動正成為連鎖模式突破增長瓶頸、實現高效復制的“隱形引擎”。本文將從技術科普與方法論心得兩個維度&#xff0c;深度拆解數據如何重塑連鎖…

數據庫學習MySQL系列2、Windows11系統安裝MySQL方法一.msi安裝詳細教程

方法一.msi安裝詳細教程 Windows系統下MySQL——.msi安裝詳細教程&#xff08;默認--只安裝服務端“Server only”&#xff09;MySql官網地址&#xff1a;https://www.mysql.com/&#xff1b;快速下載通道請單擊→ No thanks, just start my download.ps&#xff1a;其他資源(…

html+css+vue實現增刪改查

代碼如下&#xff1a;<!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>優化版 Vue.js CRUD 示例&l…

(計算機網絡)DNS解析流程及兩種途徑

在計算機網絡中&#xff0c;DNS&#xff08;Domain Name System&#xff09;用于 將域名解析為 IP 地址。一個完整的解析過程涉及 遞歸查詢、迭代查詢&#xff0c;以及多個關鍵角色&#xff08;LDNS、本地域名服務器&#xff1b;根服務器&#xff1b;頂級域名服務器&#xff1b…

數據結構——隊列(Java)

一.基本概念 隊列用來存儲邏輯關系為“一對一”的數據&#xff0c;是一種“特殊”的線性存儲結構。 特點&#xff1a; ?先進先出&#xff1a;隊列中元素的添加&#xff08;入隊enqueue&#xff09;和移除&#xff08;出隊dequeue&#xff09;遵循先進先出的原 則。 ?端點&…

【Go】:mac 環境下GoFrame安裝開發工具 gf-cli——gf_darwin_arm64

當前主要是關于gf_darwin_arm64的安裝步驟 如何快速給mac電腦安裝gfgf是什么安裝步驟方法1&#xff1a;去github下載gf-cli去git上下載對應電腦版本的gf-cli驗證下載文件是否二進制文件授予該文件權限方法2&#xff1a;去goframe官網教你下載步驟驗證gf是否安裝成功可能遇到的問…

【新】ApiHug官方文檔-ApiHug Spring Security 擴展-補充說明

概述 在上次說明中我們寫了ApiHug 如何做授權的&#xff0c; 這里有個概念的混淆&#xff0c; 其實 apihug 不是在spring security 上做的安全擴展&#xff0c; 應該是 apihug spring, 安全設計框架&#xff0c; 和本身 spring security 沒有半毛錢關系&#xff0c; 而如果你…

【Flask】測試平臺開發,新增說明書編寫和展示功能 第二十三篇

概述&#xff1a;本篇是接著上一篇&#xff0c;細分出說明書的編寫部分&#xff0c;實現這個功能的需求&#xff0c;是內部很多同事反饋&#xff0c;需要有個地方存工具&#xff0c;并且可以寫說明書&#xff0c;如果需要的人&#xff0c;那么可以在界面上直接下載工具和查看工…

Mac設置中的安全性缺少“任何來源”

問題&#xff1a;用Mac安裝軟件&#xff0c;隱私性與安全性&#xff0c;想切換“任何來源”用來下載網站的app&#xff0c;但是菜單欄找不到“任何來源”選項&#xff0c;無法安裝dmg的文件終端中一行代碼設置出來&#xff1a;sudo spctl --global-disable &#xff08;禁用Mac…

uniapp開發小程序,列表 點擊后加載更多數據

一、需求 1.初始顯示限制:將每頁條數limit改為5,確保初始只顯示5條數據 2.查看更多功能:添加了loadMore方法,點擊"查看更多"時加載下一頁數據 3.實現查看更多功能,點擊后加載更多數據 4.添加loading狀態防止重復請求 添加hasMore狀態判斷是否還有更多數據 …

Windows 部署 Gerrit 與 Apache24 配置

Windows 部署 Gerrit 與 Apache24 并配置反向代理 準備工作 下載并安裝 Java JDK 確保配置 JAVA_HOME 環境變量博主這里安裝openjdk21 https://jdk.java.net/archive/下載所需軟件 Apache24&#xff1a;https://httpd.apache.org/download.cgi Gerrit&#xff1a;https://www.g…

從 Excel 趨勢線到機器學習:拆解 AI 背后的核心框架?

引言&#xff1a;你其實早就 “玩轉” 過機器學習&#xff1f;提到 “機器學習”&#xff0c;你是不是第一時間聯想到復雜的代碼、密密麻麻的公式&#xff0c;還有那些讓人頭暈的 “算法”“模型”“訓練” 術語&#xff1f;仿佛它是高高在上的技術&#xff0c;離我們的日常無比…

Lenovo聯想YOGA Pro 16 IAH10 2025款筆記本電腦(83L0)開箱狀態預裝OEM原廠Win11系統

適用機型(MTM)&#xff1a;【83L0】 鏈接&#xff1a;https://pan.baidu.com/s/1tDpeBb93t1u0XIgqAZ3edg?pwdqy2r 提取碼&#xff1a;qy2r 聯想原裝系統自帶所有驅動、出廠主題壁紙、系統屬性聯機支持標志、系統屬性專屬LOGO標志、Office辦公軟件、聯想瀏覽器、電腦管家、…

Android 開發 - 一些畫板第三方庫(DrawBoard、FingerPaintView、PaletteLib)

一、DrawBoard 1、Dependencies 模塊級 build.gradle implementation com.github.jenly1314:drawboard:1.1.02、Test &#xff08;1&#xff09;Activity Layout activity_draw_board.xml <?xml version"1.0" encoding"utf-8"?> <LinearLayout …

捷多邦揭秘超厚銅板:從制造工藝到設計關鍵環節?

一、超厚銅板制造工藝要點超厚銅板&#xff08;3oz 及以上&#xff09;的制造工藝對精度和穩定性要求嚴苛&#xff0c;核心環節需突破多重技術壁壘。蝕刻工藝中&#xff0c;因銅箔厚度達 105μm 以上&#xff0c;需采用高濃度酸性蝕刻液&#xff08;氯化銅濃度控制在 180-220g/…

【MYSQL | 高級篇 MyCat實現分庫分表】

摘要&#xff1a;本文圍繞分庫分表展開&#xff0c;先分析單庫性能瓶頸&#xff0c;介紹垂直與水平拆分策略及實現技術&#xff0c;再詳述 MyCat 中間件的概述、環境準備、目錄結構&#xff0c;講解其入門配置與測試&#xff0c;深入說明核心配置文件&#xff0c;最后演示垂直和…

Docker部署Drawnix開源白板工具

Drawnix簡介 Drawnix 是一款開源的在線白板工具&#xff08;SaaS&#xff09;&#xff0c;集思維導圖、流程圖繪制、自由畫圖等多種功能于一體&#xff0c;支持協作與插件擴展&#xff0c;適用于個人創作、團隊協作和遠程辦公場景。它完全免費且開源&#xff0c;提供豐富的編輯…