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

太原网站建设方案服务河南的网络推广公司

太原网站建设方案服务,河南的网络推广公司,智能建站免费,哈尔滨网络公司新闻前言 Redisson是一个强大的分布式Java对象和服务库#xff0c;专为简化在分布式环境中的Java开发而设计。通过Redisson#xff0c;开发人员可以轻松地在分布式系统中共享数据、实现分布式锁、创建分布式对象#xff0c;并处理各种分布式场景的挑战。 Redisson的设计灵感来…前言 Redisson是一个强大的分布式Java对象和服务库专为简化在分布式环境中的Java开发而设计。通过Redisson开发人员可以轻松地在分布式系统中共享数据、实现分布式锁、创建分布式对象并处理各种分布式场景的挑战。 Redisson的设计灵感来自于Redis但它不仅仅是Redis的Java客户端更是在分布式环境下构建分布式系统所需的一套工具。无论是分布式集合、分布式锁、还是分布式调度器Redisson都提供了简单而强大的API使得开发者能够专注于业务逻辑而不必担心复杂的分布式细节。 底层原理 通过提供易于使用的API和丰富的功能集Redisson旨在帮助开发者更轻松地构建可靠的、高性能的分布式系统。 Redisson的底层原理主要基于Redis的分布式特性和Java的高级特性。以下是一些关键的底层原理 Redis协议 Redisson使用Redis协议进行与Redis服务器的通信。这意味着它能够与任何遵循Redis协议的Redis服务器进行交互。通过利用Redis的分布式特性Redisson实现了分布式对象和服务。Java序列化 Redisson使用Java对象的序列化和反序列化机制将Java对象转化为Redis数据结构。这使得在Java应用程序和Redis之间传递对象变得简单。默认情况下Redisson使用标准的Java序列化但也支持其他序列化方式如JSON、Jackson等。分布式锁的实现 Redisson的分布式锁是通过Redis的SETNXset if not exists命令实现的。它利用了Redis的原子性操作确保在分布式环境中只有一个客户端能够成功获取锁。监听器和事件通知 Redisson通过订阅/发布机制实现事件通知。当分布式对象发生变化时Redisson会发布相应的事件已注册的监听器将得到通知。这基于Redis的PUB/SUB功能使得分布式环境下的事件通知成为可能。分布式集群 对于Redis集群Redisson使用了Redis的集群模式。它能够识别集群中的不同节点并根据需要进行数据分片和分布式操作。线程模型 Redisson使用异步的线程模型来处理与Redis服务器的通信。这有助于提高性能允许多个操作同时执行而不阻塞主线程。 总体而言Redisson利用了Redis强大的分布式功能并通过Java的特性将其封装为易于使用的API。底层的实现涵盖了分布式锁、分布式对象、事件通知等方面以满足在分布式环境中构建高性能应用程序的需求。 Redisson分布式锁类型 Redisson提供了多种类型的分布式锁以满足不同场景的需求。以下是一些常见的Redisson分布式锁类型 可重入锁Reentrant Lock 可以被同一个线程重复加锁的锁。同一个线程在持有锁的情况下可以再次加锁而不会引起死锁。公平锁Fair Lock 公平锁按照请求加锁的顺序进行获取锁即先来先得。这有助于避免某些线程长时间等待的问题提高公平性。联锁MultiLock 可以同时获取多个锁且在释放锁时可以选择全部释放或部分释放。适用于需要操作多个资源的场景。红锁RedLock RedLock是一种分布式锁算法使用多个Redis节点来确保锁的强一致性。通过在不同的节点上创建锁即使其中一个节点失效其他节点依然可以工作。读写锁ReadWrite Lock 读写锁分为读锁和写锁多个线程可以同时持有读锁但只有一个线程能够持有写锁。适用于读多写少的场景。信号量Semaphore 类似于Java的Semaphore用于控制同时访问某个资源的线程数量。闭锁CountDownLatch 用于等待多个线程完成操作后再执行下一步操作。过期锁Lease Lock 具有自动过期时间的锁确保在一定时间内锁会被释放避免锁长时间占用。 这些锁的类型使得Redisson适用于各种分布式场景开发者可以根据具体的需求选择合适的锁类型来确保分布式环境下的协同和同步。 可重入锁Reentrant Lock 基于Redis的Redisson分布式可重入锁RLockJava对象实现了java.util.concurrent.locks.Lock接口。同时还提供了异步Async、反射式Reactive和RxJava2标准的接口。 引入 Maven 依赖 在微服务的 pom.xml 引入 redisson 的 maven 依赖 dependencygroupIdorg.redisson/groupIdartifactIdredisson/artifactIdversion3.16.2/version !-- 使用最新版本 --/dependency自定义配置类 下面的代码是单节点 Redis 的配置。 package com.example.demo.config;import org.redisson.Redisson; import org.redisson.api.RedissonClient; import org.redisson.config.Config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;import java.io.IOException;Configuration public class RedissonConfig {/*** 对 Redisson 的使用都是通过 RedissonClient 对象* return* throws IOException*/Bean(destroyMethodshutdown) // 服务停止后调用 shutdown 方法。public RedissonClient redisson() throws IOException {// 创建配置Config config new Config();config.useSingleServer().setAddress(redis://xx.xx.x.x:6379).setPassword(123456);// 集群模式// config.useClusterServers().addNodeAddress(127.0.0.1:7004, 127.0.0.1:7001);return Redisson.create(config);} }测试API package com.example.demo.controller;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;RestController RequestMapping(/api/redis) public class MyController {Autowiredprivate ReentrantLockService reentrantLockService;GetMapping(/locked-operation)public String performLockedOperation() {// 模拟多个线程同时调用可重入锁的操作for (int i 1; i 5; i) {final int threadNumber i;new Thread(() - {reentrantLockService.performLockedOperation();}).start();}return Locked operation initiated.;} }测试类 package com.example.demo.controller;import lombok.extern.slf4j.Slf4j; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;import java.util.concurrent.TimeUnit;Service Slf4j public class ReentrantLockService {Autowiredprivate RedissonClient redissonClient;public void performLockedOperation() {// 获取可重入锁RLock lock redissonClient.getLock(myReentrantLock);String threadName Thread.currentThread().getName();try {// 尝试加锁最多等待10秒锁的自动释放时间为30秒boolean isLocked lock.tryLock(10, 30, TimeUnit.SECONDS);if (isLocked) {// 执行需要加锁的操作log.info(threadName - 获取锁成功执行加锁操作...);// 模拟业务操作Thread.sleep(5000);log.info(threadName - 加锁操作完成。);} else {log.info(threadName 在指定时间内无法获取锁。);}} catch (InterruptedException e) {Thread.currentThread().interrupt();System.err.println(threadName 尝试获取锁时发生中断。);} finally {// 释放锁if (lock.isHeldByCurrentThread()) {log.info(threadName - 释放锁);lock.unlock();}}} }输出日志 2023-11-17 15:56:13.935 INFO 12316 --- [ Thread-17] c.e.d.controller.ReentrantLockService : Thread-17 - 获取锁成功执行加锁操作... 2023-11-17 15:56:18.945 INFO 12316 --- [ Thread-17] c.e.d.controller.ReentrantLockService : Thread-17 - 加锁操作完成。 2023-11-17 15:56:18.969 INFO 12316 --- [ Thread-17] c.e.d.controller.ReentrantLockService : Thread-17 - 释放锁 2023-11-17 15:56:19.020 INFO 12316 --- [ Thread-16] c.e.d.controller.ReentrantLockService : Thread-16 - 获取锁成功执行加锁操作... 2023-11-17 15:56:23.901 INFO 12316 --- [ Thread-19] c.e.d.controller.ReentrantLockService : Thread-19在指定时间内无法获取锁。 2023-11-17 15:56:23.901 INFO 12316 --- [ Thread-20] c.e.d.controller.ReentrantLockService : Thread-20在指定时间内无法获取锁。 2023-11-17 15:56:23.909 INFO 12316 --- [ Thread-18] c.e.d.controller.ReentrantLockService : Thread-18在指定时间内无法获取锁。 2023-11-17 15:56:24.023 INFO 12316 --- [ Thread-16] c.e.d.controller.ReentrantLockService : Thread-16 - 加锁操作完成。 2023-11-17 15:56:24.046 INFO 12316 --- [ Thread-16] c.e.d.controller.ReentrantLockService : Thread-16 - 释放锁分析日志 这段日志展示了一个使用Redisson实现的分布式锁的情景。让我详细解释一下日志和代码的原理 获取锁Thread-17: Thread-17 成功获取了名为 “myReentrantLock” 的可重入锁。执行了一段需要锁保护的业务操作模拟了一个长时间的操作持有锁。 释放锁Thread-17: - Thread-17 完成了业务操作释放了锁。获取锁Thread-16: Thread-16 在 Thread-17 释放锁之后成功获取了相同的锁。执行了一段需要锁保护的业务操作然后释放了锁。 获取锁失败Thread-19, Thread-20, Thread-18: Thread-19, Thread-20, 和 Thread-18 在指定的等待时间内无法获取锁因为此时 Thread-16 持有锁。 总结原理: 通过redissonClient.getLock(myReentrantLock)创建了一个可重入锁对象。lock.tryLock(10, 30, TimeUnit.SECONDS)尝试获取锁在10秒内等待锁的自动释放时间为30秒。如果获取锁成功执行需要加锁的操作然后释放锁。其他线程在获取锁时如果超过指定时间未能成功获取会得到相应的提示。 这段代码通过Redisson实现了一个可重入的分布式锁确保在分布式环境下对共享资源的安全访问。成功获取锁的线程执行受保护的操作其他线程则需要等待或处理获取锁失败的情况。这有助于协调分布式系统中的并发访问防止竞争条件和数据不一致性。 阻塞与非阻塞 阻塞方式 在阻塞方式中线程在尝试获取锁时如果锁已被其他线程占用那么当前线程会被阻塞一直等到锁被释放后才能继续执行。在阻塞模式下线程可能会等待相当长的时间直到获取到锁。 ReentrantLock lock new ReentrantLock();// 阻塞方式获取锁 lock.lock(); try {// 执行需要锁保护的代码 } finally {lock.unlock(); } 非阻塞方式 在非阻塞方式中线程尝试获取锁时如果锁已被其他线程占用当前线程不会被阻塞而是立即返回一个结果告知是否成功获取锁。非阻塞方式下线程不会等待而是可以继续执行其他操作。 ReentrantLock lock new ReentrantLock();// 非阻塞方式尝试获取锁 if (lock.tryLock()) {try {// 执行需要锁保护的代码} finally {lock.unlock();} } else {// 未获取到锁的处理逻辑 } 看门狗Watchdog Redisson 使用看门狗Watchdog机制来保持分布式锁的有效性。看门狗是一种定时任务负责定期延长锁的过期时间确保在业务执行时间较长或者发生异常情况时锁不会过早释放。 下面是 Redisson 看门狗的简要原理 锁的过期时间 当获取分布式锁时会设置锁的过期时间通常是锁的租期。这个过期时间是在 Redis 中设置的表示锁在这段时间内有效。看门狗的作用 Redisson 的看门狗定期比如每隔一定时间检查当前线程持有的锁是否过期。如果锁的过期时间快到了看门狗会尝试续租延长锁的过期时间。续租操作 续租操作是通过发送一个延长锁过期时间的命令到 Redis。如果当前线程在续租时发生了异常比如网络异常看门狗会尽力保证在后续的定时任务中继续尝试续租。锁的释放 如果看门狗发现锁已经过期且无法续租它会尝试删除锁释放资源。这是为了防止因为业务执行时间较长或者发生异常情况导致锁一直被占用而不释放。线程关闭时的处理 Redisson 看门狗还处理了线程关闭的情况。如果获取锁的线程关闭了看门狗会立即释放锁以避免死锁情况。 通过看门狗机制Redisson 能够确保在使用分布式锁的场景下锁不会因为持有锁的线程异常退出或者执行时间过长而导致锁被过早释放。这提高了分布式锁的可靠性和稳定性。 源码解析 这段代码是 Redisson 中续租锁过期时间的方法。让我们逐步解析其中的关键部分 renewExpiration 方法 这个方法用于执行锁的过期时间续租操作。 private void renewExpiration() {ExpirationEntry ee EXPIRATION_RENEWAL_MAP.get(getEntryName());if (ee null) {return;}// 创建定时任务定时执行续租操作Timeout task commandExecutor.getConnectionManager().newTimeout(new TimerTask() {Overridepublic void run(Timeout timeout) throws Exception {// 获取续租信息ExpirationEntry ent EXPIRATION_RENEWAL_MAP.get(getEntryName());if (ent null) {return;}Long threadId ent.getFirstThreadId();if (threadId null) {return;}// 异步执行续租操作RFutureBoolean future renewExpirationAsync(threadId);future.onComplete((res, e) - {if (e ! null) {// 续租失败记录错误日志移除续租信息log.error(Cant update lock getRawName() expiration, e);EXPIRATION_RENEWAL_MAP.remove(getEntryName());return;}if (res) {// 续租成功重新调度续租任务renewExpiration();} else {// 续租失败取消续租任务cancelExpirationRenewal(null);}});}}, internalLockLeaseTime / 3, TimeUnit.MILLISECONDS); // 续租时间为租约时间的1/3// 将定时任务绑定到续租信息中ee.setTimeout(task); }internalLockLeaseTime 变量 定时任务创建 使用 commandExecutor.getConnectionManager().newTimeout 创建一个定时任务这个任务会在 internalLockLeaseTime / 3 毫秒后执行。 续租操作 在定时任务执行时异步执行 renewExpirationAsync 方法该方法负责向 Redis 发送命令更新锁的过期时间。 回调处理 在异步续租操作完成时根据续租操作的结果进行相应的处理。 如果续租成功重新调度下一次续租任务。如果续租失败取消续租任务并记录错误日志。 这个机制通过定时任务实现了定期的锁续租确保分布式锁在持有期间不会因为过期而被自动释放。 ​
http://www.ho-use.cn/article/10819708.html

相关文章:

  • 做网站常熟个性化网站建设公司
  • 湖北钟祥建设局网站娄星区建设局网站
  • 凡科建站弊端新冠最新消息实时数据
  • 利用淘宝视频服务做视频网站品牌推广公司是做什么的
  • 云南建设网站首页百度怎么发帖做推广
  • 制作一个视频网站pc端网站怎么做自适应
  • 温州网站建设优化公司民制作网站价格
  • 红酒网站制作淘客网站开发
  • 专业网站建设必要性设计主题网站
  • 烟台网站建设 烟台网亿网络公司网页设计流程的四个阶段
  • 浙江网站优化公司手机seo网站推广
  • 访问网站 403.14错误英文网站如何做关键词
  • 平台网站建设有哪些方面企业做响应式网站好吗
  • 多种专业网站建设小程序源码大全
  • 苏州市城市建设局网站汕头建站模板系统
  • 构建网站无障碍建设网站建设需要什么程序员
  • 网站打开不对网页制作公司是做什么的
  • 网站建设与维护工作内容电脑视频制作软件
  • 外贸公司网站建设费会计科目群晖wordpress错乱
  • 四川建设网有限责 任公司网站更合网站设计制作
  • 西宁圆井模板我自己做的网站wordpress建壁纸站
  • 在哪里可以建网站凡科投票
  • 青岛百度整站优化服务浙江银安建设有限公司网站
  • 长沙房产网站南宁网络推广方案
  • 做英文简历的网站做指甲的网站
  • 营销软文网站网站建设需要那些基础
  • 网站设计的专业流程河南网站建设及推广
  • 搭建织梦网站视频教程企业网站建设的经验心得
  • 上海公司做网站的价格网络优化app
  • 镇江市机关效能与作风建设网站开发一款游戏能赚多少钱