mirror of
https://github.com/kaka111222333/kaka111222333.github.io.git
synced 2025-12-19 00:04:46 +08:00
update blog
This commit is contained in:
@@ -1,13 +1,13 @@
|
|||||||
---
|
---
|
||||||
layout: post
|
layout: post
|
||||||
title: "后台服务高并发编程-抢红包"
|
title: "后台服务高并发编程-抢红包"
|
||||||
date: 2020-1-28
|
date: 2020-1-27
|
||||||
tags: [后台开发]
|
tags: [后台开发]
|
||||||
comments: true
|
comments: true
|
||||||
author: lemonchann
|
author: lemonchann
|
||||||
---
|
---
|
||||||
|
|
||||||
今年春节响应国家号召在家宅着抵抗疫情,今年拜年也改用微信红包,春节发了很多也抢了很多微信红包,如今微信抢红包已经是非常平常的事情。
|
今年春节响应国家号召在家宅着抵抗疫情,拜年也改用微信红包,春节发了很多也抢了很多微信红包,也算支持了公司业务,想到WXG的小伙伴丰厚的年终奖我柠檬了,微信支付融入生活,抢红包已经是非常平常的事情。
|
||||||
|
|
||||||
抢红包这一简单的动作,每一次都是对红包服务后台的一次请求,在春节期间海量的服务请求下,其实是一个很典型的高并发编程模型。后台开发程序员都有一个共识:**实现一个功能很容易,难的是大量请求下提高服务性能**。
|
抢红包这一简单的动作,每一次都是对红包服务后台的一次请求,在春节期间海量的服务请求下,其实是一个很典型的高并发编程模型。后台开发程序员都有一个共识:**实现一个功能很容易,难的是大量请求下提高服务性能**。
|
||||||
|
|
||||||
@@ -47,14 +47,16 @@ author: lemonchann
|
|||||||
悲观锁把抢红包这三个步骤打包成一个整体做成互斥操作,**“在我抢了没更新数据之前你别来查余额,查到也不准确”**。也可以类比数据库的**事务**来理解。
|
悲观锁把抢红包这三个步骤打包成一个整体做成互斥操作,**“在我抢了没更新数据之前你别来查余额,查到也不准确”**。也可以类比数据库的**事务**来理解。
|
||||||
|
|
||||||
> **事务必须具备以下四个属性,简称ACID 属性:**
|
> **事务必须具备以下四个属性,简称ACID 属性:**
|
||||||
> `原子性(Atomicity)`:事务是一个完整的操作。事务的各步操作是不可分的(原子的);要么都执 行,要么都不执行
|
> `原子性(Atomicity)`:事务是一个完整的操作。事务的各步操作是不可分的(原子的);要么都执 行,要么都不执行
|
||||||
> `一致性(Consistency)`:当事务完成时,数据必须处于一致状态
|
> `一致性(Consistency)`:当事务完成时,数据必须处于一致状态
|
||||||
> `隔离性(Isolation)`:对数据进行修改的所有并发事务是彼此隔离的,这表明事务必须是独立的,它不应以任何方式依赖于或影响其他事务
|
> `隔离性(Isolation)`:对数据进行修改的所有并发事务是彼此隔离的,这表明事务必须是独立的,它不应以任何方式依赖于或影响其他事务
|
||||||
> `永久性(Durability)`:事务完成后,它对数据库的修改被永久保持,事务日志能够保持事务的永久性
|
> `永久性(Durability)`:事务完成后,它对数据库的修改被永久保持,事务日志能够保持事务的永久性
|
||||||
|
|
||||||
它假设你每次去抢红包必然有其他人也在跟你同时在抢,所以你这条线程在抢的时候要独占资源,其他线程需要阻塞挂起等待你抢完才能进来,挂起的线程就干不了其他事了,何其浪费!
|
它悲观的认为你每次去抢红包必然有其他人也同时在抢,所以你这条线程在抢的时候要独占资源,其他线程需要阻塞挂起等待你抢完才能进来抢,挂起的线程就干不了其他事了。
|
||||||
|
|
||||||
而一旦你抢完红包释放了锁,其他在等待中的线程又要抢占资源、抢到了又要恢复线程上下文。
|
> 鲁迅先生说过,浪费CPU资源就是浪费生命!
|
||||||
|
|
||||||
|
而一旦你抢完红包释放了锁,其他在等待中的线程又要抢占资源、抢到了还要恢复线程上下文。
|
||||||
|
|
||||||
CPU不断的切换线程上下文非常浪费服务器资源,严重的会导致不能及时处理后续抢红包请求,需要想办法提高效率,于是有了**乐观锁**
|
CPU不断的切换线程上下文非常浪费服务器资源,严重的会导致不能及时处理后续抢红包请求,需要想办法提高效率,于是有了**乐观锁**
|
||||||
|
|
||||||
@@ -78,11 +80,13 @@ CPU不断的切换线程上下文非常浪费服务器资源,严重的会导
|
|||||||
|
|
||||||
上面两种锁的形式都是基于对数据库的更新来做的,在大请求高并发的时候,频繁的存取数据库,尤其是乐观锁重试会对数据库产生很大的冲击,在实际生产环境要尽量减少对数据库的访问。
|
上面两种锁的形式都是基于对数据库的更新来做的,在大请求高并发的时候,频繁的存取数据库,尤其是乐观锁重试会对数据库产生很大的冲击,在实际生产环境要尽量减少对数据库的访问。
|
||||||
|
|
||||||
Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。也可以用redis实现**分布式锁**,只在第一次获取红包余额和抢完更新红包状态,与数据库交互两次,抢锁和更新操作都在内存中进行,这可比数据库操作快了几个数量级,显著改善服务并发性能。
|
Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。也可以用redis实现**分布式锁**,与数据库交互两次:第一次获取红包余额,第二次抢完更新红包状态。抢红包和中间过程更新操作都在内存中进行,这可比数据库操作快了几个数量级,显著改善服务并发性能。
|
||||||
|
|
||||||
redis分布式锁:
|
redis分布式锁:
|
||||||
|
|
||||||
> 利用Redis的SET操作在内存中保存key-value键值对,加锁就是获取这个键值对的值,解锁就是删除这个键值对。
|
> 利用Redis的SET操作在内存中保存key-value键值对,加锁就是获取这个键值对的值,解锁就是删除这个键值对。
|
||||||
|
|
||||||
分布式锁也不阻塞线程,关于这种分布式锁的实现不在这里展开说明,参考我公众号文章,[文章链接](1)
|
分布式锁也不阻塞线程,关于这种分布式锁的实现不在这里展开说明,参考我另一篇公众号文章,[redis分布式锁3种实现方式分析](1)
|
||||||
|
|
||||||
|
#### 更多原创技术干货分享在我的公众号:柠檬橙学编程 欢迎关注。
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user