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

网站制作尺寸软件工程师报名官网

网站制作尺寸,软件工程师报名官网,网页制作工具 知乎,好的平面设计灵感网站缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…

缓存架构

代码结构

代码详情

功能点:

  1. 多级缓存,先查本地缓存,再查Redis,最后才查数据库
  2. 热点数据重建逻辑使用分布式锁,二次查询
  3. 更新缓存采用读写锁提升性能
  4. 采用Redis的发布订阅机制通知所有实例更新本地缓存
  5. 适用读多写少的场景
/*** 常量**/
public class Constants {public static final String PRODUCT_CACHE = "product:cache:";public static final Integer PRODUCT_CACHE_TIMEOUT = 60 * 60 * 24;public static final String EMPTY_CACHE = "{}";public static final String LOCK_PRODUCT_HOT_CACHE_PREFIX = "lock:product:hot_cache:";public static final String LOCK_PRODUCT_UPDATE_PREFIX = "lock:product:update:";public static final String NOTIFY_LOCAL_CACHE_UPDATE = "notify_local_cache_update";
}
/*** 本地缓存**/
public class LocalCacheHolder {@Getterprivate static Map<String, Product> localCache = new ConcurrentHashMap<>();}
/*** 控制器**/
@RestController
@RequestMapping("/api/product/")
public class ProductController {@Autowiredprivate ProductService productService;@PostMapping(value = "/create")public Product createProduct(@RequestBody Product product) {return productService.createProduct(product);}@PostMapping(value = "/update")public Product updateProduct(@RequestBody Product product) {return productService.updateProduct(product);}@GetMapping("/get/{productId}")public Product getProduct(@PathVariable Long productId) {return productService.getProduct(productId);}}
/*** DAO层**/
@Repository
public class ProductDao {public Product createProduct(Product product) {try {Thread.sleep(10);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("创建商品成功");return product;}public Product updateProduct(Product product) {try {Thread.sleep(10);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("修改商品成功");return product;}public Product getProduct(Long productId) {try {Thread.sleep(10);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("查询商品成功");Product product = new Product();product.setId(productId);product.setName("test");return product;}}
/*** 商品实体**/
@Data
public class Product implements Serializable {private Long id; // 商品IDprivate String name; // 商品名称private String category; // 商品分类(如 "电子产品"、"图书")private BigDecimal price; // 价格(精确到分,使用BigDecimal避免浮点精度问题)private int stock; // 库存数量private String description; // 商品描述private LocalDateTime createTime; // 创建时间private LocalDateTime updateTime; // 更新时间
}
/*** 商品服务**/
@Service
public class ProductService {@Autowiredprivate ProductDao productDao;@Autowiredprivate Redisson redisson;@Autowiredprivate RTopic localCacheUpdateTopic;//写锁public Product createProduct(Product product) {Product productResult = null;RReadWriteLock readWriteLock = redisson.getReadWriteLock(Constants.LOCK_PRODUCT_UPDATE_PREFIX + product.getId());RLock writeLock = readWriteLock.writeLock();writeLock.lock();try {productResult = productDao.createProduct(product);redisson.getBucket(Constants.LOCK_PRODUCT_UPDATE_PREFIX + product.getId()).set(JSON.toJSONString(productResult), Duration.ofSeconds(genProductCacheTimeout()));LocalCacheHolder.getLocalCache().put(Constants.PRODUCT_CACHE + productResult.getId(), product);localCacheUpdateTopic.publish(JSON.toJSONString(productResult));} finally {writeLock.unlock();}return productResult;}//写锁public Product updateProduct(Product product) {Product productResult = null;RReadWriteLock readWriteLock = redisson.getReadWriteLock(Constants.LOCK_PRODUCT_UPDATE_PREFIX + product.getId());RLock writeLock = readWriteLock.writeLock();writeLock.lock();try {productResult = productDao.updateProduct(product);redisson.getBucket(Constants.LOCK_PRODUCT_UPDATE_PREFIX + product.getId()).set(JSON.toJSONString(productResult), Duration.ofSeconds(genProductCacheTimeout()));LocalCacheHolder.getLocalCache().put(Constants.PRODUCT_CACHE + productResult.getId(), product);localCacheUpdateTopic.publish(JSON.toJSONString(productResult));} finally {writeLock.unlock();}return productResult;}public Product getProduct(Long productId) {Product product = null;String productCacheKey = Constants.PRODUCT_CACHE + productId;product = getProductFromCache(productCacheKey);if (product != null) {return product;}//热点缓存重建,加分布式锁,第一个请求写缓存成功后,做二次读取缓存操作,其余请求都可以走RedisRLock hotCacheLock = redisson.getLock(Constants.LOCK_PRODUCT_HOT_CACHE_PREFIX + productId);hotCacheLock.lock();try {product = getProductFromCache(productCacheKey);if (product != null) {return product;}RReadWriteLock readWriteLock = redisson.getReadWriteLock(Constants.LOCK_PRODUCT_UPDATE_PREFIX + productId);RLock rLock = readWriteLock.readLock();rLock.lock();try {product = productDao.getProduct(productId);if (product != null) {redisson.getBucket(productCacheKey).set(JSON.toJSONString(product),Duration.ofSeconds(genProductCacheTimeout()));LocalCacheHolder.getLocalCache().put(productCacheKey, product);localCacheUpdateTopic.publish(JSON.toJSONString(product));} else {redisson.getBucket(productCacheKey).set(Constants.EMPTY_CACHE, Duration.ofSeconds(genEmptyCacheTimeout()));}} finally {rLock.unlock();}} finally {hotCacheLock.unlock();}return product;}//随机超时时间,防止缓存击穿(失效)private Integer genProductCacheTimeout() {return Constants.PRODUCT_CACHE_TIMEOUT + new Random().nextInt(5) * 60 * 60;}//空数据的超时时间private Integer genEmptyCacheTimeout() {return 60 + new Random().nextInt(30);}//从缓存获取数据private Product getProductFromCache(String productCacheKey) {Product product = LocalCacheHolder.getLocalCache().get(productCacheKey);if (product != null) {return product;}RBucket<String> bucket = redisson.getBucket(productCacheKey);String productStr = bucket.get();if (!StringUtils.isEmpty(productStr)) {if (Constants.EMPTY_CACHE.equals(productStr)) {bucket.expire(Duration.ofSeconds(genEmptyCacheTimeout()));return new Product();}product = JSON.parseObject(productStr, Product.class);bucket.expire(Duration.ofSeconds(genProductCacheTimeout())); //读延期}return product;}}
@SpringBootApplication
public class RedisMultiCacheApplication {public static void main(String[] args) {SpringApplication.run(RedisMultiCacheApplication.class, args);}@Beanpublic Redisson redisson() {// 此为单机模式Config config = new Config();config.useSingleServer().setAddress("redis://localhost:6379").setDatabase(0);return (Redisson) Redisson.create(config);}//通知其它实例更新本地缓存@Beanpublic RTopic localCacheUpdateTopic(Redisson redisson) {RTopic topic = redisson.getTopic(Constants.NOTIFY_LOCAL_CACHE_UPDATE);topic.addListener(String.class, (channel, message) -> {System.out.println("收到消息:" + channel + ":" + message);Product product = JSON.parseObject(message, Product.class);LocalCacheHolder.getLocalCache().put(Constants.LOCK_PRODUCT_UPDATE_PREFIX + product.getId(), product);});return topic;}}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.3.12</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example.mutilcache</groupId><artifactId>redis-multi-cache</artifactId><version>0.0.1-SNAPSHOT</version><name>redis-multi-cache</name><description>redis-multi-cache</description><url/><licenses><license/></licenses><developers><developer/></developers><scm><connection/><developerConnection/><tag/><url/></scm><properties><java.version>17</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.48.0</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.83</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><annotationProcessorPaths><path><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></path></annotationProcessorPaths></configuration></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build></project>
http://www.dtcms.com/a/616442.html

相关文章:

  • 网站式登录页面模板下载小程序开发教程资料
  • joomla 做的网站网络舆情事件
  • 做房地产用什么网站好深圳龙岗企业网站建设
  • 在线书店网站怎么做公司logo设计含义
  • 服务网点网站建设百度关键词推广条件
  • seo网站外链工具网站开发公司网站
  • 做目录网站注意可信网站认证查询
  • 商家自己做的商品信息查询网站网站建设背景及意义
  • 手机网站做落地页广州多区最新通告
  • gl账号注册网站广州外贸网站建设公司
  • 网站开发第几类商标做包装盒有哪些网站
  • 贵阳市网站做的最好的还原wordpress
  • 做公司的网站大概多少钱百度网站加v
  • 企业网站模板上一品资源做网站用到哪些软件
  • 电子商务网站建设做视频必须知道的一些网站
  • 网站安全建设进展情况汇报网站部署步骤网站开发
  • wordpress网站页面打开很慢网站建设初步策划方案
  • 怎样做网站网站ui用户界面设计
  • 廊坊北京网站建设濮阳网站建设哪家好
  • 网站开发实训指导书嘉兴网站建设公司电话
  • 常见的网站推广方式有哪些网站后台如何备份
  • 网站建设需要很强的编程沪尚茗居装修价格怎样
  • 国内建站平台有哪些网站模板怎样发布
  • 个人网站风格设计wordpress 忘记管理员密码
  • 操作系统分区
  • 谷歌云 wordpress 建站网站建设推广和网络推广
  • 网站改版seowordpress调用当前分类
  • 解决pip install gym==0.19.0安装失败问题
  • 网站开发小图标设计网站网站名称
  • 初中生电脑作业做网站网站建设工作内容