搶紅包案例分析以及程式碼實現
概述
電商的秒殺、搶購,春運搶票,微信QQ搶紅包,從技術的角度來說,這對於Web 系統是一個很大的考驗. 高併發場景下,系統的優化和穩定是至關重要的.
網際網路的開發包括 Java 後臺、 NoSQL、資料庫、限流、CDN、負載均衡等內容, 目前並沒有權威性的技術和設計,有的只是長期經驗的總結,但是使用這些經驗可以有效優化系統,提高系統的併發能力.
我們接下來的幾篇博文主要討論 Java 後臺、 NoSQL ( Redis )和資料庫部分技術.
搶紅包案例
主要分以下幾大部分:
環境搭建
模擬超量傳送的場景-DataBase(MySql5.7)
悲觀鎖的實現版本-DataBase(MySql5.7)
樂觀鎖的實現版本-DataBase(MySql5.7)
Redis實現搶紅包
案例關注點
模擬 20 萬元的紅包,共分為 2 萬個可搶的小紅包,有 3 萬人同時搶奪的場景 ,模擬出現超發和如何保證資料一致性的問題。
在高併發的場景下,除了資料的一致性外,還要關注效能的問題 , 因為一般而言 , 時間太長使用者體驗就會很差,所以要測試資料一致性和系統的效能 。
工程結構
庫表設計
MySql5.7
/*==============================================================*/
/* Table: 紅包表 */
/*==============================================================*/
create table T_RED_PACKET
(
id int(12) not null auto_increment COMMENT '紅包編號',
user_id int(12) not null COMMENT '發紅包的使用者id',
amount decimal(16,2) not null COMMENT '紅包金額',
send_date timestamp not null DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '發紅包日期',
total int(12) not null COMMENT '紅包總數',
unit_amount decimal(12) not null COMMENT '單個紅包的金額',
stock int(12) not null COMMENT '紅包剩餘個數',
version int(12) default 0 not null COMMENT '版本(為後續擴充套件用)',
note varchar(256) null COMMENT '備註',,
primary key clustered (id)
);
紅包表表示存放紅包的是一個大紅包的資訊,它會分為若干個小紅包,為了業務簡單,假設每一個紅包是等額的。而對於搶紅包而言,就是從大紅包中搶奪那些剩餘的小紅包,剩餘紅包數會被記錄在紅包表中。 兩個表有外來鍵關聯 T_RED_PACKET.id = T_USER_RED_PACKET.red_packet_id
/*==============================================================*/
/* Table: 使用者搶紅包表 */
/*==============================================================*/
create table T_USER_RED_PACKET
(
id int(12) not null auto_increment COMMENT '使用者搶到的紅包id',
red_packet_id int(12) not null COMMENT '紅包id',
user_id int(12) not null COMMENT '搶紅包使用者的id',
amount decimal(16,2) not null COMMENT '搶到的紅包金額',
grab_time timestamp not null DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '搶紅包時間',
note varchar(256) null COMMENT '備註',
primary key clustered (id)
);
/**
* 插入一個20萬元金額,2萬個小紅包,每個10元的紅包資料
*/
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元');
commit;
這樣就建好了兩個表,並且將一個 20 萬元金額,2 萬個小紅包,每個 10 元的紅包資訊插入到了紅包表中,用作模擬資料。
Domain
有了這兩個表,我們就可以為這兩個表建兩個 POJO 了,讓這兩個表和 POJO 對應起來,這兩個 POJO 為 RedPacket 和 UserRedPacket,實現類序列化介面。
紅包資訊
package com.artisan.redpacket.pojo;
import java.io.Serializable;
import java.sql.Timestamp;
/**
*
*
* @ClassName: RedPacket
*
* @Description: 紅包表對應的實體類,可序列化
*
* @author: Mr.Yang
*
* @date: 2018年10月8日 下午3:42:58
*/
public class RedPacket implements Serializable {
private static final long serialVersionUID = 9036484563091364939L;
// 紅包編號
private Long id;
// 發紅包的使用者id
private Long userId;
// 紅包金額
private Double amount;
// 發紅包日期
private Timestamp sendDate;
// 紅包總數
private Integer total;
// 單個紅包的金額
private Double unitAmount;
// 紅包剩餘個數
private Integer stock;
// 版本(為後續擴充套件用)
private Integer version;
// 備註
private String note;
// 省略set/get
}
搶紅包資訊
package com.artisan.redpacket.pojo;
import java.io.Serializable;
import java.sql.Timestamp;
/**
*
*
* @ClassName: UserRedPacket
*
* @Description: 使用者搶紅包表
*
* @author: Mr.Yang
*
* @date: 2018年10月8日 下午3:47:40
*/
public class UserRedPacket implements Serializable {
private static final long serialVersionUID = 7049215937937620886L;
// 使用者紅包id
private Long id;
// 紅包id
private Long redPacketId;
// 搶紅包的使用者的id
private Long userId;
// 搶紅包金額
private Double amount;
// 搶紅包時間
private Timestamp grabTime;
// 備註
private String note;
// 省略set/get
}
Dao層實現
MyBatis Dao介面類及對應的Mapper檔案
使用 MyBatis 開發,先來完成大紅包資訊的查詢先來定義一個 DAO 物件
package com.artisan.redpacket.dao;
import org.springframework.stereotype.Repository;
import com.artisan.redpacket.pojo.RedPacket;
@Repository
public interface RedPacketDao {
/**
* 獲取紅包資訊.
* @param id --紅包id
* @return 紅包具體資訊
*/
public RedPacket getRedPacket(Long id);
/**
* 扣減搶紅包數.
* @param id -- 紅包id
* @return 更新記錄條數
*/
public int decreaseRedPacket(Long id);
}
其中的兩個方法 , 一個是查詢紅包,另一個是扣減紅包庫存。
搶紅包的邏輯是,先查詢紅包的資訊,看其是否擁有存量可以扣減。如果有存量,那麼可以扣減它,否則就不扣減。
接著將對應的Mapper對映檔案編寫一下
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.artisan.redpacket.dao.RedPacketDao">
<!-- 查詢紅包具體資訊 -->
<select id="getRedPacket" parameterType="long"
resultType="com.artisan.redpacket.pojo.RedPacket">
select id, user_id as userId, amount, send_date as
sendDate, total,
unit_amount as unitAmount, stock, version, note from
T_RED_PACKET
where id = #{id}
</select>
<!-- 扣減搶紅包庫存 -->
<update id="decreaseRedPacket">
update T_RED_PACKET set stock = stock - 1 where id =
#{id}
</update>
</mapper>
這裡getRedPacket並沒有加鎖這類動作,目的是為了演示超發紅包的情況。
然後是搶紅包的設計了 ,先來定義插入搶紅包的 DAO ,緊接著是Mapper對映檔案
package com.artisan.redpacket.dao;
import org.springframework.stereotype.Repository;
import com.artisan.redpacket.pojo.UserRedPacket;
@Repository
public interface UserRedPacketDao {
/**
* 插入搶紅包資訊.
* @param userRedPacket ——搶紅包資訊
* @return 影響記錄數.
*/
public int grapRedPacket(UserRedPacket userRedPacket);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.artisan.redpacket.dao.UserRedPacketDao">
<!-- 插入搶紅包資訊 -->
<insert id="grapRedPacket" useGeneratedKeys="true"
keyProperty="id" parameterType="com.artisan.redpacket.pojo.UserRedPacket">
insert into T_USER_RED_PACKET( red_packet_id, user_id, amount, grab_time, note)
values (#{redPacketId}, #{userId}, #{amount}, now(), #{note})
</insert>
</mapper>
這裡使用了 useGeneratedKeys 和 keyPrope町,這就意味著會返回資料庫生成的主鍵資訊,這樣就可以拿到插入記錄的主鍵了 , 關於 DAO 層就基本完成了。別忘了單元測試!!!
Service層實現
接下來定義兩個 Service 層介面,分別是 UserRedPacketService和RedPacketService
package com.artisan.redpacket.service;
import com.artisan.redpacket.pojo.RedPacket;
public interface RedPacketService {
/**
* 獲取紅包
* @param id ——編號
* @return 紅包資訊
*/
相關推薦
搶紅包案例分析以及程式碼實現
概述電商的秒殺、搶購,春運搶票,微信QQ搶紅包,從技術的角度來說,這對於Web 系統是一個很大的
搶紅包案例分析以及程式碼實現(三)
前文回顧接下來我們使用樂觀鎖的方式來修復紅包超發的bug樂觀鎖樂觀鎖是一種不會阻塞其他執行緒併發
搶紅包案例分析以及程式碼實現(三) 侵立刪
轉自:https://mp.weixin.qq.com/s/Pp-nCYrzXXXfLcFFS_ttWg
前文回顧
搶紅包案例分析以及程式碼實現(一)
搶紅包案例分析以及程式碼實現(二)
接下來我們使用樂觀鎖的方式來修復紅包超發的bug
搶紅包案例分析以及程式碼實現(二) 侵立刪
轉自:https://mp.weixin.qq.com/s/F1U1nUK2KF5R0nxT8lmfBg
概述
上一篇文章中使用ssm+mysql實現,存在併發超發問題,這裡我們使用悲觀鎖的方式來解決這個邏輯錯誤,並驗證資料一致性和效能狀況。
超發問題分析
針對
搶紅包案例分析以及程式碼實現(一) 侵立刪
轉自:https://mp.weixin.qq.com/s/d3HyAtWua38TSpelF-v6nQ
概述
電商的秒殺、搶購,春運搶票,微信QQ搶紅包,從技術的角度來說,這對於Web 系統是一個很大的考驗. 高併發場景下,系統的優化和穩定是至關重要的.
網際網路的開
搶紅包案例分析
概述
電商的秒殺、搶購,春運搶票,微信QQ搶紅包,從技術的角度來說,這對於Web 系統是一個很大的考驗. 高併發場景下,系統的優化和穩定是至關重要的.
網際網路的開發包括 Java 後臺、 NoSQL、資料庫、限流、CDN、負載均衡等內容, 目前並沒有權威性的技術和設計,
使用者註冊登入案例分析以及簡單實現
使用者註冊登入案例
功能分析
本案例主要是使用者註冊和登入功能。根據使用者輸入的使用者名稱和密碼判斷使用者能否登入進去。使用者的資訊儲存在userInformation.txt檔案中。
分析順序如下:
1. 分包和建類
2. 實現功能
分
高併發-【搶紅包案例】之四:使用Redis+Lua指令碼實現搶紅包並非同步持久化到資料庫
文章目錄導讀概述
導讀
概述
上面三篇博文是使用的MySql資料庫來作為資料的載體資料最終會將資料儲存到磁碟中,而Redis使用的是記憶體,記憶體的速度比磁碟速度肯定要快很多.
對於使用 Redis實現搶紅包,首先需要知道的是Redis的功能不如資料庫
PHP 控制反轉與依賴注入詳細分析與程式碼實現
PHP有很多的設計模式,比如單例模式,訂閱模式,策略模式,工廠模式,觀察者模式,這些設計模式其實無非都是為了讓程式簡化,容易維護,模組間解耦。現在我們來講講PHP的另外一種設計模式,控制反轉/依賴注入,這兩者其實是同一個概念,只是凶不同的角度去解釋的而已。
依賴注入:是從需要實現的業務邏輯上面去
Hash表分析以及Java實現
這篇部落格主要探討Hash表中的一些原理/概念,及根據這些原理/概念,自己設計一個用來存放/查詢資料的Hash表,並且與JDK中的HashMap類進行比較。
我們分一下七個步驟來進行。
一。 Hash表概念
二 . &n
氣泡排序,選擇排序、二分法查詢圖示以及程式碼實現
氣泡排序
請看下面的這個栗子:
需要排序的陣列arr = {99,88,77,55,66,44};
具體排序細節各位客官請看圖:
程式碼實現:
public class BubbleSort {
public static void main(String[] ar
高併發搶紅包案列以及使用鎖,版本號,redis快取解決,專案可執行,詳細註釋(三)
1redis搶紅包實現
在redis中首先設定紅包的數量和金額,使用者搶到紅包之後,在redis中計算紅包數量-1,儲存使用者的資訊,直到紅包被搶完。再將使用者資訊批量儲存到資料庫中。由於redis的計算是原子性的,所以不會出現資料錯誤,可以理解成atomic系列
具體的環境搭建請檢視
高併發搶紅包案列以及使用鎖,版本號,redis快取解決,專案可執行,詳細註釋(二)
1 悲觀鎖
<!-- 查詢紅包具體資訊 --> <select id="getRedPacketForUpdate" parameterType="int" resultType="test814RedPacket.pojo.Red
高併發搶紅包案列以及使用鎖,版本號,redis快取解決,專案可執行,詳細註釋(一)
1.問題描述
簡單來說就是當大量資料來訪問資料庫的時候,可能導致資料不一致。如下:
發一個2000元的大紅包,總共2000個小紅包,每個一元,但是有30000個人去搶,紅包少一個就減一,插入搶紅包使用者資訊,結果看圖:
stock表示餘留的紅包數,結果是負一
高併發-「搶紅包案例」之一:SSM環境搭建及復現紅包超發問題
文章目錄
概述
搶紅包案例
案例關注點
工程結構
庫表設計
Domain
Dao層實現
Service層實現
使用全註解搭建SSM 開發環境
Controller層
View層
執行測試
超量傳送的BUG驗證
超發問題解決思路
概述
電商的秒殺、搶購,春運搶票,微信QQ搶
大資料MR模型以及程式碼實現
資料: [customers.txt]
1,tom,12
2,tom,13
3,tom,14
4,tom,15
&
機器學習系列文章:Apriori關聯規則分析演算法原理分析與程式碼實現
1.關聯規則淺談
關聯規則(Association Rules)是反映一個事物與其他事物之間的相互依存性和關聯性,如果兩個或多個事物之間存在一定的關聯關係,那麼,其中一個事物就能通過其他事物預測到。關聯規則是資料探勘的一個重要技術,用於從大量資料中挖掘出有價值的資料
電商產品評論的資料情感分析python程式碼實現
步驟1:從爬取的資料中提取對應的評論資訊
#-*- coding: utf-8 -*-
import pandas as pd
inputfile = '.../huizong.csv' #評論彙總檔案
outputfile = '.../meidi_jd.t
高併發-【搶紅包案例】之一:SSM環境搭建及復現紅包超發問題
概述
電商的秒殺、搶購,春運搶票,微信QQ搶紅包,從技術的角度來說,這對於Web 系統是一個很大的考驗. 高併發場景下,系統的優化和穩定是至關重要的.
網際網路的開發包括 Java 後臺、 NoSQL、資料庫、限流、CDN、負載均衡等內容, 目前並沒有權威性
ML-01-線性迴歸以及程式碼實現
一、表示方式以及數學符號解釋
準備工作:
訓練資料集
attr1
attr2
value
1.3
1.9
3.2
1.1
1.5
2.5
1.5
2.3
3.9
1.7
2.7
4.6