谷粒网

更新时间:2023-03-13 14:24:01 阅读: 评论:0

宠物猫多少钱-开机启动项怎么设置

谷粒网
2023年3月13日发(作者:车厘子多少钱)

⾕粒商城:秒杀系统设计与编写

1.秒杀系统设计

秒杀(⾼并发)系统关注的问题

1、服务单独职责+独⽴部署

秒杀系统为单独的服务,即使⾃⼰扛不住压⼒挂掉,也不要影响其他服务

2、秒杀链接加密

防⽌恶意攻击,模拟秒杀请求,1000次/s的攻击;防⽌链接暴露,⾃⼰⼯作⼈员,提前秒杀商品;我们使⽤了带uuid随机码的机制;

3、库存预热+快速扣减

秒杀读多写少,⽆需每次实时校验库存,我们库存预热,放到redis中,信号量控制进来秒杀的请求;为了保证redis可以保证千万并发,可以

给redis做集群,做成分⽚⾼可⽤;我们是⽤定时任务提取三天写到缓存中;

4、动静分离

Nginx做好动静分离,保证秒杀和商品详情页的动态请求才打到后端的服务集群,使⽤CDN⽹络,分担本集群的压⼒;⽐如访问静态资源,

阿⾥云CDN会在最快的节点返回静态资源;

5、恶意请求拦截

识别⾮法攻击请求并进⾏拦截(⽹关层),⽐如伪造的请求没带令牌;保证能放到后端的请求都是正常⾏为;

6、流量错峰

使⽤各种⼿段,将流量分担到更⼤宽度的时间点。⽐如验证码(⼩⽶商城)、加⼊购物车(结账,锁库存还有⼀段时间);

7、限流&熔断&降级(必须)

前端限流+后端限流(限流把不合理的去除掉,如:⼀秒发送1w次的请求;就算合理的,次数太多也应该限制起来);限制次数,限制总

量,快速失败降级运⾏(⼀部分流量引导到降级页⾯),熔断隔离防⽌雪崩;

8、队列削峰

1万个商品,每个1000件秒杀,双11;所有秒杀成功的请求,进⼊队列,慢慢创建订单,扣减库存即可;

2.秒杀核⼼流程

秒杀流程+消息队列监听流程

3.秒杀系统编写

秒杀请求

@Autowired

privateSeckillServiceckillService;

@GetMapping("/kill")

publicStringcKill(@RequestParam("killId")StringkillId,//ssion_skuID

@RequestParam("key")Stringkey,

@RequestParam("num")Integernum,Modelmodel){

StringorderSn=(killId,key,num);

//1.判断是否登录

ribute("orderSn",orderSn);

return"success";

}

登录验证:编写拦截器

@Component

publicclassLoginUrInterceptorimplementsHandlerInterceptor{

publicstaticThreadLocalthreadLocal=newThreadLocal<>();

@Override

publicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponrespon,Objecthandler)throwsException{

Stringuri=uestURI();

//这个请求直接放⾏

booleanmatch=newAntPathMatcher().match("/kill",uri);

//如果是秒杀请求,才做这⼀系列的登录验证

if(!match){

HttpSessionssion=sion();

MemberRespVoMemberRespVo=(MemberRespVo)ribute(_USER);

if(MemberRespVo!=null){

(MemberRespVo);

returntrue;

}el{

//没登陆就去登录

ribute("msg",_LOGIN);

direct("/");

returnfal;

}

}

returntrue;

}

}

将登录验证拦截器添加到webmvc的配置中

@Configuration

publicclassSeckillWebConfigimplementsWebMvcConfigurer{

@Autowired

privateLoginUrInterceptorloginUrInterceptor;

@Override

publicvoidaddInterceptors(InterceptorRegistryregistry){

erceptor(loginUrInterceptor).addPathPatterns("/**");

}

}

流量削峰

配置rabbitmq

ipAddr:"192.168.56.10"

spring:

rabbitmq:

virtual-host:/

host:${ipAddr}

引⼊rabbitmq配置类,使⽤JSON序列化器,进⾏消息转换

@Configuration

publicclassMyRabbitConfig{

@Bean

publicMessageConvertermessageConverter(){

returnnewJackson2JsonMessageConverter();

}

}

设置交换机和队列的名字常量

package;

publicclassRabbitInfo{

publicstaticclassOrder{

//其实⼚⾥应该⼤写,但是我们为了区分,这⾥也不改了

publicstaticfinalStringexchange="order-event-exchange";

publicstaticfinalStringdelayQueue="";

publicstaticfinalStringdelayRoutingKey="";

publicstaticfinalStringreleaQueue="";

publicstaticfinalStringreleaRoutingKey="e";

//其他路由key也是跳到releaQueue

publicstaticfinalStringbaRoutingKey="order.#";

publicstaticfinalintttl=900000;

}

publicstaticclassStock{

publicstaticfinalStringexchange="stock-event-exchange";

publicstaticfinalStringdelayQueue="";

publicstaticfinalStringdelayRoutingKey="";

publicstaticfinalStringreleaQueue="";

publicstaticfinalStringreleaRoutingKey="";

publicstaticfinalStringbaRoutingKey="stock.#";

publicstaticfinalintttl=900000;

}

publicstaticclassSecKill{

publicstaticfinalStringexchange="ckill-event-exchange";

publicstaticfinalStringdelayQueue="";

publicstaticfinalStringdelayRoutingKey="";

publicstaticfinalStringreleaQueue="";

publicstaticfinalStringreleaRoutingKey="";

publicstaticfinalintttl=900000;

}

}

给交换机发请求

//+skuId在redis中标识买过商品

StringredisKey=()+"-"+skuId;

//让数据⾃动过期

longttl=Time()-rtTime();

//SETNX,也就是不存在的时候才占位,如果能占位成功,说明这个⼈没买过

BooleanaBoolean=Value()

.tIfAbnt(redisKey,

ng(),

ttl<0?0:ttl,

ECONDS);

if(aBoolean){

//占位成功说明从来没买过

RSemaphoremaphore=aphore(SKUSTOCK_SEMAPHONE+randomCode);

//使⽤tryAcquire()⽅法,因为acquire()是阻塞的

booleanacquire=uire(num);

if(acquire){

//秒杀成功

//快速下单发送MQ

/**⽣成订单号,这样数据库通过消息队列保存后,订单⽀付页⾯也知道保存的id是多少*/

StringorderSn=eId()+UUID().toString().replace("-","").substring(7,8);

SecKillOrderToorderTo=newSecKillOrderTo();

erSn(orderSn);

berId(());

(num);

Id(Id());

killPrice(killPrice());

motionSessionId(motionSessionId());

tAndSend(ge,

outingKey,orderTo);

//返回订单号

returnorderSn;

}

监听秒杀单的队列

package;

@RabbitListener(queues=ueue)

@Component

publicclassOrderSecKillListener{

@Autowired

privateOrderServiceorderService;

@RabbitHandler

publicvoidlistener(SecKillOrderTocKillOrderTo,Channelchannel,Messagemessage)throwsIOException{

try{

//秒杀的时候没有订单,这时候才创建订单

SecKillOrder(cKillOrderTo);

//⼿动ack确认消费

ck(sageProperties().getDeliveryTag(),fal);

}catch(Exceptione){

eject(sageProperties().getDeliveryTag(),true);

}

}

}

本⽂完

本文发布于:2023-03-13 14:24:01,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/zhishi/a/16786886419418.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:谷粒网.doc

本文 PDF 下载地址:谷粒网.pdf

上一篇:三四成语
下一篇:返回列表
标签:谷粒网
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 实用文体写作网旗下知识大全大全栏目是一个全百科类宝库! 优秀范文|法律文书|专利查询|