电商网站的制作,网络营销推广方法包括有哪些?,会展行业门户网站建设,2023新闻头条最新消息今天大技术使用Redisson使用Redisson在秒杀服务中有两个作用#xff0c;一个是作为分布式锁来确保多个秒杀服务同时在线时同时上架秒杀商品#xff0c;只允许有一个秒杀服务成功上架秒杀商品#xff0c;其他的上架失败。第二个作用是作为分布式信号量#xff0c;每个秒杀商品在…大技术使用Redisson使用Redisson在秒杀服务中有两个作用一个是作为分布式锁来确保多个秒杀服务同时在线时同时上架秒杀商品只允许有一个秒杀服务成功上架秒杀商品其他的上架失败。第二个作用是作为分布式信号量每个秒杀商品在存到Redis中时都设置一个分布式信号量把每个秒杀商品的数量作为信号量的值这是为了防止秒杀的时候出现穿库的情况就是只设置了3个秒杀数量结果秒杀结束后秒杀数量是5个这就亏本了1、导入依赖!-- 以后使用redisson作为分布式锁分布式对象等功能框架 --
dependencygroupIdorg.redisson/groupIdartifactIdredisson/artifactIdversion3.16.8/version
/dependency2、设置Redission配置类package com.saodai.saodaimall.saodaimall.seckill.config;import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.io.IOException;/**
* redission分布式锁配置类
*/
Configuration
public class MyRedissonConfig {/*** 所有对Redisson的使用都是通过RedissonClient* return* throws IOException*/Bean(destroyMethodshutdown)public RedissonClient redisson() throws IOException {//1、创建配置Config config new Config();//配置虚拟机的地址config.useSingleServer().setAddress(redis://192.168.241.128:6379);//2、根据Config创建出RedissonClient实例(单个实例)//Redis url should start with redis:// or rediss://RedissonClient redissonClient Redisson.create(config);return redissonClient;}
}3、Redission作为分布式锁package com.saodai.saodaimall.saodaimall.seckill.scheduled;
import com.saodai.saodaimall.saodaimall.seckill.service.SeckillService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;/**
* 秒杀商品定时上架
* 每天晚上3点上架最近三天需要三天秒杀的商品
* 当天00:00:00 - 23:59:59
* 明天00:00:00 - 23:59:59
* 后天00:00:00 - 23:59:59
*/Slf4j
Service
public class SeckillScheduled Autowiredprivate SeckillService seckillService;Autowiredprivate RedissonClient redissonClient;//秒杀商品上架功能的锁private final String upload_lock seckill:upload:lock;/**保证幂等性问题**/// Scheduled(cron */5 * * * * ? ) //秒 分 时 日 月 周Scheduled(cron 0 0 1/1 * * ? ) public void uploadSeckillSkuLatest3Days() {//1、重复上架无需处理log.info(上架秒杀的商品...);//分布式锁RLock lock redissonClient.getLock(upload_lock);try {//加锁指定锁定时间为10s)lock.lock(10, TimeUnit.SECONDS);seckillService.uploadSeckillSkuLatest3Days();} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}
}使用Redisson作为分布式锁是为了确保多个秒杀服务同时在线时同时上架秒杀商品只允许有一个秒杀服务成功上架秒杀商品其他的上架失败4、Redission实现分布式信号量作为分布式信号量每个秒杀商品在存到Redis中时都设置一个分布式信号量把每个秒杀商品的数量作为信号量的值这是为了防止秒杀的时候出现穿库的情况就是只设置了3个秒杀数量结果秒杀结束后秒杀数量是5个这就亏本了/*** 封装秒杀活动的关联商品信息到缓存里* param sessions 秒杀活动信息*/private void saveSessionSkuInfo(ListSeckillSessionWithSkusVo sessions) {if (sessions!null){sessions.stream().forEach(session - {//准备hash操作绑定hash值seckill:skusBoundHashOperationsString, Object, Object operations redisTemplate.boundHashOps(SECKILL_CHARE_PREFIX);//遍历秒杀活动中的商品项seckillSkuVo表示的就是每个遍历的商品项session.getRelationSkus().stream().forEach(seckillSkuVo - {//生成随机码String token UUID.randomUUID().toString().replace(-, );//查看redis中有没有这个key 秒杀场次id_秒杀商品idString redisKey seckillSkuVo.getPromotionSessionId().toString() - seckillSkuVo.getSkuId().toString();if (!operations.hasKey(redisKey)) {//缓存我们商品信息SeckillSkuRedisTo是存入缓存中的对象SeckillSkuRedisTo redisTo new SeckillSkuRedisTo();Long skuId seckillSkuVo.getSkuId();//1、先查询sku的基本信息调用远程服务R info productFeignService.getSkuInfo(skuId);if (info.getCode() 0) {SkuInfoVo skuInfo info.getData( skuInfo,new TypeReferenceSkuInfoVo(){});redisTo.setSkuInfo(skuInfo);}//2、sku的秒杀信息BeanUtils.copyProperties(seckillSkuVo,redisTo);//3、设置当前商品的秒杀时间信息redisTo.setStartTime(session.getStartTime().getTime());redisTo.setEndTime(session.getEndTime().getTime());//4、设置商品的随机码防止恶意攻击redisTo.setRandomCode(token);//序列化json格式存入Redis中String seckillValue JSON.toJSONString(redisTo);//秒杀活动的商品项的详细信息存入redis/**格式是key:4_47 value:SeckillSkuRedisTo对象的String类型**/operations.put(seckillSkuVo.getPromotionSessionId().toString() - seckillSkuVo.getSkuId().toString(),seckillValue);//如果当前这个场次的商品库存信息已经上架就不需要上架/**5、使用库存作为分布式Redisson信号量限流**///把每个秒杀商品的总数量作为信号量存入redis缓存信号量标识seckill:stock:随机相当于keyRSemaphore semaphore redissonClient.getSemaphore(SKU_STOCK_SEMAPHORE token);/**库存的格式key:seckill:stock:5d1df46618d34f9f9808f25cda60ba01 value:秒杀商品的总数量 其中5d1df46618d34f9f9808f25cda60ba01是随机码**/semaphore.trySetPermits(seckillSkuVo.getSeckillCount());}});});}else {log.error(没有秒杀活动);}}Autowired
private RedissonClient redissonClient;/**5、使用库存作为分布式Redisson信号量限流**/
//获取分布式信号量信号量名称为seckill:stock:随机码
RSemaphore semaphore redissonClient.getSemaphore(SKU_STOCK_SEMAPHORE token);
// 秒杀商品的库存数量作为信号量的值允许同时seckillSkuVo.getSeckillCount()个用户获取到信号量
semaphore.trySetPermits(seckillSkuVo.getSeckillCount());实现uploadSeckillSkuLatest3Days方法中saveSessionSkuInfo封装秒杀活动的关联商品信息到缓存里每一个Redis缓存中具体sku信息用的是HashMap结构通过HashMap结构把每个秒杀商品的详细信息以下面的格式存到Redis中然后通过Redisson实现分布式信号量来把秒杀商品的库存总数量作为信号量存入redis缓存每一个Redis缓存中具体sku信息的格式如下hash值是seckill:skus key: 4_47 value: SeckillSkuRedisTo对象其中key的4表示秒杀的场次id47表示秒杀商品的skuId由于用的是hashMap结构其中hash值是seckill:skusRedission实现分布式信号量设置时就会把信号量以key-value的格式存到reids缓存中Redis缓存中信号量信息的格式如下key: seckill:stock:随机码 value:每个秒杀商品的总数量其中key的seckill:stock是固定前缀随机码就是随机成功的uuid值把每个秒杀商品的总数量作为信号量的值准备hash操作绑定seckill:skus关键字的hash遍历封装存入redis的秒杀活动的秒杀商品项生成随机码封装SeckillSkuRedisTo对象并序列化后存入redis缓存远程调用product商品服务使用Redission实现分布式信号量来把秒杀商品的库存总数量作为信号量存入redis缓存限流秒杀活动的商品项的详细信息存入redis缓存设置商品的随机码防止恶意攻击设置当前商品的秒杀时间信息封装秒杀活动中秒杀商品项信息4、秒杀时具体实现Autowired
private RedissonClient redissonClient;//分布式锁
RSemaphore semaphore redissonClient.getSemaphore(key);
//尝试快速拿到信号量100毫秒没有用拿到就返回false
//在指定的时间内尝试地获取1个许可如果获取不到就返回false
boolean semaphoreCount semaphore.tryAcquire(num, 100, TimeUnit.MILLISECONDS);