24小时咨询热线

016-680975882

新闻动态

您的位置:主页 > 新闻动态 > 企业新闻 >

Serverless 在 SaaS 领域的最佳实践-welcome欢迎光临威尼斯

发布日期:2023-09-07 01:41浏览次数:
本文摘要:随着互联网人口红利逐渐削弱,基于流量的增长已经放缓,互联网行业迫切需要找到一片足以承载自身连续增长的新蓝海,工业互联网正是这一弘大配景下的新趋势。我们看到互联网浪潮正在席卷传统行业,云盘算、大数据、人工智能开始大规模融入到金融、制造、物流、零售、文娱、教育、医疗等行业的生产环节中,这种融合称为工业互联网。而在工业互联网中,有一块不行小觑的领域是SaaS领域,它是ToB赛道的中坚气力,好比CRM、HRM、费控系统、财政系统、协同办公等等。

welcome欢迎光临威尼斯官方网站

随着互联网人口红利逐渐削弱,基于流量的增长已经放缓,互联网行业迫切需要找到一片足以承载自身连续增长的新蓝海,工业互联网正是这一弘大配景下的新趋势。我们看到互联网浪潮正在席卷传统行业,云盘算、大数据、人工智能开始大规模融入到金融、制造、物流、零售、文娱、教育、医疗等行业的生产环节中,这种融合称为工业互联网。而在工业互联网中,有一块不行小觑的领域是SaaS领域,它是ToB赛道的中坚气力,好比CRM、HRM、费控系统、财政系统、协同办公等等。SaaS系统面临的挑战在消费互联网时代,大家是搜索想要的工具,各个厂商在云盘算、大数据、人工智能等技术基座之上建设流量最大化的服务与生态,基于海量内容分发与流量共享为逻辑构建系统。

而到了工业互联网时代,供应关系发生了变化,大家是定制想要的工具,需要从供应与需求两侧出发举行双向建设,这个时候系统的灵活性和扩展性面临着前所未有的挑战,尤其是ToB的SaaS领域。特别对于当下的经济情况,SaaS厂商要明确,不能再通过烧钱的方式,只关注在自己的用户数量上,而更多的要思考如何资助客户降低成本、增加效率,所以需要将更多的精神放在自己产物的定制化能力上。如何应对挑战SaaS领域中的佼佼者Salesforce,将CRM的观点扩展到Marketing、Sales、Service,而这三块领域中只有Sales有专门的SaaS产物,其他两个领域都是各个ISV在差别行业的行业解决方案,靠的是什么?毋庸置疑,是Salesforce强大的aPaaS平台。ISV、内部实施、客户均可以在各自维度通过aPaaS平台构建自己行业、自己领域的SaaS系统,建设完整的生态。

所以在我看来,现在的Salesforce已经由一家SaaS公司升华为一家aPaaS平台公司了。这种演进的历程也印证了消费互联网和工业互联网的转换逻辑以及后者的焦点诉求。

然而不是所有SaaS公司都有财力和时间去孵化和打磨自己的aPaaS平台,但市场的变化、用户的诉求是实实在在存在的。若要生存,就要求变。这个变的焦点就是能够让自己现在的SaaS系统变得灵活起来,相对建设难题的aPaaS平台,我们其实可以选择轻量且有效的Serverless方案来提升现有系统的灵活性和可扩展性,从而实现用户差别的定制需求。

Serverless事情流在上一篇文章《资源成本双优化!看Serverless颠覆编程教育的创新实践》中,已经对Serverless的观点做过论述了,而且也先容了Serverless函数盘算(FC)的观点和实践。这篇文章中先容一下构建系统灵活性的焦点要素服务编排——Serverless事情流。Serverless 事情流是一个用来协调多个漫衍式任务执行的全托管云服务。

在 Serverless事情流中,可以用顺序、分支、并行等方式来编排漫衍式任务,Serverless事情流会根据设定好的步骤可靠地协调任务执行,跟踪每个任务的状态转换,并在须要时执行您界说的重试逻辑,以确保事情流顺利完成。Serverless事情流通过提供日志记载和审计来监视事情流的执行,可以轻松地诊断和调试应用。

下面这张图形貌了Serverless事情流如何协调漫衍式任务,这些任务可以是函数、已集成云服务API、运行在虚拟机或容器上的法式。看完Serverless事情流的先容,大家可能已经几多有点思路了吧。系统灵活性和可扩展性的焦点是服务可编排,无论是以前的BPM还是现在的aPaaS。

所以基于Serverless事情流重构SaaS系统灵活性方案的焦点思路,是将系统内用户最希望定制的功效举行梳理、拆分、抽离,再配合函数盘算(FC)提供无状态的能力,通过Serverless事情流举行这些功效点的编排,从而实现差别的业务流程。通过函数盘算FC和Serverless事情流搭建灵活的订餐模块订餐场景相信大家都不会生疏,在家叫外卖或者在餐馆点餐,都涉及到这个场景。当下也有许多提供点餐系统的SaaS服务厂商,有许多不错的SaaS点餐系统。随着消费互联网向工业互联网转换,这些SaaS点餐系统面临的定制化的需求也越来越多,其中有一个需求是差别的商家在支付时会显示差别的支付方式,好比从A商家点餐后付款时显示支付宝、微信支付、银联支付,从B商家点餐后付款时显示支付宝、京东支付。

突然美团又冒出来了美团支付,此时B商家接了美团支付,那么从B商家点餐后付款时显示支付宝、京东支付、美团支付。诸如此类的定制化需求越来越多,这些SaaS产物如果没有PaaS平台,那么就会疲于不停的通过硬代码增加条件判断来实现差别商家的需求,这显然不是一个可连续生长的模式。那么我们来看看通过函数盘算FC和Serverless事情流如何优雅的解决这个问题。

先来看看这个点餐流程:通过Serverless事情流建立流程首先我需要将上面用户侧的流程转变为法式侧的流程,此时就需要使用Serverless事情流来担任此任务了。打开Serverless控制台,建立订餐流程,这里Serverless事情流使用流程界说语言FDL建立事情流,如何使用FDL建立事情流请参阅文档。流程图如下图所示:FDL代码为:version: v1beta1type: flowtimeoutSeconds: 3600steps: - type: task name: generateInfo timeoutSeconds: 300 resourceArn: acs:mns:::/topics/generateInfo-fnf-demo-jiyuan/messages pattern: waitForCallback inputMappings: - target: taskToken source: $context.task.token - target: products source: $input.products - target: supplier source: $input.supplier - target: address source: $input.address - target: orderNum source: $input.orderNum - target: type source: $context.step.name outputMappings: - target: paymentcombination source: $local.paymentcombination - target: orderNum source: $local.orderNum serviceParams: MessageBody: $ Priority: 1 catch: - errors: - FnF.TaskTimeout goto: orderCanceled - type: task name: payment timeoutSeconds: 300 resourceArn: acs:mns:::/topics/payment-fnf-demo-jiyuan/messages pattern: waitForCallback inputMappings: - target: taskToken source: $context.task.token - target: orderNum source: $local.orderNum - target: paymentcombination source: $local.paymentcombination - target: type source: $context.step.name outputMappings: - target: paymentMethod source: $local.paymentMethod - target: orderNum source: $local.orderNum - target: price source: $local.price - target: taskToken source: $input.taskToken serviceParams: MessageBody: $ Priority: 1 catch: - errors: - FnF.TaskTimeout goto: orderCanceled - type: choice name: paymentCombination inputMappings: - target: orderNum source: $local.orderNum - target: paymentMethod source: $local.paymentMethod - target: price source: $local.price - target: taskToken source: $local.taskToken choices: - condition: $.paymentMethod == "zhifubao" steps: - type: task name: zhifubao resourceArn: acs:fc:cn-hangzhou:your_account_id:services/FNFDemo-jiyuan/functions/zhifubao-fnf-demo inputMappings: - target: price source: $input.price - target: orderNum source: $input.orderNum - target: paymentMethod source: $input.paymentMethod - target: taskToken source: $input.taskToken - condition: $.paymentMethod == "weixin" steps: - type: task name: weixin resourceArn: acs:fc:cn-hangzhou:your_account_id:services/FNFDemo-jiyuan.LATEST/functions/weixin-fnf-demo inputMappings: - target: price source: $input.price - target: orderNum source: $input.orderNum - target: paymentMethod source: $input.paymentMethod - target: taskToken source: $input.taskToken - condition: $.paymentMethod == "unionpay" steps: - type: task name: unionpay resourceArn: acs:fc:cn-hangzhou:your_account_id:services/FNFDemo-jiyuan.LATEST/functions/union-fnf-demo inputMappings: - target: price source: $input.price - target: orderNum source: $input.orderNum - target: paymentMethod source: $input.paymentMethod - target: taskToken source: $input.taskToken default: goto: orderCanceled - type: task name: orderCompleted resourceArn: acs:fc:cn-hangzhou:your_account_id:services/FNFDemo-jiyuan.LATEST/functions/orderCompleted end: true - type: task name: orderCanceled resourceArn: acs:fc:cn-hangzhou:your_account_id:services/FNFDemo-jiyuan.LATEST/functions/cancerOrder在剖析整个流程之前,我先要说明的一点是,我们不是完全通过Serverless函数盘算和Serverless事情流来搭建订餐模块,只是用它来解决灵活性的问题,所以这个示例的主体应用是Java编写的,然后联合了Serverless函数盘算和Serverless事情流。

下面我们来详细剖析这个流程。启动流程按常理,开始点餐时流程就应该启动了,所以在这个示例中,我的设计是当我们选择完商品和商家、填完地址后启动流程:这里我们通过Serverless事情流提供的OpenAPI来启动流程。Java启动流程这个示例我使用Serverless事情流的Java SDK,首先在POM文件中添加依赖:<dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-core</artifactId> <version>[4.3.2,5.0.0)</version></dependency><dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-fnf</artifactId> <version>[1.0.0,5.0.0)</version></dependency>然后建立初始化Java SDK的Config类:@Configurationpublic class FNFConfig { @Bean public IAcsClient createDefaultAcsClient(){ DefaultProfile profile = DefaultProfile.getProfile( "cn-xxx", // 地域ID "ak", // RAM 账号的AccessKey ID "sk"); // RAM 账号Access Key Secret IAcsClient client = new DefaultAcsClient(profile); return client; }}再来看Controller中的startFNF方法,该方法袒露GET方式的接口,传入三个参数:fnfname:要启动的流程名称。

execuname:流程启动后的流程实例名称。input:启动输入参数,好比业务参数。@GetMapping("/startFNF/{fnfname}/{execuname}/{input}") public StartExecutionResponse startFNF(@PathVariable("fnfname") String fnfName, @PathVariable("execuname") String execuName, @PathVariable("input") String inputStr) throws ClientException { JSONObject jsonObject = new JSONObject(); jsonObject.put("fnfname", fnfName); jsonObject.put("execuname", execuName); jsonObject.put("input", inputStr); return fnfService.startFNF(jsonObject); }再来看Service中的startFNF方法,该方法分两部门,第一个部门是启动流程,第二部门是建立订单工具,并模拟入库(示例中是放在Map里了): @Override public StartExecutionResponse startFNF(JSONObject jsonObject) throws ClientException { StartExecutionRequest request = new StartExecutionRequest(); String orderNum = jsonObject.getString("execuname"); request.setFlowName(jsonObject.getString("fnfname")); request.setExecutionName(orderNum); request.setInput(jsonObject.getString("input")); JSONObject inputObj = jsonObject.getJSONObject("input"); Order order = new Order(); order.setOrderNum(orderNum); order.setAddress(inputObj.getString("address")); order.setProducts(inputObj.getString("products")); order.setSupplier(inputObj.getString("supplier")); orderMap.put(orderNum, order); return iAcsClient.getAcsResponse(request); }启动流程时,流程名称和启动流程实例的名称是需要传入的参数,这里我将每次的订单编号作为启动流程的实例名称。至于Input,可以凭据需求结构JSON字符串传入。

这里我将商品、商家、地址、订单号结构了JSON字符串在流程启动时传入流程中。另外,建立了此次订单的Order实例,并存在Map中,模拟入库,后续环节还会查询该订单实例更新订单属性。VUE选择商品/商家页眼前端我使用VUE搭建,当点击选择商品和商家页面中的下一步后,通过GET方式挪用HTTP协议的接口/startFNF/{fnfname}/{execuname}/{input}。

和上面的Java方法对应。fnfname:要启动的流程名称。execuname:随机生成uuid,作为订单的编号,也作为启动流程实例的名称。

input:将商品、商家、订单号、地址构建为JSON字符串传入流程。submitOrder(){ const orderNum = uuid.v1() this.$axios.$get('/startFNF/OrderDemo-Jiyuan/'+orderNum+'/{n' + ' "products": "'+this.products+'",n' + ' "supplier": "'+this.supplier+'",n' + ' "orderNum": "'+orderNum+'",n' + ' "address": "'+this.address+'"n' + '}' ).then((response) => { console.log(response) if(response.message == "success"){ this.$router.push('/orderdemo/' + orderNum) } }) }generateInfo节点第一个节点generateInfo,先来看看FDL的寄义: - type: task name: generateInfo timeoutSeconds: 300 resourceArn: acs:mns:::/topics/generateInfo-fnf-demo-jiyuan/messages pattern: waitForCallback inputMappings: - target: taskToken source: $context.task.token - target: products source: $input.products - target: supplier source: $input.supplier - target: address source: $input.address - target: orderNum source: $input.orderNum - target: type source: $context.step.name outputMappings: - target: paymentcombination source: $local.paymentcombination - target: orderNum source: $local.orderNum serviceParams: MessageBody: $ Priority: 1 catch: - errors: - FnF.TaskTimeout goto: orderCanceledname:节点名称。timeoutSeconds:超时时间。该节点等候的时长,凌驾时间后会跳转到goto分支指向的orderCanceled节点。

pattern:设置为waitForCallback,表现需要等候确认。inputMappings:该节点入参。

taskToken:Serverless事情流自动生成的Token。products:选择的商品。supplier:选择的商家。

address:送餐地址。orderNum:订单号。outputMappings:该节点的出参。

paymentcombination:该商家支持的支付方式。orderNum:订单号。catch:捕捉异常,跳转到其他分支。

这里resourceArn和serviceParams需要拿出来单独解释。Serverless事情流支持与多个云服务集成,即将其他服务作为任务步骤的执行单元。

服务集成方式由FDL语言表达,在任务步骤中,可以使用resourceArn来界说集成的目的服务,使用pattern界说集成模式。所以可以看到在resourceArn中设置acs:mns:::/topics/generateInfo-fnf-demo-jiyuan/messages信息,即在generateInfo节点中集成了MNS消息行列服务,当generateInfo节点触发后会向generateInfo-fnf-demo-jiyuanTopic中发送一条消息。

那么消息正文和参数则在serviceParams工具中指定。MessageBody是消息正文,设置$表现通过输入映射inputMappings发生消息正文。

8797威尼斯老品牌

看完第一个节点的示例,大家可以看到,在Serverless事情流中,节点之间的信息通报可以通过集成MNS发送消息来通报,也是使用比力广泛的方式之一。generateInfo-fnf-demo函数向generateInfo-fnf-demo-jiyuanTopic中发送的这条消息包罗了商品信息、商家信息、地址、订单号,表现一个下订单流程的开始,既然有发消息,那么一定有接受消息举行后续处置惩罚。所以打开函数盘算控制台,建立服务,在服务下建立名为generateInfo-fnf-demo的事件触发器函数,这里选择Python Runtime:建立MNS触发器,选择监听generateInfo-fnf-demo-jiyuanTopic。

打开消息服务MNS控制台,建立generateInfo-fnf-demo-jiyuanTopic:做好函数的准备事情,我们来开始写代码:# -*- coding: utf-8 -*-import loggingimport jsonimport timeimport requestsfrom aliyunsdkcore.client import AcsClientfrom aliyunsdkcore.acs_exception.exceptions import ServerExceptionfrom aliyunsdkfnf.request.v20190315 import ReportTaskSucceededRequestfrom aliyunsdkfnf.request.v20190315 import ReportTaskFailedRequestdef handler(event, context): # 1. 构建Serverless事情流Client region = "cn-hangzhou" account_id = "XXXX" ak_id = "XXX" ak_secret = "XXX" fnf_client = AcsClient( ak_id, ak_secret, region ) logger = logging.getLogger() # 2. event内的信息即接受到Topic generateInfo-fnf-demo-jiyuan中的消息内容,将其转换为Json工具 bodyJson = json.loads(event) logger.info("products:" + bodyJson["products"]) logger.info("supplier:" + bodyJson["supplier"]) logger.info("address:" + bodyJson["address"]) logger.info("taskToken:" + bodyJson["taskToken"]) supplier = bodyJson["supplier"] taskToken = bodyJson["taskToken"] orderNum = bodyJson["orderNum"] # 3. 判断什么商家使用什么样的支付方式组合,这里的示例比力简朴粗暴,正常情况下,应该使用元数据设置的方式获取 paymentcombination = "" if supplier == "haidilao": paymentcombination = "zhifubao,weixin" else: paymentcombination = "zhifubao,weixin,unionpay" # 4. 挪用Java服务袒露的接口,更新订单信息,主要是更新支付方式 url = "http://xx.xx.xx.xx:8080/setPaymentCombination/" + orderNum + "/" + paymentcombination + "/0" x = requests.get(url) # 5. 给予generateInfo节点响应,并返回数据,这里返回了订单号和支付方式 output = "{"orderNum": "%s", "paymentcombination":"%s" " "}" % (orderNum, paymentcombination) request = ReportTaskSucceededRequest.ReportTaskSucceededRequest() request.set_Output(output) request.set_TaskToken(taskToken) resp = fnf_client.do_action_with_exception(request) return 'hello world'因为generateInfo-fnf-demo函数设置了MNS触发器,所以当TopicgenerateInfo-fnf-demo-jiyuan有消息后就会触发执行generateInfo-fnf-demo函数。整个代码分五部门:构建Serverless事情流Client。event内的信息即接受到TopicgenerateInfo-fnf-demo-jiyuan中的消息内容,将其转换为Json工具。判断什么商家使用什么样的支付方式组合,这里的示例比力简朴粗暴,正常情况下,应该使用元数据设置的方式获取。

好比在系统内有商家信息的设置功效,通过在界面上设置该商家支持哪些支付方式,形成元数据设置信息,提供查询接口,在这里举行查询。挪用Java服务袒露的接口,更新订单信息,主要是更新支付方式。给予generateInfo节点响应,并返回数据,这里返回了订单号和支付方式。因为该节点的pattern是waitForCallback,所以需要等候响应效果。

payment节点我们再来看第二个节点payment,先来看FDL代码:- type: task name: payment timeoutSeconds: 300 resourceArn: acs:mns:::/topics/payment-fnf-demo-jiyuan/messages pattern: waitForCallback inputMappings: - target: taskToken source: $context.task.token - target: orderNum source: $local.orderNum - target: paymentcombination source: $local.paymentcombination - target: type source: $context.step.name outputMappings: - target: paymentMethod source: $local.paymentMethod - target: orderNum source: $local.orderNum - target: price source: $local.price - target: taskToken source: $input.taskToken serviceParams: MessageBody: $ Priority: 1 catch: - errors: - FnF.TaskTimeout goto: orderCanceled当流程流转到payment节点后,意味着用户进入了支付页面。这时payment节点会向MNS的Topicpayment-fnf-demo-jiyuan发送消息,会触发payment-fnf-demo函数。

payment-fnf-demo函数payment-fnf-demo函数的建立方式和generateInfo-fnf-demo函数类似,这里不再累赘。我们直接来看代码:# -*- coding: utf-8 -*-import loggingimport jsonimport osimport timeimport loggingfrom aliyunsdkcore.client import AcsClientfrom aliyunsdkcore.acs_exception.exceptions import ServerExceptionfrom aliyunsdkcore.client import AcsClientfrom aliyunsdkfnf.request.v20190315 import ReportTaskSucceededRequestfrom aliyunsdkfnf.request.v20190315 import ReportTaskFailedRequestfrom mns.account import Account # pip install aliyun-mnsfrom mns.queue import *def handler(event, context): logger = logging.getLogger() region = "xxx" account_id = "xxx" ak_id = "xxx" ak_secret = "xxx" mns_endpoint = "http://your_account_id.mns.cn-hangzhou.aliyuncs.com/" queue_name = "payment-queue-fnf-demo" my_account = Account(mns_endpoint, ak_id, ak_secret) my_queue = my_account.get_queue(queue_name) # my_queue.set_encoding(False) fnf_client = AcsClient( ak_id, ak_secret, region ) eventJson = json.loads(event) isLoop = True while isLoop: try: recv_msg = my_queue.receive_message(30) isLoop = False # body = json.loads(recv_msg.message_body) logger.info("recv_msg.message_body:======================" + recv_msg.message_body) msgJson = json.loads(recv_msg.message_body) my_queue.delete_message(recv_msg.receipt_handle) # orderCode = int(time.time()) task_token = eventJson["taskToken"] orderNum = eventJson["orderNum"] output = "{"orderNum": "%s", "paymentMethod": "%s", "price": "%s" " "}" % (orderNum, msgJson["paymentMethod"], msgJson["price"]) request = ReportTaskSucceededRequest.ReportTaskSucceededRequest() request.set_Output(output) request.set_TaskToken(task_token) resp = fnf_client.do_action_with_exception(request) except Exception as e: logger.info("new loop") return 'hello world'该函数的焦点思路是等候用户在支付页面选择某个支付方式确认支付。所以这里使用了MNS的行列来模拟等候。

循环等候吸收行列payment-queue-fnf-demo中的消息,当收到消息后将订单号和用户选择的详细支付方式以及金额返回给payment节点。VUE选择支付方式页面因为经由generateInfo节点后,该订单的支付方式信息已经有了,所以对于用户而言,当填完商品、商家、地址后,跳转到的页面就是该确认支付页面,而且包罗了该商家支持的支付方式。当进入该页面后,会请求Java服务袒露的接口,获取订单信息,凭据支付方式在页面上显示差别的支付方式。

代码片段如下:当用户选定某个支付方式点击提交订单按钮后,向payment-queue-fnf-demo行列发送消息,即通知payment-fnf-demo函数继续后续的逻辑。这里我使用了一个HTTP触发器类型的函数,用于实现向MNS发消息的逻辑,paymentMethod-fnf-demo函数代码如下。# -*- coding: utf-8 -*-import loggingimport urllib.parseimport jsonfrom mns.account import Account # pip install aliyun-mnsfrom mns.queue import *HELLO_WORLD = b'Hello world!n'def handler(environ, start_response): logger = logging.getLogger() context = environ['fc.context'] request_uri = environ['fc.request_uri'] for k, v in environ.items(): if k.startswith('HTTP_'): # process custom request headers pass try: request_body_size = int(environ.get('CONTENT_LENGTH', 0)) except (ValueError): request_body_size = 0 request_body = environ['wsgi.input'].read(request_body_size) paymentMethod = urllib.parse.unquote(request_body.decode("GBK")) logger.info(paymentMethod) paymentMethodJson = json.loads(paymentMethod) region = "cn-xxx" account_id = "xxx" ak_id = "xxx" ak_secret = "xxx" mns_endpoint = "http://your_account_id.mns.cn-hangzhou.aliyuncs.com/" queue_name = "payment-queue-fnf-demo" my_account = Account(mns_endpoint, ak_id, ak_secret) my_queue = my_account.get_queue(queue_name) output = "{"paymentMethod": "%s", "price":"%s" " "}" % (paymentMethodJson["paymentMethod"], paymentMethodJson["price"]) msg = Message(output) my_queue.send_message(msg) status = '200 OK' response_headers = [('Content-type', 'text/plain')] start_response(status, response_headers) return [HELLO_WORLD]该函数的逻辑很简朴,就是向MNS的行列payment-queue-fnf-demo发送用户选择的支付方式和金额。

VUE代码片段如下:paymentCombination节点paymentCombination节点是一个路由节点,通过判断某个参数路由到差别的节点,这里自然使用paymentMethod作为判断条件。FDL代码如下:- type: choice name: paymentCombination inputMappings: - target: orderNum source: $local.orderNum - target: paymentMethod source: $local.paymentMethod - target: price source: $local.price - target: taskToken source: $local.taskToken choices: - condition: $.paymentMethod == "zhifubao" steps: - type: task name: zhifubao resourceArn: acs:fc:cn-hangzhou:your_account_id:services/FNFDemo-jiyuan/functions/zhifubao-fnf-demo inputMappings: - target: price source: $input.price - target: orderNum source: $input.orderNum - target: paymentMethod source: $input.paymentMethod - target: taskToken source: $input.taskToken - condition: $.paymentMethod == "weixin" steps: - type: task name: weixin resourceArn: acs:fc:cn-hangzhou:your_account_id:services/FNFDemo-jiyuan.LATEST/functions/weixin-fnf-demo inputMappings: - target: price source: $input.price - target: orderNum source: $input.orderNum - target: paymentMethod source: $input.paymentMethod - target: taskToken source: $input.taskToken - condition: $.paymentMethod == "unionpay" steps: - type: task name: unionpay resourceArn: acs:fc:cn-hangzhou:your_account_id:services/FNFDemo-jiyuan.LATEST/functions/union-fnf-demo inputMappings: - target: price source: $input.price - target: orderNum source: $input.orderNum - target: paymentMethod source: $input.paymentMethod - target: taskToken source: $input.taskToken default: goto: orderCanceled这里的流程是,用户选择支付方式后,通过消息发送给payment-fnf-demo函数,然后将支付方式返回,于是流转到paymentCombination节点通过判断支付方式流转到详细处置惩罚支付逻辑的节点和函数。

zhifubao节点我们详细来看一个zhifubao节点: choices: - condition: $.paymentMethod == "zhifubao" steps: - type: task name: zhifubao resourceArn: acs:fc:cn-hangzhou:your_account_id:services/FNFDemo-jiyuan/functions/zhifubao-fnf-demo inputMappings: - target: price source: $input.price - target: orderNum source: $input.orderNum - target: paymentMethod source: $input.paymentMethod - target: taskToken source: $input.taskToken这个节点的resourceArn和之前两个节点的差别,这里设置的是函数盘算中函数的ARN,也就是说当流程流转到这个节点时会触发zhifubao-fnf-demo函数,该函数是一个事件触发函数,但不需要建立任何触发器。流程将订单金额、订单号、支付方式传给zhifubao-fnf-demo函数。

zhifubao-fnf-demo函数现在我们来看zhifubao-fnf-demo函数的代码:# -*- coding: utf-8 -*-import loggingimport jsonimport requestsimport urllib.parsefrom aliyunsdkcore.client import AcsClientfrom aliyunsdkcore.acs_exception.exceptions import ServerExceptionfrom aliyunsdkfnf.request.v20190315 import ReportTaskSucceededRequestfrom aliyunsdkfnf.request.v20190315 import ReportTaskFailedRequestdef handler(event, context): region = "cn-xxx" account_id = "xxx" ak_id = "xxx" ak_secret = "xxx" fnf_client = AcsClient( ak_id, ak_secret, region ) logger = logging.getLogger() logger.info(event) bodyJson = json.loads(event) price = bodyJson["price"] taskToken = bodyJson["taskToken"] orderNum = bodyJson["orderNum"] paymentMethod = bodyJson["paymentMethod"] logger.info("price:" + price) newPrice = int(price) * 0.8 logger.info("newPrice:" + str(newPrice)) url = "http://xx.xx.xx.xx:8080/setPaymentCombination/" + orderNum + "/" + paymentMethod + "/" + str(newPrice) x = requests.get(url) return {"Status":"ok"}示例中的代码逻辑很简朴,吸收到金额后,将金额打8折,然后将价钱更新回订单。其他支付方式的节点和函数如法炮制,变换实现逻辑就可以。在这个示例中,微信支付打了5折,银联支付打7折。

完整流程流程中的orderCompleted和orderCanceled节点没做什么逻辑,大家可以自行发挥,思路和之前的节点一样。所以完整的流程是这样:从Serverless事情流中看到的节点流转是这样的:总结到此,我们基于Serverless事情流和Serverless函数盘算构建的订单模块示例就算完成了,在示例中,有两个点需要大家注意:设置商家和支付方式的元数据规则。确认支付页面的元数据规则。因为在实际生产中,我们需要将可定制的部门都抽象为元数据形貌,需要有设置界面制定商家的支付方式即更新元数据规则,然后前端页面基于元数据信息展示相应的内容。

所以如果之后需要接入其他的支付方式,只需在paymentCombination路由节点中确定好路由规则,然后增加对应的支付方式函数即可。通过增加元数据设置项,就可以在页面显示新加的支付方式,而且路由随处理新支付方式的函数中。

作者:阿里云解决方案架构师 计缘本文为阿里云原创内容,未经允许不得转载。


本文关键词:Serverless,在,SaaS,领域,的,最佳,实践,-welcome,8797威尼斯老品牌

本文来源:welcome欢迎光临威尼斯-www.mibojf.com

XML地图 welcome欢迎光临威尼斯(中国)官方网站-8797威尼斯老品牌