php做网站参考文献,网站页面效果图怎么做,免费的自助设计网站,网站代理在线前言
在当今的互联网时代#xff0c;抢单活动已经成为了电商平台、外卖平台等各种电子商务平台中常见的营销手段。通过抢单活动#xff0c;商家可以吸引大量用户参与#xff0c;从而提高销量和知名度。然而#xff0c;抢单活动所带来的高并发请求往往会给系统带来巨大的压…前言
在当今的互联网时代抢单活动已经成为了电商平台、外卖平台等各种电子商务平台中常见的营销手段。通过抢单活动商家可以吸引大量用户参与从而提高销量和知名度。然而抢单活动所带来的高并发请求往往会给系统带来巨大的压力如何在抢单活动开始前进行预热以确保系统能够稳定运行成为了技术人员需要解决的重要问题。
在这篇博客中我们将深入探讨如何利用Redis技术来进行抢单预热以应对抢单活动带来的高并发访问压力。我们将介绍Redis的基本概念和特点以及如何利用Redis来进行缓存预热、数据预加载等操作从而提高系统的并发处理能力和稳定性。同时我们也将分享一些实际案例和经验帮助读者更好地理解和应用Redis技术解决抢单预热的挑战。
通过本文的学习读者将能够深入了解抢单预热的必要性和原理掌握利用Redis进行抢单预热的具体方法和技巧从而为自己的系统应对抢单活动带来的高并发访问压力提供有效的解决方案。让我们一起深入探讨Redis在抢单预热中的应用吧 一、前期准备
1、新建项目结构如下 2、添加依赖
dependencies!-- 放在最前面依赖依据依赖的最短路径原则将不在使用spring-data中的slf4j否则会引发冲突--dependencygroupIdch.qos.logback/groupIdartifactIdlogback-classic/artifactIdversion1.3.8/version/dependency!-- spring data框架提供了对redis的整合支持内部支持lettuce以及Jedis客户端--dependencygroupIdorg.springframework.data/groupIdartifactIdspring-data-redis/artifactIdversion2.5.6/version/dependencydependencygroupIdjavax.servlet/groupIdartifactIdjavax.servlet-api/artifactIdversion4.0.1/versionscopeprovided/scope/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-webmvc/artifactIdversion5.3.29/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-jdbc/artifactIdversion5.3.29/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-tx/artifactIdversion5.3.29/version/dependencydependencygroupIdcom.alibaba/groupIdartifactIddruid/artifactIdversion1.2.3/version/dependencydependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion8.0.32/version/dependencydependencygroupIdio.lettuce/groupIdartifactIdlettuce-core/artifactIdversion6.2.2.RELEASE/version/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdversion1.18.12/version/dependencydependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.12/version/dependencydependencygroupIdcom.fasterxml.jackson.core/groupIdartifactIdjackson-databind/artifactIdversion2.11.2/version/dependencydependencygroupIdorg.mybatis/groupIdartifactIdmybatis/artifactIdversion3.5.6/version/dependencydependencygroupIdorg.mybatis/groupIdartifactIdmybatis-spring/artifactIdversion2.0.6/version/dependency/dependencies 这个Maven项目中包含了多个依赖以下是每个依赖的作用 logback-classic: 这是logback日志框架的经典模块用于在应用程序中进行日志记录和管理。 spring-data-redis: 提供了Spring Data框架对Redis的整合支持包括对lettuce和Jedis客户端的支持可以方便地使用Redis进行数据操作。 javax.servlet-api: 这是Java Servlet API的依赖提供了对Servlet的支持通常在Java Web应用中使用。 spring-webmvc: Spring框架的Web MVC模块提供了基于MVC架构的Web应用程序开发支持。 spring-jdbc: Spring框架的JDBC模块提供了对JDBC的封装和支持用于在Spring应用中进行数据库操作。 spring-tx: Spring框架的事务管理模块提供了声明式事务管理的支持。 druid: 阿里巴巴开源的数据库连接池在应用中用于管理数据库连接。 mysql-connector-java: MySQL数据库的JDBC驱动用于连接MySQL数据库。 lettuce-core: Lettuce是一个高性能的开源Java Redis客户端用于与Redis进行交互。 lombok: Lombok是一个Java库可以通过注解的方式来简化Java代码的编写提高开发效率。 junit: JUnit是一个Java单元测试框架用于编写和运行自动化的单元测试。 jackson-databind: Jackson是一个流行的Java JSON处理库jackson-databind模块提供了数据绑定功能用于将Java对象和JSON数据进行相互转换。 mybatis: MyBatis是一个持久层框架用于在Java应用中进行数据库操作。 mybatis-spring: MyBatis与Spring框架的整合模块提供了MyBatis和Spring框架的无缝集成支持。 这些依赖项涵盖了日志记录、Web开发、数据库操作、缓存操作、测试等多个方面可以满足一个典型的Java应用程序的开发需求。 二、编写 dao
由于代码量太多了就不一一讲解了本次案例只是讲重要的怎么预热和减库存。
1、GoodsDao
public interface GoodsDao {/*** 查询参与活动的商品* return*/ListGoods listProduct();/*** 减库存* param id* return*/void decrStock(int id);
} 首先要有一个查询库存的方法和一个删减库存的方法。 三、编写 service
1、OrderService
public interface OrderService {/*** 下单* param id*/void placeOrder(int id);
}当库存放生改变时我们需要为这写下单的用户添加订单记录。
2、GoodsService
public interface GoodsService {/*** 扣减库存* param id*/void decrStock(int id);
}当下单成功后需要扣减数据库的库存数量。
3、GoodsServiceImpl
Service
Slf4j
RequiredArgsConstructor
Transactional(rollbackFor RuntimeException.class)
public class GoodsServiceImpl implements GoodsService {private final GoodsDao goodsDao;private final RedisTemplateString, Object redisTemplate;/*** 缓存预热*/PostConstructpublic void initProductCache() {goodsDao.listProduct().forEach(goods - {//将商品数量加入redis缓存String key GoodsEnum.PREFIX.value() goods.getId();redisTemplate.opsForValue().set(key, goods.getStock(), Duration.ofMinutes(60));});}Overridepublic void decrStock(int id) {goodsDao.decrStock(id);}
} 这段代码是一个名为GoodsServiceImpl的服务类使用了Lombok的RequiredArgsConstructor注解来自动生成构造函数并且使用了Slf4j来实现日志记录。同时Service注解表明这是一个Spring的服务类Transactional注解表明这个类中的方法将进行事务管理并且在遇到RuntimeException时进行回滚。 这个类中有两个成员变量GoodsDao和RedisTemplate。GoodsDao是一个数据访问对象用于对商品数据进行持久化操作而RedisTemplate是Spring提供的用于操作Redis的模板类。 在这个类中有一个PostConstruct注解的方法initProductCache()它在类实例化后会被自动调用。这个方法通过goodsDao.listProduct()获取所有商品并将它们的库存数量加入到Redis缓存中以实现商品的缓存预热。对于每个商品它会将商品的id作为key库存数量作为value存入Redis并设置了缓存的有效期为60分钟。 另外这个类还实现了GoodsService接口其中包含了decrStock(int id)方法用于减少商品库存。在这个方法中它调用了goodsDao.decrStock(id)来实现对商品库存的减少操作。 总的来说这个类主要负责商品库存的管理通过缓存预热来提高系统性能并且在减少商品库存时进行事务管理。 4、OrderServiceImpl Service
Slf4j
RequiredArgsConstructor
Transactional
public class OrderServiceImpl implements OrderService {private final RedisTemplateString, Object redisTemplate;private final OrderDao orderDao;private final GoodsDao goodsDao;/*** 下单* param id*/Overridepublic void placeOrder(int id) {//扣减库存decrCacheStock(id);//生成订单createOrder(id);//同步数据库的库存goodsDao.decrStock(id);}/*** 在缓存中扣减库存* param id*/private void decrCacheStock(int id) {//扣减库存(原子减)并返回剩余库存量long stock redisTemplate.opsForValue().decrement(GoodsEnum.PREFIX.value() id);//如果redis中库存为0则抛出异常告诉用户已经售罄if(stock 0) {//在并发时redis扣减后的库存为负数因此要将redis自增回来redisTemplate.opsForValue().increment(GoodsEnum.PREFIX.value() id);throw new OrderException(ErrorMessageEnum.SELL_OUT);}}/*** 生成订单* param gid*/private Order createOrder(int gid) {try {Order order new Order();//用户IDorder.setUserId(1);//商品IDorder.setGoodsId(gid);//0表示未支付order.setStatus(0);orderDao.save(order);return order;} catch (Exception e) {log.error(e.getMessage(), e);throw new RuntimeException(e);}}
}这段代码是一个名为OrderServiceImpl的服务类同样使用了Lombok的RequiredArgsConstructor注解来自动生成构造函数并且使用了Slf4j来实现日志记录。同时Service注解表明这是一个Spring的服务类Transactional注解表明这个类中的方法将进行事务管理。 这个类中有三个成员变量RedisTemplate用于操作Redis缓存OrderDao用于对订单数据进行持久化操作GoodsDao用于对商品数据进行持久化操作。 在这个类中有一个placeOrder(int id)方法用于处理下单操作。在这个方法中首先调用了decrCacheStock(int id)方法来扣减商品的库存然后调用了createOrder(int id)方法来生成订单最后调用了goodsDao.decrStock(id)方法来同步数据库中的库存信息。 在decrCacheStock(int id)方法中它使用了RedisTemplate来实现对Redis缓存中商品库存的扣减操作并且通过判断库存是否小于0来判断商品是否售罄如果售罄则抛出OrderException异常。 在createOrder(int gid)方法中它创建了一个订单对象并将订单信息存入数据库中。如果在存入数据库时出现异常它会记录错误日志并抛出RuntimeException异常。 总的来说这个类主要负责处理订单的生成和库存的扣减操作通过调用RedisTemplate来实现对Redis缓存的操作并且在数据库操作时进行事务管理。 四、编写controller
RestController
RequiredArgsConstructor
public class OrderController extends BaseController{private final OrderService orderService;PostMapping(/seckill)public ResultVO placeOrder(Integer gid) {orderService.placeOrder(2);return success();}
}这段代码是一个名为OrderController的控制器类使用了Lombok的RequiredArgsConstructor注解来自动生成构造函数并且继承了BaseController。同时RestController注解表明这是一个Spring的RESTful控制器类。 在这个类中有一个成员变量OrderService用于处理订单相关的业务逻辑。在控制器中有一个PostMapping注解的方法placeOrder(Integer gid)用于处理秒杀下单的请求。在这个方法中它调用了orderService.placeOrder(2)来处理下单操作并且返回了一个ResultVO对象通过success()方法来表示操作成功。 总的来说这个控制器类主要用于处理秒杀下单的请求通过调用OrderService来实现下单操作并返回相应的结果。 五、使用jmeter测试
官网网址Apache JMeter - Apache JMeter™
去官网下载下来我们用 jmeter 来测试我们的controller。 1、jmeter有什么用
JMeter是一个用于进行性能测试的开源工具它最初是为测试Web应用程序而设计的但后来扩展到其他测试领域。JMeter的主要用途包括 性能测试JMeter可以模拟多个并发用户对目标系统如Web服务器、数据库、FTP服务器等发起请求以评估系统的性能和稳定性。它可以测量系统在不同负载下的响应时间、吞吐量和并发用户数等指标帮助开发人员和测试人员发现系统性能方面的问题。 负载测试通过模拟大量用户请求JMeter可以测试系统在高负载情况下的表现评估系统的承载能力和性能瓶颈以便确定系统是否能够满足预期的用户需求。负载测试也可以用于验证系统的可伸缩性和稳定性。 压力测试JMeter可以模拟系统在正常或异常负载下的表现以便评估系统在不同压力下的稳定性和可靠性。通过压力测试可以发现系统在极端情况下可能出现的问题如内存泄漏、资源竞争等。 功能测试除了性能测试JMeter也可以用于进行功能测试例如测试网站的登录、注册、搜索等功能以及测试API的响应等。
总的来说JMeter是一个功能强大的测试工具可以帮助开发人员和测试人员进行性能、负载、压力和功能测试以确保系统能够稳定、高效地运行。
2、测试
1打开 jmeter ,bin目录下双击ApacheJMeter.jar 运行 运行 2添加线程组 3添加HTTP请求 4添加汇总报告 5填写信息 添加循环数量我们的库存中有100个库存我们执行150次看会不会出现超卖的情况。还是售完了直接就抛异常。 填写 HTTP 协议 请求路径不要写错了还有就是请求的方式是什么就选择什么。
6测试结果 当运行测试后售完100个数量之后并没有出现超卖的现象证明我们的代码就没有写错并且在售完之后直接提示用户商品已售完。 六、gitee 案例
地址ch02 · qiuqiu/Redis-study - 码云 - 开源中国 (gitee.com)