欢迎进Allbet欧博官网,欧博官网是欧博集团的官方网站。Allbet欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。

首页快讯正文

usdt钱包支付(www.caibao.it):Serverless 在 SaaS 领域的更佳实践

admin2021-04-0577

原题目:Serverless 在 SaaS 领域的更佳实践

简介: 随着互联网人口盈利逐渐削弱,基于流量的增进已经放缓,互联网行业迫切需要找到一片足以承载自身持续增进的新蓝海,产业互联网正是这一远大靠山下的新趋势。我们看到互联网浪潮正在席卷传统行业,云盘算、大数据、人工智能更先大规模融入到金融、制造、物流、零售、文娱、教育、医疗等行业的生产环节中,这种融合称为产业互联网。而在产业互联网中,有一块不能小觑的领域是 SaaS 领域,它是 ToB 赛道的中心气力,好比 CRM、HRM、费控系统、财政系统、协同办公等等。

在消费互联网时代,人人是搜索想要的器械,各个厂商在云盘算、大数据、人工智能等手艺基座之上确立流量更大化的服务与生态,基于海量内容分发与流量共享为逻辑构建系统。而到了产业互联网时代,供应关系发生了转变,人人是定制想要的器械,需要从供应与需求两侧出发举行双向建设,这个时刻系统的天真性和扩展性面临着亘古未有的挑战,尤其是 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 事情流若何优雅的解决这个问题。先来看看这个点餐流程:

1. 通过 Serverless 事情流建立流程

首选我需要将上面用户侧的流程转变为程序侧的流程,此时就需要使用 Serverless 事情流来担任此义务了。

打开 Serverless 控制台,建立订餐流程,这里 Serverless 事情流使用流程界说语言 FDL 建立事情流,若何使用 FDL 建立事情流请参阅文档。流程图如下图所示:

FDL 代码为:

version: v1beta1

type: flow

timeoutSeconds: 3600

steps:

- 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 事情流。下面我们来详细剖析这个流程。

2. 启动流程

按常理,更先点餐时流程就应该启动了,以是在这个示例中,我的设计是当我们选择完商品和商家、填完地址后启动流程:

这里我们通过 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 类:

@Configuration

public 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 {

*** ONObject jsonObject = new *** ONObject();

jsonObject.put("fnfname", fnfName);

jsonObject.put("execuname", execuName);

jsonObject.put("input", inputStr);

return fnfService.startFNF(jsonObject);

}

再来看 Service 中的 startFNF 方式,该方式分两部门,第一个部门是启动流程,第二部门是建立订单工具,并模拟入库(示例中是放在 Map 里了):

@Override

public StartExecutionResponse startFNF( *** ONObject 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"));

*** ONObject inputObj = jsonObject.get *** ONObject("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,可以凭据需求组织 *** ON 字符串传入。这里我将商品、商家、地址、订单号组织了 *** ON 字符串在流程启动时传入流程中。

另外,建立了此次订单的 Order 实例,并存在 Map 中,模拟入库,后续环节还会查询该订单实例更新订单属性。

VUE 选择商品/商家页面

前端我使用 VUE 搭建,当点击选择商品和商家页面中的下一步后,通过 GET 方式挪用 HTTP 协议的接口/startFNF/{fnfname}/{execuname}/{input}。和上面的 Java 方式对应。

fnfname:要启动的流程名称。

execuname:随机天生 uuid,作为订单的编号,也作为启动流程实例的名称。

input:将商品、商家、订单号、地址构建为 *** ON 字符串传入流程。

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)

}

})

}

3. 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: orderCanceled

```

- name:节点名称。

- 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 发生新闻正文。

看完第一个节点的示例,人人可以看到,在 Serverless 事情流中,节点之间的信息通报可以通过集成 MNS 发送新闻来通报,也是使用对照普遍的方式之一。

## 4. generateInfo-fnf-demo 函数

向 generateInfo-fnf-demo-jiyuanTopic 中发送的这条新闻包含了商品信息、商家信息、地址、订单号,示意一个下订单流程的更先,既然有发新闻,那么一定有接受新闻举行后续处置。以是打开函数盘算控制台,建立服务,在服务下建立名为 generateInfo-fnf-demo 的事宜触发器函数,这里选择 Python Runtime:

![8.png](https://ucc.alicdn.com/pic/developer-ecology/291e93740e48446197f29aa179a5f7cb.png)

建立 MNS 触发器,选择监听 generateInfo-fnf-demo-jiyuanTopic。

![9.png](https://ucc.alicdn.com/pic/developer-ecology/880c91561a6747d59c29bb7894eb727a.png)

打开新闻服务 MNS 控制台,建立 generateInfo-fnf-demo-jiyuanTopic:

![10.png](https://ucc.alicdn.com/pic/developer-ecology/e9ab6266f1f046e08a78b9144c797db0.png)

做好函数的准备事情,我们来更先写代码:

-- coding: utf-8 --

import logging

import json

import time

import requests

from aliyunsdkcore.client import AcsClient

,

欧博官网手机

欢迎进入欧博官网手机(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe *** 、Allbet电脑客户端、Allbet手机版下载等业务。

,

from aliyunsdkcore.acs_exception.exceptions import ServerException

from aliyunsdkfnf.request.v20190315 import ReportTaskSucceededRequest

from aliyunsdkfnf.request.v20190315 import ReportTaskFailedRequest

def 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,以是需要守候响应效果。

## 5. 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 函数。

6. payment-fnf-demo 函数

payment-fnf-demo 函数的建立方式和 generateInfo-fnf-demo 函数类似,这里不再累赘。我们直接来看代码:

# -*- coding: utf-8 -*-

import logging

import json

import os

import time

import logging

from aliyunsdkcore.client import AcsClient

from aliyunsdkcore.acs_exception.exceptions import ServerException

from aliyunsdkcore.client import AcsClient

from aliyunsdkfnf.request.v20190315 import ReportTaskSucceededRequest

from aliyunsdkfnf.request.v20190315 import ReportTaskFailedRequest

from mns.account import Account # pip install aliyun-mns

from 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 节点。

7. VUE 选择支付方式页面

由于经由 generateInfo 节点后,该订单的支付方式信息已经有了,以是对于用户而言,当填完商品、商家、地址后,跳转到的页面就是该确认支付页面,而且包含了该商家支持的支付方式。

当进入该页面后,会请求 Java 服务露出的接口,获取订单信息,凭据支付方式在页面上显示差别的支付方式。代码片断如下:

当用户选定某个支付方式点击提交订单按钮后,向 payment-queue-fnf-demo 行列发送新闻,即通知 payment-fnf-demo 函数继续后续的逻辑。

这里我使用了一个 HTTP 触发器类型的函数,用于实现向 MNS 发新闻的逻辑,paymentMethod-fnf-demo 函数代码如下。

# -*- coding: utf-8 -*-

import logging

import urllib.parse

import json

from mns.account import Account # pip install aliyun-mns

from 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代码片断如下:

8. 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 节点通过判断支付方式流转到详细处置支付逻辑的节点和函数。

9. 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 函数。

10. zhifubao-fnf-demo 函数

现在我们来看 zhifubao-fnf-demo 函数的代码:

# -*- coding: utf-8 -*-

import logging

import json

import requests

import urllib.parse

from aliyunsdkcore.client import AcsClient

from aliyunsdkcore.acs_exception.exceptions import ServerException

from aliyunsdkfnf.request.v20190315 import ReportTaskSucceededRequest

from aliyunsdkfnf.request.v20190315 import ReportTaskFailedRequest

def 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 折。

11. 完整流程

流程中的 orderCompleted 和 orderCanceled 节点没做什么逻辑,人人可以自行施展,思绪和之前的节点一样。以是完整的流程是这样:

从 Serverless 事情流中看到的节点流转是这样的:

总结

到此,我们基于 Serverless 事情流和 Serverless 函数盘算构建的订单模块示例就算完成了,在示例中,有两个点需要人人注重:

设置商家和支付方式的元数据规则。

确认支付页面的元数据规则。

由于在现实生产中,我们需要将可定制的部门都抽象为元数据形貌,需要有设置界面制订商家的支付方式即更新元数据规则,然后前端页面基于元数据信息展示响应的内容。

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

作者:计缘

网友评论

1条评论
  • 2021-04-05 00:06:03

    欧博网址开户www.allbet6.com欢迎进入欧博网址(Allbet Gaming),欧博网址开放会员注册、代理开户、电脑客户端下载、苹果安卓下载等业务。真是,很认真的作品

最新评论

  • 电银付官网 03/07 说:

    联博开奖www.326681.com采用以太坊区块链高度哈希值作为统计数据,联博以太坊统计数据开源、公平、无任何作弊可能性。联博统计免费提供API接口,支持多语言接入。都有谁在看啊?

  • 电银付官网 03/07 说:

    联博开奖www.326681.com采用以太坊区块链高度哈希值作为统计数据,联博以太坊统计数据开源、公平、无任何作弊可能性。联博统计免费提供API接口,支持多语言接入。都有谁在看啊?

  • 下载欧博真人客户端 03/07 说:

    sunbet 申博有甜有苦,很真

  • 皇冠足球 03/07 说:

    欢迎进入allbet欧博真人客户端(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。满满的诚意呀

  • allbet登陆官网 03/07 说:

    皇冠注册平台www.huangguan.us是一个提供皇冠代理APP下载、皇冠会员APP下载、皇冠体育最新登录线路、新2皇冠网址的的体育平台。新皇冠体育官网是多年来值得广大客户信赖的平台,我们期待您的到来!可以看看,不会失望

  • 电银付激活码 03/07 说:

    10【月】11「日」,《陕西宝鸡》,『一位宝妈套路萌娃』喝中《药的》视频‘走红’,『引一』众“网”友神评。【视频】中,【宝妈通过乱数数的方】式,‘乐成套路孩’子喝完中药。“网”友:(但凡)有个幼儿园文凭也《不会这样》。每个人都应该看

  • 以太坊开奖网 03/06 说:

    欧博开户www.sunbet.us欢迎进入欧博开户平台(Allbet Game),欧博开户平台开放欧博Allbet开户、欧博Allbet代理开户、欧博Allbet电脑客户端、欧博AllbetAPP下载等业务。这情节我都想不到

  • 电银付大盟主 03/06 说:

    环球UGwww.ugbet.us欢迎进入环球UG官网(UG环球),环球UG官方网站:www.ugbet.net开放环球UG网址访问、环球UG会员注册、环球UG代理申请、环球UG电脑客户端、环球UG手机版下载等业务。来入坑吧