java配置SSM纯注解整合Redis开发高并发抢红包项目
前言:
前段时间学习点Redis,这次结合ssm实现一个高并发抢红包的项目。
跟以前不一样的:
- 基于java配置SSM,而并非XML.为什么要这样呢?
找了点网络上的答案:
在使用Spring开发时,我们经常会看到各种各样xml配置,过于繁多的xml配置显得复杂烦人。 在Spring3之后,Spring支持使用JavaConfig来代替xml配置, 这种方式也得到越来越多人的推荐,甚至在Spring Boot的项目中,基本上已经见不到xml的影子了。
- 抢红包的记录使用Lua保存到Redis内存中,最后再异步使用批量事务插入到Mysql。
目的:Redis内存响应速度比Mysql硬盘响应速度快。
这个项目的目的也是为了实现上面的两个内容。
具体的项目我已经放到Github上了:有兴趣的朋友可以下载看看,里面也都写好了注释,如果有不明白的,可以联系我QQ:1115106468 一起交流
https://github.com/jjc123/Grab_RED_PACKET/blob/master/README.md
问题:此项目中高并发为了使用Redis?
如果使用Mysql直接保存,也可以,那如何解决数据不一致的问题?
可以使用乐观锁和悲观锁,此次项目中我使用的是Lua+Redis,看一下这三者区别:
悲观锁:
使用数据库的锁机制,并发的过程中同时只能有一个线程操作数据,其他得不到资源的线程就会被挂起,过程中会频繁得被挂起和恢复,导致cpu频繁切换现场上下文。
可以通过for update语句锁行如果是使用主键查询如where id=#{id}是锁行,如果是非主键查询要考虑是否对全表加锁。可以消除数据不一致性,但是性能会下降,因为他是阻塞性的,而且需要大量的恢复过程。
乐观锁:
不会阻塞并发,是非阻塞锁,他是具有CAS原理,但是会有ABA问题(CAS和ABA具体百度,更详细),可以通过添加版本号,但是会导致多次请求服务失败的概率大大提高,可以通过重入的方法(按时间戳或者次数限定)来提高成功率,但是会导致大量SQL被执行,容易引发性能瓶颈。
Lua+Redis:
正是因为上面集中方法的局限性,所以选择Redis去实现高并发,因为Lua具有原子性,消除了数据不一致。而且Redis是保存在内存中的,响应速度极快。注意:
为了不影响最后抢一个红包的响应时间,在最后一次操作数据的时候,开启一个新的线程,批量处理数据插入Mysql。而且最后还会删除Redis中批量处理的数据。
现在正是开始这个高并发的抢红包项目吧!
首先我们先配置数据库:
两个表:
T_RED_PACKET存红包信息
T_USER_RED_PACKET存用户抢红包信息
create table T_RED_PACKET( id int(12) not null auto_increment, user_id int(12) not null, amount decimal(16,2) not null, send_date timestamp not null, total int(12) not null, unit_amount decimal(12) not null, stock int(12) not null, version int(12) default 0 not null, note varchar(256) null, primary key clustered(id) ); create table T_USER_RED_PACKET( id int(12) not null auto_increment, red_packet_id int(12) not null, user_id int(12) not null, amount decimal(16,2) not null, grab_time timestamp not null, note varchar(256) null, primary key clustered (id) ); insert into T_RED_PACKET(user_id,amount,send_date,total,unit_amount,stock,note) values(1,200000.00,now(),20000,10.00,20000,'20万元金额,2万个小红包 每个10元');
注意:
amount :金额 要用decimal而不是double send_date :发红包时间 stock:剩余的红包数 primary key clustered (id) 是设置主键和聚集索引
题外话:Ubuntu下设置MySQL字符集为utf8
1.mysql配置文件地址
/etc/mysql/my.cnf
2.在[mysqld]在下方添加以下代码
[mysqld]
init_connect='SET collation_connection = utf8_unicode_ci'
init_connect='SET NAMES utf8'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake
3.重启mysql服务
sudo service mysql restart
4.检测字符集是否更新成utf8.
进入mysql,mysql -u root -p,输入show variables like '%character%' 查看字符集 | |
---|---|
Variable_name | Value |
character_set_client | utf8 |
character_set_connection | utf8 |
character_set_database | utf8 |
character_set_filesystem | binary |
character_set_results | utf8 |
character_set_server | utf8 |
character_set_system | utf8 |
character_sets_dir | /usr/share/mysql/charsets/ |
配置Redis:
注意:
redis的数据即使电脑关机下次打开redis的时候还会存在
进入redis的src然后./redis-server ../redis.conf &
指定配置文件启动而且是后台启动
再打开新的客户端:./redis-cli
127.0.0.1:6379> hset red_packet_2 stock 20000 (保存红包库存 也可以用来直接修改)
(integer) 0
127.0.0.1:6379> hset red_packet_2 unit_amount 10 (保存单个红包库存)
(integer) 0
题外话:
hget red_packet_2 stock hash获取该键的值 ltrim red_packet_list_2 1 0 清空list对应键的值 RPUSH red_packet_list_2 c list添加单个元素 LRANGE red_packet_list_2 0 -1 获取对应list的所有值 LLEN red_packet_list_2 获取list长度
这些外部内容已经配置好了,具体的项目我也放到了github上 有兴趣的朋友可以看看。
需要注意的是ubuntu每次开机运行项目的时候老是我的端口被占用:
查看端口:
sudo netstat -lnp | grep 8082
杀死占用端口进程:
sudo kill-9 进程号
注意:使用jdbc批量处理的时候需要:url添加rewriteBatchedStatements=true
我的测试数据:
url添加rewriteBatchedStatements=true
开始保存数据 耗时:5917插入数量:20000
url不添加rewriteBatchedStatements=true
开始保存数据 耗时:13315插入数量:20000
所以批量处理一定要加上rewriteBatchedStatements=true
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
别开心太早,Python 官方文档的翻译差远了
近几天,很多公众号发布了 Python 官方文档的消息。然而,一个特别奇怪的现象就发生了,让人啼笑皆非。 Python 文档的中文翻译工作一直是“默默无闻”,几个月前,我还吐槽过这件事《再聊聊Python中文社区的翻译》,当时我们的进度是 10.3%,远远落后于日本和法国,甚至落后于巴西! 这次所谓的中文版,当然是未完成翻译的残品。刚查了下,整体进度是 19.7%。 有的公众号在发布消息的时候,说明了这不是官宣、不是正式发布版,还指出了中文版的访问地址是隐藏入口。这都是忠于事实的。 然而,怪异的事情就在于,还有一些公众号在发布时,不知怎么误传,这个消息变成了官方正式发布、全部翻译完成、激动人心期盼已久,至于这个隐藏入口跳转问题、下载的文档为何是英文版的问题,则完全无法解释。这带来了极大的误导。 由于曾搜集过 PEP 文档的翻译,我无意中也了解到关于翻译官方文档的一些情况。有以下几个现状吧: 1、人员分散,缺乏核心。就我所见,在V站、华蟒邮件组、简书、知乎,分别有不同的人发起过翻译召集或者咨询,然而应者无几,并没有形成过足够大的核心组织。 2、官方的翻译?Python 官方在 2017 ...
- 下一篇
2019牛客提前批一血:猝不及防的java实习面经
1. 前言: 牛客网2019提前批直通实习专场 咳咳,说来惭愧,假期是划水过来的,刚好赶上牛客提前批投递.顶着头皮海投了几十家,果然简历没料是很难入大公司法眼的.在石沉大海几天后的元宵节晚上一个陌生电话call醒了我:请问你是xxx同学吗,我们是xxx公司,收到了你在牛客网上投递的简历,请问明天下午14:00有空线上视频面试吗. 心都蹦出来了,一晚上开始突击java基础.废话不多说了,直接进正题. 1. 前十分钟:进入客服发送的链接里面测试视频和语音是否通畅 2. 正式开场:第一眼面试官很和谐,没有给我压力,事实上后来也是很nice, 会根据简历上的内容引导性地问我问题,全程半小时技术面挺愉快(自认为), 不过前期框架内容因为没好好补的原因导致答非所问,不太理想,后期Java基础还算平坦. 2. 背景: 普通二本大三渣渣 3. 结果: 第一次面试,一面挂(中型互联网公司,具体公司名保密),当晚就知道结果了 建议:简历内容最好浓缩到一张A4纸内容 4. 视频面试内容: 4.1. 大致介绍一下自己巴拉巴拉介绍了一下自己的,很简洁,主要介绍了自己专业以及大二大三的历程4.2. 最近有看什么书...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS6,CentOS7官方镜像安装Oracle11G
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- CentOS8编译安装MySQL8.0.19
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Windows10,CentOS7,CentOS8安装Nodejs环境