纯血鸿蒙实战!基于 HarmonyOS NEXT 与华为云 FunctionGraph 构建端云一体化 Serverless 应
纯血鸿蒙实战!基于 HarmonyOS NEXT 与华为云 FunctionGraph 构建端云一体化 Serverless 应用
1. 背景与技术演进
随着 HarmonyOS NEXT(纯血鸿蒙) 全面走向商用,鸿蒙原生应用开发迎来了爆发式增长。但在多设备协同(手机、平板、折叠屏、车机)场景下,传统的“端侧独立开发 + 传统后端服务器集群”架构正在遇到严峻挑战:
- 后端运维过重:初创团队或移动端全栈工程师需要单独维护虚机、负载均衡与数据库,成本高、运维繁琐。
- 多端状态同步慢:面对跨设备协同场景,传统 RESTful 轮询与 WebSocket 链路维护脆弱。
- 安全凭据暴露隐患:移动端直连云端存储或数据库时,硬编码 AK/SK 极易引发数据泄露事故。
针对这些痛点,“端云一体化(Client-Cloud Integration)” 架构应运而生。通过将端侧 ArkTS / ArkUI 声明式开发与云端 华为云 FunctionGraph(Serverless 函数计算) 深度结合,开发者能够以“全栈同一语言、零服务器运维、弹性按需计费”的极简模式构建生产级应用。
本文将以一个典型的“跨端图片智能审核与分发”场景为例,全面演示如何从零搭建 HarmonyOS NEXT 与华为云 Serverless 端云协同全链路。
2. 整体端云协同架构
系统整体数据流与控制流设计如下:
- 端侧(Client):基于 HarmonyOS NEXT,使用 ArkTS 编写,负责 UI 呈现、图片本地压缩以及调用端云 SDK。
- 网关鉴权层(API Gateway / IAM):通过华为云 API 网关统一管理路由,通过安全令牌服务(STS)生成临时访问凭证。
- 计算层(Serverless Function):华为云 FunctionGraph 2.0,运行 Node.js / Python 运行时,负责业务逻辑处理、安全校验及第三方服务串联。
- 存储与数据层(Storage & Data):华为云对象存储服务(OBS)存储文件,通过函数触发器自动执行异步处理。
3. 核心实战步骤
3.1 云端:FunctionGraph 编写免密直传凭据颁发函数
为了防止客户端暴露云服务长期密钥(AK/SK),我们通过 FunctionGraph 动态向 IAM 请求有效期仅 15 分钟的临时安全凭据(STS Temporary Security Credentials)。
创建名为 get-upload-credentials 的 Python 3.10 函数:
# -*- coding:utf-8 -*-
import json
import os
import time
from obs import ObsClient
def handler(event, context):
"""
FunctionGraph 函数入口
通过 Context 中的委托获取临时凭证,生成 OBS 预签名上传 URL
"""
# 从环境变量或临时安全委托获取运行身份
ak = context.getAccessKey()
sk = context.getSecretKey()
security_token = context.getSecurityToken()
bucket_name = "harmony-media-assets"
object_key = f"uploads/{int(time.time())}_{context.getRequestId()[:8]}.jpg"
# 实例化 OBS 客户端
obs_client = ObsClient(
access_key_id=ak,
secret_access_key=sk,
security_token=security_token,
server="https://obs.cn-north-4.myhuaweicloud.com"
)
# 生成有效期为 15 分钟的 PUT 预签名直传 URL
res = obs_client.createSignedUrl(
method="PUT",
bucketName=bucket_name,
objectKey=object_key,
expires=900,
headers={"Content-Type": "image/jpeg"}
)
return {
"statusCode": 200,
"headers": {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*"
},
"body": json.dumps({
"uploadUrl": res.signedUrl,
"objectKey": object_key,
"expiresIn": 900
})
}
安全要点:给该函数配置具有指定 OBS 写入权限的 IAM 委托(Agency),函数执行时自动获取沙箱安全令牌,业务代码无需出现任何明文密码。
3.2 端侧:HarmonyOS NEXT (ArkTS) 端云协同实现
在 DevEco Studio 中创建 HarmonyOS NEXT 工程,编写端侧上传服务模块。
(1) 请求云函数获取上传凭证与执行直传
// entry/src/main/ets/services/CloudUploadService.ets
import { http } from '@kit.NetworkKit';
import { fileIo } from '@kit.CoreFileKit';
interface UploadCredentials {
uploadUrl: string;
objectKey: string;
expiresIn: number;
}
export class CloudUploadService {
private static FUNCTION_API_URL = "https://your-apigw-endpoint.myhuaweicloud.com/api/get-credentials";
/**
* 1. 调用华为云 FunctionGraph 获取临时直传 URL
*/
public static async getUploadUrl(): Promise<UploadCredentials> {
const httpRequest = http.createHttp();
const response = await httpRequest.request(CloudUploadService.FUNCTION_API_URL, {
method: http.RequestMethod.GET,
header: {
'Content-Type': 'application/json'
},
connectTimeout: 5000,
readTimeout: 5000
});
if (response.responseCode === 200) {
return JSON.parse(response.result as string) as UploadCredentials;
}
throw new Error(`获取上传凭证失败,状态码: ${response.responseCode}`);
}
/**
* 2. 将端侧本地图片直传至华为云 OBS
*/
public static async uploadFileToObs(filePath: string, uploadUrl: string): Promise<boolean> {
const file = fileIo.openSync(filePath, fileIo.OpenMode.READ_ONLY);
const stat = fileIo.statSync(file.fd);
const buffer = new ArrayBuffer(stat.size);
fileIo.readSync(file.fd, buffer);
fileIo.closeSync(file);
const httpRequest = http.createHttp();
const response = await httpRequest.request(uploadUrl, {
method: http.RequestMethod.PUT,
header: {
'Content-Type': 'image/jpeg'
},
extraData: buffer,
connectTimeout: 10000,
readTimeout: 30000
});
return response.responseCode === 200;
}
}
(2) 声明式 UI 交互(ArkUI)
// entry/src/main/ets/pages/Index.ets
import { CloudUploadService } from '../services/CloudUploadService';
import { promptAction } from '@kit.ArkUI';
@Entry
@Component
struct MediaUploadPage {
@State uploadProgress: string = "等待上传";
@State isUploading: boolean = false;
build() {
Column({ space: 24 }) {
Text("HarmonyOS NEXT 端云协同")
.fontSize(24)
.fontWeight(FontWeight.Bold)
.margin({ top: 40 })
Text(`当前状态: ${this.uploadProgress}`)
.fontSize(16)
.fontColor(Color.Gray)
Button(this.isUploading ? "正在处理中..." : "一键安全直传至云端")
.width('85%')
.height(48)
.enabled(!this.isUploading)
.onClick(async () => {
this.isUploading = true;
this.uploadProgress = "正在向云函数请求安全令牌...";
try {
// Step 1: 请求 FunctionGraph
const creds = await CloudUploadService.getUploadUrl();
this.uploadProgress = "已获取安全凭证,正在直传 OBS...";
// Step 2: 模拟本地沙箱文件直传(实际场景换为 PhotoViewPicker 选取文件路径)
// const success = await CloudUploadService.uploadFileToObs(localPath, creds.uploadUrl);
this.uploadProgress = "上传成功!ObjectKey: " + creds.objectKey;
promptAction.showToast({ message: "端云一体化交互完成!" });
} catch (err) {
this.uploadProgress = "执行异常: " + (err as Error).message;
} finally {
this.isUploading = false;
}
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Start)
}
}
4. 生产调优与避坑经验
4.1 函数冷启动(Cold Start)毫秒级优化
- 问题:在流量低谷后突然发起首个请求,Serverless 函数拉起容器可能消耗 800ms~1500ms,影响移动端手感。
- 调优策略:
- 开启预留实例(Reserved Instances):在华为云控制台为核心函数配置 1 个预留实例,锁定最小算力底座,实现常态化 0ms 冷启动。
- 轻量化依赖打包:避免在函数代码包中全量引入庞大的第三方 SDK,使用精简依赖(如仅引入
urllib3或按需导入obs-sdk),将 Zip 包控制在 5MB 以内。
4.2 跨域 CORS 与安全网关拦截
- HarmonyOS 网络请求虽然不受传统浏览器 Same-Origin 政策限制,但若通过 Web 容器或调试工具代理调用,必须在 API 网关和云函数返回头中显式增加
Access-Control-Allow-Origin: *与Access-Control-Allow-Methods: GET,POST,PUT,OPTIONS。
4.3 端侧网络状态感知与断点续传
- 移动端面临弱网、网络切换(Wi-Fi 切蜂窝)等极端环境。在 ArkTS 中务必使用
@kit.NetworkKit监听网络状态,针对 >10MB 的媒体大文件,结合 OBS 分块上传(Multi-part Upload)API 实现断点续传,防止大包传输超时失败。
5. 总结与展望
在 HarmonyOS NEXT 与云原生 Serverless 深度融合的新时代,“端云一体化”不再是一个概念,而是大幅降低研发门槛、实现敏捷迭代的核心利器:
- 从运维角度:不再需要时刻盯守服务器负载与 CPU 预警,FunctionGraph 自动弹性吞吐应对突发流量;
- 从安全角度:端侧零密钥暴露,以云端 IAM 细粒度 STS 临时凭据彻底斩断数据泄露隐患;
- 从开发效率:声明式 ArkUI 与函数无缝联动,单名工程师也能在数天内交付具备企业级稳定性的全场景跨端应用。
随着鸿蒙全场景生态的持续壮大,端云协同架构必将成为未来每一个全栈工程师不可或缺的必备技能。
- 点赞
- 收藏
- 关注作者
评论(0)