这里讲的是作为客户端, 怎么设计邮件发送服务.具体到邮件服务器怎么设计配置, 垃圾邮件识别与拦截等本文并没有涉及
发送协议: SMTP (客户端发送时, 需要账号密码先登录邮件服务器的)
接收/拉取协议: POP3, IMAP
邮件服务器主域名是: www.test.com
分配给某个人的邮箱是: [email protected]
简化,去掉mail: [email protected]
分为触发型和批量两种, 防止批量发时被厂商拉黑, 也可用于统计
(我们系统都是功能提醒类邮件, 暂无批量发送的需求, 这个一般是营销邮件)
国内/海外不同的配置, 也就是发给不同的邮箱服务器, 配置中记录下这些服务器的账户密码
不同的业务分配给他们不同的app_code / app_secret
可用于安全校验/便于统计和筛选
总开关: 决定所有邮件是否发送
项目开关: 决定是否发送某个项目的邮件
业务开关: 决定是否发送某个项目的某个业务的邮件 (一个业务可能对应多个模板)
收件人开关: 决定是否发给某个人
测试环境的测试邮件, 不能发给生产环境的真实用户;
每个应用/业务可以配置固定的测试用收件人;
1.每个应用的发送情况
2.某段时间的发送情况
3.某个人的收件情况
(可选, 由发送方管理, 还是邮件服务管理, 建议发送方进入到邮件服务页面进行管理 )
1.1内容形式: 纯文本模板, HTML模板(带样式)
1.2模板编号(方便管理, 简化接口调用, 支持多语言)
1.3模板状态可用时才能发
1.4支持页面增加,编辑,失效等操作
2.1 调用方传递附件下载地址, 由发送服务下载后发送
2.2 或者对接第三方网盘, 发送链接由对方自行下载
3.1支持系统自动重发, 未成功发到邮件服务器
3.2支持手工重发(改状态, 页面操作)
4.1海外邮件要考虑时区, 不能半夜给人家发邮件
4.2业务有要求定时发送
标记邮件是具体什么用途, 比如活动到期提醒邮件, 注册成功的邮件等
系统自动重试,
手工重试,
发送失败报警等
(一期先不考虑)
1. 接入账号管理(验签机制, app_key app_secret, 可选)
2. 模板管理 (app_key, 编号, 标题, 模板内容, 状态, 格式(纯文本/HTML), 海外/国内(使用不同的服务器往外发)), 是否停发
3. 异步发送(app_key, 模板编号, 关键字(病例编号/活动编号等, 便于筛选), 邮件信息(接收人, 抄送人, 内容等等), 发送状态, 是否定时发送, 指定的发送时间(精确到分), 发送结果(错误原因), 实际发送时间, 最后更改时间)
4. 配置
4.1 开关配置: 项目, 模板编号, 是否发送), 如果不发送, 仍会往`异步发送`表中, 状态改为不发送, 可通过改状态来重发
4.2 服务器配置: 服务器域名, 用户名, 密码, smtp协议, 加密方式等 (不会频繁更改, 也可做成配置文件)
-- notice 数据库
CREATE DATABASE IF NOT EXISTS `notice`;
USE `notice`;
-- 接入项目管理
CREATE TABLE IF NOT EXISTS `em_app` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增ID',
`name` varchar(20) NOT NULL DEFAULT '' COMMENT '项目名称',
`app_key` varchar(20) NOT NULL DEFAULT '' COMMENT '编码',
`app_secret` varchar(70) NOT NULL DEFAULT '' COMMENT '签名',
`remark` varchar(200) NOT NULL DEFAULT '' COMMENT '备注',
`notify_url` varchar(200) NOT NULL DEFAULT '' COMMENT '回调URL',
`status` tinyint(4) NOT NULL DEFAULT 0 COMMENT '状态',
`deleted` tinyint(4) NOT NULL DEFAULT 0 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`),
KEY `app_key_secret` (`app_key`,`app_secret`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='接入项目管理';
-- 配置信息
CREATE TABLE IF NOT EXISTS `em_config` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增ID',
`type` tinyint(4) NOT NULL DEFAULT 0 COMMENT '类型:0.默认1.邮件服务器账号',
`name` varchar(20) NOT NULL DEFAULT '' COMMENT '简单说明',
`config_key` varchar(50) NOT NULL DEFAULT '' COMMENT '键',
`config_value` text DEFAULT '' COMMENT '值',
`status` tinyint(4) NOT NULL DEFAULT 0 COMMENT '状态',
`deleted` tinyint(4) NOT NULL DEFAULT 0 COMMENT '是否删除',
`remark` varchar(100) DEFAULT '' 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`),
KEY `config_key` (`config_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='配置信息';
-- 待发送的邮件
CREATE TABLE IF NOT EXISTS `em_message` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增ID',
`app_key` varchar(20) NOT NULL DEFAULT '' COMMENT '项目编号',
`tpl_code` varchar(20) NOT NULL DEFAULT '' COMMENT '模板编号',
`code` varchar(100) NOT NULL DEFAULT '' COMMENT '业务编号用于筛选',
`status` tinyint(4) NOT NULL DEFAULT 0 COMMENT '状态: -1.失败 0.待发送 1.发送中 2.发送完毕',
`message` text DEFAULT NULL COMMENT '内容',
`send_type` tinyint(4) NOT NULL DEFAULT 0 COMMENT '发送类型: 0.尽快发送 1.定时发送',
`send_time` datetime DEFAULT NULL COMMENT '指定发送时间',
`remark` varchar(200) NOT NULL DEFAULT '' COMMENT '备注',
`deleted` tinyint(4) NOT NULL DEFAULT 0 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`),
KEY `code` (`code`),
KEY `status` (`status`),
KEY `app_key` (`app_key`),
KEY `send_type` (`send_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='待发送的邮件';
-- 模板
CREATE TABLE IF NOT EXISTS `em_tpl` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增ID',
`code` varchar(20) NOT NULL DEFAULT '' COMMENT '编码',
`app_key` varchar(20) NOT NULL DEFAULT '' COMMENT '项目',
`account` varchar(20) NOT NULL DEFAULT '' COMMENT '邮件服务器账号编码',
`subject` varchar(100) NOT NULL DEFAULT '' COMMENT '主题',
`content` text DEFAULT NULL COMMENT '模板内容',
`content_type` tinyint(4) NOT NULL DEFAULT 0 COMMENT '类型:0.文本 1:html',
`remark` varchar(100) NOT NULL DEFAULT '' COMMENT '备注',
`status` tinyint(4) NOT NULL DEFAULT 0 COMMENT '状态: 0:正常 -1:停发',
`deleted` tinyint(4) NOT NULL DEFAULT 0 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`),
KEY `code` (`code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='模板';
-- 取消订阅
CREATE TABLE em_unsubscribe(
`id` int PRIMARY KEY NOT NULL AUTO_INCREMENT COMMENT '自增ID',
`app_key` varchar(20) NOT NULL DEFAULT '' COMMENT '项目编号',
`tag` varchar(50) NOT NULL DEFAULT '' COMMENT '具体业务',
`email` varchar(100) NOT NULL DEFAULT '' COMMENT '邮箱',
`deleted` tinyint NOT NULL DEFAULT 0 COMMENT '是否删除',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
KEY `app_key_email` (app_key,email)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT="取消订阅";
1. 邮件发送接口:
1.1 参数: 项目编码, 业务码, 模板编码, 模板参数, 发送时间(有值:定时发送, 无值: 尽快发送), 接收人, 抄送人, 密送人, 附件链接
1.2 验签功能 (一期可先不实现, 仅内部调用)
1.3 业务码, 一个业务可能对应多个模板, 比如, 活动快结束提醒, 不同的活动类型模板是不一样的.
2. 退订接口
2.1 参数: 项目编码, 用户邮箱地址, 业务编码, 是否退订
1.模板管理相关接口, 添加/编辑/删除/失效/生效等
2.接入账号管理相关, 添加/编辑/删除/暂停等
3.邮件列表, 列表(筛选)
4.重发接口
5.开关管理
发送成功或失败时, 通知到调用方
1. 定时扫描em_message表, 进行发送
2. 可考虑每个接入项目一个进程去发送, 能隔离开不同的业务, 提高可用性.
先由单个系统接入, 运行一段时间后, 稳定性和易用性提升后, 再接入其他系统