业务功能--优惠券秒杀(优化)
前言 在优化之前我们完成了基于redis分布式锁的优惠券秒杀功能,但是这个功能并不完善,虽然能用但在高并发的情况下处理速度是很慢的。为什么呢? 我们回顾一遍业务流程:用户下单-判断库存-尝试加锁-添加订单-返回订单,这样我们业务流程是单线程的,这样每次用户下单都会执行这一整套流程,速度是很慢的。如何优化呢? 我们何不将添加订单的过程交给另一些线程去完成,将判断用户是否有权添加订单的同时,为另外一些用户添加订单,判断和添加过程异步执行,这样效率明显更高。 利用lua脚本保证业务的原子性 为了保证判断业务的原子性,我们使用lua脚本编写判断业务的代码。 12345678910111213141516171819202122232425262728-- 1.参数列表-- 1.1.优惠券idlocal voucherId = ARGV[1];-- 1.2.用户idlocal userId = ARGV[2];-- 1.3.订单idlocal orderId = ARGV[3];-- 2.数据key-- 2.1.库存keylocal storeKey =...
业务功能--优惠券秒杀(基础)
前言 最近学习了利用redis解决许多业务问题的方法,优惠券秒杀是其中一个综合性较强的业务问题。 全局唯一id 雪花算法:雪花算法的原理就是生成一个的 64 位比特位的 long 类型的唯一 id。id组成为符号位(1bit)、时间戳(41bits)、工作机器ID(10bits)、序列号(12bits)。雪花算法能基于时间戳生成自增的id,但正是因为基于时间戳,雪花算法有可能出现时间(时钟)回拨的问题。 组成: 1:最高 1 位是符号位,固定值 0,表示id 是正整数 41:接下来 41 位存储毫秒级时间戳,2^41/(1000606024365)=69,大概可以使用 69 年。 10:再接下 10 位存储机器码,包括 5 位 datacenterId 和 5 位 workerId。最多可以部署 2^10=1024 台机器。 12:最后 12 位存储序列号。同一毫秒时间戳时,通过这个递增的序列号来区分。即对于同一台机器而言,同一毫秒时间戳下,可以生成 2^12=4096 个不重复...
线程变量、全局异常处理器
...
Token令牌技术+Interceptor过滤器
前言 简单了解一下原理,重点知道怎么用 Token:简单来说就是一个用户在一段时间内的标识,只有登录成功才能获得Token,一般情况下只有携带Token的请求才能被Interceptor放行。 Interceptor:这是一个过滤器技术,可以将Interceptor理解为一个筛子,在请求到达控制层前进行拦截,根据具体的业务需求,可以对请求进行一定操作,比如拦截、放行等等。 Jwt快速入门 JwtToken的组成 Header 标头,一般用来标识令牌类型和所使用的签名算法。 1234{ "alg": "HS256", "typ": "JWT"} Payload 有效载荷,保存自定义信息。 123456{ "sub": "1234567890", "name": "John Doe", "admin": true, "iat":...
ArrayList底层实现
前言 第一次记录源码文章没什么经验,希望从以下几个角度能帮助你加深对java数据结构ArrayList(jdk17)的理解。 源码分析 执行流程图 面试题 源码分析 下面通过注解方式为大伙简单讲一下底层逻辑 构造方式 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable{ @java.io.Serial //这是序列号 private static final long serialVersionUID = 8683452581122892189L; //无参构造时的默认容量 ...
Mysql语句的执行逻辑
Mysql的架构 简单来说Mysql分为Server层和存储引擎层。 Server层 主要包括连接器、查询缓存、分析器、优化器、执行器等,所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图,函数等,还有一个通用的日志模块 binlog 日志模块。 连接器:身份认证和权限分析。 缓存(Mysql8.0中移除):将近期查询结果储存下来,加快查询效率。 分析器:词法分析和语法分析。 优化器:优化查询路径。 执行器:执行语句和返回结果。 (架构关系如图所示) 存储引擎层 主要负责数据的存储和读取,采用可以替换的插件式架构,支持 InnoDB、MyISAM、Memory 等多个存储引擎,其中 InnoDB 引擎有自有的日志模块 redolog 模块。现在最常用的存储引擎是 InnoDB,它从 MySQL 5.5 版本开始就被当做默认存储引擎了。 语句分析 Mysql的语句分为查询与更新(增删改)。 1select * from user where id = 1 and name =...
java多线程中wait/notify机制
wait/notify机制 wait():在获得对象锁后主动进入等待状态让出对象锁。 notify():同样时通知正在等待的其他线程,主动让出对象锁,但是,与 wait() 方法不同,执行 notify() 后,不会立即释放对象锁,而需要执行完 synchronize 的代码块或方法才会释放锁,所以接收通知的线程也不会立即获得锁,也需要等待执行 notify() 方法的线程释放锁后再获取锁。 应用 问题:写两个线程打印1-100,一个线程打印奇数,一个线程打印偶数 1234567891011121314151617181920212223242526272829303132333435363738394041424344public class Printer { //打印的数量 private final int max; //定义对象锁 private final Object lock = new Object(); private int count = 1; public void printEven(){...
watch监听函数
属性监听 源对象是一个ref的属性值及其衍生式 当监听的属性值发生变化时会触发监听函数执行响应的操作 1234567891011121314151617181920const x = ref(0)const y = ref(0)// 单个 refwatch(x, (newX) => { console.log(`x is ${newX}`)})// getter 函数watch( () => x.value + y.value, (sum) => { console.log(`sum of x + y is: ${sum}`) })// 多个来源组成的数组watch([x, () => y.value], ([newX, newY]) => { console.log(`x is ${newX} and y is...
VueRouter
前言 VueRouter(以下称为route)是Vue提供的路由组件,主要由3方面构成: router-link:请求链接组件,浏览器会解析成a标签 router-view:动态视图组件,用来渲染展示与路由路径对应的组件 路由表router如下图 下面我们从三个角度了解route router-link 该标签通常添加在button,menu等标签外,表示点击该组件,启动路由跳到下一个页面,例如 12345<router-link to=""> //添加下一跳的地址 <el-menu-item index="/index"> <el-icon><Promotion /></el-icon> 首页 </el-menu-item></router-link> element的menu组件中集成了该功能上述代码等价于 12345<el-menu router> <el-menu-item...
二级域名及vercel绑定
前言 这里默认大家已经拥有自己的域名,创建二级域名主要目的是: 在你主域名已经绑定的前提下,不想重新再买一个域名进行别的网站的绑定 创建二级域名 打开你购买域名的官网(这里以阿里云为例) 搜索域名控制台,进入域名管理 进入域名列表,点击解析 点击添加域名,填入域名的名字前缀不能是大写 点击TXT授权校验,保存TXT记录 进入主域名的解析设置,这里一定得是主域名! 添加记录,将记录填入,记录类型要选择TXT 返回进行TXT检测 将域名解析至vercel 这里假设你已经在vercel上面创建好项目,准备绑定域名 进入项目,点击Domains 点击add domains,输入你的域名并保存 你会看到Invalid...