邮件发送服务设计方案

摘要

这里讲的是作为客户端, 怎么设计邮件发送服务.具体到邮件服务器怎么设计配置, 垃圾邮件识别与拦截等本文并没有涉及

基础知识

协议相关

发送协议: SMTP (客户端发送时, 需要账号密码先登录邮件服务器的)

接收/拉取协议: POP3, IMAP

域名解析相关

邮件服务器主域名是: www.test.com

分配给某个人的邮箱是: user1@mail.test.com

简化,去掉mail: user@test.com

全局配置管理

1.发信人

分为触发型和批量两种, 防止批量发时被厂商拉黑, 也可用于统计

(我们系统都是功能提醒类邮件, 暂无批量发送的需求, 这个一般是营销邮件)

国内/海外不同的配置, 也就是发给不同的邮箱服务器, 配置中记录下这些服务器的账户密码

2. 接入项目管理

不同的业务分配给他们不同的app_code / app_secret

可用于安全校验/便于统计和筛选

3. 支持开关

总开关: 决定所有邮件是否发送

项目开关: 决定是否发送某个项目的邮件

业务开关: 决定是否发送某个项目的某个业务的邮件 (一个业务可能对应多个模板)

收件人开关: 决定是否发给某个人

4. 测试环境不往外发

测试环境的测试邮件, 不能发给生产环境的真实用户;

每个应用/业务可以配置固定的测试用收件人;

统计功能

1.每个应用的发送情况

2.某段时间的发送情况

3.某个人的收件情况

邮件本身功能

1. 模板管理

(可选, 由发送方管理, 还是邮件服务管理, 建议发送方进入到邮件服务页面进行管理 )

1.1内容形式: 纯文本模板, HTML模板(带样式)

1.2模板编号(方便管理, 简化接口调用, 支持多语言)

1.3模板状态可用时才能发

1.4支持页面增加,编辑,失效等操作

2. 支持附件

2.1 调用方传递附件下载地址, 由发送服务下载后发送

2.2 或者对接第三方网盘, 发送链接由对方自行下载

3. 异步发送

3.1支持系统自动重发, 未成功发到邮件服务器

3.2支持手工重发(改状态, 页面操作)

4. 支持定时发送

4.1海外邮件要考虑时区, 不能半夜给人家发邮件

4.2业务有要求定时发送

5. 支持标签

标记邮件是具体什么用途, 比如活动到期提醒邮件, 注册成功的邮件等

6. 支持重试

系统自动重试,

手工重试,

发送失败报警等

7.邮件发送区分优先级

(一期先不考虑)

表结构设计

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. 可考虑每个接入项目一个进程去发送, 能隔离开不同的业务, 提高可用性.

子项目接入规划

先由单个系统接入, 运行一段时间后, 稳定性和易用性提升后, 再接入其他系统

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值