当前位置: 首页 > 后端技术 > Java

人人都是Serverless架构师-“盲盒抽奖”创意营销实践

时间:2023-04-02 09:54:15 Java

简介:当Serverless和low-code两种不同的技术在同一个业务中交叉,会展现出怎样的价值?本文以ServerlessDevs的创意营销活动“盲盒抽奖”为例,告诉你Serverless和低代码是如何匹配到一个业务需求的。作者|HanXie&JiangYu当Serverless和Low-Code这两种不同的技术在同一个业务中交叉,会展现出怎样的价值?本文以ServerlessDevs的创意营销活动“盲盒抽奖”为例,告诉你Serverless和低代码是如何匹配到一个业务需求的。前言将线上H5创意动画与线下实物奖励相结合,是网络营销活动的常用手段。为了抓住关键时间点,活动从策划到实施的周期一般都比较短,短时间内上线线上服务对于做技术开发的同学来说是一个不小的挑战。尤其是当需求比较多的时候,比如增加后台管理、前端关键接入数据埋点等,挑战的难度往往会翻倍。对于开发,除了要满足业务的核心需求外,往往还需要关注非业务需求以外的其他情况,比如系统访问安全、高并发流量响应、可观察的系统运行指标等。以往这种需求往往需要产品、前端、后端、设计、测试、运维、运维等多个角色的参与,导致投入产出比比较低而且活动的连续性比较差。今天,使用无服务器+低代码技术,我们可以大大降低做这些活动的成本,并把它变成一个持续的活动,从而大大提高运营效率。事实上,ServerlessDevs在这次盲盒抽签中只投了3.5人,他们完成了活动策划、产品设计、前后端实现、系统部署、运维等,并借助Serverless服务能力,轻松应对系统访问安全、高并发流量、系统可观察性等非业务挑战。功能完善+效率提升让本次运营获得了非常不错的收益,赛事服务的模板沉淀为后续类似赛事打下了良好的基础。“盲盒抽奖”活动整体流程如下:需求设计(包括业务逻辑和交互逻辑)设计稿低代码实现前端编码实现Serverless服务联调测试部署线上活动问题修复后活动预览应用效果:《1》《Serverless盲盒分分钟部署》抽奖活动已经结束,有兴趣的同学还是可以体验一下:https://developer.aliyun.com/...架构预览:本部署架构不使用AlibabaCloudAPIGateway,而是直接使用FunctionComputeCustomRuntime作为托管形式,这是因为这个需求的特殊性,我们是“自己部署,自己抽水”,其实就是端侧访问去中心化,而端侧接入服务也比较薄,只是调用数据处理接口并提供静态渲染服务,然后通过一个集中的逻辑后台处理中奖概率,管理奖品查询数据库等。如果你在做一个自己集中事件后台,推荐参考如下架构模型,以API网关作为流量入口。方便做更多的安全限制和更灵活的扩展,实现前端交互分析和低代码实现。此前端实现使用低代码工作炒作4。hype4的具体使用这里就不详细介绍了。感兴趣的同学可以自行搜索。除了在设计稿完成后裁剪出需要的图片,然后像处理Flash一样实现动画效果,最后就是添加js代码实现界面访问、场景切换等能力。整个过程会比全编码快很多,尤其是动效的实现比纯手写效率高2-3倍。架构中显示了数据层无服务器服务。这里的数据层其实就是我们理解的SSF。该层只进行数据转发和静态渲染。代码实现比较简单,使用express框架,然后以FunctionComputeCustomruntime的形式部署。目的是这个服务既可以承载静态内容,也可以承载动态数据转发。值得注意的是,用户信息的获取也是在这一层实现的。这里我们获取了阿里云用户的accountId,方便对齐中奖信息发放奖品。对于普通开发者来说,这个参数意义不大。我们会提前部署好抽奖后台,接下来每个用户在部署完这一层服务后,访问部署好的服务,然后将uid等基本信息传递给抽奖后台,发起抽奖。最后将中奖结果返回并透传给前端显示。作为管理员,您可以通过后台操作设置奖品和概率。后端抽奖逻辑实现。后台服务使用PythonWeb框架:Django实现。主要方法有:1、获取用户的uid信息,并对uid信息进行校验,保证uid信息的准确性。客户端服务通过ServerlessDevs开发者工具的部署;2、当日奖池建设;3、初步确定用户中奖信息;4、审核用户中奖信息;5、将最终结果返回给客户;,通过ServerlessDevs开发者工具部署盲盒抽奖的客户端服务,并部署到用户自己的账号中;在部署期间,需要给用户发放一个临时域名(这个临时域名需要使用用户的uid),ServerlessDevs会在发放临时域名的过程中生成一部分clienttoken,以及记录在ServerlessDevs后端服务中;这个令牌实际上是识别用户的重要标记;(如果用户在Yaml中声明不使用系统自动下发的域名信息,可能无法顺利参与本次活动)。2、用户部署完成后,会返回一个ServerlessDevs颁发的临时域名,供用户学习测试。3、接下来用户通过浏览器打开临时域名,可以看到抽奖的相关页面,用户可以点击进行抽奖操作。4、用户点击开奖操作后,会发起请求请求用户账号下的Serverless服务。服务会根据用户的uid信息进行相关处理,并向本次活动的后端Serverless服务发起真实的抽奖请求;5、本次活动后端Serverless服务收到用户的抽奖请求时,会:获取用户账号下的Serverless服务发起抽奖请求时传递的uid信息;数据匹配,确定用户本次使用了临时域名分配系统,并下发了对应的域名;实现开奖操作;一个简单易实现的抽奖功能,可用于小型抽奖活动:关于这部分,Django项目的实现方法:@csrf_exemptdefprize(request):uid=request.POST.get("uid",None)ifnotuid:returnJsonResponse({"Error":"uidisrequired."})temp_url="<获取uid的合法性和有效性,判断的重要依据>?uid="+str(uid)ifjson.loads(urllib.request.urlopen(temp_url).read().decode("utf-8"))["Response"]=='0':returnJsonResponse({"Error":"Uidisrequired."})token=randomStr(10)#获取当天的奖品={}foreve_prizeinPrizeModel.objects.filter(date=time.strftime("%Y-%m-%d",time.localtime())):奖品[eve_prize.name]={"count":eve_prize.count,"rate":eve_prize.rate}#构建抽奖池prize_list=[]forevePrize,eveInfoinprizes.items():temp_prize_list=[evePrize,]*int((100*eveInfo['rate']))prize_list=prize_list+temp_prize_listnone_list=[None,]*(100-len(prize_list))prize_list=prize_list+none_listpre_prize=random.choice(prize_list)#数据入库try:UserModel.objects.create(uid=uid,token=token,pre_prize=pre_prize,result=False)except:try:ifnotUserModel.objects.get(uid=uid).result:returnJsonResponse({"Result":"0"})除了:通过returnJsonResponse({"Error":"Everyonecanonlyparticipateonce."})ifnotpre_prize:returnJsonResponse({"Result":"0"})user_id=UserModel.objects.get(uid=uid,token=token).idusers_count=UserModel.objects.filter(pre_prize=pre_prize,id__lt=user_id,date=time.strftime("%Y-%m-%d",time.localtime())).count()#最后判断是否中奖ifusers_count>=prizes.get(pre_prize,{}).get("count",0):returnJsonResponse({"Result":"0"})U??serModel.objects.filter(uid=uid,token=token).update(result=True)returnJsonResponse({"Result":{"token":token,"prize":pre_prize}})系统安全设置当用户中奖时,系统会生成一个token,token和uid的组合是判断用户是否中奖的重要依据。可能有一个这里涉及到的问题:什么有uid,还要加一个token做组合判断?其实道理很简单,提交查询中奖信息,如果直接通过uid处理,很有可能部分用户会通过遍历等方式非法获取。对于其他用户提交的信息,而这部分信息很可能会涉及到用户提交的收货地址等,所以为了安全,增加了一个token,一定程度上也增加了被遍历的复杂度暴力增加。而这一部分的方法也很简单:@csrf_exemptdefinformation(request):uid=request.GET.get("uid",None)token=request.GET.get("token",None)ifNonein[uid,token]:returnJsonResponse({"Error":"Uidandtokenarerequired."})userInfor=UserModel.objects.filter(uid=uid,token=token)ifuserInfor.count()==0:returnJsonResponse({"Error":"Noinformationhasbeenfound."})ifnotuserInfor[0].result:returnJsonResponse({"Error":"Noinformationhasbeenfound."})ifrequest.method=="GET":returnJsonResponse({"Result":{"prize":userInfor[0].pre_prize,"name":userInfor[0].name,"phone":userInfor[0].phone,"address":userInfor[0].address}})elifrequest.method=="POST":name=request.POST.get("name",None)phone=request.POST.get("phone",None)address=request.POST.get("address",None)ifNonein[name,phone,address]:returnJsonResponse({"Error":"需要姓名、电话和地址。"})userInfor.update(name=name,phone=phone,address=address)returnJsonResponse({"Result":"Savedsuccessfully."})整个过程是:通过用户的uid和token获取相关的用户信息;如果请求方法是GET方法,则直接返回用户的中奖信息(指收款信息);如果是If请求方式为POST,允许用户修改中奖信息(指收款信息);其他安全补充:如何保证用户的token等信息的唯一性和不可伪造性,这部分在浏览器端吧实现起来并不容易,因为用户可能会更换浏览器,但是在函数计算平台为用户提供的函数服务中相对容易实现,所以采用域名传递阶段,在指定的时间段内传递域名信息时间。记录下来,稍后再比对,确保用户确实通过ServerlessDevs开发者工具部署了项目,发放了临时域名,并在规定时间内参与了活动;(当然,如果用户注册了多个阿里云账号,此时是允许参与此活动的)如何保证奖品不会多发,这部分在系统中采用了比较“笨”的方法,但是它对于小平台也比较容易实现的方法是先给用户一个奖品标记,然后根据用户奖品在数据库中的时间序列位置来判断最终的中奖信息。比如用户中奖了一个机械键盘,是机械键盘在数据库中的第6位,但是机械键盘一共只有5个,所以这时候,用户的中奖信息会被检查两次,标记为不中奖(当然这种方式对于小规模的活动是可以的,但是对于大型的活动是不可取的,因为用户是否中奖会造成多次数据库读写操作,这对某某来说是不合理的extent)用户中奖后,提交奖品的邮寄信息后,如何保证信息的安全,防止被他人遍历,也是一个值得关注的问题。这里加入随机token,增加被暴力遍历的复杂度,进一步保证安全性;部署准备此部署不需要域名。您可以使用函数计算生成的自定义域名。您仍然需要安装ServerlessDevs工具。这一次,你只需要开启函数计算即可。操作步骤彩票后台部分模板还在准备中,仅演示前端和数据层服务的部署。第一步:秘钥配置参考ServerlessdevsAlibabaCloudkeyconfiguration第二步:初始化使用serverlessdevs命令行工具执行:`sinitblindbox-game`进入引导操作:第三步:构建部署修改相关配置信息,执行sdeployeffect查看功能部署状态:页面效果:抽奖部分的应用模板正在准备中,将统一在本应用模板中给大家展示。结束语经过以上实践,我想和大家一起展开关于低代码和无服务器的话题。下面的部分将以理论为主,希望能给读者带来不一样的收获。一个开发者角度的Serverless+lowcode就我而言,明确的结论是我不排除两者的兼容性,而是期待两者的结合进一步让我的工作更加高效和安全。这次活动我最大的感受就是如果低代码平台能和Serverless无缝对接就好了。比如我之前只能在low-code上调用接口,现在只能建好发上线后才能测试。这是一个天然集成的平台。优势会很明显。另外,前端发布构建后,还得和后端接口进行组装。如果这是一个统一的平台,完成需求后可以一键发布,这样会省去很多麻烦。但是,这里也有一个矛盾,因为我也担心一旦低代码前端和serverless后端耦合起来,就会变得死板,被服务商锁死。从供应商角度看Serverless+低代码可以看到,Serverless和云服务商的低代码服务商现在正在相互融合。例如,低代码平台领导者outsystem早在2016年就开始使用AWS服务,如Lambda为其客户提供原生APP服务的构建。Trillo是一个以无服务器和模型驱动应用程序为主要服务的低代码平台,基于GoogleCloudServices帮助其用户构建无服务器服务和前端应用程序。当然,国内外各家云厂商也没有闲着。低代码产品PowerApps整合了Serverless的能力形成ServerlessPowerApps,充分融合了两者的优势。AWS将前端集成交给合作伙伴,在服务端更专注于Serverless集成,推出了StepFunctionsWorkflowStudio产品,将Serverless与旗下几乎所有产品打通。在国内,腾讯推出了微建低代码平台,同样主打Serverless+低代码,发力小程序场景。各家厂商的跟进也表明了他们对这一领域的重视。构建serverless+低代码平台的思路serverless+低代码平台的价值比较明确。效率、安全和成本是它的关键词。那么如果我们要搭建这样一个平台,需要做哪些考虑呢?首先,在平台能力上,应该能够覆盖一个应用开发从前到后的方方面面。例如:数据建模、数据模型API、使用Serverless构建后端应用逻辑、支持部署Long-Running后端服务、可扩展的外部服务、集成文件存储、身份验证、权限等各种安全能力的逻辑排列控件等UI编排CI/CDApplicationObservability在这里,我们可以简单了解一下这个平台的功能设计,依托云厂商的基础设施来构建相应的能力。有一些低代码能力相关的开源产品,可以在这里分享给大家:ui页面搭建https://github.com/alibaba/de...数据库建模https://gitee.com/robergroup/...流程安排https://github.com/i5ting/imove另外可以考虑利用ServerlessDevs的Iac能力对接云基础设施,尤其是目前与FC的集成已经比较成熟,可以可以很方便的管理函数的整个生命周期。当然,以上只是笔者的一些想法。我知道要实现这样一个系统并不容易,我只是在这里使用它。追求生产效率的提高一直是企业生产中的重要课题。Serverless和low-code在各自的技术领域有着独立的分工,但也有提高生产效率的共同特点。学习同时掌握和使用这两种生产力工具是可能的。这将是学生从事信息产业的重要竞争力。原文链接本文为阿里云原创内容,未经许可不得转载。