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.rhkb.cn/news/207499.html

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

相关文章

为何Go爬虫依然远没有Python爬虫流行

编程语言有很多种&#xff0c;哪种编程适合爬虫具体还得因项目而异。就以我常用GO和Python语言交替来写爬虫一样&#xff0c;针对不同项目采用不同语言来写爬虫。至于python为什么相比go更受欢迎&#xff0c;我总结了下面几种原因。 Go语言和Python语言在爬虫开发上的流行度差…

稻盛和夫:毕生经验总结出的36条管理经验,总有一条能戳中你。

大家好&#xff0c;我是老原。 进入职场&#xff0c;每个道理在每个人身上都有不同的理解。 大家经理不同&#xff0c;血泪自然不同&#xff0c;毕竟人类的悲喜并不相通&#xff0c;只有总结下来的经验才最有用。 我平时给你们分享的硬干货比较多&#xff0c;这种软道理写的…

Git——使用Git进行程序开发

主要介绍个人开发提交记录的主要流程&#xff0c;包括以下内容&#xff1a; 索引- 提交的暂存区。查看工作的状态和内部变更。如何读取用于描述变更的已扩展统一diff格式。支持查询和交互的提交&#xff0c;修改提交。创建、显示和选择&#xff08;切换&#xff09;分支。切换…

数据结构总复习

文章目录 线性表动态分配的顺序存储结构链式存储 栈与队列栈顺序栈链栈 队列 线性表 动态分配的顺序存储结构 通过分析代码&#xff0c;我们发现&#xff0c;要注意什么&#xff1a; 要分清你的下标Insert 函数是可以用来没有元素的时候&#xff0c;增加元素的Init(或者Crea…

Servlet概念视频笔记

学习地址:121-尚硅谷-Servlet-什么是Servlet_哔哩哔哩_bilibili 目录 1.Servlet技术 a.什么是Servlet b.手动实现Servlet程序 c.url地址如何定位到Servlet程序去访问 d.Servlet的生命周期 e.GET 和 POST 请求的分发处理 f.通过继承 HttpServlet 实现 Servlet程序 g.使用…

微服务架构:解析分布式系统的演进

目录 微服务是什么&#xff1f; 微服务的优势 微服务的挑战 应对微服务挑战的方法 结论 在当今快速发展的软件开发领域&#xff0c;微服务架构成为一种备受瞩目的设计理念&#xff0c;被广泛应用于构建灵活、可扩展的分布式系统。本文将深入探讨什么是微服务&#xff0c;为…

论文阅读:“Appearance Capture and Modeling of Human Teeth”

文章目录 AbstractIntroductionMethod OverviewTeeth Appearance ModelEnamelDentinGingiva and oral cavity Data AcquisitionImage captureGeometry capture ResultsReferences Abstract 如果要为电影&#xff0c;游戏或其他类型的项目创建在虚拟环境中显示的人类角色&#…

模糊C均值(Fuzzy C-means,FCM)聚类的可运行的python程序代码,复制即可用!!切记需要安装库 scikit-fuzzy

文章目录 前言一、安装库 scikit-fuzzy二、具体程序代码&#xff08;复制可运行&#xff09;三、结果展示总结 前言 模糊C均值&#xff08;Fuzzy C-means&#xff0c;FCM&#xff09;聚类是一种软聚类方法&#xff0c;它允许数据点属于多个聚类&#xff0c;每个数据点对所有聚…

Matlab 点云线性指数计算(加权)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 思路其实很简单,即对每个邻近点集中的点,根据其到点集中心的距离进行加权处理(权重函数),之后再基于加权之后的点获取其协方差矩阵,最后再求取其相关的特征值,以此来获取该点的线性指数。相关公式如下所示:…

IntelliJ IDEA安装使用教程

IntelliJ IDEA是一个流行的Java 集成开发环境&#xff08;IDE&#xff09;&#xff0c;由JetBrains公司开发。它是一款全功能的IDE&#xff0c;支持多种编程语言&#xff0c;如Java、Kotlin、Groovy、Scala、Python、JavaScript、HTML、CSS等等。IntelliJ IDEA 提供了高效的代码…

docker-compose脚本编写及常用命令

安装 linux DOCKER_CONFIG/usr/local/lib/docker/cli-plugins sudo mkdir -p $DOCKER_CONFIG/cli-plugins sudo curl -SL https://521github.com/docker/compose/releases/download/v2.6.1/docker-compose-linux-x86_64 -o $DOCKER_CONFIG/cli-plugins/docker-compose sudo c…

AntDB“超融合+流式实时数仓”——颠覆50年未变的数据库内核

流式处理引擎&#xff0c;颠覆50年未变的数据库内核 流式处理的概念 2001年9月11日&#xff0c;美国世贸大楼被袭击&#xff0c;美国国防部第一次将“主动预警”纳入国防的宏观战略规划。而IBM作为当时全球最大的IT公司&#xff0c;承担了大量基础支撑软件研发的任务。其中200…

2021年11月10日 Go生态洞察:Twelve Years of Go

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

计算机网络:快速了解网络框架

文章目录 前言一、什么是Internet&#xff1f;1.从具体构成角度什么是协议&#xff1f; 2.从服务角度3小结 二、网络边缘1.采用网络设施面向连接服务&#xff08;TCP&#xff09;2.采用基础设施的无连接服务&#xff08;UDP&#xff09; 三、网络的核心1.电路交换2.分组交换3.分…

软件工程 - 第8章 面向对象建模 - 2 静态建模

静态建模&#xff08;类和对象建模&#xff09; 类和对象模型的基本模型元素有类、对象以及它们之间的关系。系统中的类和对象模型描述了系统的静态结构&#xff0c;在UML中用类图和对象图来表示。 类图由系统中使用的类以及它们之间的关系组成。类之间的关系有关联、依赖、泛…

Google Chrome 下载 (离线版)

1 访问网址 Google Chrome 网络浏览器 2 点击 下载Chrome 3 直接运行 ChromeStandaloneSetup64.exe 其他&#xff1a; ####################### 谷歌浏览器 (Google Chrome) 最新版离线安装包下载 https://www.iplaysoft.com/tools/chrome/#google_vignette Google Chrome …

【译】Spring 6 入参数据校验: 综合指南

原文地址&#xff1a;Spring 6 Programmatic Validator: A Comprehensive Guide 一、前言 在 Spring 6.1 中&#xff0c;有一个非常值得注意的重要改进——编程式验证器实现。Spring 长期以来一直通过注解支持声明式验证&#xff0c;而 Spring 6.1 则通过提供专用的编程式验证…

kafka学习笔记(一)--脑裂

我知道你想裂&#xff0c;但你先别裂 目录 脑裂Kafka脑裂实验Kafka如何防止脑裂--Leader Epochepoch的局限性ISR列表ISR列表的伸缩机制 脑裂 用集群部署的大多数的分布式系统无可避免会面临脑裂问题。简单来说&#xff0c;脑裂就是在同一时刻出现了两个“Leader&#xff08;或…

Vue+Element-ui实例_在form中动态校验tag标签

1.开发需求 在日常开发中&#xff0c;我们会遇到form表单的动态添加和校验&#xff0c;当我们需要在动态添加的内容中再次动态使用输入框的时候&#xff0c;就会变得很繁琐&#xff0c;我在网上找了很多案例&#xff0c;没有符合自己需求的内容&#xff0c;只好闲暇时间自己搞…

css加载会造成阻塞吗??

前言 前几天面试问到了这个问题&#xff0c;当时这个答得不敢确定哈哈&#xff0c;虽然一面还是过了 现在再分析下这个&#xff0c;总结下&#xff0c;等下次遇到就能自信得回答&#xff0c;666 准备工作 为了完成本次测试&#xff0c;先来科普一下&#xff0c;如何利用chr…