通过一个小的业务点出发,搭建一个可以实例使用的项目工程,将各种知识点串联起来; 实战演练专题中,每一个项目都是可以独立运行的,包含若干知识点,甚至可以不做修改直接应用于生产项目;
今天的实战项目主要解决的业务需求为: 每日新增用户统计,生成报表,并邮件发送给相关人
本项目将包含以下知识点:
-
基于 MySql 的每日新增用户报表统计(如何统计每日新增用户,若日期不连续如何自动补 0?)
-
定时执行报表统计任务
-
MyBatis + MySql 数据操作
-
邮件发送
-
Thymeleaf 引擎实现报表模板渲染
I. 需求拆解
需要相对来说属于比较明确的了,目的就是实现一个自动报表统计的任务,查询出每日的用户新增情况,然后推送给指定的用户
因此我们将很清晰的知道,我们需要干的事情
定时任务
这里重点放在如何来支持这个任务的定时执行,通常来说定时任务会区分为固定时刻执行 + 间隔时长执行两种(注意这种区分主要是为了方便理解,如每天五点执行的任务,也可以理解为每隔 24h 执行一次)
前者常见于 一次性任务
,如本文中的每天统计一次,这种就是相对典型的固定时刻执行的任务;
后者常见于 轮询式任务
,如常见的应用探活(每隔 30s 发一个 ping 消息,判断服务是否健在)
定时任务的方案非常多,有兴趣的小伙伴可以关注一波“一灰灰 blog”公众号,蹲守一个后续
本文将直接采用 Spring 的定时任务实现需求场景,对这块不熟悉的小伙伴可以看一下我之前的分享的博文
-
180801-Spring 之定时任务基本使用篇
-
180803-Spring 定时任务高级使用篇
每日新增用户统计
每日新增用户统计,实现方式挺多的,比如举几个简单的实现思路
-
基于 redis 的计数器:一天一个 key,当天有新用户时,同步的实现计数器+1
-
基于数据库,新增一个统计表,包含如日期 + 新增用户数 + 活跃用户数 等字段
-
有新用户注册时,对应日期的新增用户数,活跃用户数 + 1
-
老用户今日首次使用时,活跃用户数 + 1
上面两个方案都需要借助额外的库表来辅助支持,本文则采用直接统计用户表,根据注册时间来聚合统计每日的新增用户数
-
优点:简单,无额外要求,适用于数据量小的场景(比如用户量小于百万的)
-
缺点:用户量大时,数据库压力大
关于如何使用 mysql 进行统计每日新增用户,不熟悉的小伙伴,推荐参考博主之前的分享文章
- 220707-MySql 按时、天、周、月进行数据统计 - 一灰灰 Blog [4]
报表生成&推送用户
接下来就是将上面统计的数据,生成报表然后推送给用户;首先是如何将数据生成报表?其次则是如何推送给指定用户?
将数据组装成报表的方式通常取决于你选择的推送方式,如飞书、钉钉之类的,有对应的开发 api,可以直接推送富文本;
本文的实现姿势则选择的是通过邮件的方式进行发送,why?
-
飞书、钉钉、微信之类的,需要授权,对于不使用这些作为办公软件的小伙伴没什么意义
-
短信需要钱…
对于邮件,大家应该都有,无论是 qq 邮箱,还是工作邮箱;基本上对于想要直接跑本文的小伙伴来说,没有什么额外的门槛
关于 java/spring 如何使用邮箱,对此不太熟悉的小伙伴,可以参考博主之前的分享文章
- 【中间件】SpringBoot 系列之邮件发送姿势介绍 | 一灰灰 Blog [5]
上面文章中介绍的是 FreeMaker 来实现模板渲染,本文则介绍另外一个知识点,借助 Thymleaf 来实现数据报表的生成 (一篇文章获取这么多知识点,就问你开不开心 O(∩_∩)O)
II. 分布实现
1. 项目搭建
首选搭建一个基本的 SpringBoot 应用,相信这一步大家都很熟悉了;若有不懂的小伙伴,请点赞、评论加博主好友,手把手教你,不收费
最终的项目依赖如下
<dependencies>
<!-- 邮件发送的核心依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version