java分布式锁分布式锁

java分布式&锁&分布式锁

  1. 锁的作用:有限资源的情况下,控制同一时间段,只有某些线程(用户/服务器)能访问到资源。
    在这里插入图片描述
  2. 锁在java中的实现:
    • synchronized关键字
    • 并发包的类
  3. 缺点:只对单个的jvm有效
    在这里插入图片描述

分布式锁

  1. 为什么实现分布式锁
    • 有限资源的情况下,控制同一段时间只有某些用户/服务器才能访问到资源
    • 单个锁只对单个jvm有效
  2. 分布锁实现(核心思想,先来server把数据改成自己的标识,后来的人发现标识已经存在就等待)
    • 抢锁机制 ==> 同一时间只有一个服务器能抢到资源 ==>
      1. Mysql数据库实现,数据库中有一个字段标识锁,哪个服务器先到达数据库,就将此标识改为自己服务器的值,下一个服务器查到达查看不为空就等待,知道此上一个服务器用完,将标识位改为空时,方可用。
        • 查select(控制只有一个服务器在查)(1.select for update 行级锁,2.乐观锁)
        • 改update
      2. redis实现,存标识。读写速度快,支持setnx,lua脚本实现
        • 原理:使用redis的setnx方法保证原子性质
          setnx:set if not exist如果不存在,则设置,只有设置成功才会返回true,否则返回false
          在这里插入图片描述
        • 注意1: 用完锁之后要释放,防止在释放之前服务器出现意外,因此要设置过期时间
        • 注意2:如果方法执行时间过长,锁提前过期,出现多个服务器同时执行。=> 续期(redisson中提供续期机制,原理:监听当前线程,默认过期时间是30s,每10s续期一次(补充到30s),如果线程挂了,则不会续期,如果debug模式也会被当成服务器宕机)。
        • 注意3:连锁效应:释放了其他server的锁 .=> 判断如果不是我的锁就不释放
        • 注意4:释放锁的时候,有可能先判断出是自己的锁,但是这时候锁过期了,会释放其他服务器/用户的锁 => 判断和释放的时候不允许其他任何的方法进入,redis原子性操作。配合redis+lua脚本。
    1. Zookeeper实现

控制定时任务的执行(在同一时间只有一个服务器能执行)

  1. 原因:

    • 浪费资源,假设有1000台服务器同时工作
    • 脏数据
      在这里插入图片描述
  2. 实现方式

    1. 分离定时任务,把控制定时任务从主程序中拆开(成本太大)
      在这里插入图片描述

    2. 配置,写死配置,每个服务器都执行定时任务,但是只有ip符合配置的才真实执行业务逻辑,其他的直接返回。
      在这里插入图片描述

    3. ☆动态配置,这个配置是可以轻松的跟新的,把配置写到数据库,Redis,配置中心(Nacos,Apollo,spring Cloud config)(问题:如果服务器数据太多,ip不可控制)
      在这里插入图片描述

    4. 分布式锁【只有抢到锁的服务器才能执行定时任务】

      在这里插入图片描述

Reddisson实现分布式锁

  1. Redisson:是一个java操作Redis的客户端,提供了大量的分布式数据集来简化对Redis的操作和使用,可以让开发者像使用本地集合一样使用Redis,完全感觉不到Redis的存在。
    redisson官网:redisson
  2. Redisson使用方法
    1. 支持springboot整合Rdisson,写配置,默认整合客户端。(版本迭代太快)
    2. 只引入Redisson,自己创建客户端
      1. 引入项目依赖Redisson类库
         <!--https://github.com/redisson/redisson#quick-start--><dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.21.3</version></dependency>
        
      2. 新建redisson客户端
        /*** redisson配置*/
        @Configuration
        @ConfigurationProperties(prefix = "spring.redis")
        @Data
        public class RedissonConfig {private String host;private String port;@Beanpublic RedissonClient redissonClient(){// 1. 创建配置对象Config config = new Config();String redisAddress = String.format("redis://%s:%s",host,port);config.useSingleServer().setAddress(redisAddress).setDatabase(3);// 2. 创建实例RedissonClient redisson = Redisson.create(config);return redisson;}
        }
        
      3. 使用锁实现缓存预热
        waitTime = 0 只抢一次
        /*** 缓存预热任务*/
        @Slf4j
        public class PreCacheJob {@Resourceprivate RedisTemplate<String, Object> redisTemplate;@Resourceprivate UserService userService;@Resourcepublic UserMapper userMapper;//重点用户private List<Long> mainUserList = Arrays.asList(1L);//引入redisson客户端@Resourceprivate RedissonClient redissonClient;//每天执行,预热推荐用户@Scheduled(cron = "0 31 19 * * ? ")public void doCacheRecommendUser() {RLock lock = redissonClient.getLock("yupao:precachejob:docache:lock");try {//waitTime:其他线程等待的时间,因为我们缓存预热每天只做一次,所以只要有一个线程拿到锁就//leaseTime:锁过期时间if (lock.tryLock(0, 30000L, TimeUnit.MILLISECONDS)) {//是否拿到锁for (Long userId : mainUserList) {QueryWrapper<User> queryWrapper = new QueryWrapper<>();Page<User> userPage = userService.page(new Page<>(1, 20),queryWrapper);String redisKey = String.format("yupao:user:recommend:%s", userId);ValueOperations<String, Object> valueOperations =redisTemplate.opsForValue();//写缓存try {valueOperations.set(redisKey, userPage, 30000,TimeUnit.MILLISECONDS);} catch (Exception e) {log.error("redis set key error", e);}}}} catch (InterruptedException e) {log.error("doCacheRecommendUser error",e);} finally {//释放自己的锁if (lock.isHeldByCurrentThread()) {//是否是当前线程System.out.println("unlock: " + Thread.currentThread().getId());lock.unlock();}}}
        }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/177720.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Flutter】graphic图表的快速上手

简介 graphic是一个数据可视化语法和Flutter图表库。 官方github示例 网上可用资源很少,只有作者的几篇文章,并且没有特别详细的文档,使用的话还是需要一定的时间去调研,在此简单记录。 示例 以折线图为例(因为我只用到了折线图,但其他的图大差不差) 创建一个两个文…

世微 舞台灯深度调光 大功率 dc-dc降压恒流驱动IC APS54083

产品描述 APS54083 是一款 PWM 工作模式,高效率、外围简单、外置功率 MOS 管&#xff0c;适用于 5-220V 输入高精度降压 LED 恒流驱动芯片。输出最大功率150W最大电流 6A。APS54083 可实现线性调光和 PWM 调光&#xff0c;线性调光脚有效电压范围 0.5-2.5V.PWM 调光频率范围 10…

C++ :静态成员

静态成员 静态成员就是在成员变量和成员函数前加上关键字 static &#xff0c;称为静态成员 静态成员分为&#xff1a; 静态成员变量 1.所有对象共享同一份数据 2.在编译阶段分配内存 3.类内声明&#xff0c;类外初始化 静态成员函数 1.所有对象共享同一个函数 2.静态成…

第29期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大型语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以…

C# 实现微信退款及对帐

目录 需求 基础准备 关键代码 操作界面 ​编辑 退款订单类及方法 退款功能实现 对帐 支付商家后台相关要点 实时交易帐单查询 精确交易帐单查询 小结 需求 在招聘报名系统里&#xff0c;考务费支付是其中一个环节&#xff0c;支付方式很多种&#xff0c;比如银联、…

操作系统CLOCK算法

操作系统时钟(CLOCK)置换算法_时钟置换算法-CSDN博客 前七步相同 第八步的时候 发现页面在内存中 标记位变成1 但是指针不需要移动。

什么软件可以去视频水印?分享3个超实用去水印工具

什么软件可以去视频水印&#xff1f;短视频已然成为了我们日常生活或工作的一部分&#xff0c;当我们遇到感兴趣的视频想保存发现无法保存&#xff0c;或者保存后留有水印&#xff0c;非常影响我们视频观看度和分享欲&#xff0c;为了解决这一问题&#xff0c;许多针对视频水印…

如何用CHAT写“科技探索者”视频号运营方案

问CHAT&#xff1a;生成一篇“科技探索者”视频号运营方案&#xff0c;要求内容&#xff1a; &#xff08;1&#xff09;视频号的定位、面向的人群、主要发布哪方面的内容 &#xff08;2&#xff09;视频号的内容设计&#xff08;用什么样的方式来体现、最好有内容创意&#xf…

学习笔记-瑞吉外卖项目实战(一)

软件开发整体介绍 软件开发流程 角色分工 软件环境 瑞吉外卖项目介绍 项目介绍 产品原型介绍 技术选型 功能架构 角色 开发环境搭建 数据 创建database reggie&#xff0c;在里面创建表&#xff1a; maven 创建springboot项目并导入相关依赖坐标&#xff1a; 我们可以在项目…

【已解决】AttributeError: module ‘matplotlib‘ has no attribute ‘imshow‘

首先 在学习OpenCV的第一个程序&#xff0c;碰到这个问题记录一下。首先我已经安装好了matplotlib 如下图&#xff1a; 所以可以排除的就是我已经具备了这个库&#xff0c;那就是我在调用的时候出现的问题。 其次 回到pycharm&#xff0c;检查一下代码并做出如下的修改。 …

通达信抛物线SAR指标原理详解、参数设置及选股公式

抛物线指标(SAR)是由技术分析大师威尔斯威尔德(Welles Wilder)发明的&#xff0c;在其1978 年出版的《技术交易系统新概念》一书中介绍了该指标。SAR指标通过跟踪股票价格的动态变化&#xff0c;在走势图上以一系列点的形式显示&#xff0c;提供了一种判断趋势反转的方法&#…

鸿蒙应用开发-初见:入门知识、应用模型

基础知识 Stage模型应用程序包结构 开发并打包完成后的App的程序包结构如图 开发者通过DevEco Studio把应用程序编译为一个或者多个.hap后缀的文件&#xff0c;即HAP一个应用中的.hap文件合在一起称为一个Bundle&#xff0c;bundleName是应用的唯一标识 需要特别说明的是&…

某医院小程序存在支付漏洞和越权

某医院小程序存在支付漏洞和越权查看他人身份证&#xff0c;手机号&#xff0c;住址等信息 一个医院线上的小程序 登陆后点击个人信息&#xff0c;抓包&#xff0c;放到repeter模块&#xff0c; 修改strUserID参数可以越权查看别人信息 放intruder模块可以跑数据&#xff0c;这…

Redis缓存设计典型问题

目录 缓存穿透 缓存失效&#xff08;击穿&#xff09; 缓存雪崩 热点缓存key重建优化 缓存与数据库双写不一致 缓存穿透 缓存穿透是指查询一个根本不存在的数据&#xff0c; 缓存层和存储层都不会命中&#xff0c; 通常出于容错的考虑&#xff0c; 如果从存储层查不到数据…

MybatisPlus改造逻辑删除有多方便

MybatisPlus的逻辑删除可以有效保留历史数据。之前没有用逻辑删除的项目&#xff0c;想改造成逻辑删除总共需要几步&#xff1f; 答案&#xff1a;4步搞定 一、修改pom.xml的MybatisPlus版本&#xff08;注意版本兼容性&#xff09; <properties>...<!--<mybatis-…

anyRTC 融合音视频能力底座:助力企业数字化转型

随着全球化的发展&#xff0c;产业竞争日益激烈。数字化转型和创新成为了企业提高竞争力、实现可持续发展的重要手段&#xff0c;面对产业结构调整、资源环境挑战、数字技术与创新带来的行业颠覆与机遇&#xff0c;企业需要进行数字化转型和创新以适应新环境和新时代的挑战。 …

P13 C++ 类 | 结构体内部的静态static

目录 01 前言 02 类内部创建静态变量的例子 03 在类的内部创建静态变量的作用 04 最后的话 01 前言 本期我们讨论 static 在一个类或一个结构体中的具体情况。 在几乎所有面向对象的语言中&#xff0c;静态在一个类中意味着特定的东西。这意味着在类的所有实例中&#xff…

Springbot启动报错-类文件具有错误的版本 61.0, 应为 52.0

错误再现&#xff1a; 启动Springboot项目时候报错 java: 无法访问org.springframework.boot.SpringApplication 错误的类文件: /D:/Maven/apache-maven-3.6.3/repository/org/springframework/boot/spring-boot/3.0.0/spring-boot-3.0.0.jar!/org/springframework/boot/Sprin…

vue2+el-select实现分页加载更多功能

需求&#xff1a; 由于项目下拉框数据过多&#xff0c;一次性加载完&#xff0c;会有性能问题&#xff0c;于是希望可以增加分页加载更多功能。 实现效果&#xff1a; 如上图&#xff1a;点击“点击加载更多”按钮&#xff0c;实现分页加载下一页&#xff0c;直到最后一页&am…

香港优才计划是什么意思?一文详解2023年最新政策!

香港优才计划是什么意思&#xff1f;一文详解2023年最新政策&#xff01; 目前香港优才计划申请火热&#xff0c;但是还是有很多新手不太了解这个项目&#xff0c;跟风申请绝对不是什么好事&#xff0c;先了解清楚再考虑也是对自己对家人的一种交代。这篇文章就再来科普下。 优…