01、GoodGuy 的诞生(一个消息推送平台)
大家好,我是处于 Java 行业下水道,励志重见天日的好人。
本篇博客没有配图,会比较枯燥,大家一定要耐住性子。
看了第一篇的朋友应该知道我打算搞一个叫做 GoodGuy 的开源项目,旨在搭建一套较为完善的公司内部消息推送平台,让公司的一切消息发送都能够通过 GoodGuy 来实现。
这两天我研究了一些产品应该研究的东西,我甚至还看了好几篇关于“如何做好一个产品”的文章。主要是上一篇博客已经信口开了河了,咱还是得投入一点精力去做这件事情。经过我这两天的研究,我系统的研究了一下我的 GoodGuy 应该做哪些功能。
毕竟咱不是专业的,我只是试图去越一下界,在开发合产品的边缘疯狂试探,可能会存在许多错误的地方,还请各位批评指正。
GoodGuy 是一个消息推送平台,我们先来聊聊消息推送,消息推送可以简单理解为消息发送方将信息传递给消息接收方。产生是消息发送方,用户是消息接收方,而消息是信息的载体。我们可以通过短信、邮件、push、微信公众号等形式进行消息的推送。应用场景非常多,比如618大促马上要开始了,各个商家会向顾客疯狂发送营销短信进行活动宣传;比如,好人要在某平台上注册账号,填写手机号后,平台会向好人推送验证码短信;又比如,好人今天上班打卡迟到了一分钟,OA系统就会向好人推送扣工资的通知。无论是信息的快速传递,还是商业营销,都具有非常大的价值。
拿实时触发消息推送举例,在很多业务实现中需要进行消息推送,可能很多人会直接在项目代码里面实现消息推送的逻辑。这不仅会让信息推送难以管理,而且当需要消息变动时,可能还需要修改源码,维护成本很大。
而有了消息推送平台,通过统一的消息推送和消息管理,既能够提高业务线和产品线的推送效率,也能够提高运营推广效率。
一般来说,消息的推送可以分为两种。
一种是实时触发推送。比如前面提到的OA扣工资的通知,好人打卡时,系统判断出好人迟到了,实时触发推送:“亲,您本次打卡迟到一分钟,将扣除您当日全天工资。”
还有一种是定时推送。这种可能更多的是批量推送,比如上面提到了618大促,运营小姐姐提前设置了推送任务,在大促开始前的四小时向一千万店铺粉丝推送营销短信:“亲,618大促今晚20点开售,全店三件五折等你抢购。”
以上两个场景是不是很有画面感。
一般来说实时性推送的消息内容复用性比较强,一般会有消息模板,通过改变几个差异化参数,拼接成一条完整的消息。所以我们可以抽取出消息模板,在模板中预留占位符,根据差异化参数进行占位符替换。
而定时推送,运营活动批量定时投放,需要运营提供名单,编辑文案,经过上级领导审查后方可定时推送。相对来说复用性没那么强,可以不使用模板,根据实际情况,选择是否使用占位符。
目前的打算是,因为没有实际的业务数据做支撑,咱们就不考虑用户筛选功能的开发了,直接通过上传 csv 文件的方式提供名单。为什么不用 excel?因为 excel 有大小限制,而 csv 没有。excel 上限 1048576 行,如果要给店铺的一千万粉丝推送消息,那得分割成好几个 excel,太麻烦了。
最常见的渠道有短信、邮件、push、微信公众号、微信小程序、钉钉、OA系统等。这些主要根据公司内部满足哪些渠道来进行选择。
根据推送渠道的不同,需要提供不同的数据。比如发短信需要电话号码,微信推送需要 open id,而 push 推送需要 SDK 上报的 token、标题、跳转链接等。
因为渠道不同,会产生一些差异化,所以需要根据用户的不同选择,实时改变表单项。
实时触发推送的话,主要根据业务所涉及人群直接编写业务调用 API 即可。
而运营推送的话,需要运营同学根据一定需求和用户特征筛选出人群,GoodGuy 暂不提供人群筛选功能,运营同学可将筛选出的数据导出 CSV 文件,上传到 GoodGuy 即可实现批量推送。
前面我们提到了一下,不同的渠道,推送消息需要的数据是不同的,我们需要根据实际情况来切换表单项,通过占位符的方式填充不同的数据。就不过多赘述了。
我们设想这样一个场景,618大促,系统正在批量发送一千万条营销短信。这一千万条短信数据量庞大,系统不可能一下子全部发完,这时很容易造成系统阻塞。
而在这时好人要注册账号,如果消息是顺序推送的,那这条验证码短信要等那一千条营销短信全部推送完毕后才被推送。可能半小时已经过去了,那好人是不是就要做坏人了,早就口头芬芳了。
其实很明显,验证码短信比营销短信重要得多,营销短信推送少个几百上千条,慢个几分钟十几分钟,其实关系都不大。但是验证码短信慢个半分钟,是不是都会十分影响用户体验。
所以应当给消息分等级,权重高的先走,各位弟弟都要给我让路。
目前主要将消息消息分为三类:通知、营销、验证码。目前仅分为此三种,验证码权重最高,通知其次,营销是弟弟。其实这是比较粗糙的分类,还可以根据实际业务进行更细颗粒度的分类。
对于不同的推送分类来说,推送时间是不一样的。
像接口调用的话,一般来说实时推送的概率会很高,当然我们也可以提供定时推送的接口。
而通过管理后台设置的消息发送任务,除了立即推送之外,还会有很多定时推送,比如前面提到的 618 前四小时推送,也会有一些固化的推送任务会采取周期推送,比如每个月的 1 号推送消费账单。
所以主要可以有三种推送时间:暂不推送、立即推送,定时推送(一次性定时+周期定时)。
定时推送可以使用 cron 表达式来定义,之后有时间可以单独写一篇来介绍 cron 表达式,不了解的同学可先自行了解,还是比较简单的,很多定时任务框架都是使用 cron 表达式。暂不推送和立即推送可以定义两个特殊值来表示,比如 0 是暂不推送,1 是立即推送。
消息是人为设置的,很容易出现纰漏,如果向用户推送了错误的消息难免会造成或大或小的后果。所以,在消息发送之前检查消息的正确性是必不可少的。
例如可以在推送之前进行推送测试,给一个或多个特定账户预推送一条消息,检查推送是否正确。
也可以设置审核机制,营销推送任务创建后,由领导审核通过之后才定时生效。这样就可以把锅甩给领导,是不是很妙。
并不是说,API 调用了,或者是运营同学设置了推送任务,我们系统就要无条件满足他们的推送任务。虽然 GoodGuy 作为一个烂好人会尽可能满足他们,但也是有原则的,做守得住底线的好人才不会让自己太受伤。
底线一:不能过分打扰
根据消息类型的不同,应当设置相应的频率上限,比如营销类推广三天内最多一次,push 一天最多 10 条,同一业务线一天最多推送 5 条。
底线二:禁违法、暴力
触犯法律的事情,咱不能干。
底线三:不能死皮赖脸的纠缠
用户已经退订了,就应该将用户拉入黑名单中,不要继续推送。
底线四:让我睡睡觉吧
推送时间应该把握住,尽量白天推送。好人晚上睡得正香,你突然一条推送,被你推送消息的铃声给吵醒了,好人是不是又要骂人了。
底线五:……
暂时没想出来,反正推送之前应当设置一些拦截规则,将部分不符合规则的消息过滤掉。用户对很多消息的容忍度是很低的,特别是营销类消息,应当把握好推送消息的质量和频率,吊着用户的耐心,别突破耐心的上限。
终于可以发消息了,没想到简简单单的发消息需要经历这么复杂的过程。发送消息主要是后端根据不同的消息渠道实现不同的发送逻辑了。
除了正确的消息发送逻辑之外,应当注重性能的优化,提升吞吐量;注重系统的稳定性,避免服务瘫痪、消息丢失;同时做好日志的记录,保存珍贵数据,和便以快速定位 bug。
消息发送的过程中,会产生很多宝贵的数据。比如创建了一个 1000 万发送量的发送任务,最终只成功发送了 800 万,有 200 万消息哪去了呢?可能是 token 过期了,可能是对方取关了公众号,可能是频繁发送被过滤了,可能是对方退订给过滤了,等等,有太多可能会导致消息没能成功发送了。
还有,消息推送成功了,而用户有没有看?用户有没有点击?用户有没有因为点击了消息而产生注册或者消费等带来公司获利的行为。
知道这些问题的原因,其实是很有用的,我们可能分析系统的性能,可以分析用户画像,可以根据推送情况调整推送策略。
除了这些,我们还可以知道成功下发的消息数。像发短信这种业务,每一条短信我们都是要为之付费的,如果实际下发数和扣费数有太大差距,那亏了钱我们也没处说理去。而我们自己记录了数据,知道那条消息下发成功,知道成功了多少条,就能对账单有一个初步的预估,如果差距太大,那我们就找短信提供商说理去。
我们一直提到运营同学是需要上传 csv 文件的,那当然是在后台管理系统上传。后台管理系统需要提供模板创建、任务审核、数据仪表盘、拦截规则配置等功能。
各位同学,点个赞吧,写着写着,现在凌晨十二点了,四千字。不过你能看到这,我也要给你点赞。
以上就是今天要讲的内容,主要讨论了一些 GoodGuy 的功能需求。这也是我这两天研究的成果,花的时间不多,可能会有很多不是很合理的地方,希望大家批评指正。
当然,上面讲了这么多功能,我应该是不会全部做了,比较时间和精力有限,先将主要功能做出来,再慢慢扩展优化吧。
本来想在这篇将代码仓库一起发出来的,但是发生了两个意外。