parent
8835e9042a
commit
86653156f4
6
pom.xml
6
pom.xml
|
@ -153,6 +153,12 @@
|
|||
<artifactId>beanstalkc</artifactId>
|
||||
<version>2.3.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.tencentcloudapi</groupId>
|
||||
<artifactId>tencentcloud-sdk-java</artifactId>
|
||||
<version>3.1.322</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
<build>
|
||||
<finalName>spring-boot-seckill</finalName>
|
||||
|
|
|
@ -9,6 +9,9 @@ import com.itstyle.seckill.common.entity.Result;
|
|||
import com.itstyle.seckill.common.redis.RedisUtil;
|
||||
import com.itstyle.seckill.common.webSocket.WebSocketServer;
|
||||
import com.itstyle.seckill.service.ISeckillService;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 消费者 spring-kafka 2.0 + 依赖JDK8
|
||||
* @author 科帮网 By https://blog.52itstyle.com
|
||||
|
@ -17,8 +20,9 @@ import com.itstyle.seckill.service.ISeckillService;
|
|||
public class KafkaConsumer {
|
||||
@Autowired
|
||||
private ISeckillService seckillService;
|
||||
|
||||
private static RedisUtil redisUtil = new RedisUtil();
|
||||
|
||||
@Autowired
|
||||
private RedisUtil redisUtil;
|
||||
/**
|
||||
* 监听seckill主题,有消息就读取
|
||||
* @param message
|
||||
|
@ -32,9 +36,9 @@ public class KafkaConsumer {
|
|||
if(redisUtil.getValue(array[0])==null){
|
||||
Result result = seckillService.startSeckilAopLock(Long.parseLong(array[0]), Long.parseLong(array[1]));
|
||||
if(result.equals(Result.ok(SeckillStatEnum.SUCCESS))){
|
||||
WebSocketServer.sendInfo(array[0], "秒杀成功");
|
||||
WebSocketServer.sendInfo("秒杀成功", array[0]);
|
||||
}else{
|
||||
WebSocketServer.sendInfo(array[0], "秒杀失败");
|
||||
WebSocketServer.sendInfo("秒杀失败", array[0]);
|
||||
redisUtil.cacheValue(array[0], "ok");
|
||||
}
|
||||
}else{
|
||||
|
|
|
@ -142,7 +142,7 @@ public class SeckillDistributedController {
|
|||
executor.execute(task);
|
||||
}
|
||||
try {
|
||||
Thread.sleep(10000);
|
||||
Thread.sleep(30000);
|
||||
redisUtil.cacheValue(killId+"", null);
|
||||
Long seckillCount = seckillService.getSeckillCount(seckillId);
|
||||
LOGGER.info("一共秒杀出{}件商品",seckillCount);
|
||||
|
|
|
@ -1,6 +1,14 @@
|
|||
package com.itstyle.seckill.web;
|
||||
|
||||
import com.itstyle.seckill.common.redis.RedisUtil;
|
||||
import com.itstyle.seckill.queue.kafka.KafkaSender;
|
||||
import com.tencentcloudapi.captcha.v20190722.CaptchaClient;
|
||||
import com.tencentcloudapi.captcha.v20190722.models.DescribeCaptchaResultRequest;
|
||||
import com.tencentcloudapi.captcha.v20190722.models.DescribeCaptchaResultResponse;
|
||||
import com.tencentcloudapi.common.Credential;
|
||||
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
|
||||
import com.tencentcloudapi.common.profile.ClientProfile;
|
||||
import com.tencentcloudapi.common.profile.HttpProfile;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
|
||||
|
@ -42,13 +50,18 @@ public class SeckillPageController {
|
|||
@Autowired
|
||||
private ActiveMQSender activeMQSender;
|
||||
|
||||
@Autowired
|
||||
private KafkaSender kafkaSender;
|
||||
|
||||
@Autowired
|
||||
private RedisUtil redisUtil;
|
||||
|
||||
@Autowired
|
||||
private HttpClient httpClient;
|
||||
@Value("${qq.captcha.url}")
|
||||
private String url;
|
||||
|
||||
@Value("${qq.captcha.endPoint}")
|
||||
private String endPoint;
|
||||
@Value("${qq.captcha.SecretId}")
|
||||
private String secretId;
|
||||
@Value("${qq.captcha.SecretKey}")
|
||||
private String secretKey;
|
||||
@Value("${qq.captcha.aid}")
|
||||
private String aid;
|
||||
@Value("${qq.captcha.AppSecretKey}")
|
||||
|
@ -65,29 +78,40 @@ public class SeckillPageController {
|
|||
|
||||
@PostMapping("/startSeckill")
|
||||
public Result startSeckill(String ticket,String randstr,HttpServletRequest request) {
|
||||
HttpMethod method =HttpMethod.POST;
|
||||
MultiValueMap<String, String> params= new LinkedMultiValueMap<String, String>();
|
||||
params.add("aid", aid);
|
||||
params.add("AppSecretKey", appSecretKey);
|
||||
params.add("Ticket", ticket);
|
||||
params.add("Randstr", randstr);
|
||||
params.add("UserIP", IPUtils.getIpAddr());
|
||||
String msg = httpClient.client(url,method,params);
|
||||
/**
|
||||
* response: 1:验证成功,0:验证失败,100:AppSecretKey参数校验错误[required]
|
||||
* evil_level:[0,100],恶意等级[optional]
|
||||
* err_msg:验证错误信息[optional]
|
||||
*/
|
||||
//{"response":"1","evil_level":"0","err_msg":"OK"}
|
||||
JSONObject json = JSONObject.parseObject(msg);
|
||||
String response = (String) json.get("response");
|
||||
if("1".equals(response)){
|
||||
//进入队列、假数据而已
|
||||
Destination destination = new ActiveMQQueue("seckill.queue");
|
||||
activeMQSender.sendChannelMess(destination,1000+";"+1);
|
||||
return Result.ok();
|
||||
}else{
|
||||
return Result.error("验证失败");
|
||||
try {
|
||||
Credential cred = new Credential(secretId, secretKey);
|
||||
HttpProfile httpProfile = new HttpProfile();
|
||||
httpProfile.setEndpoint(endPoint);
|
||||
ClientProfile clientProfile = new ClientProfile();
|
||||
clientProfile.setHttpProfile(httpProfile);
|
||||
CaptchaClient client = new CaptchaClient(cred, "", clientProfile);
|
||||
DescribeCaptchaResultRequest req = new DescribeCaptchaResultRequest();
|
||||
req.setCaptchaType(9L);
|
||||
req.setTicket(ticket);
|
||||
req.setUserIp(IPUtils.getIpAddr());
|
||||
req.setRandstr(randstr);
|
||||
req.setCaptchaAppId(Long.valueOf(aid));
|
||||
req.setAppSecretKey(appSecretKey);
|
||||
DescribeCaptchaResultResponse resp = client.DescribeCaptchaResult(req);
|
||||
// {"CaptchaCode":1,"CaptchaMsg":"OK","EvilLevel":0,"GetCaptchaTime":0,"RequestId":"8f11aabf-d319-4884-b6d3-8fa6fa561418"}
|
||||
/**
|
||||
* CaptchaCode: 1:验证成功,0:验证失败,100:AppSecretKey参数校验错误[required]
|
||||
* EvilLevel:[0,100],恶意等级[optional]
|
||||
* CaptchaMsg:验证错误信息[optional]
|
||||
*/
|
||||
JSONObject json = JSONObject.parseObject(DescribeCaptchaResultResponse.toJsonString(resp));
|
||||
Integer response = (Integer) json.get("CaptchaCode");
|
||||
if(1 == response) {
|
||||
//进入队列、假数据而已
|
||||
kafkaSender.sendChannelMess("seckill", 1000+";"+2);
|
||||
// Destination destination = new ActiveMQQueue("seckill.queue");
|
||||
// activeMQSender.sendChannelMess(destination,1000+";"+1);
|
||||
return Result.ok();
|
||||
}else{
|
||||
return Result.error("验证失败");
|
||||
}
|
||||
} catch (TencentCloudSDKException e) {
|
||||
return Result.error("验证失败");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
# 项目contextPath 科帮网https://blog.52itstyle.vip
|
||||
# \u9879\u76EEcontextPath \u79D1\u5E2E\u7F51https://blog.52itstyle.vip
|
||||
server.context-path=/seckill
|
||||
# 服务端口
|
||||
# \u670D\u52A1\u7AEF\u53E3
|
||||
server.port=8080
|
||||
# session最大超时时间(分钟),默认为30
|
||||
# session\u6700\u5927\u8D85\u65F6\u65F6\u95F4(\u5206\u949F)\uFF0C\u9ED8\u8BA4\u4E3A30
|
||||
server.session-timeout=60
|
||||
# tomcat最大线程数,默认为200
|
||||
# tomcat\u6700\u5927\u7EBF\u7A0B\u6570\uFF0C\u9ED8\u8BA4\u4E3A200
|
||||
server.tomcat.max-threads=100
|
||||
# tomcat的URI编码
|
||||
# tomcat\u7684URI\u7F16\u7801
|
||||
server.tomcat.uri-encoding=UTF-8
|
||||
|
||||
#spring boot从控制台打印出来的日志级别只有ERROR, WARN 还有INFO,如果你想要打印debug级别的日志
|
||||
#spring boot\u4ECE\u63A7\u5236\u53F0\u6253\u5370\u51FA\u6765\u7684\u65E5\u5FD7\u7EA7\u522B\u53EA\u6709ERROR, WARN \u8FD8\u6709INFO\uFF0C\u5982\u679C\u4F60\u60F3\u8981\u6253\u5370debug\u7EA7\u522B\u7684\u65E5\u5FD7
|
||||
#debug=true
|
||||
logging.level.root=INFO
|
||||
|
||||
|
@ -19,10 +19,10 @@ spring.devtools.livereload.enabled=true
|
|||
spring.thymeleaf.cache=false
|
||||
spring.thymeleaf.cache-period=0
|
||||
spring.thymeleaf.template.cache=false
|
||||
# 静态文件请求匹配方式
|
||||
# \u9759\u6001\u6587\u4EF6\u8BF7\u6C42\u5339\u914D\u65B9\u5F0F
|
||||
spring.mvc.static-path-pattern=/**
|
||||
|
||||
#注意中文乱码
|
||||
#\u6CE8\u610F\u4E2D\u6587\u4E71\u7801
|
||||
spring.datasource.url=jdbc:mysql://localhost:3306/seckill?characterEncoding=utf-8&useSSL=false
|
||||
spring.datasource.username=root
|
||||
spring.datasource.password=root
|
||||
|
@ -39,23 +39,23 @@ spring.jpa.hibernate.naming.strategy = org.hibernate.cfg.ImprovedNamingStrategy
|
|||
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
|
||||
|
||||
# Redis
|
||||
# 数据库索引(默认为0)
|
||||
# \u6570\u636E\u5E93\u7D22\u5F15\uFF08\u9ED8\u8BA4\u4E3A0\uFF09
|
||||
spring.redis.database=0
|
||||
# 服务器地址 变更为自己的
|
||||
# \u670D\u52A1\u5668\u5730\u5740 \u53D8\u66F4\u4E3A\u81EA\u5DF1\u7684
|
||||
spring.redis.host=127.0.0.1
|
||||
# 服务器连接端口
|
||||
# \u670D\u52A1\u5668\u8FDE\u63A5\u7AEF\u53E3
|
||||
spring.redis.port=6379
|
||||
# 服务器连接密码(默认为空)如果有变更为自己的
|
||||
spring.redis.password=123456
|
||||
# 连接池最大连接数(使用负值表示没有限制)
|
||||
# \u670D\u52A1\u5668\u8FDE\u63A5\u5BC6\u7801\uFF08\u9ED8\u8BA4\u4E3A\u7A7A\uFF09\u5982\u679C\u6709\u53D8\u66F4\u4E3A\u81EA\u5DF1\u7684
|
||||
#spring.redis.password=123456
|
||||
# \u8FDE\u63A5\u6C60\u6700\u5927\u8FDE\u63A5\u6570\uFF08\u4F7F\u7528\u8D1F\u503C\u8868\u793A\u6CA1\u6709\u9650\u5236\uFF09
|
||||
spring.redis.pool.max-active=8
|
||||
# 连接池最大阻塞等待时间(使用负值表示没有限制)
|
||||
# \u8FDE\u63A5\u6C60\u6700\u5927\u963B\u585E\u7B49\u5F85\u65F6\u95F4\uFF08\u4F7F\u7528\u8D1F\u503C\u8868\u793A\u6CA1\u6709\u9650\u5236\uFF09
|
||||
spring.redis.pool.max-wait=-1
|
||||
# 连接池中的最大空闲连接
|
||||
# \u8FDE\u63A5\u6C60\u4E2D\u7684\u6700\u5927\u7A7A\u95F2\u8FDE\u63A5
|
||||
spring.redis.pool.max-idle=8
|
||||
# 连接池中的最小空闲连接
|
||||
# \u8FDE\u63A5\u6C60\u4E2D\u7684\u6700\u5C0F\u7A7A\u95F2\u8FDE\u63A5
|
||||
spring.redis.pool.min-idle=0
|
||||
# 连接超时时间(毫秒)
|
||||
# \u8FDE\u63A5\u8D85\u65F6\u65F6\u95F4\uFF08\u6BEB\u79D2\uFF09
|
||||
spring.redis.timeout=30000
|
||||
|
||||
spring.session.store-type=redis
|
||||
|
@ -63,18 +63,18 @@ spring.session.store-type=redis
|
|||
|
||||
# redisson lock
|
||||
redisson.address=redis://127.0.0.1:6379
|
||||
redisson.password=123456
|
||||
#redisson.password=123456
|
||||
|
||||
#kafka相关配置 参考:https://blog.52itstyle.vip/archives/2868/
|
||||
#kafka\u76F8\u5173\u914D\u7F6E \u53C2\u8003\uFF1Ahttps://blog.52itstyle.vip/archives/2868/
|
||||
spring.kafka.bootstrap-servers=192.168.1.180:9092
|
||||
#设置一个默认组
|
||||
#\u8BBE\u7F6E\u4E00\u4E2A\u9ED8\u8BA4\u7EC4
|
||||
spring.kafka.consumer.group-id=0
|
||||
#key-value序列化反序列化
|
||||
#key-value\u5E8F\u5217\u5316\u53CD\u5E8F\u5217\u5316
|
||||
spring.kafka.consumer.key-deserializer=org.apache.kafka.common.serialization.StringDeserializer
|
||||
spring.kafka.consumer.value-deserializer=org.apache.kafka.common.serialization.StringDeserializer
|
||||
spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.StringSerializer
|
||||
spring.kafka.producer.value-serializer=org.apache.kafka.common.serialization.StringSerializer
|
||||
#每次批量发送消息的数量
|
||||
#\u6BCF\u6B21\u6279\u91CF\u53D1\u9001\u6D88\u606F\u7684\u6570\u91CF
|
||||
spring.kafka.producer.batch-size=65536
|
||||
spring.kafka.producer.buffer-memory=524288
|
||||
|
||||
|
@ -82,7 +82,7 @@ spring.kafka.producer.buffer-memory=524288
|
|||
#zookeeper.address
|
||||
zookeeper.address = 192.168.1.180:2181
|
||||
|
||||
#freemarker(用于商品静态页生成简化版)
|
||||
#freemarker(\u7528\u4E8E\u5546\u54C1\u9759\u6001\u9875\u751F\u6210\u7B80\u5316\u7248)
|
||||
spring.freemarker.template-loader-path=classpath:/static/template/
|
||||
spring.freemarker.suffix=.flt
|
||||
spring.freemarker.enabled=true
|
||||
|
@ -95,46 +95,48 @@ spring.freemarker.expose-request-attributes=false
|
|||
spring.freemarker.expose-session-attributes=false
|
||||
spring.freemarker.expose-spring-macro-helpers=false
|
||||
|
||||
#商品静态页(自定义映射路径)
|
||||
#\u5546\u54C1\u9759\u6001\u9875(\u81EA\u5B9A\u4E49\u6620\u5C04\u8DEF\u5F84)
|
||||
spring.freemarker.html.path = D://file//
|
||||
|
||||
# 特别注意:我们通过添加 spring-boot-starter-activemq 依赖即可默认采用内嵌的activeMQ,在生产环境下个人认为尽量还是采用外部服务,提高扩展性和维护性。
|
||||
# activemq 基础配置
|
||||
# \u7279\u522B\u6CE8\u610F\uFF1A\u6211\u4EEC\u901A\u8FC7\u6DFB\u52A0 spring-boot-starter-activemq \u4F9D\u8D56\u5373\u53EF\u9ED8\u8BA4\u91C7\u7528\u5185\u5D4C\u7684activeMQ\uFF0C\u5728\u751F\u4EA7\u73AF\u5883\u4E0B\u4E2A\u4EBA\u8BA4\u4E3A\u5C3D\u91CF\u8FD8\u662F\u91C7\u7528\u5916\u90E8\u670D\u52A1\uFF0C\u63D0\u9AD8\u6269\u5C55\u6027\u548C\u7EF4\u62A4\u6027\u3002
|
||||
# activemq \u57FA\u7840\u914D\u7F6E
|
||||
#spring.activemq.broker-url=tcp://47.94.232.109:61616
|
||||
# 生产环境设置密码
|
||||
# \u751F\u4EA7\u73AF\u5883\u8BBE\u7F6E\u5BC6\u7801
|
||||
#spring.activemq.user=admin
|
||||
#spring.activemq.password=123456
|
||||
#spring.activemq.in-memory=true
|
||||
#spring.activemq.pool.enabled=false
|
||||
|
||||
# 验证码参数(自行替换)
|
||||
qq.captcha.url= https://ssl.captcha.qq.com/ticket/verify
|
||||
qq.captcha.aid= 20426***
|
||||
qq.captcha.AppSecretKey= 0OsIkPt******
|
||||
# \u9A8C\u8BC1\u7801\u53C2\u6570(\u81EA\u884C\u66FF\u6362)
|
||||
qq.captcha.endPoint= captcha.tencentcloudapi.com
|
||||
qq.captcha.SecretId= AKIDqW***********
|
||||
qq.captcha.SecretKey= JL6an********************
|
||||
qq.captcha.aid= 196******
|
||||
qq.captcha.AppSecretKey= 82q********
|
||||
|
||||
# 监控的HTTP端口
|
||||
# \u76D1\u63A7\u7684HTTP\u7AEF\u53E3
|
||||
management.port=28806
|
||||
# 忽略拦截
|
||||
# \u5FFD\u7565\u62E6\u622A
|
||||
management.security.enabled=false
|
||||
# 当前应用信息
|
||||
# \u5F53\u524D\u5E94\u7528\u4FE1\u606F
|
||||
info.app.version=v1.0.0
|
||||
info.app.name=爪哇笔记
|
||||
info.app.name=\u722A\u54C7\u7B14\u8BB0
|
||||
info.app.email=345849402@qq.com
|
||||
info.app.url=https://blog.52itstyle.vip
|
||||
#开启shutdown远程关闭功能
|
||||
#\u5F00\u542Fshutdown\u8FDC\u7A0B\u5173\u95ED\u529F\u80FD
|
||||
endpoints.shutdown.enabled=true
|
||||
#访问:http://localhost:28806/shutdown 关闭服务
|
||||
#关闭metrics功能
|
||||
#\u8BBF\u95EE\uFF1Ahttp://localhost:28806/shutdown \u5173\u95ED\u670D\u52A1
|
||||
#\u5173\u95EDmetrics\u529F\u80FD
|
||||
#endpoints.metrics.enabled=false
|
||||
#设置beansId
|
||||
#\u8BBE\u7F6EbeansId
|
||||
#endpoints.beans.id=mybean
|
||||
#设置beans路径
|
||||
#\u8BBE\u7F6Ebeans\u8DEF\u5F84
|
||||
#endpoints.beans.path=/bean
|
||||
#关闭beans 功能
|
||||
#\u5173\u95EDbeans \u529F\u80FD
|
||||
#endpoints.beans.enabled=false
|
||||
#关闭所有的
|
||||
#\u5173\u95ED\u6240\u6709\u7684
|
||||
#endpoints.enabled=false
|
||||
#开启单个beans功能
|
||||
#\u5F00\u542F\u5355\u4E2Abeans\u529F\u80FD
|
||||
#endpoints.beans.enabled=true
|
||||
#所有访问添加根目录
|
||||
#\u6240\u6709\u8BBF\u95EE\u6DFB\u52A0\u6839\u76EE\u5F55
|
||||
#management.context-path=/manage
|
|
@ -137,7 +137,7 @@ A.info:hover {color:green;background:transparent;text-decoration:underline}
|
|||
</ul>
|
||||
<div class="clear"></div>
|
||||
<p class="chima">尺码:</p>
|
||||
<p class="buy"><a href="#" id="TencentCaptcha" data-appid="2042633230" data-cbfn="callback">立即购买</a><a href="#">加入购物车</a></p>
|
||||
<p class="buy"><a href="#" id="TencentCaptcha" data-appid="196226826" data-cbfn="callback">立即购买</a><a href="#">加入购物车</a></p>
|
||||
<div class="clear"></div>
|
||||
<div class="fenx"><a href="#"><img src="goods/images/shopdetail/tell07.png"></a></div>
|
||||
<p class="fuwu">服务承诺:</p>
|
||||
|
|
Loading…
Reference in New Issue