当前位置: 首页 > news >正文

手机网站推广怎么做wordpress怎么做404页面跳转

手机网站推广怎么做,wordpress怎么做404页面跳转,自建网站的劣势,图片制作方法用户锁的作用 秒杀、支付等场景,用户频繁点击按钮,会造成同一时刻调用多次接口【第一次请求接口还没响应数据,用户又进行了第二次请求】,造成数据异常和网络拥堵。添加用户锁,在用户第二次点击按钮时,拦击用…

用户锁的作用

秒杀、支付等场景,用户频繁点击按钮,会造成同一时刻调用多次接口【第一次请求接口还没响应数据,用户又进行了第二次请求】,造成数据异常和网络拥堵。添加用户锁,在用户第二次点击按钮时,拦击用户请求。限制用户在操作未完成前不能再进行下一次相同操作

1.主要组成

Dul:用户锁注解,自定义锁注解,然后给需要加锁的方法加上此注解
DistributedUserLock:锁接口
RedisDistributedUserLock:分布式锁实现类
DistributedUserLockAspect:切面类【核心】

自定义锁注解,利用切面给所有加注解的方法加分布式锁防止用户重复点击按钮。

2.关键代码分析:

DistributedUserLockAspect:用redis的setIfAbsent 进行加锁,防止死锁,10秒后自动释放锁。

@Around("@annotation(com.nascent.ecrp.mall.common.distribute.Dul)")public Object distributedLock(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {if (request == null) {return proceedingJoinPoint.proceed();}String token = request.getHeader("token");if (StringUtils.isBlank(token)) {return proceedingJoinPoint.proceed();}MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();Method method = methodSignature.getMethod();String lockKey = "USER_LOCK_KEY_OF_" + method.getDeclaringClass().getName() + "." + method.getName();Dul distributedKey = method.getAnnotation(Dul.class);int lockTime = distributedKey.lockTimeSeconds();TimeUnit timeUnit = distributedKey.timeUnit();// USER_LOCK_KEY_OF_+类名+方法名+token作为redis的keylockKey += "_" + token;try {// 加锁成功,说明请求已经处理完,可以继续访问if (distributedUserLock.lock(lockKey, lockTime, timeUnit)) {return proceedingJoinPoint.proceed();} else {// 加锁失败,说明第一次的请求还没处理完throw new WmDefinitelyRuntimeException("操作过于频繁,请稍后再试");}} catch (InterruptedException e) {Thread.currentThread().interrupt();throw new WmDefinitelyRuntimeException(e);} finally {distributedUserLock.unlock(lockKey);}}

3.全部代码

Dcl

/*** 分布式用户锁* 限制用户在操作未完成前不能再进行下一次相同操作**/
@Documented
@Inherited
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Dul {/*** 锁定的时间防止死锁,单位秒,默认10** @return 同步锁定的时间*/int lockTimeSeconds() default 10;/*** 时间单位** @return 时间单位*/TimeUnit timeUnit() default TimeUnit.SECONDS;
}

DistributedUserLock

默认10s后自动释放锁

/*** 分布式用户锁*/
public interface DistributedUserLock extends Lock {/*** 锁住用户操作** @param lockKey       锁* @param expireSeconds 锁有效时间* @param timeUnit      时间单位* @return 是否获取成功* @throws InterruptedException 中断异常*/boolean lock(String lockKey, int expireSeconds, TimeUnit timeUnit) throws InterruptedException;/*** 释放分布式锁** @param lockKey   锁*/void unlock(String lockKey);
}

RedisDistributedUserLock

/*** redis 分布式锁*/
@SuppressWarnings({"UnusedReturnValue", "NullableProblems", "unused", "RedundantThrows"})
@Component
public class RedisDistributedUserLock implements DistributedUserLock {/*** 锁存在*/private final static Long TYPE_LOCK = 1L;/*** 缓存*/@Autowiredprivate RedisTemplate<String, Object> redisTemplate;@Overridepublic void lock() {throw new UnsupportedOperationException();}@Overridepublic void lockInterruptibly() throws InterruptedException {throw new InterruptedException();}@Overridepublic boolean tryLock() {throw new UnsupportedOperationException();}/*** 锁* @param lockKey       锁* @param expireSeconds 锁有效时间* @param timeUnit      时间单位* @return true 可以进行操作,false 锁已存在* @throws InterruptedException*/@Overridepublic boolean lock(String lockKey, int expireSeconds, TimeUnit timeUnit) throws InterruptedException {/* Object obj = redisTemplate.opsForValue().get(lockKey);if (obj != null) {return false;}redisTemplate.opsForValue().set(lockKey, TYPE_LOCK, expireSeconds, timeUnit);return true;*/// 加锁,如果key不存在,进行加锁,如果key已经存在返回加锁失败return  redisTemplate.opsForValue().setIfAbsent(lockKey, TYPE_LOCK, expireSeconds, timeUnit);}@Overridepublic boolean tryLock(long time, TimeUnit unit) throws InterruptedException {throw new UnsupportedOperationException();}/*** 解锁* @param lockKey   锁*/@Overridepublic void unlock(String lockKey) {redisTemplate.delete(lockKey);}@Overridepublic void unlock() {throw new UnsupportedOperationException();}@SuppressWarnings("NullableProblems")@Overridepublic Condition newCondition() {throw new UnsupportedOperationException();}}

DistributedUserLockAspect

/*** 用户操作锁Aspect*/
@Aspect
@Component
@Order(-1)
public class DistributedUserLockAspect {/*** 分布式锁*/@Autowiredprivate DistributedUserLock distributedUserLock;@Autowiredprivate HttpServletRequest request;/*** @param proceedingJoinPoint proceedingJoinPoint*/@Around("@annotation(com.nascent.ecrp.mall.common.distribute.Dul)")public Object distributedLock(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {if (request == null) {return proceedingJoinPoint.proceed();}String token = request.getHeader("token");if (StringUtils.isBlank(token)) {return proceedingJoinPoint.proceed();}MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();Method method = methodSignature.getMethod();String lockKey = "USER_LOCK_KEY_OF_" + method.getDeclaringClass().getName() + "." + method.getName();Dul distributedKey = method.getAnnotation(Dul.class);int lockTime = distributedKey.lockTimeSeconds();TimeUnit timeUnit = distributedKey.timeUnit();// USER_LOCK_KEY_OF_+类名+方法名+token作为redis的keylockKey += "_" + token;try {// 加锁成功,说明请求已经处理完,可以继续访问if (distributedUserLock.lock(lockKey, lockTime, timeUnit)) {return proceedingJoinPoint.proceed();} else {// 加锁失败,说明第一次的请求还没处理完throw new WmDefinitelyRuntimeException("操作过于频繁,请稍后再试");}} catch (InterruptedException e) {Thread.currentThread().interrupt();throw new WmDefinitelyRuntimeException(e);} finally {distributedUserLock.unlock(lockKey);}}
}

秒杀接口添加锁注解

秒杀活动开始,用户点击按钮,进行上锁,lockTimeSeconds【默认10秒】内不能再点击,lockTimeSeconds秒后自动释放锁。

/*** 参与秒杀** @return CommonResult*/@Dul@Dcl(keyIndex = 0)@Transactional(rollbackFor = Exception.class)@Overridepublic CommonResult doSeckill(WmMarketingSeckillPostVo seckillPostVo) {String checkResult = checkGoodsSeckillInfo(seckillPostVo.getSeckillOrderInfoList(),seckillPostVo.getShopId());if(checkResult.equals(ErrorCode.SECKILL_ACTIVITY_UPDATE.getCode())){return new CommonResult().setFailed().setCode(ErrorCode.SECKILL_ACTIVITY_UPDATE.getCode()).setMsg("活动状态已变更,请重新下单");}List<JSONObject> seckillOrderList = new ArrayList<>();//下单校验List<SecKillBuyInfo> buyInfos = new ArrayList<>();SeckillOrderCheckRequest seckillOrderCheckRequest = new SeckillOrderCheckRequest();seckillOrderCheckRequest.setCustomerId(getCustomerId());seckillOrderCheckRequest.setShopId(seckillPostVo.getShopId());for(WmMarketingSeckillPostVo.SeckillOrderInfo seckillOrderInfo : seckillPostVo.getSeckillOrderInfoList()){SecKillBuyInfo secKillBuyInfo = new SecKillBuyInfo();secKillBuyInfo.setActivityId(seckillOrderInfo.getMarketingGuid());List<SeckillBuyGoodsInfo> seckillBuyGoodsInfos = new ArrayList<>();SeckillBuyGoodsInfo seckillBuyGoodsInfo = new SeckillBuyGoodsInfo();seckillBuyGoodsInfo.setGoodsId(seckillOrderInfo.getGoodsId());seckillBuyGoodsInfo.setGoodsLibId(seckillOrderInfo.getGoodsLibId());List<SeckillBuySkuInfo> seckillBuySkuInfos = new ArrayList<>();SeckillBuySkuInfo seckillBuySkuInfo = new SeckillBuySkuInfo();seckillBuySkuInfo.setGoodsSkuId(StringUtil.isBlank(seckillOrderInfo.getGoodsSkuId()) ? "0" : seckillOrderInfo.getGoodsSkuId());seckillBuySkuInfo.setBuyCount(seckillOrderInfo.getGoodsNum());seckillBuySkuInfos.add(seckillBuySkuInfo);seckillBuyGoodsInfo.setSkuInfos(seckillBuySkuInfos);seckillBuyGoodsInfos.add(seckillBuyGoodsInfo);secKillBuyInfo.setGoodsList(seckillBuyGoodsInfos);buyInfos.add(secKillBuyInfo);}seckillOrderCheckRequest.setBuyInfos(buyInfos);seckillOrderCheckRequest.setGroupId(getGroupId());SeckillOrderCheckResponse seckillOrderCheckResponse = OpenPlatformClient.exec(getGroupId(), seckillOrderCheckRequest);log.info("【调用中台下单校验接口响应结果】seckillOrderCheckResponse="+JSON.toJSONString(seckillOrderCheckResponse));if(!seckillOrderCheckResponse.success&&seckillOrderCheckResponse.getCode().equals("50402")){log.info("【秒杀下单已达限购上限】");return new CommonResult().setFailed().setCode("50402").setMsg("已达限购上限");}if(!seckillOrderCheckResponse.success&&seckillOrderCheckResponse.getCode().equals("50404")){log.info("【秒杀剩余库存不足】");return new CommonResult().setFailed().setCode("50404").setMsg("剩余库存不足");}if(!seckillOrderCheckResponse.success&&seckillOrderCheckResponse.getCode().equals("50005")){log.info("【秒杀活动已结束】");return new CommonResult().setFailed().setCode("50005").setMsg("活动已结束");}AssertUtil.assertTrue(seckillOrderCheckResponse.getSuccess()&&seckillOrderCheckResponse.getResult().isSeckillSuccess(),"秒杀活动校验失败");Map<String,ActivitySeckillCheckInfo> activityCheckInfoMap = new HashMap<>();for(ActivitySeckillCheckInfo activitySeckillCheckInfo : seckillOrderCheckResponse.getResult().getCheckInfos()){Long goodsId = activitySeckillCheckInfo.getItemInfos().get(0).getGoodsId();Long goodsLibId = activitySeckillCheckInfo.getItemInfos().get(0).getGoodsLibId();String skuId = activitySeckillCheckInfo.getItemInfos().get(0).getSkuInfos().get(0).getSkuId();//无sku也会返回到sku级,skuid为0activityCheckInfoMap.put(activitySeckillCheckInfo.getActivityId()+"_"+goodsLibId+"_"+goodsId+"_"+skuId,activitySeckillCheckInfo);}Map<String, ItemDetailsInfo> itemInfoMap = getGoodsInfos(seckillPostVo.getShopId(),seckillPostVo.getSeckillOrderInfoList());Integer expireMinute = seckillOrderCheckResponse.getResult().getExpireMinute();for(WmMarketingSeckillPostVo.SeckillOrderInfo seckillOrderInfo :seckillPostVo.getSeckillOrderInfoList()){ItemDetailsInfo itemInfo = itemInfoMap.get(seckillOrderInfo.getGoodsId()+"_"+seckillOrderInfo.getGoodsLibId());Long marketGuid = seckillOrderInfo.getMarketingGuid();Long goodsId = seckillOrderInfo.getGoodsId();Long goodsLibId = seckillOrderInfo.getGoodsLibId();String goodsSkuId = seckillOrderInfo.getGoodsSkuId()==null?"0":seckillOrderInfo.getGoodsSkuId();//无sku也会返回到sku级,skuid为0ActivitySeckillCheckInfo activitySeckillCheckInfo = activityCheckInfoMap.get(marketGuid+"_"+goodsLibId+"_"+goodsId+"_"+goodsSkuId);String activityName = activitySeckillCheckInfo.getActivityName();//秒杀价BigDecimal price = itemInfo.getPrice();for(ActivitySeckillCheckItemInfo activitySeckillCheckItemInfo : activitySeckillCheckInfo.getItemInfos()){if(activitySeckillCheckItemInfo.getGoodsId().longValue() == seckillOrderInfo.getGoodsId().longValue() && activitySeckillCheckItemInfo.getGoodsLibId().longValue() == seckillOrderInfo.getGoodsLibId().longValue()){for(ActivitySeckillCheckSkuInfo seckillCheckSkuInfo : activitySeckillCheckItemInfo.getSkuInfos()){if(seckillCheckSkuInfo.getSkuId().equals("0")||seckillCheckSkuInfo.getSkuId().equals(seckillOrderInfo.getGoodsSkuId())){price = seckillCheckSkuInfo.getPrice();}}}}JSONObject orderJson = createOrderDetail(marketGuid,activityName,expireMinute,seckillOrderInfo.getGoodsNum(), goodsId, goodsSkuId, price, itemInfo);seckillOrderList.add(orderJson);}return new CommonResult(seckillOrderList);}
http://www.yayakq.cn/news/846917/

相关文章:

  • 青岛网站建设公司怎么样ps做网站大小
  • 网站建设公司宣传册大连知名的seo外包
  • 哈尔滨建站模板展示莒县网站制作公司
  • discuz做网站赚钱经历百度快照怎么打开
  • 医院网站建设公司价格低网页制作教案
  • 广州建网站要多少钱Wordpress自动回复评论
  • 飞行时代网站建设温州专业微网站制作公司
  • 赣州网站建设哪家好做威尼斯网站代理算是违法吗
  • 做艺术品展览的网站国内做的比较好的跨境电商网站
  • 网站虚拟主机免备案免费网站推广大
  • 上海长宁区网站建设做网站的分辨率
  • 如何做网站代码网站设计是什么意思
  • 简单设计网站免费申请商城网站
  • 药膳网站建设的目的网页设计基础教程结课论文
  • 做餐饮酒店网站做2手物品通过网站去卖掉好做吗
  • 做电影下载网站赚钱花垣做网站
  • 免费开源建站教学网站网站预订模板怎么做
  • 天津网站建设zhy88淘宝买cdk自己做网站
  • 个人类网站类网站仿站 做网站
  • 网站菜单怎么做wordpress 判断加密
  • 整套html企业网站模板h5制作微信小程序
  • 网站设计的意义莆田seo培训
  • 一些免费的网站合适做服装的国际网站
  • 连云港网站建设哪家好网站建设公司做销售好不好?
  • 菏泽网站建设多少钱wamp下安装wordpress
  • 上海网站设计制作报价网站留言板 html
  • 佛山网吧什么时候恢复营业网站关键词优化怎么做的
  • 外网图片素材网站wordpress 管理密码忘记
  • 中文个人网站模板下载网络推广软件排行榜
  • 河南整站百度快照优化网站无法访问