首页 > 作文

Spring Boot实战解决高并发数据入库之 Redis 缓存+MySQL 批量入库问题

更新时间:2023-04-04 23:26:16 阅读: 评论:0

目录
前言架构设计代码实现测试总结

前言

最近在做阅读类的业务,需要记录用户的pv,uv;

项目状况:前期尝试业务阶段;

特点:

快速实现(不需要做太重,满足初期推广运营即可)快速投入市场去运营

收集用户的原始数据,三要素:

谁在什么时间阅读哪篇文章

提到pv,uv脑海中首先浮现特点:

需要考虑性能(每个客户每打开一篇文章进行记录)允许数据有较小误差(少部分数据丢失)

架构设计

架构图:

时序图

记录基础数据mysql表结构

create table `zh_article_count` (  `id` bigint(20) not null auto_increment,  `bu_no` varchar(32) default null comment '业务编码',  `customer_id` varchar(32) default null comment '用户编码',  `type` int(2) default '0' comment '统计类型:写中秋的诗0app内文章阅读',  `article_no` varchar(32) default null comment '文章编码',  `read_time` datetime default null comment '阅读时间',  `create_time` datetime default current_timestamp comment '创建时间',  `update_time` datetime default current_timestamp comment '更新时间',  `param1` int(2) default null comment '预留字段1',  `param2` int(4) default null comment '预留字段2',  `param3` int(11) default null comment '预留字段3',  `param4` varchar(20) default null comment '预留字段4',  `param5` varchar(32) default null comment '预留字段5',  `param6` varchar(64) default null comment '预留字段6',  primary key (`id`) using btree,  unique key `uk_zh_article_count_buno` (`bu_no`),  key `key_zh_article_count_csign` (`customer_id`),  key `key_zh_article_count_ano` (`article_no`),  key `key_zh_article_count_rtime` (`read_time`)) engine=innodb default chart=utf8mb4 comment='文章阅读统计表';

技术实现方案

springboot

redis

mysql

代码实现

完整代码(github,欢迎大家star,fork,watch)

/d/file/titlepic/springboot

主要代码展示

controller

/* * copyright (c) 2020. zhanghan_java@163.com all rights rerved. * 项目名称:spring boot实战解决高并发数据入库: redis 缓存+mysql 批量入库 * 类名称:articlecountcontroller.java * 创建人:张晗 * 联系方式:zhanghan_java@163.com * 开源地址: /d/file/titlepic/springboot * 博客地址: /d/file/titlepic/zhanghan.blog.csdn.net */package com.zhanghan.zhredistodb.controller;import org.springframework.beans.factory.annotation.autowired;import org.springframework.validation.annotation.validated;import org.springframework.web.bind.annotation.requestbody;import org.springframework.web.bind.annotation.requestmapping;import org.springframework.web.bind.annotation.requestmethod;import org.springframework.web.bind.annotation.restcontroller;import com.zhanghan.zhredistodb.controller.request.postarticleviewsrequest;import com.zhanghan.zhredistodb.rvice.articlecountrvice;@restcontrollerpublic class articlecountcontroller {    @autowired    private articlecountrvice articlecountrvice;   /**    * 记录用户访问记录    */    @requestmapping(value = "/post/article/views", method = requestmethod.post)    public object postarticleviews(@requestbody @validated postarticleviewsrequest postarticleviewsrequest) {        return articlecountrvice.postarticleviews(postarticleviewsrequest);    }    /**     *  批量将缓存中的数据同步到mysql(模拟定时任务操作)     */    @requestmapping民族大团结手抄报(value = "/post/batch", method = requestmethod.post)    public object postbatch() {        return articlecountrvice.postbatchredistodb();}

rvice

/* * copyright (c) 2020. zhanghan_java@163.com all rights rerved. * 项目名称:spring boot实战解决高并发数据入库: redis 缓存+mysql 批量入库 * 类名称:articlecountrviceimpl.java * 创建人:张晗 * 联系方式:zhanghan_java@163.com * 开源地址: /d/file/titlepic/springboot * 博客地址: /d/file/titlepic/zhanghan.blog.csdn.net */package com.zhanghan.zhredistodb.rvice.impl;import java.util.arraylist;import java.util.date;import java.util.list;import java.util.stream.collectors;import org.slf4j.logger;import org.slf4j.loggerfactor郑凯身高y;import org.springframework.beans.factory.annotation.autowired;import org.springframework.beans.factory.annotation.value;import org.springframework.data.redis.core.redistemplate;import org.springframework.stereotype.rvice;import org.springframework.util.collectionutils;import com.alibaba.fastjson.json;import com.zhanghan.zhredistodb.controller.request.postarticleviewsrequest;import com.zhanghan.zhredistodb.dto.articlecountdto;import com.zhanghan.zhredistodb.mybatis.mapper.xarticlecountmapper;import com.zhanghan.zhredistodb.rvice.articlecountrvice;import com.zhanghan.zhredistodb.util.wrapper.wrapmapper;import cn.hutool.core.util.idutil;@rvicepublic class articlecountrviceimpl implements articlecountrvice {    private static logger logger = loggerfactory.getlogger(articlecountrviceimpl.class);    @autowired    private redistemplate<string, string> strredistemplate;    private xarticlecountmapper xarticlecountmapper;    @value("${zh.article.count.redis.key:zh}")    private string zharticlecountrediskey;    @value("#{t(java.lang.integer).parint('${zh..article.read.num:3}')}")    private integer articlereadnum;    /**     * 记录用户访问记录     */    @override    public object postarticleviews(postarticleviewsrequest postarticleviewsrequest) {        articlecountdto articlecountdto = new articlecountdto();        articlecountdto.tbuno(idutil.simpleuuid());        articlecountdto.tcustomerid(postarticleviewsrequest.getcustomerid());        articlecountdto.tarticleno(postarticleviewsrequest.getarticleno());        articlecountdto.treadtime(new date());        string strarticlecountdto = json.tojsonstring(articlecountdto);        strredistemplate.opsforlist().rightpush(zharticlecountrediskey, strarticlecountdto);        return wrapmapper.ok();    }     * 批量将缓存中的数据同步到mysql    public object postbatchredistodb() {        date now = new date();        while (true) {            list<string> strarticlecountlist =                    strredistemplate.opsforlist().range(zharticlecountrediskey, 0, articlereadnum);            if (collectionutils.impty(strarticlecountlist)) {                return wrapmapper.ok();            }            li孔繁森的儿子st<articlecountdto> articlecountdtolist = new arraylist<>();            strarticlecountlist.stream().foreach(x -> {                articlecountdto articlecountdto = json.parobject(x, articlecountdto.class);                articlecountdtolist.add(articlecountdto);            });            //过滤出本次定时任务之前的缓存中数据,防止死循环            list<articlecountdto> beforearticlecountdtolist = articlecountdtolist.stream().filter(x -> x.getreadtime()                    .before(now)).collect(collectors.tolist());            if (collectionutils.impty(beforearticlecountdtolist)) {            xarticlecountmapper.batchadd(beforearticlecountdtolist);            integer delsize = beforearticlecountdtolist.size();            strredistemplate.opsforlist().trim(zharticlecountrediskey, delsize, -1l);        }}

测试

模拟用户请求访问后台(多次请求)

查看缓存中访问数据

模拟定时任务将缓存中数据同步到db中

这时查看缓存中的数据已经没了

查看数据库表结构

总结

项目中定时任务问演示方便用http代替定时任务调度;实际项目中用xxl-job,参考:定时任务项目中用re女职工劳动保护办法dis锁防止并发(定时任务调度端多次调度等),参考:redis实现计数器—接口防刷—升级版(redis+lua)后期运营数据可以从阅读记录表中拉数据进行相关分析访问量大:可以将mysql中的阅读记录表定时迁移走(mysql建历史表,mongodb等)

到此这篇关于spring boot实战解决高并发数据入库之 redis 缓存+mysql 批量入库的文章就介绍到这了,更多相关spring boot高并发数据入库内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!

本文发布于:2023-04-04 23:25:18,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/1c4b366ea4e43237d36b705e73dcfb96.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:Spring Boot实战解决高并发数据入库之 Redis 缓存+MySQL 批量入库问题.doc

本文 PDF 下载地址:Spring Boot实战解决高并发数据入库之 Redis 缓存+MySQL 批量入库问题.pdf

标签:缓存   数据   字段   批量
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图