「Serverless云开发72变」Serverless邮件推送系统实现

本文涉及的产品
Serverless 应用引擎免费试用套餐包,4320000 CU,有效期3个月
函数计算FC,每月15万CU 3个月
简介: Java 作为历年开发者使用榜前列的编程语言。因其丰富的生态圈被众多开发者说熟知。现如今,随着Serverless的不断推广,Java函数计算也逐渐走向开发者的视野。最近在负责系统服务支撑功能的编写。在剥离完邮件服务后。考虑到其支撑系统的特性以及与业务系统的特殊关系。就想着使用阿里云函数计算去将其从系统中剥离,从而降低系统负载。邮件推送系统主要包含推送 校验码 结果信息三种场景。本文主要是对业务迁移到函数计算下的业务的分析与思考。

我的场景选择和思考


场景选择


某WEB网站在用户注册成功后,会发一封欢迎邮件,通过函数计算把邮件内容定制成模板,每次触发,每次执行都是幂等无状态。因为做过对应业务,对阿里的对应的文档比较熟悉,且有部分实现代码。所以就是选择了这个业务场景。


思考


第一次选择函数计算去做对应的业务场景实现,个人在场景选择上比较谨慎。由于之前做过SpringCloud项目对阿里云邮件服务的整合,并完成了注册后邮件推送的代码逻辑实现,所以我就在思考把传统代码实现搬到云上使用函数计算来实现的可行性。


在原来的SpringCloud项目实现中,我主要使用了Redis MySQL 阿里云SDK集成等服务。首先就要考虑的就是阿里云函数计算JavaSDK对阿里云自己的SDK以及其他的第三方SDK的支持程度。我先找宁中大佬询问了阿里云函数计算 Java SDK对MySQL的支持后(可行的),就坚定了可以将原有代码设计转移到云上的决心。


系统设计与代码实现

系统设计


首先我设计的这个邮件推送系统主要包括以下的职能:


  1. 完成注册结果的推送
  2. 完成邮件校验码的发送
  3. 完成订阅者的定期邮件推送


对于一般的邮件系统来说,上述三条应该包含了大多数的业务场景,因此我主要围绕上述三点进行论述。由于系统用的是函数计算,且对于邮件系统来说,业务逻辑其实并不是过分的复杂,所以尽量轻量化的去做代码实现,减少重消耗的服务的引入。


我在做技术选择的时候(做SpringCloud的邮件服务的时候),参考了多家的邮件服务,为什么选择阿里云呢,其实是接口文档给的比较充足且具备可视化及统计服务。考虑到系统的稳定性,所以采用了阿里云的邮件推送服务。然后为了考虑扩展性我采用了上传HTML模板然后在用代码对预留关键字进行修改的形式去做代码的自定义处理。其实主要的也就是这两块 具体的分析我将在服务依赖中一一讲解。


服务依赖


该系统为Maven项目所以对依赖的管理较为方便 ,我主要使用的几个组件


  1. 阿里云邮件服务SDK
  2. Redis
  3. Mybatis
  4. FastJson
  5. Junit
  6. slf4j


使用阿里云邮件SDK的原因我已经在上面做了阐述,下面我主要讲一下Redis MySQL的使用。先说一下MySQL,有人会问不就是发送一个邮件吗,写几个模板丢到项目代码里面代码指一下不就好了。这样说也没什么问题,确实是可以这样实现。但是存在一个问题,假如模板格式发生了变动,那么整个代码也就需要改动。这样的话对于扩展性来说就显得相当不利了,还有就是SDK中的配置很多,每种邮件都会有自己不同的参数配置 ,假若如此,每个都在代码中申明其实问题和上面一样,对于修改与维护相当不利。所以我将其抽取出来 做成了两个类 1、SmtpConfig(存储配置) 2、SmtpTemplate(存储模板)。这两个类的代码实现,可以在我后面贴的码云链接里面找到。在这两个类的设计中我采用了充血模式,将部分对象封装业务以及对应的核心数据处理业务放到了实体类当中。大家有兴趣的可以在代码中查看一下,希望能提出宝贵的意见。


还有人会说你说使用MySQL是为了代码的维护性,那Redis是怎么一回事呢。这也和你之前说的轻量化也不符合啊。回答这个问题我们还要回到业务上面,对于邮件推送和验证码发送场景,邮件的频繁发送合理吗。显然不合理,连续的随意发送和有可能会使你的发送地址被邮件接收方标记成垃圾邮件。还有就是验证码发送场景,其实不只是验证码发送出去就了结的,其实还包含了校验的逻辑,所以使用Redis的原因其实大家就了解了。


其实还有一个原因:做缓存 从上面可知 我的模板是放在MySQL里面的以一个OSS链接的形式做的 ,那么每次调用的时候就需要请求OSS链接拿到对应的模板然后在进行解析。然后再替换对应的预设字段进行发送。从日常使用中大家都知道字符串替换的速度其实很快但是,文件的解析则需要根绝网络的速度来决定,并且将文件读成一个String串其实也很麻烦。所以我在第一次读取该模板后将原先的读取好的子串信息放入到Redis中 在第二次调用同一模板时则直接从Redis里面取数据,假如三天之后这个模板还是没有再被调用,则说明该模板并不常有,比较偏,所以就从Redis自动删除(预设时间3天)这样的话执行损耗就可以从300ms降低到100ms左右。


解耦思维


在代码发送前,其实需要做一些状态检查和一些条件拦截的操作。假如光使用Ifelse做简单的代码实现,则代码可读性和代码扩展性就会降低。我之前读过阿里大佬张建飞(大飞哥)的书,对其写的Cola框架有过一定的了解,所以我使用了其中的责任链模式以及其对异常处理的一些实现。


 首先看一下责任链设计


/*** @author mac_zyj*  一分钟内不能重复发送短信规则*/publicclassEmailOneMinNotRepeatFilterimplementsFilter<Map<String,Object>> {
privatefinalLoggerlogger=LoggerFactory.getLogger(EmailOneMinNotRepeatFilter.class);
privatestaticfinalStringSMS_ERROR_MESSAGE="请不要一分钟内重复发送";
privateRedisUtilsredisService=newRedisUtils();
@OverridepublicvoiddoFilter(Map<String, Object>contextMap, FilterInvokernextFilter) {
StringemailAddress= (String) contextMap.get("emailAddress");
StringrepeatCheckKey=emailAddress+SmtpServiceConstants.REPEAT_CHECK;
if(null!=redisService.get(repeatCheckKey)){
logger.warn("SmsException with error code,error message");
thrownewBizException(SMS_ERROR_MESSAGE);
        }
nextFilter.invoke(contextMap);
    }
}


上面的代码主要是做的重复发送的校验,若不存在重复情况则进行下一个条件校验若存在重复情况则进行异常抛出。返回错误信息。其余的情况也如此:例如 一定时间内过多的发送 同Ip发送次数过多等 都可以在后面进行追加具体使用如下


privatefinalFilterChainfilterChain=FilterChainFactory.buildFilterChain(
EmailOneMinNotRepeatFilter.class,
EmailSendTooMuchFilter.class    );
@OverridepublicvoidsendEmailCode(StringtoAddress, Stringcode)   {
//先执行拦截操作Map<String,Object>content=newHashMap<>(16);
content.put("emailAddress",toAddress);
filterChain.doFilter(content);
        ...........
}


项目不足与展望


 在上述文字和代码实现中 ,我完成了部分代码的实现(只完成了验证码发送场景),还有一部分由于时间原因并没有来得及进行编码,所以也有一些遗憾。还有就是对于数据库存储邮件模板的问题,是不是最优解也有待商榷。在后续的时间里,我会在码云上完善上述案例争取覆盖我之前说的其余的 没有实现的场景,并且优化现有的代码,希望大家多多帮助。提出宝贵的意见。


代码实现


我把代码上传到了码云上面 https://gitee.com/zhuyongjie1212/serverless-email

后续计划逐步完善上面所说的不足,并不断更新。也请有兴趣的大佬提出宝贵的意见,大家互相进步。


小结


  在阿里云 云开发平台的这次活动中,通过对具体的业务场景进行分析。对代码的设计与实现使我对Serverless云开发有了更深的认识与理解,特别是对于Java函数计算的使用,使我了解到了对于Java这种老牌开发语言在处理传统业务场景之外的使用,对我扩充技术栈具有一定的帮助。

  另外,感谢阿里云云开发平台给了我这个参与活动的机会,使我有机会和大家分享我对Serverless云开发的理解和具体的使用。大家可以访问云开发平台的官网(http://workbench.aliyun.com/)。那里有更多的Serverless上云的实践,云开发平台是一个可以满足开发者、研发团队完全基于「云+浏览器」就能完成日常开发工作的环境,它的设计理念是使自己成为团队大协同中的一环,它会跟阿里云诸多研发能力和工具进行集成,籍由更强大的阿里研发生态,为用户提供更大的协同研发可能,比如您在使用云开发平台的时候,可以根据您的需要,主动选择去开通使用项目管理、需求管理、文档管理等其他服务。


同时,为了帮助用户提供一个无缝应用阿里云服务的环境,云开发平台会跟阿里云的诸多云产品进行集成,随时为用户的使用而准备;您可以在云开发平台创建基于各种场景解决方案的应用,并为每个应用选用不同的云服务,这些云服务会开通在您的阿里云主账号之下,您主动开通的各种云资源会按照您的使用,正常地计量计费。


云开发平台鼓励所有的场景解决方案尽可能多的基于阿里云的 Serverless 类型产品去提供服务。Serverless 类型的产品都具有实时弹性以及按量付费的特征,这可以帮助到商业化研发团队,以尽可能低的成本去实现自己的商业价值。


背景知识


什么是函数计算


  函数计算是事件驱动的全托管计算服务。使用函数计算,您无需采购与管理服务器等基础设施,只需编写并上传代码。函数计算为您准备好计算资源,弹性地、可靠地运行任务,并提供日志查询、性能监控和报警等功能。


  借助函数计算,您可以快速构建任何类型的应用和服务,并且只需为任务实际消耗的资源付费。


Java函数计算


  函数计算支持Java8运行环境。Java语言由于需要编译后才可以在JVM虚拟机中运行。和Python、Node.js这类脚本型语言不同,Java语言有以下限制:


  不支持上传代码:仅支持上传已经开发完成、编译打包后的ZIP包或JAR包。函数计算不提供Java的编译能力。

  不支持在线编辑:由于不支持上传代码,所以不支持在线编辑代码,仅能看到通过页面上传或OSS上传两种方法提交代码。

事件函数接口

  您在使用Java编程时,必须要实现函数计算提供的接口类,对于事件入口函数目前有两个预定义接口可以选择。这两个预定义接口分别是:


StreamRequestHandler


  以流的方式接受调用输入event和返回执行结果,您需要从输入流中读取调用函数时的输入,处理完成后把函数执行结果写入到输出流中来返回。


PojoRequestHandler


  通过泛型的方式,您可以自定义输入和输出的类型,但是输入和输出的类型必须是POJO类型。


常见业务场景


  1. IoT应用:设备端通过函数计算来订阅天气信息和空气质量,设备和设备之间无依赖,执行过程中无需记录状态,获取到第三方数据即可返回。
  2. WEB应用:某WEB网站在用户注册成功后,会发一封欢迎邮件,通过函数计算把邮件内容定制成模板,每次触发,每次执行都是幂等无状态。
  3. 图片处理:基于OSS的事件触发,当用户上传的图片转入到某Bucket中后,自动触发函数岁图片进行可定制化处理
  4. 音频转换文字处理:当用户通过语音来发出某些指令的时候,可以通过函数计算来触发阿里云的ET公开API获取到音频转换成文字的方式。



还没有使用过Serverless云开发?

现在花3分钟体验新手任务即领10元阿里云无门槛代金券。

720X150x.png

本文参加Serverless云开发的有奖征文活动,已经获得作者授权

相关文章
|
1月前
|
人工智能 运维 安全
加速智能体开发:从 Serverless 运行时到 Serverless AI 运行时
在云计算与人工智能深度融合的背景下,Serverless 技术作为云原生架构的集大成者,正加速向 AI 原生架构演进。阿里云函数计算(FC)率先提出并实践“Serverless AI 运行时”概念,通过技术创新与生态联动,为智能体(Agent)开发提供高效、安全、低成本的基础设施支持。本文从技术演进路径、核心能力及未来展望三方面解析 Serverless AI 的突破性价值。
|
7月前
|
分布式计算 运维 搜索推荐
立马耀:通过阿里云 Serverless Spark 和 Milvus 构建高效向量检索系统,驱动个性化推荐业务
蝉妈妈旗下蝉选通过迁移到阿里云 Serverless Spark 及 Milvus,解决传统架构性能瓶颈与运维复杂性问题。新方案实现离线任务耗时减少40%、失败率降80%,Milvus 向量检索成本降低75%,支持更大规模数据处理,查询响应提速。
375 57
|
4月前
|
分布式计算 Serverless OLAP
实时数仓Hologres V3.1版本发布,Serverless型实例从零开始构建OLAP系统
Hologres推出Serverless型实例,支持按需计费、无需独享资源,适合新业务探索分析。高性能查询内表及MaxCompute/OSS外表,弹性扩展至512CU,性能媲美主流开源产品。新增Dynamic Table升级、直读架构优化及ChatBI解决方案,助力高效数据分析。
实时数仓Hologres V3.1版本发布,Serverless型实例从零开始构建OLAP系统
|
9月前
|
Cloud Native 安全 Serverless
云原生应用实战:基于阿里云Serverless的API服务开发与部署
随着云计算的发展,Serverless架构日益流行。阿里云函数计算(Function Compute)作为Serverless服务,让开发者无需管理服务器即可运行代码,按需付费,简化开发运维流程。本文从零开始,介绍如何使用阿里云函数计算开发简单的API服务,并探讨其核心优势与最佳实践。通过Python示例,演示创建、部署及优化API的过程,涵盖环境准备、代码实现、性能优化和安全管理等内容,帮助读者快速上手Serverless开发。
|
12月前
|
算法 Serverless
通过函数计算部署ComfyUI以实现一个AIGC图像生成系统
快来报名参与ComfyUI活动,体验一键部署模型,生成粘土风格作品赢取体脂秤。活动时间从即日起至2024年12月13日24:00:00,每个工作日限量50个,先到先得!访问活动页面了解更多详情。
359 54
|
11月前
|
JSON 人工智能 Serverless
一键生成毛茸萌宠形象,基于函数计算极速部署ComfyUI生图系统
通过阿里云函数计算FC 和文件存储NAS,用户体验 ComfyUI 和预置工作流文件,用户可以快速生成毛茸茸萌宠等高质量图像。
一键生成毛茸萌宠形象,基于函数计算极速部署ComfyUI生图系统
|
10月前
|
人工智能 JSON 自然语言处理
一键生成毛茸萌宠形象,基于函数计算极速部署 ComfyUI 生图系统
本次方案将帮助大家实现使用阿里云产品函数计算FC,只需简单操作,就可以快速配置ComfyUI大模型,创建出你的专属毛茸茸萌宠形象。内置基础大模型+常用插件+部分 Lora,以风格化图像生成只需用户让体验键配置简单方便,后续您可以根据自己的需要更换需要的模型、Lora、增加插件。
581 14
|
12月前
|
监控 Serverless 云计算
探索Serverless架构:开发实践与优化策略
本文深入探讨了Serverless架构的核心概念、开发实践及优化策略。Serverless让开发者无需管理服务器即可运行代码,具有成本效益、高可扩展性和提升开发效率等优势。文章还详细介绍了函数设计、安全性、监控及性能和成本优化的最佳实践。
|
12月前
|
弹性计算 算法 搜索推荐
活动实践 | 通过函数计算部署ComfyUI以实现一个AIGC图像生成系统
ComfyUI是基于节点工作流稳定扩散算法的新一代WebUI,支持高质量图像生成。用户可通过阿里云函数计算快速部署ComfyUI应用模板,实现个性化定制与高效服务。首次生成图像因冷启动需稍长时间,之后将显著加速。此外,ComfyUI允许自定义模型和插件,满足多样化创作需求。
|
12月前
|
关系型数据库 Serverless 分布式数据库
PolarDB Serverless 模式通过自动扩缩容技术,根据实际工作负载动态调整资源,提高系统灵活性与成本效益
PolarDB Serverless 模式通过自动扩缩容技术,根据实际工作负载动态调整资源,提高系统灵活性与成本效益。用户无需预配高固定资源,仅需为实际使用付费,有效应对流量突变,降低总体成本。示例代码展示了基本数据库操作,强调了合理规划、监控评估及结合其他云服务的重要性,助力企业数字化转型。
287 6

相关产品

  • 函数计算