如何设计一个短信发送功能

本文主要分享了如何设计一个发送短信功能。

一、总结简述

1.梳理多个平台短信API的发送参数,集成封装提供统一的API,支持多个短信平台(阿里云、腾讯云、百度云、京东云、七牛云)灵活切换

2.提供存储方案,表结构设计

3.提供真实生产项目代码案例,实现异步机制、定时发送、超时取消发送等功能

4.文末提供代码仓库,有兴趣的小伙伴可以fork代码

二、架构图

如何设计一个短信发送功能_第1张图片

三、代码实现(渠道SDK封装)

1.短信抽象核心代码(项目:sms-sender-core)

如何设计一个短信发送功能_第2张图片

1)抽象短信发送器,定义一个接口

如何设计一个短信发送功能_第3张图片

2)以阿里云短信对接实现类为demo的代码展示,其他渠道代码类似,当然也可以增加自定义渠道实现,实现SmsSender的接口即可(可通过gitee查看源码)

如何设计一个短信发送功能_第4张图片

3)阿里云短信封装SmsClient核心代码

如何设计一个短信发送功能_第5张图片

2.简化项目sms-sender-core的引用,springboot自动装配(项目:sms-sender-spring-boot-starter)

如何设计一个短信发送功能_第6张图片

1)这里就只展示SmsSenderAutoConfiguration的代码,其他的可以通过gitee查看源码

如何设计一个短信发送功能_第7张图片

简单的短信代码SDK封装到此结束,但在我们实际项目开发是远不够的。实际项目中还需要考虑存储方案、异步机制、定时发送、超时取消发送、失败重试机制、渠道切换等。

四、代码实现(项目实际应用)

1.数据库表结构设计

CREATE TABLE `sms_type_template_config` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
  `type` varchar(16) NOT NULL COMMENT '业务类型(verifycode:验证码,market:营销活动,tips:提示信息)',
  `channel` varchar(16) NOT NULL COMMENT '发送渠道(log:打印日志(测试),ali:阿里云,tencent:腾讯云)',
  `template_code` varchar(32) NOT NULL COMMENT '模板编码',
  `remark` varchar(255) DEFAULT NULL COMMENT '备注',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE KEY `uniq_type_channel` (`type`,`channel`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='短信业务-模板配置';

CREATE TABLE `sms_template` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
  `channel` varchar(16) NOT NULL COMMENT '发送渠道(log:打印日志(测试),ali:阿里云,tencent:腾讯云)',
  `template_code` varchar(32) NOT NULL COMMENT '模板编码',
  `template_content` varchar(255) DEFAULT NULL COMMENT '模板内容',
  `remark` varchar(255) DEFAULT NULL COMMENT '备注',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE KEY `uniq_channel_templatecode` (`channel`,`template_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='短信模板';

CREATE TABLE `sms_task` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
  `type` varchar(16) NOT NULL COMMENT '业务类型(verifycode:验证码,market:营销活动,tips:提示信息)',
  `plan_send_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '计划发送时间',
  `over_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '超时取消发送时间',
  `remark` varchar(255) DEFAULT NULL COMMENT '备注',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `idx_type` (`type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='短信发送任务';

CREATE TABLE `sms_task_detail` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
  `task_id` int(11) unsigned NOT NULL COMMENT 'sms_task.id',
  `mobile` varchar(11) NOT NULL COMMENT '手机号码',
  `template_param_json` varchar(255) DEFAULT NULL COMMENT '模板参数json',
  `plan_send_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '计划发送时间',
  `actual_send_time` datetime DEFAULT NULL COMMENT '实际发送时间',
  `status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '状态(1:待发送,2:待定时发送,11:发送MQ成功,12:MQ消费成功,21:请求成功,22:请求失败,31:取消发送)',
  `content` varchar(255) DEFAULT NULL COMMENT '短信内容',
  `remark` varchar(255) DEFAULT NULL COMMENT '备注',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `idx_taskid` (`task_id`),
  KEY `idx_mobile` (`mobile`),
  KEY `idx_plansendtime_status` (plan_send_time,`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='短信发送任务明细';

CREATE TABLE `sms_record` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
  `channel` varchar(16) NOT NULL COMMENT '发送渠道(log:打印日志(测试),ali:阿里云,tencent:腾讯云)',
  `mobile` varchar(11) NOT NULL COMMENT '手机号码',
  `sign_name` varchar(12) NOT NULL COMMENT '短信签名(2~12个字符),如:【XX公司】,【】不用填写',
  `template_code` varchar(32) NOT NULL COMMENT '模板编码',
  `template_param_json` varchar(255) DEFAULT NULL COMMENT '模板参数json',
  `content` varchar(255) DEFAULT NULL COMMENT '短信内容',
  `result` varchar(8) NOT NULL COMMENT '结果(success:成功,fail:失败)',
  `message` varchar(255) DEFAULT NULL COMMENT '信息',
  `request_id` varchar(64) DEFAULT NULL COMMENT '请求ID',
  `remark` varchar(255) DEFAULT NULL COMMENT '备注',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `idx_mobile` (`mobile`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='短信发送记录';

表说明:

sms_type_template_config:主要是记录业务类型与模板编码的关系,这样可以避免在代码中写死模板编码,因为不同的渠道模板编码也会不一致

sms_template:配置不同渠道的短信模板

sms_task、sms_task_detail:短信任务,可以理解为每次发送短信都是1个短信任务,每个短信任务可以给多个用户发送短信,营销短信常用,支持即时发送和定时发送

sms_record:短信发送记录,最终调用完发送短信API记录(不代表一定发送成功,部分渠道平台还提供了查询发送状态的API,如果需要了解最终状态需要增加状态API的查询

数据样例说明:

短信业务-模板配置

如何设计一个短信发送功能_第8张图片

1)代码中会写死type,跟据type+channel查询到template_code

短信模板

1)跟据channel+template_code查询到template_content

为什么要记录模板内容?

1)其实template_content一般是不需要传递给第三方API的,大部分都是通过“模板编码+短信参数”的方式来发送短信,但也有部分渠道API有特殊情况,直接通过“短信内容”来发送

2)运营人员在发送营销短信时需要在管理后台能看到短信模板

3)短信的实际内容是需要保留存储的,而渠道API一般都不会返回实际发送内容,只能由程序拼凑

短信发送记录

2.将sms_type_template_config、sms_template都做成后台配置功能,这里就不细讲了

3.核心代码展示

1)项目结构

如何设计一个短信发送功能_第9张图片

2)生产者核心代码

如何设计一个短信发送功能_第10张图片

3)消费者核心代码

如何设计一个短信发送功能_第11张图片

如何设计一个短信发送功能_第12张图片

补充:失败重试机制(可利用template-tool下的innercallback代码实现)、渠道切换尚未实现,后续有时间再补充!!!

怎么样?如果你觉得有用的话,还不快快收藏起来!!!

附:涉及的代码目录

github: GitHub - 897665787/sms-sender: 一个封装了短信发送的框架,支持阿里云短信、腾讯云短信等。、GitHub - 897665787/springcloud-template: 一个基于springcloud netflix微服务框架,记录了关于微服务开发的一些最佳应用,欢迎大家学习指导。

gitee:sms-sender: 一个封装了短信发送的框架,支持阿里云短信、腾讯云短信等。、springcloud-template: 一个基于springcloud netflix微服务框架,记录了关于微服务开发的一些最佳应用,欢迎大家学习指导。


sms-sender
├── sms-sender-core -- 核心代码
     └── ali -- 阿里云
     └── baidu -- 百度云
     └── jingdong -- 京东云
     └── log -- 测试渠道(一般用于测试环境不想真正的发送短信,短信可是要收费的)
     └── qiniu-- 七牛云
     └── tencent -- 腾讯云
└── sms-sender-boot-starter -- 整合springboot代码
└── sms-sender-jdbc-spring-boot-starter -- 整合springboot代码,增加了jdbc存储方案,自动创建表短信模板(sms_template)、短信发送记录(sms_record)2张表
     └── processor
          └── SqlSendPostProcessor -- jdbc存储实现
└── sms-sender-springboot-demo -- 在springboot中使用sms-sender的demo代码

springcloud-template
└── template-tool
     └──controller
          └── SmsController -- 短信任务轮询API
          └── VerifyCodeController -- 验证码短信发送demo
     └── sms
          └── AsyncSmsSender -- 异步发送短信,MQ生产者逻辑
          └── MysqlSendPostProcessor -- 记录短信发送记录
          └── SmsSenderConsumer -- 异步发送短信,MQ消费者逻辑
└── sql
     └── tool
          └── 短信设计相关表.sql

你可能感兴趣的:(Java)