-
# 1.服务说明 FunctionGraph服务:基于事件驱动的函数托管计算服务。通过函数工作流,只需编写业务函数代码并设置运行的条件,无需配置和管理服务器等基础设施,函数以弹性、免运维、高可靠的方式运行。 # 2.方案说明 ## 2.1 需求及痛点 需求:实现CDN日志实时转存到OBS 痛点:当前CDN日志模块不支持转储能力,需要客户代码实现该能力 ## 2.2 方案设计 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/202201/04/190656nmqzbbpz40kig5nh.png) **方案说明:** - 定时触发器,固定频率启动函数 - 函数请求CDN日志接口,获取日志下载链接 - 函数请求下载链接,将下载的日志上传到OBS固定目录下。 ## 2.3 服务创建 ### 2.3.1 确认CDN日志记录状态 - 在华为云控制台查看CDN日志记录是否正常,如图可知日志会有5个小时的延迟。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/202201/04/190856zdcjtkqyewrsooic.png) ### 2.3.2 FunctionGraph新建函数 - 登录华为云控制台,进入“管理与部署>统一身份认证服务”,选择“委托”页签,点击创建“委托”。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/202201/04/1910153nhdrqvk74q82hb6.png) - 下一步,进入委托配置权限界面。作用范围:全局服务;权限选择:OBS OperateAccess 、CDN LogsReadOnlyAccess。点击确认 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/202201/04/191040k87llhvgseqdu1nq.png) - 华为云控制台,选择“计算>函数工作流”,进入函数工作流界面,点击右上角“创建函数”,输入图片中的信息,点击创建函数 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/202201/04/191149gbn7qkrqhwpjo0n2.png) - 创建后,进入代码编辑界面,将 Demo代码 的代码内容复制到在线IDE ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/202201/04/191259oqvkcaat58youzoz.png) - 点击配置按钮,配置“环境变量” ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/202201/04/191323qvv1ehjiw76dxrtq.png) **注:** url :https://cdn.myhuaweicloud.com/v1.0/cdn/logs(CDN日志查询的url)。 domain_name :xxx.com(需要转存日志的CDN加速域名)。 obsAddress :xxx.com(用于存日志的OBS桶域名)。 destBucket :******(用于存日志的OBS桶文件夹名称)。 - 在函数配置界面选择“触发器”,点击右侧“创建触发器”,配置内容如下,点击确定。(实例代码中日志转储的日志为最新生成的近一小时日志) ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/202201/04/191415icec47stds0swpz1.png) - 在函数配置界面,单击右上角“请选择测试事件”下拉框,选择“配置测试事件”,配置内容如下,点击保存即可。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/202201/04/191451yyfy3yoellu8yno6.png) - 在函数配置界面,单击右上角“请选择测试事件”下拉框,选择“配置测试事件”,配置内容如下,点击保存即可。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/202201/04/191514h51v3b1wmoyhfcx0.png) - 点击函数的保存按钮即可,函数配置成功。 # 3.FunctionGraph适用说明 该FunctionGraph函数工作流适用于CDN日志转储OBS,转储规则为增量转储,可通过配置触发器以及修改代码实现定时增量转储固定周期的CDN日志。 # 4.Demo代码 ```python # -*- coding:utf-8 -*- import requests import datetime import time import os import sys import json from com.obs.client.obs_client import ObsClient from urllib.parse import urlparse if sys.version_info.major == 2 or not sys.version > '3': import httplib else: import http.client as httplib current_file_path = os.path.dirname(os.path.realpath(__file__)) sys.path.append(current_file_path) TEMP_ROOT_PATH = "/tmp/" # OBS文件下载后的存储路径 region = 'china' # 默认值,用于FunctionGraph连接OBS使用 secure = True # 默认值,用于FunctionGraph连接OBS使用 signature = 'v4' # 默认值,用于FunctionGraph连接OBS使用 port = 443 # 默认值,用于FunctionGraph连接OBS使用 path_style = True # 默认值,用于FunctionGraph连接OBS使用 def handler(event, context): #引用context的logger方法 logger = context.getLogger() #CDN日志记录查询接口的起始时间,转换成时间戳;当前为近6个小时的日志记录 timer = (datetime.datetime.now()-datetime.timedelta(hours=6)).strftime("%Y-%m-%d %H") timeStamp = int(time.mktime(time.strptime(timer,"%Y-%m-%d %H"))*1000) #配置日志转储的起始时间点,转换成时间戳 timeStr = (datetime.datetime.now()-datetime.timedelta(hours=6)).strftime("%Y-%m-%d %H") timeStrStamp = int(time.mktime(time.strptime(timeStr,"%Y-%m-%d %H"))*1000) #配置日志转储的终止时间点,转换成时间戳 timeEnd = (datetime.datetime.now()-datetime.timedelta(hours=5)).strftime("%Y-%m-%d %H") timeSEndStamp= int(time.mktime(time.strptime(timeEnd,"%Y-%m-%d %H"))*1000) #CDN日志记录查询接口参数字段,显示数量为 pageSize* pageNumber pageSize = 5000 pageNumber = 1 #https请求加上verify=False忽略SSL验证后会出现警告,使用以下代码忽略警告 requests.packages.urllib3.disable_warnings() #queryDate 日志的产日日期,用于日志存储路径使用 queryDate = (datetime.datetime.now()-datetime.timedelta(hours=6)).strftime("%Y-%m-%d") #使用start函数 start(context, queryDate, timeStamp, pageSize, pageNumber,timeStrStamp,timeSEndStamp) #定义start函数,进行日志记录查询 def start(context, queryDate, timeStamp, pageSize, pageNumber,timeStrStamp,timeSEndStamp): #引用context的logger方法 logger = context.getLogger() #引用context的中用户参数(新建函数后配置的参数),引用url,domain_name logUrl = context.getUserData('url') domainName = context.getUserData('domain_name') #request的请求参数 params = {'query_date': timeStamp, 'domain_name': domainName, 'page_size': pageSize, 'page_number': pageNumber, 'enterprise_project_id':'ALL'} #request的请求头 headers = {'Content-Type': 'application/json;charset=UTF-8', 'X-Auth-Token': context.getToken()} #发起日志记录接口的请求, res = requests.get(logUrl, params=params, headers=headers, verify=False) # 请求状态码判断,若非200,打印响应信息 if res.status_code != 200: logger.info("query log urls: " + res.url + ", error: " + res.text) return ("query log urls: " + res.url + ", error: " + res.text) #创建res.text的python对象 resJson = json.loads(res.text) #打印res.text的内容 logger.info(res.text) #将响应信息中的total的值赋予total total = resJson['total'] #定义变量i ,用于循环计数 i = 0 #从resjson logs值中循环取值 for val in resJson['logs']: i += 1 #打印 val中的link的值 logger.info(val["link"]) #val中的start_time的值赋予start_time start_time = val["start_time"] #取时间段内日志记录 if int(start_time) >= timeStrStamp and int(start_time) timeSEndStamp: # link分为6个部分,协议、位置、路径、参数、查询、片段。 url = urlparse(val["link"]) # 将url 中的请求地址根据“:”进行分片 netlocs = url.netloc.split(":") # 创建连接 conn = httplib.HTTPConnection(netlocs[0], int(netlocs[1])) conn.request('GET', url.path + "?" + url.query) # CDN日志,OBS的存储路径 objName = os.path.join(val["domain_name"], queryDate, val["name"]) #使用 put_content_to_obs函数 put_content_to_obs(context, objName, conn.getresponse()) else: continue # 判断转储的日志量与total对比;不满足则重新执行start函数 if i > total: start(context, queryDate, timeStamp, pageSize, pageNumber + 1,timeStrStamp,timeSEndStamp) #定义put_content_to_obs函数,上传日志到OBS def put_content_to_obs(context, objName, content): #引用context中的方法获取ak,sk ak = context.getAccessKey() sk = context.getSecretKey() #引用context中的用户定义变量obsAddress,destBucket obsAddress = context.getUserData('obsAddress') destBucket = context.getUserData('destBucket') #创建OBS上传实例 TestObs = ObsClient(access_key_id=ak, secret_access_key=sk, is_secure=secure, server=obsAddress, signature=signature, path_style=path_style, region=region, ssl_verify=False, port=port, max_retry_count=5, timeout=20) #上传日志 resp = TestObs.putContent(destBucket, objName, content=content) #判断执行结果 if resp.status 300: print('requestId:', resp.requestId) else: print('errorCode:', resp.errorCode) print('errorMessage:', resp.errorMessage) ``` # 5.Demo代码说明 ## 5.1 注释说明 ```python #CDN日志记录查询接口的起始时间,转换成时间戳;当前为近6个小时的日志记录 timer = (datetime.datetime.now()-datetime.timedelta(hours=6)).strftime("%Y-%m-%d %H") timeStamp = int(time.mktime(time.strptime(timer,"%Y-%m-%d %H"))*1000) #配置日志转储的起始时间点,转换成时间戳 timeStr = (datetime.datetime.now()-datetime.timedelta(hours=6)).strftime("%Y-%m-%d %H") timeStrStamp = int(time.mktime(time.strptime(timeStr,"%Y-%m-%d %H"))*1000) #配置日志转储的终止时间点,转换成时间戳 timeEnd = (datetime.datetime.now()-datetime.timedelta(hours=5)).strftime("%Y-%m-%d %H") timeSEndStamp= int(time.mktime(time.strptime(timeEnd,"%Y-%m-%d %H"))*1000) ``` **示例说明:** 假设代码执行时间为 2021-12-30 20:30 日志记录查询接口的查询时间为 timestamp=2021-12-30 14:00 至 2021-12-30 20:30 由于CDN的日志生成时间延迟6小时,则 2021-12-30 14:00 至 2021-12-30 20:30 的时间内只有2021-12-30 14:00 的日志文件生成。 由于设置触发器每小时触发一次,即可每小时上传一次最新生成的日志,实现增量上传。 ## 5.2 Context说明 | 方法名 | 方法说明 | |:---|:---| | getRequestID() | 获取请求ID。 | | getRemainingTimeInMilliSeconds () | 获取函数剩余运行时间。 | | getAccessKey() | 获取用户委托的AccessKey(有效期24小时),使用该方法需要给函数配置委托。 | | getSecretKey() | 获取用户委托的SecretKey(有效期24小时),使用该方法需要给函数配置委托。 | | getUserData(string key) | 通过key获取用户通过环境变量传入的值。 | | getFunctionName() | 获取函数名称。 | | getRunningTimeInSeconds () | 获取函数超时时间。 | | getVersion() | 获取函数的版本。 | | getMemorySize() | 分配的内存。 | | getCPUNumber() | 获取函数占用的CPU资源,单位为millicore(1 core=1000 millicores)。取值与MemorySize成比例,默认是128M内存占0.1个核(100 millicores),函数占用的CPU为基础CPU:200 millicores,再加上内存按比例占用的CPU,计算方法:内存/128 * 100 + 200。 | | getProjectID() | 获取projectID。 | | getPackage() | 获取函数组。 | | getToken() | 获取用户委托的token(有效期24小时),使用该方法需要给函数配置委托。 | | getLogger() | 获取context提供的logger方法,返回一个日志输出类,通过使用其info方法按“时间-请求ID-输出内容”的格式输出日志。如调用info方法输出日志:logg = context.getLogger() logg.info("hello") | # 6.实测结果 - FunctionGraph函数界面,点击测试按钮。查看执行结果以及转储到OBS中的日志。 **a.FunctionGraph 函数界面** ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/202201/04/193158yasrqum1u2ybm92z.png) **b.OBS界面查看日志** ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/202201/04/193225v7gkfzyz942wdpfi.png)
-
体验通过DevStar服务的“人脸特征检测应用开发”模板自动生成人脸特征检测应用代码,一站式托管到代码仓,以及作为云函数发布到函数工作流(FunctionGraph)后,快速体验由AI自动检测所上传图片中的人脸特征信息。您将学到什么您将学会如何通过DevStar实现一站式快速开发基于Serverless人脸特征检测应用,并基于华为云EI产品开放能力扩展功能,体验云上开发的乐趣。您需要什么硬件要求PC电脑软件要求Chrome浏览器需要的知识点熟悉常规电脑操作常识具备基本的软件开发能力 环境准备注册华为云账号、实名认证如果您已拥有华为账号且已通过实名认证,可直接体验。若您还没有通过实名认证的账号,请注册华为账号,然后完成实名认证(推荐使用“扫码认证”方式,即时完成)。参考如何实名认证和如何扫码认证。创建应用使用Chrome浏览器,访问DevStar 人脸特征检测应用开发 模板,点击“开发应用”按钮,基于该模板快速开发应用。若您是首次使用该模板开发应用,需要授权DevStar访问该模板涉及的华为云服务。若之前已完成过授权,可忽略此步骤。点击“同意授权”按钮进行授权,待完成授权后,点击“继续创建应用”按钮新建应用。在应用创建页面根据页面提示完成项目、应用名信息输入注:如果没有任何DevCloud项目,可点击“创建项目”新建一个项目注:在创建项目过程中如提示“该企业租户服务处于关闭状态 ”,请点击“立即开通”。在DevCloud服务购买页面,选择基础版进行购买操作(基础版5人及以下免费)。开通后,继续完成项目创建。注:创建完项目后,点击所属项目选项列表旁的“刷新”图标,可显示新创建的项目,选中并完成页面其它信息输入,点击”立即创建”按钮,进入应用详情界面等待应用使用的代码仓等资源创建完成(约20s),点击左侧的应用部署菜单,查看依赖云服务的状态。若云服务未开通,则点击“去开通”按钮完成服务开通。注意:人脸检测服务API按需付费模式每月前2000次调用免费,若您使用次数超过免费次数,将会产生费用,详情可点击“参考价格”查看,如调用次数不超出免费额度,可忽略此条。函数工作流FunctionGraph按照实际使用量付费,每月调用超100万次或计量时间超过400,000 GB-秒,将会产生费用,详情可点击“参考价格”查看。如调用次数不超出免费额度,可忽略此条。开通完成后点击对应服务的刷新按钮,查看服务开通状态。依赖的云服务全部完成开通后,点击“部署”按钮,进行应用部署待部署完成后,点击“看看”链接访问部署到函数工作流的云函数。点击“上传图片”,选择您需要进行人脸特征检测的图片,然后点击“提交”进行检测体验。 进阶体验-添加对发型,胡须等识别项的检测9.在应用详情界面点击左侧菜单栏的“在线开发”按钮进入在线开发界面10.您可选择”免费体验 CloudIDE 打开”,如果您购买了CloudIDE永久实例也可选择使用。注意:CloudIDE实例首次启动耗时约30s,请您等待界面加载完成,期间请勿切换页面,否则会终止加载。11.代码中使用的是人脸识别服务的人脸检测接口DetectFaceByFile,attributes入参值设置为“1,2,4,6”,见svelte文件的第45行代码。12.前往API Explorer查看该人脸识别接口中attributes的取值含义13.(可选)在API Explorer中设置人脸检测DetectFaceByFile接口的attributes值为“1,2,4,6,7,8”进行调试,查看调用效果14.根据接口文档资料,在CloudIDE修改DetectFaceByFile接口的attributes参数值(如改为“1,2,4,6,7,8”),将代码提交到仓库(注意:CloudIDE免费实例30分钟无使用则会被自动回收,未提交代码无法找回,请及时提交保存)注:在CloudIDE中点击Terminal菜单选择New Terminal,在命令行使用git提交代码到代码仓,参考以下命令:git add .git commit -m "modify attributes"git push origin master 使用以下命令查看代码提交历史,确认提交成功:git log 15.回到DevStar任务页(DevSar控制台-“我的应用”点击打开刚刚建立的任务)在左侧菜单栏切换到“应用部署”页面,点击“部署”按钮,选择“创建新的软件包”,点击“确定”重新部署代码。注意:此处必须选择创建新的软件包,否则修改后的代码将不生效。16.待部署完成后,点击“看看”体验修改后的效果。 恭喜您已完成体验,您还可以了解和体验其它的DevStar模板。
-
请问在FunctionGraph中怎么使用psycopg2类库?
-
在Sandbox中函数如何访问Redis?是不是不能访问本地启动的Redis服务?
-
华为云FunctionGraph支持使用定时器Timer触发任务调度,任务调度的对象是提前写好业务逻辑代码,从而实现面向多租户的任务调度。调度规则可以是固定调度,也可以写Cron表达式,从而实现更精细的调度。FunctionGraph的定时调度指导详见https://support.huaweicloud.com/usermanual-functiongraph/functiongraph_01_0207.html典型应用场景:1、面向多租户的定期数据处理,先将开发好的数据库操作脚本用FunctionGraph承载,再设计定期的任务调度,实现数据库数据按预置好的逻辑处理;
Huawei_baiyan 发表于2021-03-19 10:46:08 2021-03-19 10:46:08 最后回复 Huawei_baiyan 2021-03-19 10:46:08
1616 0 -
【功能模块】【操作步骤&问题现象】1、2、【截图信息】【日志信息】(可选,上传日志内容或者附件)
-
【重要公告】《开发者最佳实践挑战营》第八期活动已结束打卡名单及邀请名单已公示见:FAQ帖>>>注:统计截止2020年12月31日24:00前打卡数据为保证您顺利领取活动奖品,请全通关和获得邀请TOP奖的伙伴提前填写下方奖品收货信息链接。填写截止时间为1月8日,如您没有填写,视为放弃奖励填写地址请戳我>>欢迎参加华为云“开发者最佳实践挑战营”第八期这是本次挑战营的第2关,坚持闯关成功有机会获12900码豆/机械键盘/背包等精美好礼!本期活动截止12月31日。注意:参与闯关前,请确保已报名加入活动群并领取实践资源,如未入群请添加小助手微信(hwpaas01),回复“最佳实践”进入学习交流群!点击这里了解活动详情>> | 点击这里查看活动FAQ>>为避免无法发放码豆,请从未登录过会员中心的用户需提前登陆下DevCloud会员中心本手册基于函数工作流服务实践所编写,用于指导您使用函数工作流服务实现为图片打水印的功能。什么是函数工作流?函数工作流(FunctionGraph)是华为云提供的一款无服务器(Serverless)计算服务,无服务器计算是一种托管服务,服务提供商会实时为用户分配充足的资源,而不需要预留专用的服务器或容量,真正按实际使用付费。华为无服务器计算包含函数和工作流两个功能模块,分别实现函数计算和函数编排的功能。 (1)实践资源说明:① 函数工作流 FunctionGraph:函数前100万次/月调用免费。点击了解价格详情>>② 对象存储服务 OBS:标准存储价格¥0.099/GB/月起,实践完后请及时删除存储文件。点击了解价格详情>>提示:本次实践建议选择“华北-北京四”区域;实践函数工作流+OBS总费用预计:0元≤实践费用<1元。(2)最佳实践指南:点击查看实践指南>> (3)视频演示:点击查看实践视频演示>> 提示:本次如选择“华北-北京四”,需在函数代码中,修改OBS的地址,详情见→FAQ第13条。任务一:创建函数,并将函数详情页“代码”截图,截图需包含右上角华为云账号名,并按回帖格式要求在本帖中回帖;任务二:根据实践指南完成实践操作(可查看实践视频演示),将函数日志截图,将打完水印的图片截图,并按回帖格式要求在本帖中回帖;注:已参加过上一期在本帖已闯关完成打卡的用户参与第八期通本关将不在发放通关奖励1.【通关、参与奖励&规则】点击这里填写报名登记表,完成提交可获100码豆(已提交的可忽略)① 参与奖励:每关完成创建实例可获100码豆,共8关最高可获得800码豆;② 通关奖励:通过2关赠送:2000码豆(可选关)通过4关赠送:4000码豆(可选关)通过6关赠送:6000码豆(可选关)通过8关赠送:8000码豆(全通关)取通关最高数发放码豆,全通关可额外获得旅行本(套装)1本(限量100本取最先全通关者发放)和“开发者最佳实践挑战达人”荣誉证书;全通关用户点击填写问卷,以便证书发放;2.【邀请奖励】:每邀请1位好友并成功完成1关或多关实践并打卡,可额外获得1000码豆(最高可获得3000码豆);3.【邀请TOP榜奖励】:邀请好友并完成1关或多关实践并打卡,邀请榜前3可获得机械键盘(雷柏)1个,邀请榜4-10名可获得华为云定制背包1个(如有并列取最先邀请完成打卡者)4.【分享奖励】:点击这里进入分享活动(最高可获1000码豆)>>>5.【邀请有礼】:点击这里进入邀请好友报名活动瓜分30万码豆,(最高可获得66666码豆)>>>活动结束后5个工作日内公示通关名单,15个工作日内发放码豆奖励; 码豆有什么用?码豆为虚拟货币可用于在华为云码豆会员中心-兑换商城中进行实物/虚拟礼品的兑换(礼品会不定期更换)兑换礼品点击查看:华为云专属码豆商城>>> 请务必按照以下格式要求进行回帖,否则无法计算奖励:1、华为云账号:xxx(即右上角的字母数字组合ID)2、邀请人华为云账号:xxx(即右上角的字母数字组合ID,如无就不填)3、实践感想:(如对课程内容、产品体验的建议或感想等)4、体验任务截图:(打卡样例图)注:华为云账号请勿填错,如填错码豆无法发放到账。实践截图:至少包含(a)函数代码截图、(b)上传图片触发函数后,函数指标截图(c)日志截图、(d)打了水印的图片截图,共 4 张截图。例1-函数详情页“代码”截图:例2-上传图片触发函数后,查看函数指标并截图:例3-上传图片触发函数后,查看函数日志并截图:例4-OBS中下载打完水印的图片,并截图: 【快速传送门】第1关任务:基于API网关的电话号码归属地查询第2关任务:使用函数工作流服务为图片打水印第3关任务:使用Redis实现排行榜功能第4关任务:使用DMS Kafka优化消费者poll第5关任务:使用CPTS进行电商网站性能测试第6关任务:基于ServiceStage的天气预报应用部署第7关任务:使用CloudIDE在云端环境开发AI交付实操第8关任务:使用ModelArts实现零代码美食分类模型开发>>点击进入:开发者最佳实践挑战营第八期活动页>>点击进入:活动FAQ帖>>点击进入:邀请有礼,瓜分30万码豆,最高可获66666码豆!>>点击进入:分享任务,获码豆换好礼!
-
感谢参与本期活动!本期《开发者最佳实践挑战营》活动已于7月8日24:00结束,可添加小助手微信等待下期开启添加小助手微信:zhongjianjianxiaoge欢迎参加华为云“开发者最佳实践挑战营”!这是本次挑战营的第2关,坚持闯关成功有机会获7000+码豆/体脂秤/手环/摄像机等精美好礼!本期活动截止7月8日。注意:参与闯关前,请确保已报名加入活动群并领取实践资源,如未入群请添加小助手微信(zhongjianjianxiaoge),回复“最佳实践”报名入群!点击这里了解活动详情>> | 点击这里查看活动FAQ>>本手册基于函数工作流服务实践所编写,用于指导您使用函数工作流服务实现为图片打水印的功能。 什么是函数工作流?函数工作流(FunctionGraph)是华为云提供的一款无服务器(Serverless)计算服务,无服务器计算是一种托管服务,服务提供商会实时为用户分配充足的资源,而不需要预留专用的服务器或容量,真正按实际使用付费。华为无服务器计算包含函数和工作流两个功能模块,分别实现函数计算和函数编排的功能。 (1)实践资源说明:① 函数工作流 FunctionGraph:函数前100万次/月调用免费。计费价格详情见:https://www.huaweicloud.com/pricing.html?tab=detail#/function② 对象存储服务 OBS:标准存储价格¥0.099/GB/月起,实践完后请及时删除存储文件。计费价格详情见:https://www.huaweicloud.com/pricing.html?tab=detail#/obs提示:本次实践建议选择“北京四”或“上海二”区域;实践函数工作流+OBS总费用预计:0元≤实践费用<1元。(2)最佳实践指南: https://support.huaweicloud.com/bestpractice-functiongraph/functiongraph_05_0400.html (3)视频演示:本次实践操作步骤比较简单,根据实践指南即可完成,无需视频演示;(4)入门教学:https://support.huaweicloud.com/functiongraph_video/index.html提示:本次如选择“北京四”或“上海二”,需在函数代码中,修改OBS的地址,详情见→FAQ第13条。任务一:创建函数,并将函数详情页“代码”截图,截图需包含右上角华为云账号名,并按回帖格式要求在本帖中回帖;任务二:根据实践指南完成实践操作,将函数日志截图,将打完水印的图片截图,并按回帖格式要求在本帖中回帖;1)通关、参与奖励&规则参与奖励、通关奖励限前150名完成的开发者(码豆奖励有限先到先得)① 参与奖励:每关完成创建实例可获100码豆,共6关最高可获得600码豆② 通关奖励:通过2关赠送:1000码豆通过4关赠送:2000码豆通过6关赠送:4000码豆活动结束后5个工作日内公示通关名单,15个工作日内发放码豆奖励。注:取通关最高值发放码豆奖励 2)分享任务规则&奖励:分享海报,每次分享可获得500码豆,最多可分享5次,可获2500码豆激励第一步: 分享以下文案+海报至朋友圈或100人以上技术群(微信、QQ、钉钉不限)。每次分享可获得500码豆,最高2500码豆!码豆可用于兑换DevCloud会员中心精美实物礼品。(1)文案:我正在参与华为云开发者最佳实践挑战营,场景化实战get云上开发技能,闯关还能赢好礼!(2)海报:添加小助手微信(zhongjianjianxiaoge),回复“分享海报”获取海报和文案。第二步: 分享完成后,截图点击链接https://www.wjx.top/jq/79372993.aspx 上传分享截图;符合要求的截图即可算作分享成功1次,获得500码豆,最高可获2500码豆!码豆奖励会在活动结束后15个工作日内发放3)幸运奖抽奖规则&奖励:(1)全通关可参与抽取:荣耀小哨兵智能摄像机 广角版、华为手环跑步精灵3e手环、荣耀智能体脂秤2;(2)活动结束后5个工作日内公示通关名单,并在微信群中统一抽奖。中奖名单公布后,用户需单独提供收件信息,奖品将于15个工作日内发放。为避免无法发放码豆,从未登录过会员中心的用户需提前登陆下DevCloud会员中心本次活动发放的码豆有效期至2020年9月1日 请务必按照以下格式要求进行回帖,否则无法计算奖励:华为云账号名:XXX(即右上角的字母数字组合ID)微信昵称:XXX实践感想:XXX实践截图:至少包含(a)函数代码截图、(b)上传图片触发函数后,函数指标截图(c)日志截图、(d)打了水印的图片截图,共 4 张截图。例1-函数详情页“代码”截图:例2-上传图片触发函数后,查看函数指标并截图:例3-上传图片触发函数后,查看函数日志并截图:例4-OBS中下载打完水印的图片,并截图: 附各关卡快速入口:第1关任务:基于API网关的电话号码归属地查询第2关任务:使用函数工作流服务为图片打水印第3关任务:使用Redis实现排行榜功能第4关任务:使用DMS Kafka优化消费者poll第5关任务:使用CPTS进行电商网站性能测试第6关任务:基于ServiceStage的天气预报应用部署
-
欢迎参加华为云“中间件最佳实践挑战营”!这是本次挑战营的第2关,坚持闯关成功有机会获第五期好礼:码豆/荣耀手环/华为背包等,全通关还有大奖!本期活动截止5月24日。注意:参与闯关前,请确保已报名加入活动群并领取实践资源,如未入群请点击添加小助手微信(zhongjianjianxiaoge),回复“中间件”报名入群!点击这里了解活动详情>> | 点击这里查看活动FAQ>> 一、 场景介绍本手册基于函数工作流服务实践所编写,用于指导您使用函数工作流服务实现为图片打水印的功能。 什么是函数工作流?函数工作流(FunctionGraph)是华为云提供的一款无服务器(Serverless)计算服务,无服务器计算是一种托管服务,服务提供商会实时为用户分配充足的资源,而不需要预留专用的服务器或容量,真正按实际使用付费。华为无服务器计算包含函数和工作流两个功能模块,分别实现函数计算和函数编排的功能。 二、 实践指南(1)实践资源说明:① 函数工作流 FunctionGraph:函数前100万次/月调用免费。计费价格详情见:https://www.huaweicloud.com/pricing.html?tab=detail#/function② 对象存储服务 OBS:标准存储价格¥0.099/GB/月起,实践完后请及时删除存储文件。计费价格详情见:https://www.huaweicloud.com/pricing.html?tab=detail#/obs提示:本次实践建议选择“北京四”或“上海二”区域;实践函数工作流+OBS总费用预计:0元≤实践费用<1元。(2)最佳实践指南: https://support.huaweicloud.com/bestpractice-functiongraph/functiongraph_05_0400.html (3)视频演示:本次实践操作步骤比较简单,根据实践指南即可完成,无需视频演示;(4)入门教学:https://support.huaweicloud.com/functiongraph_video/index.html 提示:本次如选择“北京四”或“上海二”,需在函数代码中,修改OBS的地址,详情见→FAQ第13条。三、 闯关任务任务一:创建函数,并将函数详情页“代码”截图,截图需包含右上角华为云账号名,并按回帖格式要求在本帖中回帖;奖励:100码豆(可用于兑换DevCloud会员中心实物好礼); 任务二:根据实践指南完成实践操作,将函数日志截图,将打完水印的图片截图,并按回帖格式要求在本帖中回帖;奖励:本期闯1关可参与抽取“荣耀手环4 Running版”;闯2关可参与抽取“华为背包”;详见FAQ评奖规则 四、 回帖格式请务必按照以下格式要求进行回帖,否则无法计算奖励:华为云账号名:XXX(即右上角的字母数字组合ID)微信昵称:XXX实践感想:XXX实践截图:至少包含(a)函数代码截图、(b)上传图片触发函数后,函数指标截图(c)日志截图、(d)打了水印的图片截图,共 4 张截图。例1-函数详情页“代码”截图: 例2-上传图片触发函数后,查看函数指标并截图: 例3-上传图片触发函数后,查看函数日志并截图: 例4-OBS中下载打完水印的图片,并截图: 附各关卡快速入口:第1关任务:基于API网关的电话号码归属地查询第2关任务:使用函数工作流服务为图片打水印第3关任务:使用Redis实现排行榜功能第4关任务:使用DMS Kafka优化消费者poll第5关任务:使用CPTS进行电商网站性能测试
-
本次活动已结束,恭喜以下小伙伴获奖请获奖的小伙伴在11月27日之前将你的收件信息(地址,电话,联系人)通过私信发给“花花”,逾期未提供信息者视为放弃中奖资格,谢谢~~本次活动总共有效楼层44楼,按照活动规则只抽取1名用户获得三等奖中奖用户为:yd_9527(华为云账号:jxhz1890607)当函数工作流遇上AI,5分钟出品图片鉴黄应用,赢华为手机大奖!云计算时代出现了大量XaaS形式的概念,从IaaS、PaaS、SaaS 到容器云引领的CaaS,再到火热的微服务架构,它们都在试着将各种软、硬件资源等抽象为一种服务提供给开发者使用,让他们不再担心基础设施、资源需求、中间件等等,在减轻心智负担的同时更好地专注于业务。无服务器架构是云计算的热点趋势,将会成为下一代IT基础架构。无服务器架构只是炒作吗?NO!!!当华为云函数工作流遇上AI5分钟即可创建出图片鉴黄应用参与以下活动即可让你真正体验无服务架构概念还能获得参与抽奖机会哦~~~ 活动时间:2018年11月05日-11月19日活动参与方式:1、进入函数工作流服务控制台, 按照下文具体操作步骤完成应用创建2、将创建完的应用截图发到评论区回帖,即可参与活动抽奖。回帖格式:“产品使用建议+华为云用户名+截图”奖品设置:1、炫酷一等奖:华为荣耀10手机。活动截止从全部有效楼层中(要求总共有效楼层数大于200楼)抽取1名用户,赠送荣耀10手机一台。2、贴心二等奖:膳魔师保温杯。每60个有效楼层抽取1名用户中奖,赠送膳魔师的保温杯一个。冬天来了,给你一杯热水的温度。3、幸运三等奖:荣耀引擎耳机。每30个有效楼层抽取1名用户中奖,赠送荣耀引擎耳机一个。 具体操作步骤:1、进入函数工作流服务控制台, 输入函数名称,按照下图直接创建函数,并配置APIG触发器(如果没有API分组,需创建一个API分组)。2、在“配置”栏中为函数配置一个委托,提供给函数具有IAM的访问权限。(如果没有此委托,按照下图指导创建委托)3、进入AI内容检测服务控制台,免费申请开通“图片反黄检测”功能。4、进入触发器页签,复制apig触发器的地址,浏览器访问该地址即可访问创建的应用了,将创建完成的应用界面截图5、截图(必须将链接截图出来)进行回帖即可,回帖格式必须为“产品使用建议+华为云用户名+截图”。PS:有些用户使用的浏览器链接可能显示不全,只需如下图红框部分的链接能截取出来即可。温馨提示:1、我们在11月13日公示获奖者名单。同时会在3个工作日内联系获奖者,在公示后7个工作日内统一发放奖品。2、有效楼层指按照要求参与活动,不同ID,且不同实名认证用户。3、每个ID只能中奖一次,如果重复中奖,顺延至下一楼层。4、禁止华为云及其业务外包方员工参加(除非作出说明),若参加了活动(含员工小号),则取消参与资格。5、请遵守华为云社区常规活动规则。注:每个用户只需要一次有效回帖(产品使用建议+华为云用户名+截图)即可,我们将会登记用户名单,按照回帖先后顺序编号。如编号1.2.3.4....,编号1~30楼会抽取一名用户中奖耳机一个,编号31~60楼再抽取一名用户中奖耳机一个,1-60楼抽取一名用户中奖保温杯,61-120楼再抽取一名用户中奖保温杯,以此类推鉴于部分用户反映不明白操作步骤的原理,完全都是机械的操作完成的,这里将该应用架构图附上,仅供各位参考关于本应用更多的原理,可以参考文章:《5分钟Serverless实践 | 构建无服务器图片鉴黄Web应用》欢迎进入“函数工作流”,探索其中更多的体验馆和函数模板,了解被誉为“云计算未来方向”的新技术,一起探讨无服务器(serverless)的更多可能性。也可以将您的想法和创意show到评论区,和专家们一起碰撞思维的火花。更多技术博客尽在微信公众号 “中间件小哥”
-
1 前 言在上一篇“5分钟Serverless实践”系列文章中,我们介绍了什么是Serverless,以及如何构建一个无服务器的图片鉴黄Web应用,本文将延续这个话题,以敏感词过滤为例,介绍如何构建一个无服务器API,即无服务器的后端系统。 2 函数工作流函数工作流(FunctionGraph,FGS)是一项基于事件驱动的函数托管计算服务,托管函数具备以毫秒级弹性伸缩、免运维、高可靠的方式运行。通过函数工作流,开发者无需配置和管理服务器,只需关注业务逻辑,编写函数代码,以无服务器的方式构建应用,便能开发出一个弹性高可用的后端系统,并按实际运行消耗的资源计费。极大地提高了开发和运维效率,减小了运作成本。 相比于传统的架构,函数工作流构建的无服务器架构具有如下优点:1. 无需关注任何服务器,只需关注核心业务逻辑,提高开发和运维效率;2. 函数运行随业务量弹性伸缩,按需付费,执行才计费,对于负载波峰波谷非常明显的场景可以减少大量成本;3. 通过简单的配置即可连通函数工作流和其它各云服务,甚至云服务和云服务; 3 构建无服务器的敏感词过滤后端系统为了进一步让大家感受函数工作流的优势,我们将介绍如何通过函数工作流快速构建一个无服务器的敏感词过滤系统,本文我们主要关注后端系统,前端的表现形式很多,大家可以自行构建。如下图,该系统会识别用户上传的文本内容是否包含敏感信息(如**、政治等),并对这些词语进行过滤。 试想,如果我们通过传统的模式开发此应用,需要如何开发?即使是基于现在的云平台,我们也仍需要购买云服务器,关注其规格、镜像、网络等各指标的选型和运维,然后在开发过程中可能还需要考虑与其他云服务的集成使用问题,使代码中耦合大量非业务代码,并且服务器等资源也并非是按需的,特别是对于访问量波峰波谷非常明显的场景,会造成大量多余的费用。 现在我们可以通过函数工作流服务来快速构建这个系统,并且完全无需关注服务器,且弹性伸缩运行、按需计费,如图:创建函数,在函数中调用华为云内容检测服务提供的文本检测接口,实现文本的敏感词检测,并为该函数配置一个APIG触发器,这样便可以对外提供一个敏感词过滤的API,从而构建出一个完整的敏感词过滤的无服务器后端系统。客户端调用API,他会自动触发函数执行,而开发者编写的函数只需实现接收到文本之后如何处理文本的逻辑即可,最后将结果返回给客户端。至此,我们就构建了一个完整的无服务器敏感词过滤后端系统。 接下来,我们将介绍如何完整地将此无服务器后端系统构建出来。1. 准备工作进入华为云内容检测服务,申请开通文本内容检测,成功申请后便可以调用内容检测服务提供的文本检测接口了。 2. 创建函数进入函数工作流服务页面,创建函数,实现文本检测的接口调用和敏感词过滤,代码如下(Python):# -*- coding:utf-8 -*- import json import base64 import urllib import urllib2 import ssl import sys reload(sys) sys.setdefaultencoding('utf-8') def do_filter(msg,str_list): result = '' try: if len(str_list) <=0: return msg for str in str_list: str_tmp = msg.replace(str,'') msg = str_tmp result = msg except: print("_do_filter catch an exception!") return result def filter(context, msg): result = '' try: ssl._create_default_https_context = ssl._create_unverified_context token = context.getToken(); headers = {'Content-Type':'application/json;charset=utf8','X-Auth-Token':token} url = "https://ais.cn-north-1.myhwclouds.com/v1.0/moderation/text" values = {} values['categories'] = ['**','ad','politics','abuse','contraband'] #msg = base64.b64encode(msg) item = {'type':'content','text':msg} values['items'] = [item] data = json.dumps(values) print("data: %s"%data) request = urllib2.Request(url,data,headers) rsp = urllib2.urlopen(request) http_rsp = rsp.read() print("http response: %s" %http_rsp) json_rsp = json.loads(http_rsp) result = json_rsp['result'] suggestion = result['suggestion'] if suggestion == 'pass': print("input msg have passed the checking!") result = msg else: detail = result['detail'] if detail.has_key('**'): list_** = detail['**'] msg = do_filter(msg,list_**) if detail.has_key('ad'): list_ad = detail['ad'] msg = do_filter(msg,list_ad) if detail.has_key('politics'): list_politics = detail['politics'] msg = do_filter(msg,list_politics) if detail.has_key('abuse'): list_abuse = detail['abuse'] msg = do_filter(msg,list_abuse) if detail.has_key('contraband'): list_contraband = detail['contraband'] msg = do_filter(msg,list_contraband) result = msg except Exception, e: print e print("filter catch an exception!") return result def handler (event, context): print("message filter begin!") result = "" response = {} http_method = event.get('httpMethod') if http_method == 'OPTIONS': response = { 'statusCode': 200, 'isBase64Encoded': True, 'headers': { "Content-Type": "application/json; charset=utf-8", "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Headers": "Content-Type,Accept", "Access-Control-Allow-Methods": "GET,POST,PUT,DELETE" }, 'body': base64.b64encode('{"result":'+ '"' + result +'"}'), } return response body = event.get('body') body_decode = base64.b64decode(body) json_object = json.loads(body_decode) msg = json_object['msg'] print('msg : %s'%msg) try: result = filter(context, msg) response = { 'statusCode': 200, 'isBase64Encoded': True, 'headers': { "Content-Type": "application/json; charset=utf-8", "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Headers": "Content-Type,Accept", "Access-Control-Allow-Methods": "GET,POST,PUT,DELETE" }, 'body': base64.b64encode('{"result":'+ '"' + result +'"}'), } except: print("function catch an exception!") return response函数创建完成之后,为其配置具有IAM访问权限的委托,因为本函数代码中获取用户的ak、sk需要拥有访问IAM的权限。 3. 创建APIG触发器为函数配置一个APIG触发器,这样便得到一个调用该函数的HTTP(S) API,供外部调用。 创建成功后,API的URL可以在函数详情页面的“触发器”栏看到: 4. 测试使用postman等工具向上一步中创建的APIG触发器的接口发送post请求,body体为:{“msg”: “过滤检测的文本”},查看返回信息。比如发送 {"msg": "just ** ..."}, 返回体为 {"result": "just ..."} 至此,我们就完整地构建了一个无服务器的敏感词过滤后端系统。 欢迎扫码查看更多精彩:
-
5分钟Serverless实践|构建无服务器的敏感词过滤后端系统 1 前 言在上一篇“5分钟Serverless实践”系列文章中,我们介绍了什么是Serverless,以及如何构建一个无服务器的图片鉴黄Web应用,本文将延续这个话题,以敏感词过滤为例,介绍如何构建一个无服务器API,即无服务器的后端系统。 2 函数工作流函数工作流(FunctionGraph,FGS)是一项基于事件驱动的函数托管计算服务,托管函数具备以毫秒级弹性伸缩、免运维、高可靠的方式运行。通过函数工作流,开发者无需配置和管理服务器,只需关注业务逻辑,编写函数代码,以无服务器的方式构建应用,便能开发出一个弹性高可用的后端系统,并按实际运行消耗的资源计费。极大地提高了开发和运维效率,减小了运作成本。 相比于传统的架构,函数工作流构建的无服务器架构具有如下优点:1. 无需关注任何服务器,只需关注核心业务逻辑,提高开发和运维效率;2. 函数运行随业务量弹性伸缩,按需付费,执行才计费,对于负载波峰波谷非常明显的场景可以减少大量成本;3. 通过简单的配置即可连通函数工作流和其它各云服务,甚至云服务和云服务; 3 构建无服务器的敏感词过滤后端系统为了进一步让大家感受函数工作流的优势,我们将介绍如何通过函数工作流快速构建一个无服务器的敏感词过滤系统,本文我们主要关注后端系统,前端的表现形式很多,大家可以自行构建。如下图,该系统会识别用户上传的文本内容是否包含敏感信息(如**、政治等),并对这些词语进行过滤。 试想,如果我们通过传统的模式开发此应用,需要如何开发?即使是基于现在的云平台,我们也仍需要购买云服务器,关注其规格、镜像、网络等各指标的选型和运维,然后在开发过程中可能还需要考虑与其他云服务的集成使用问题,使代码中耦合大量非业务代码,并且服务器等资源也并非是按需的,特别是对于访问量波峰波谷非常明显的场景,会造成大量多余的费用。 现在我们可以通过函数工作流服务来快速构建这个系统,并且完全无需关注服务器,且弹性伸缩运行、按需计费,如图:创建函数,在函数中调用华为云内容检测服务提供的文本检测接口,实现文本的敏感词检测,并为该函数配置一个APIG触发器,这样便可以对外提供一个敏感词过滤的API,从而构建出一个完整的敏感词过滤的无服务器后端系统。客户端调用API,他会自动触发函数执行,而开发者编写的函数只需实现接收到文本之后如何处理文本的逻辑即可,最后将结果返回给客户端。至此,我们就构建了一个完整的无服务器敏感词过滤后端系统。 接下来,我们将介绍如何完整地将此无服务器后端系统构建出来。1. 准备工作进入华为云内容检测服务,申请开通文本内容检测,成功申请后便可以调用内容检测服务提供的文本检测接口了。 2. 创建函数进入函数工作流服务页面,创建函数,实现文本检测的接口调用和敏感词过滤,代码如下(Python):# -*- coding:utf-8 -*- import json import base64 import urllib import urllib2 import ssl import sys reload(sys) sys.setdefaultencoding('utf-8') def do_filter(msg,str_list): result = '' try: if len(str_list) <=0: return msg for str in str_list: str_tmp = msg.replace(str,'') msg = str_tmp result = msg except: print("_do_filter catch an exception!") return result def filter(context, msg): result = '' try: ssl._create_default_https_context = ssl._create_unverified_context token = context.getToken(); headers = {'Content-Type':'application/json;charset=utf8','X-Auth-Token':token} url = "https://ais.cn-north-1.myhwclouds.com/v1.0/moderation/text" values = {} values['categories'] = ['**','ad','politics','abuse','contraband'] #msg = base64.b64encode(msg) item = {'type':'content','text':msg} values['items'] = [item] data = json.dumps(values) print("data: %s"%data) request = urllib2.Request(url,data,headers) rsp = urllib2.urlopen(request) http_rsp = rsp.read() print("http response: %s" %http_rsp) json_rsp = json.loads(http_rsp) result = json_rsp['result'] suggestion = result['suggestion'] if suggestion == 'pass': print("input msg have passed the checking!") result = msg else: detail = result['detail'] if detail.has_key('**'): list_** = detail['**'] msg = do_filter(msg,list_**) if detail.has_key('ad'): list_ad = detail['ad'] msg = do_filter(msg,list_ad) if detail.has_key('politics'): list_politics = detail['politics'] msg = do_filter(msg,list_politics) if detail.has_key('abuse'): list_abuse = detail['abuse'] msg = do_filter(msg,list_abuse) if detail.has_key('contraband'): list_contraband = detail['contraband'] msg = do_filter(msg,list_contraband) result = msg except Exception, e: print e print("filter catch an exception!") return result def handler (event, context): print("message filter begin!") result = "" response = {} http_method = event.get('httpMethod') if http_method == 'OPTIONS': response = { 'statusCode': 200, 'isBase64Encoded': True, 'headers': { "Content-Type": "application/json; charset=utf-8", "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Headers": "Content-Type,Accept", "Access-Control-Allow-Methods": "GET,POST,PUT,DELETE" }, 'body': base64.b64encode('{"result":'+ '"' + result +'"}'), } return response body = event.get('body') body_decode = base64.b64decode(body) json_object = json.loads(body_decode) msg = json_object['msg'] print('msg : %s'%msg) try: result = filter(context, msg) response = { 'statusCode': 200, 'isBase64Encoded': True, 'headers': { "Content-Type": "application/json; charset=utf-8", "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Headers": "Content-Type,Accept", "Access-Control-Allow-Methods": "GET,POST,PUT,DELETE" }, 'body': base64.b64encode('{"result":'+ '"' + result +'"}'), } except: print("function catch an exception!") return response函数创建完成之后,为其配置具有IAM访问权限的委托,因为本函数代码中获取用户的ak、sk需要拥有访问IAM的权限。 3. 创建APIG触发器为函数配置一个APIG触发器,这样便得到一个调用该函数的HTTP(S) API,供外部调用。 创建成功后,API的URL可以在函数详情页面的“触发器”栏看到: 4. 测试使用postman等工具向上一步中创建的APIG触发器的接口发送post请求,body体为:{“msg”: “过滤检测的文本”},查看返回信息。比如发送 {"msg": "just ** ..."}, 返回体为 {"result": "just ..."} 至此,我们就完整地构建了一个无服务器的敏感词过滤后端系统。 欢迎扫码查看更多精彩:
-
ServerlessServerless中文译为“无服务器”,最早可以追溯到2012年Ken Fromm发表的《Why The Future Of Software And Apps Is Serverless》[1],他描述了一种场景,从用户自己维护的物理机,到IaaS,再到PaaS,计算模式的转变并不会停止,在云计算基础设施成熟的情况下应用程序可以不需要考虑服务器的存在,无服务器计算让开发者可以在不考虑服务器的情况下构建并运行应用程序和服务。再到2016年,Mike Roberts在Martin Fowler的博客《Serverless Architectures》[2]中,将Serverless架构分为Backend as a Service(BaaS)和Functions as a Service(FaaS)。BaaS也就是后端即服务,即应用架构由大量三方云服务和API来组织,使应用中关于服务器的逻辑和状态都由服务提供方来管理。比如典型的单页应用(SPA)和移动APP这些富客户端应用,前后端的交互主要以Rest API调用为主,只需要调用服务提供方的API即可完成相应的功能,比如身份验证、数据访问等。FaaS可以被称为函数即服务,开发者可以直接将服务侧业务逻辑代码部署、运行在第三方提供的无状态计算容器中,开发者只需编写业务代码即可,无需关注服务器,且代码的执行是由事件触发的。一个Serverless的应用就是这样一个将BaaS和FaaS融合在一起的应用,用户关注于应用的业务逻辑代码,以函数为粒度将其运行在FaaS平台上,并和BaaS三方服务整合在一起,最后搭建一个完整的系统,整个过程完全无需关注服务器。Serverless的优势1、无需管理服务器开发者只需关注应用的业务逻辑,而无需关注服务器的存在,降低业务接入门槛,快速上线,提高开发和运维效率。2、灵活扩展、按需付费据Gartner和麦肯锡统计,全球的服务器CPU平均利用率只有6%到12%,大量应用的资源利用率是非常低下的,特别是对于负载波峰波谷明显的应用。而Serverless可以根据负载弹性伸缩,并按需付费,根据实际运行消耗的资源计费,且业务是以函数的粒度运行的,可以充分利用碎片资源,极大地减小运作成本。函数工作流FunctionGraph上面简单介绍了Serverless架构以及其优点之后,我们再介绍一下华为云的函数工作流(FunctionGraph,FGS)。函数工作流(FunctionGraph,FGS)是一项基于事件驱动的函数托管计算服务,托管函数具备以毫秒级弹性伸缩、免运维、高可靠的方式运行。通过函数工作流,开发者无需配置和管理服务器,只需关注业务逻辑,编写函数代码,以无服务器的方式构建应用,便能开发出一个弹性高可用的后端系统,并按实际运行消耗的资源计费。极大地提高了开发和运维效率,减小了运作成本。构建无服务器图片鉴黄web应用为了让大家对Serverless架构和函数工作流有更直观的了解,接下来我们将介绍如何通过函数工作流快速构建一个完整的无服务器的图片鉴黄Web应用,如下图,该应用接收用户上传的图片,并对图片进行分析,判断是否为**图片。试想,如果我们通过传统的模式开发此应用,需要如何开发?即使是基于现在的云平台,我们也仍需要购买云服务器,关注其规格、镜像、网络等各指标的选型和运维,然后在开发过程中可能还需要考虑与其他云服务的集成使用问题,使代码中耦合大量非业务代码,并且服务器等资源也并非是按需的,可能会造成大量多余的费用。现在我们可以通过函数工作流服务来快速构建这个系统,并且完全无需关注服务器,且按需运行,如图:创建函数,在函数中调用华为云内容检测服务提供的图片鉴黄接口,实现图片鉴黄功能,并为该函数配置一个APIG触发器,对外提供图片鉴黄的API,从而构建出一个完整的图片鉴黄无服务器后端。然后将Web页面的静态资源部署在对象存储服务(OBS)中,用户可以直接从OBS访问前端页面。用户上传图片时,页面调用前面构建的图片鉴黄API,他会自动触发函数执行,而开发者编写的函数只需实现接收到图片之后如何处理图片的逻辑(调用内容检测服务服务)即可,最后将结果返回给前端页面。至此,我们就构建了一个完整的无服务器图片鉴黄Web应用。现在,我们将介绍如何端到端地将此无服务器应用构建出来。后端API搭建:进入函数工作流服务函数创建页面,选择图片鉴黄模板。该模板已经提供了本应用中函数的代码,按照代码注释中的指示创建函数之后,就成功搭建了本应用的后端系统,为函数所创建的APIG触发器会提供一个调用该后端函数的HTTP(s) API,供外部系统(如前端页面)调用。创建成功后API的URL可以在函数详情页面的“触发器”栏看到:前端页面搭建:前端的展示形式有很多,这里我们提供了一份前端代码包供大家学习参考,可以将此代码包部署到OBS上,快速构建一个单页Web应用(SPA)。然后调用上一步后端提供的接口,连通后端系统,完成整个无服务图片鉴黄Web应用的构建。1、下载代码包并解压2、为了让前端页面访问您的函数,需要配置页面Rest请求的URL。修改代码包里/functiongraph/assets/config/apis.json文件中checkImage的值,更改为上一步“后端API搭建”中创建的APIG触发器URL,即您的后端API的访问地址。3、通过OBS托管前端页面。进入对象存储服务,创建一个OBS桶,将程序包文件逐个上传至该桶中。因为文件比较多,我们建议您下载 OBS Browser ,使用OBS Browser前,请先获取访问密钥。4、启动网站。进入桶的静态网站托管界面,单击静态网站托管,配置桶的默认首页为index.html。配置完成后,您就已经成功搭建了本案例的前端系统。您可以通过obs提供的访问地址访问您的前端页面,检测图片时,页面会发送请求到您的函数。总结通过上面端到端构建一个完整的无服务器图片鉴黄Web应用,我们可以发现Serverless的架构具有如下优点:无需关注任何服务器,只需关注核心业务逻辑,5分钟快速构建后端系统并上线,极大地提高了开发效率;函数运行随业务量弹性伸缩,按需付费,当创建的函数没有执行时,不计费。可以通过简单的配置连通函数工作流和其它云服务,甚至云服务和云服务,比如本例中只需创建一个APIG触发器便可完成API网关和函数工作流的连接,然后在函数中调用内容检测服务的鉴黄接口,那么函数就像一个粘合剂一样将两个云服务连接在一起。相关链接https://readwrite.com/2012/10/15/why-the-future-of-software-and-apps-is-serverless/https://martinfowler.com/articles/serverless.htmlhttps://console.huaweicloud.com/functiongraph/欢迎扫码查看更多精彩:
-
ServerlessServerless中文译为“无服务器”,最早可以追溯到2012年Ken Fromm发表的《Why The Future Of Software And Apps Is Serverless》[1],他描述了一种场景,从用户自己维护的物理机,到IaaS,再到PaaS,计算模式的转变并不会停止,在云计算基础设施成熟的情况下应用程序可以不需要考虑服务器的存在,无服务器计算让开发者可以在不考虑服务器的情况下构建并运行应用程序和服务。再到2016年,Mike Roberts在Martin Fowler的博客《Serverless Architectures》[2]中,将Serverless架构分为Backend as a Service(BaaS)和Functions as a Service(FaaS)。BaaS也就是后端即服务,即应用架构由大量三方云服务和API来组织,使应用中关于服务器的逻辑和状态都由服务提供方来管理。比如典型的单页应用(SPA)和移动APP这些富客户端应用,前后端的交互主要以Rest API调用为主,只需要调用服务提供方的API即可完成相应的功能,比如身份验证、数据访问等。FaaS可以被称为函数即服务,开发者可以直接将服务侧业务逻辑代码部署、运行在第三方提供的无状态计算容器中,开发者只需编写业务代码即可,无需关注服务器,且代码的执行是由事件触发的。一个Serverless的应用就是这样一个将BaaS和FaaS融合在一起的应用,用户关注于应用的业务逻辑代码,以函数为粒度将其运行在FaaS平台上,并和BaaS三方服务整合在一起,最后搭建一个完整的系统,整个过程完全无需关注服务器。Serverless的优势1、无需管理服务器开发者只需关注应用的业务逻辑,而无需关注服务器的存在,降低业务接入门槛,快速上线,提高开发和运维效率。2、灵活扩展、按需付费据Gartner和麦肯锡统计,全球的服务器CPU平均利用率只有6%到12%,大量应用的资源利用率是非常低下的,特别是对于负载波峰波谷明显的应用。而Serverless可以根据负载弹性伸缩,并按需付费,根据实际运行消耗的资源计费,且业务是以函数的粒度运行的,可以充分利用碎片资源,极大地减小运作成本。函数工作流FunctionGraph上面简单介绍了Serverless架构以及其优点之后,我们再介绍一下华为云的函数工作流(FunctionGraph,FGS)。函数工作流(FunctionGraph,FGS)是一项基于事件驱动的函数托管计算服务,托管函数具备以毫秒级弹性伸缩、免运维、高可靠的方式运行。通过函数工作流,开发者无需配置和管理服务器,只需关注业务逻辑,编写函数代码,以无服务器的方式构建应用,便能开发出一个弹性高可用的后端系统,并按实际运行消耗的资源计费。极大地提高了开发和运维效率,减小了运作成本。构建无服务器图片鉴黄web应用为了让大家对Serverless架构和函数工作流有更直观的了解,接下来我们将介绍如何通过函数工作流快速构建一个完整的无服务器的图片鉴黄Web应用,如下图,该应用接收用户上传的图片,并对图片进行分析,判断是否为**图片。试想,如果我们通过传统的模式开发此应用,需要如何开发?即使是基于现在的云平台,我们也仍需要购买云服务器,关注其规格、镜像、网络等各指标的选型和运维,然后在开发过程中可能还需要考虑与其他云服务的集成使用问题,使代码中耦合大量非业务代码,并且服务器等资源也并非是按需的,可能会造成大量多余的费用。现在我们可以通过函数工作流服务来快速构建这个系统,并且完全无需关注服务器,且按需运行,如图:创建函数,在函数中调用华为云内容检测服务提供的图片鉴黄接口,实现图片鉴黄功能,并为该函数配置一个APIG触发器,对外提供图片鉴黄的API,从而构建出一个完整的图片鉴黄无服务器后端。然后将Web页面的静态资源部署在对象存储服务(OBS)中,用户可以直接从OBS访问前端页面。用户上传图片时,页面调用前面构建的图片鉴黄API,他会自动触发函数执行,而开发者编写的函数只需实现接收到图片之后如何处理图片的逻辑(调用内容检测服务服务)即可,最后将结果返回给前端页面。至此,我们就构建了一个完整的无服务器图片鉴黄Web应用。现在,我们将介绍如何端到端地将此无服务器应用构建出来。后端API搭建:进入函数工作流服务函数创建页面,选择图片鉴黄模板。该模板已经提供了本应用中函数的代码,按照代码注释中的指示创建函数之后,就成功搭建了本应用的后端系统,为函数所创建的APIG触发器会提供一个调用该后端函数的HTTP(s) API,供外部系统(如前端页面)调用。创建成功后API的URL可以在函数详情页面的“触发器”栏看到:前端页面搭建:前端的展示形式有很多,这里我们提供了一份前端代码包供大家学习参考,可以将此代码包部署到OBS上,快速构建一个单页Web应用(SPA)。然后调用上一步后端提供的接口,连通后端系统,完成整个无服务图片鉴黄Web应用的构建。1、下载代码包并解压2、为了让前端页面访问您的函数,需要配置页面Rest请求的URL。修改代码包里/functiongraph/assets/config/apis.json文件中checkImage的值,更改为上一步“后端API搭建”中创建的APIG触发器URL,即您的后端API的访问地址。3、通过OBS托管前端页面。进入对象存储服务,创建一个OBS桶,将程序包文件逐个上传至该桶中。因为文件比较多,我们建议您下载 OBS Browser ,使用OBS Browser前,请先获取访问密钥。4、启动网站。进入桶的静态网站托管界面,单击静态网站托管,配置桶的默认首页为index.html。配置完成后,您就已经成功搭建了本案例的前端系统。您可以通过obs提供的访问地址访问您的前端页面,检测图片时,页面会发送请求到您的函数。总结通过上面端到端构建一个完整的无服务器图片鉴黄Web应用,我们可以发现Serverless的架构具有如下优点:无需关注任何服务器,只需关注核心业务逻辑,5分钟快速构建后端系统并上线,极大地提高了开发效率;函数运行随业务量弹性伸缩,按需付费,当创建的函数没有执行时,不计费。可以通过简单的配置连通函数工作流和其它云服务,甚至云服务和云服务,比如本例中只需创建一个APIG触发器便可完成API网关和函数工作流的连接,然后在函数中调用内容检测服务的鉴黄接口,那么函数就像一个粘合剂一样将两个云服务连接在一起。相关链接https://readwrite.com/2012/10/15/why-the-future-of-software-and-apps-is-serverless/https://martinfowler.com/articles/serverless.htmlhttps://console.huaweicloud.com/functiongraph/欢迎扫码查看更多精彩:
-
前言用户开发的微服务要想注册到华为云CSE的服务中心,就需要用到AK/SK认证。由于CSEJavaSDK提供了较多的配置方式,有时候容易出现错配和漏配的情况,本文从CSEJavaSDK读取AK/SK的关键代码入手进行分析,希望能够给大家提供一点AK/SK认证失败时的定位思路。(本文基于CSEJavaSDK-2.3.30进行说明)代码逻辑分析首先需要说明的是,AK/SK也是一个配置项,因此它可以配置在microservice.yaml文件里,可以通过-D设置系统属性来指定,也可以通过环境变量来指定(Windows的环境变量貌似可以带点号.,因此你可以直接在环境变量中指定cse.credentials.accessKey=ak;而Linux的环境变量不能带点,所以不能这么做)。另一方面来说,AK/SK又是一个比较特殊的配置项,因此CSEJavaSDK又提供了一个加密存储的配置方式。无论AK/SK的来源是哪里,最终CSEJavaSDK都是在AKSKManager中完成AK/SK的读取逻辑的。public static Credentials getCredential() throws Exception { // 读取AK/SK AKSKOption option = AKSKOption.readAKSK(); // 中间读写缓存等等逻辑忽略…… // 根据cse.credentials.akskCustomCipher配置获取cipher,对AK/SK进行解密 AKSKCipher cipher = (AKSKCipher)CIPHERS.get(option.getAkskCustomCipher()); // 检查逻辑忽略... char[] ak = cipher.decode(TYPE.AK, option.getAccessKey().toCharArray()); char[] sk = cipher.decode(TYPE.SK, option.getSecretKey().toCharArray()); String project = option.getProject(); if (project == null || project.isEmpty()) { // 如果用户没有配置cse.credentials.project,就尝试从配置的服务中心地址进行解析,具体的代码忽略…… // 我们平常通过APIGateway连接到服务中心,例如你要连到华北区,配置的地址就是这样的 https://cse.cn-north-1.myhuaweicloud.com // 可以从中截取出 cn-north-1,这个就是华北区的project LOGGER.info("The application missing project infomation, so choose a nearest one [{}]", project); } return credentials; }以上是AKSKManager的getCredential方法逻辑,可以看到大体的流程是读取AK/SK、根据cse.credentials.akskCustomCipher配置项获取cipher对aksk进行解密、获取cse.credentials.project配置信息。此方法返回的credentials内包含了明文的AK/SK、project信息,因此本地调试时确定AK/SK读取是否有问题的最快途径就是在getCredential方法末尾打断点,查看credentials包含的信息。而在AKSKOption.readAKSK()中读取AK/SK的关键流程如下:public static AKSKOption readAKSK() { // 从AK/SK加密存储文件读取 AKSKOption option = readFromFile(); if (option == null) { // 从配置中读取,注意:环境变量、System Property、配置文件都算在这里面 option = buildFromYaml(); } return option; } private static AKSKOption readFromFile() { // 忽略缓存逻辑…… // 先尝试从环境变量CIPHER_ROOT中读取加密存储文件的目录 String cipherPath = System.getenv("CIPHER_ROOT"); if (cipherPath == null || cipherPath.isEmpty()) { // 若不存在则从/opt/CSE/etc/cipher目录中读取 cipherPath = "/opt/CSE/etc/cipher"; } String certFilePath = cipherPath + File.separator + "certificate.yaml"; File certFile = new File(certFilePath); if (!certFile.exists() || certFile.isDirectory()) { // 文件不存在时尝试从系统属性user.dir配置的目录中读取 certFile = new File(System.getProperty("user.dir") + File.separator + "certificate.yaml"); if (!certFile.exists() || certFile.isDirectory()) { return null; } } AKSKOption option = readFromFile(certFile); return option; }可以看到CSEJavaSDK优先读取加密存储的AK/SK文件,读不到才去配置中找。而AK/SK加密文件的读取路径优先级从高到低分别是CIPHER_ROOT环境变量配置的目录、/opt/CSE/etc/cipher目录、user.dir系统属性配置的目录(这个少见)。常见问题分析思路当发生AK/SK认证失败的问题时,我们首先需要对问题有个基本的定界,即问题是出在AK/SK读取(解密)上,还是出在AK/SK的内容本身。如果是本地开发调试,那么这个问题很好确定,直接在AKSKManager的getCredential方法里打断点去看一下即可。如果是在线上部署运行的服务,那么只能看日志,凭经验来定位了。与AK/SK认证相关的日志关键词有这些:"read ak/sk from":显示AK/SK的来源是哪里,"read ak/sk from security storage file."表示服务实例从AK/SK加密存储文件中读取配置项的,"read ak/sk from microservice.yaml."表示服务实例从配置项中读物AK/SK的(注意,这里说的是配置项,包含了环境变量、系统属性以及配置文件,不单单是指microservice.yaml文件)。"add ak/sk cipher":加载AKSKCipher,cipher用于解密SK。CSEJavaSDK默认提供的cipher有default、security,default用于明文存储AK/SK的场景,security在AK/SK加密存储场景中使用。CSEJavaSDK使用SPI机制加载cipher,如果发现日志中没有打印加载default和security的内容,那么你就需要检查一下自己依赖的jar包了。"sign request failed ...... OSS_ROOT not properly set":当cipher为security时,CSEJavaSDK会去CIPHER_ROOT环境变量配置的目录里读取解密密钥文件common_shared.key和root.key,如果用户忘记配置CIPHER_ROOT了,就会打印这个错误。"Cipher decode error, will use original as plain!":SK解密失败时会打印此错误日志,常见的错误原因包括CIPHER_ROOT环境变量下没有密钥文件、程序没有权限读取密钥文件、Java没有开启高强度加密功能等。关于Java高强度加密功能,大家去网上搜一下JCE policy能找到解除限制的方法,较低版本的jdk8需要下载一个jce的jar包,高版本的直接修改jre目录下的lib/security/java.security文件配置即可,这个限制只存在于Oracle JDK中,OpenJDK没有此限制。AK/SK或project配置内容错误:当内容配置出错时,实际上AK/SK的读取加密过程并不会报错,只有等到CSEJavaSDK向CSE后端服务(sc/cc/monitor)发送请求时,才会拿到错误返回消息,错误信息包括如下类型:1. AK内容错误:401:Unauthorized, {"errorCode":"401002","errorMessage":"Request unauthorized","detail":"Get service token from iam proxy failed,{\"error\":\"get SK from AK from iam failed. error:Object Not Found - details: \"}"}2. SK内容错误:401:Unauthorized, {"errorCode":"401002","errorMessage":"Request unauthorized","detail":"Get service token from iam proxy failed,{\"error\":\"validate ak sk error\"}"}3. project配置错误:401:Unauthorized, {"errorCode":"401002","errorMessage":"Request unauthorized","detail":"Get service token from iam proxy failed,{\"error\":\"get project token from iam failed. error:http post failed, statuscode: 400\"}"}这些错误内容都是华为云服务的认证鉴权机制返回的,后期如果相关服务升级的话,也许返回的错误内容会有变化。但总之大家可以抓住关键的一点,就是如果前面的AK/SK加载过程都没有报错,只有连接CSE后端服务时拿到401的错误返回,那么你就需要检查一下自己的AK/SK、project是否配置对了。-D启动参数、环境变量、各个microservice.yaml文件都是需要排查的。至于project的配置,可以参考如何查看项目ID。project和你所连接的region是相关的,比如华北区连接的APIGateway地址就是https://cse.cn-north-1.myhuaweicloud.com ,project应该配置为cn-north-1。如果你不配置,CSEJavaSDK会尝试从sc地址中截取出来,但不一定能拿到正确的值,此时启动日志里面会打印提示信息,例如"The application missing project infomation, so choose a nearest one [cn-north-1]",就是在告诉你自动选取的project是cn-north-1。总结博主对AK/SK认证的了解大致也就是上面这些了,很多内容也只能提供一点参考和启发意义。项目实际运行的情况复杂多样,当大家遇到相关问题的时候还是需要根据上面提到的代码逻辑,结合自己服务的实际运行环境去分析,才能更好地定位问题。本文转载自【华为云微服务引擎】从代码机制看AK/SK认证问题
上滑加载中
推荐直播
-
DeepSeek 深入浅出白话解读
2025/02/12 周三 17:00-18:00
Tim-华为云中国区AI解决方案总监
DeepSeek的来龙去脉,为什么DeepSeek那么强?哪些是它的领先优势?它是怎么发展过来的?在华为云上能不能用到DeepSeek?本节课将一一解读。
回顾中
热门标签