diff --git a/pom.xml b/pom.xml
index 245d771b2e33c769ea8d80d6330e1731d99e3a3c..6d593ec03787653000ad22421331170bb654f991 100644
--- a/pom.xml
+++ b/pom.xml
@@ -153,6 +153,12 @@
beanstalkc
2.3.0
+
+ com.tencentcloudapi
+ tencentcloud-sdk-java
+ 3.1.322
+
+
spring-boot-seckill
diff --git a/src/main/java/com/itstyle/seckill/queue/kafka/KafkaConsumer.java b/src/main/java/com/itstyle/seckill/queue/kafka/KafkaConsumer.java
index f8b23a398d10c99b411d880d7ef4494b5324e83d..d8ac98d0e631c9b9cb1b772a66708638590b0c89 100644
--- a/src/main/java/com/itstyle/seckill/queue/kafka/KafkaConsumer.java
+++ b/src/main/java/com/itstyle/seckill/queue/kafka/KafkaConsumer.java
@@ -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{
diff --git a/src/main/java/com/itstyle/seckill/web/SeckillDistributedController.java b/src/main/java/com/itstyle/seckill/web/SeckillDistributedController.java
index f2500d762d0ca376bd4188c561790182e7312d91..1ca3740b4972728e8ad6237dd59fb9511ceee929 100644
--- a/src/main/java/com/itstyle/seckill/web/SeckillDistributedController.java
+++ b/src/main/java/com/itstyle/seckill/web/SeckillDistributedController.java
@@ -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);
diff --git a/src/main/java/com/itstyle/seckill/web/SeckillPageController.java b/src/main/java/com/itstyle/seckill/web/SeckillPageController.java
index a5391adfda7d3563348f534811b15fba210c469b..3623f63617121c33b30c49aafdd12c327b5b6edf 100644
--- a/src/main/java/com/itstyle/seckill/web/SeckillPageController.java
+++ b/src/main/java/com/itstyle/seckill/web/SeckillPageController.java
@@ -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 params= new LinkedMultiValueMap();
- 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("验证失败");
}
}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 3a37c1372614d09e50d716a5ad74c3115f4027cd..ab5622c22e03569b0f48a73f3adfb8973d068923 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -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
\ No newline at end of file
diff --git a/src/main/resources/templates/1000.html b/src/main/resources/templates/1000.html
index dd38ae90d5e04b74d19280c796b184ecd0402d7a..151561b692b59fa00d5e83267f966c502497f7e2 100644
--- a/src/main/resources/templates/1000.html
+++ b/src/main/resources/templates/1000.html
@@ -137,7 +137,7 @@ A.info:hover {color:green;background:transparent;text-decoration:underline}
尺码:
- 立即购买加入购物车
+ 立即购买加入购物车
服务承诺: