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

温州网站链接怎么做做视频后期的网站

温州网站链接怎么做,做视频后期的网站,池州市建设管理处网站,怎么制作图片文件夹“ 什么是分布式锁#xff1f;分布式锁是控制分布式系统之间同步访问共享资源的一种方式。在分布式系统中#xff0c;常常需要协调他们的动作。图片来自 Pexels如果不同的系统或是同一个系统的不同主机之间共享了一个或一组资源#xff0c;那么访问这些资源的时候#xff0… “ 什么是分布式锁分布式锁是控制分布式系统之间同步访问共享资源的一种方式。在分布式系统中常常需要协调他们的动作。图片来自 Pexels如果不同的系统或是同一个系统的不同主机之间共享了一个或一组资源那么访问这些资源的时候往往需要互斥来防止彼此干扰来保证一致性在这种情况下便需要使用到分布式锁。为什么要使用分布式锁为了保证一个方法或属性在高并发情况下的同一时间只能被同一个线程执行。在传统单体应用单机部署的情况下可以使用 Java 并发处理相关的 API(如 ReentrantLock 或 Synchronized)进行互斥控制在单机环境中Java 中提供了很多并发处理相关的 API。但是随着业务发展的需要原单体单机部署的系统被演化成分布式集群系统后由于分布式系统多线程、多进程并且分布在不同机器上这将使原单机部署情况下的并发控制锁策略失效单纯的 Java API 并不能提供分布式锁的能力。为了解决这个问题就需要一种跨 JVM 的互斥机制来控制共享资源的访问这就是分布式锁要解决的问题举个例子机器 A机器 B 是一个集群。AB 两台机器上的程序都是一样的具备高可用性能。AB 机器都有一个定时任务每天晚上凌晨 2 点需要执行一个定时任务但是这个定时任务只能执行一遍否则的话就会报错。那 AB 两台机器在执行的时候就需要抢锁谁抢到锁谁执行谁抢不到就不用执行了锁的处理锁的处理方式如下单个应用中使用锁(单进程多线程)Synchronize。分布式锁控制分布式系统之间同步访问资源的一种方式。分布式锁是控制分布式系统之间同步访问共享资源的一种方式。分布式锁的实现分布式锁的实现方式如下基于数据的乐观锁实现分布式锁基于 Zookeeper 临时节点的分布式锁基于 Redis 的分布式锁Redis 的分布式锁获取锁在 set 命令中有很多选项可以用来修改命令的行为以下是 set 命令可用选项的基本语法redis 127.0.0.1:6379SET KEY VALUE [EX seconds] [PX milliseconds] [NX|XX]- EX seconds 设置指定的到期时间(单位为秒)- PX milliseconds 设置指定的到期时间(单位毫秒)- NX: 仅在键不存在时设置键- XX: 只有在键已存在时设置方式 1推介   private static final String LOCK_SUCCESS  OK;   private static final String SET_IF_NOT_EXIST  NX;   private static final String SET_WITH_EXPIRE_TIME  PX;public static boolean getLock(JedisCluster jedisCluster, String lockKey, String requestId, int expireTime) {       // NX: 保证互斥性       String result  jedisCluster.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);       if (LOCK_SUCCESS.equals(result)) {           return true;      }       return false;  }方式 2public static boolean getLock(String lockKey,String requestId,int expireTime) {    Long result  jedis.setnx(lockKey, requestId);    if(result  1) {        jedis.expire(lockKey, expireTime);        return true;    }    return false;}注意推介方式 1因为方式 2 中 setnx 和 expire 是两个操作并不是一个原子操作如果 setnx 出现问题就是出现死锁的情况所以推荐方式 1。 释放锁方式 1del 命令实现public static void releaseLock(String lockKey,String requestId) {   if (requestId.equals(jedis.get(lockKey))) {       jedis.del(lockKey);  }}方式 2RedisLua 脚本实现(推荐)public static boolean releaseLock(String lockKey, String requestId) {       String script  if redis.call(get, KEYS[1])  ARGV[1] then returnredis.call(del, KEYS[1]) else return 0 end;       Object result  jedis.eval(script, Collections.singletonList(lockKey),Collections.singletonList(requestId));       if (result.equals(1L)) {           return true;}       return false;  }Zookeeper 的分布式锁 Zookeeper 分布式锁实现原理理解了锁的原理后就会发现Zookeeper 天生就是一副分布式锁的胚子。首先Zookeeper 的每一个节点都是一个天然的顺序发号器。在每一个节点下面创建子节点时只要选择的创建类型是有序(EPHEMERAL_SEQUENTIAL 临时有序或者 PERSISTENT_SEQUENTIAL 永久有序)类型那么新的子节点后面会加上一个次序编号。这个次序编号是上一个生成的次序编号加 1比如创建一个用于发号的节点“/test/lock”然后以他为父亲节点在这个父节点下面创建相同前缀的子节点。假定相同的前缀为“/test/lock/seq-”在创建子节点时同时指明是有序类型。如果是第一个创建的子节点那么生成的子节点为 /test/lock/seq-0000000000下一个节点则为 /test/lock/seq-0000000001依次类推等等。其次Zookeeper 节点的递增性可以规定节点编号最小的那个获得锁。一个 Zookeeper 分布式锁首先需要创建一个父节点尽量是持久节点(PERSISTENT 类型)然后每个要获得锁的线程都会在这个节点下创建个临时顺序节点由于序号的递增性可以规定排号最小的那个获得锁。所以每个线程在尝试占用锁之前首先判断自己是排号是不是当前最小如果是则获取锁。第三Zookeeper 的节点监听机制可以保障占有锁的方式有序而且高效。每个线程抢占锁之前先抢号创建自己的 ZNode。同样释放锁的时候就需要删除抢号的 Znode。抢号成功后如果不是排号最小的节点就处于等待通知的状态。等谁的通知呢不需要其他人只需要等前一个 Znode 的通知就可以了。当前一个 Znode 删除的时候就是轮到了自己占有锁的时候。第一个通知第二个、第二个通知第三个击鼓传花似的依次向后。Zookeeper 的节点监听机制可以说能够非常完美的实现这种击鼓传花似的信息传递。具体的方法是每一个等通知的 Znode 节点只需要监听 linsten 或者 watch 监视排号在自己前面那个而且紧挨在自己前面的那个节点。只要上一个节点被删除了就进行再一次判断看看自己是不是序号最小的那个节点如果是则获得锁。为什么说 Zookeeper 的节点监听机制可以说是非常完美呢一条龙式的首尾相接后面监视前面就不怕中间截断吗比如在分布式环境下由于网络的原因或者服务器挂了或者其他的原因如果前面的那个节点没能被程序删除成功后面的节点不就永远等待么其实Zookeeper 的内部机制能保证后面的节点能够正常的监听到删除和获得锁。在创建取号节点的时候尽量创建临时 Znode 节点而不是永久 Znode 节点。一旦这个 Znode 的客户端与 Zookeeper 集群服务器失去联系这个临时 Znode 也将自动删除。排在它后面的那个节点也能收到删除事件从而获得锁。说 Zookeeper 的节点监听机制是非常完美的。还有一个原因。Zookeeper 这种首尾相接后面监听前面的方式可以避免羊群效应。所谓羊群效应就是每个节点挂掉所有节点都去监听然后做出反映这样会给服务器带来巨大压力所以有了临时顺序节点当一个节点挂掉只有它后面的那一个节点才做出反映。Zookeeper 分布式锁实现示例Zookeeper 是通过临时节点来实现分布式锁import org.apache.curator.RetryPolicy;import org.apache.curator.framework.CuratorFramework;import org.apache.curator.framework.CuratorFrameworkFactory;import org.apache.curator.framework.recipes.locks.InterProcessMutex;import org.apache.curator.retry.ExponentialBackoffRetry;import org.junit.Before;import org.junit.Test;/*** ClassName ZookeeperLock* Description TODO* Author lingxiangxiang* Date 2:57 PM* Version 1.0**/public class ZookeeperLock {   // 定义共享资源   private static int NUMBER  10;   private static void printNumber() {       // 业务逻辑: 秒杀       System.out.println(*********业务方法开始************\n);       System.out.println(当前的值:   NUMBER);       NUMBER--;       try {           Thread.sleep(2000);      } catch (InterruptedException e) {           e.printStackTrace();      }       System.out.println(*********业务方法结束************\n);  }   // 这里使用Test会报错   public static void main(String[] args) {       // 定义重试的侧策略 1000 等待的时间(毫秒) 10 重试的次数       RetryPolicy policy  new ExponentialBackoffRetry(1000, 10);       // 定义zookeeper的客户端       CuratorFramework client  CuratorFrameworkFactory.builder()              .connectString(10.231.128.95:2181,10.231.128.96:2181,10.231.128.97:2181)              .retryPolicy(policy)              .build();       // 启动客户端       client.start();       // 在zookeeper中定义一把锁       final InterProcessMutex lock  new InterProcessMutex(client, /mylock);       //启动是个线程       for (int i  0; i 10; i) {           new Thread(new Runnable() {               Override               public void run() {                   try {                       // 请求得到的锁                       lock.acquire();                       printNumber();                  } catch (Exception e) {                       e.printStackTrace();                  } finally {                       // 释放锁                       try {                           lock.release();                      } catch (Exception e) {                           e.printStackTrace();                      }                  }              }          }).start();      }  }}基于数据的分布式锁我们在讨论使用分布式锁的时候往往首先排除掉基于数据库的方案本能的会觉得这个方案不够“高级”。从性能的角度考虑基于数据库的方案性能确实不够优异整体性能对比缓存Zookeeper、etcd数据库。也有人提出基于数据库的方案问题很多不太可靠。数据库的方案可能并不适合于频繁写入的操作。下面我们来了解一下基于数据库(MySQL)的方案一般分为三类基于表记录乐观锁悲观锁基于表记录要实现分布式锁最简单的方式可能就是直接创建一张锁表然后通过操作该表中的数据来实现了。当我们想要获得锁的时候就可以在该表中增加一条记录想要释放锁的时候就删除这条记录。为了更好的演示我们先创建一张数据库表参考如下CREATE TABLE database_lock (id BIGINT NOT NULL AUTO_INCREMENT,resource int NOT NULL COMMENT 锁定的资源,description varchar(1024) NOT NULL DEFAULT  COMMENT 描述,PRIMARY KEY (id),UNIQUE KEY uiq_idx_resource (resource)) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT数据库分布式锁表;①获得锁我们可以插入一条数据INSERT INTO database_lock(resource, description) VALUES (1, lock);因为表 database_lock 中 resource 是唯一索引所以其他请求提交到数据库就会报错并不会插入成功只有一个可以插入。插入成功我们就获取到锁。②删除锁INSERT INTO database_lock(resource, description) VALUES (1, lock);这种实现方式非常的简单但是需要注意以下几点①这种锁没有失效时间一旦释放锁的操作失败就会导致锁记录一直在数据库中其他线程无法获得锁。这个缺陷也很好解决比如可以做一个定时任务去定时清理。②这种锁的可靠性依赖于数据库。建议设置备库避免单点进一步提高可靠性。③这种锁是非阻塞的因为插入数据失败之后会直接报错想要获得锁就需要再次操作。如果需要阻塞式的可以弄个 for 循环、while 循环之类的直至 INSERT 成功再返回。④这种锁也是非可重入的因为同一个线程在没有释放锁之前无法再次获得锁因为数据库中已经存在同一份记录了。想要实现可重入锁可以在数据库中添加一些字段比如获得锁的主机信息、线程信息等。那么在再次获得锁的时候可以先查询数据如果当前的主机信息和线程信息等能被查到的话可以直接把锁分配给它。 乐观锁顾名思义系统认为数据的更新在大多数情况下是不会产生冲突的只在数据库更新操作提交的时候才对数据作冲突检测。如果检测的结果出现了与预期数据不一致的情况则返回失败信息。乐观锁大多数是基于数据版本(version)的记录机制实现的。何谓数据版本号即为数据增加一个版本标识在基于数据库表的版本解决方案中一般是通过为数据库表添加一个 “version”字段来实现读取出数据时将此版本号一同读出之后更新时对此版本号加 1。在更新过程中会对版本号进行比较如果是一致的没有发生改变则会成功执行本次操作如果版本号不一致则会更新失败。为了更好的理解数据库乐观锁在实际项目中的使用这里也就举了业界老生常谈的库存例子。一个电商平台都会存在商品的库存当用户进行购买的时候就会对库存进行操作(库存减 1 代表已经卖出了一件)。如果只是一个用户进行操作数据库本身就能保证用户操作的正确性而在并发的情况下就会产生一些意想不到的问题。比如两个用户同时购买一件商品在数据库层面实际操作应该是库存进行减 2 操作。但是由于高并发的情况第一个用户购买完成进行数据读取当前库存并进行减 1 操作由于这个操作没有完全执行完成。第二个用户就进入购买相同商品此时查询出的库存可能是未减 1 操作的库存导致了脏数据的出现【线程不安全操作】。数据库乐观锁也能保证线程安全通常代码层面我们都会这样做select goods_num from goods where goods_name  小本子;update goods set goods_num  goods_num -1 where goods_name  小本子;上面的 SQL 是一组的通常先查询出当前的 goods_num然后再 goods_num 上进行减 1 的操作修改库存。当并发的情况下这条语句可能导致原本库存为 3 的一个商品经过两个人购买还剩下 2 库存的情况就会导致商品的多卖。那么数据库乐观锁是如何实现的呢首先定义一个 version 字段用来当作一个版本号每次的操作就会变成这样select goods_num,version from goods where goods_name  小本子;update goods set goods_num  goods_num -1,version 查询的version值自增 where goods_name 小本子 and version查询出来的version其实借助更新时间戳(updated_at)也可以实现乐观锁和采用 version 字段的方式相似。更新操作执行前线获取记录当前的更新时间在提交更新时检测当前更新时间是否与更新开始时获取的更新时间戳相等。 悲观锁除了可以通过增删操作数据库表中的记录以外我们还可以借助数据库中自带的锁来实现分布式锁。在查询语句后面增加 FOR UPDATE数据库会在查询过程中给数据库表增加悲观锁也称排他锁。当某条记录被加上悲观锁之后其它线程也就无法再改行上增加悲观锁。悲观锁与乐观锁相反总是假设最坏的情况它认为数据的更新在大多数情况下是会产生冲突的。在使用悲观锁的同时我们需要注意一下锁的级别。MySQL InnoDB 引起在加锁的时候只有明确地指定主键(或索引)的才会执行行锁 (只锁住被选取的数据)否则 MySQL 将会执行表锁(将整个数据表单给锁住)。在使用悲观锁时我们必须关闭 MySQL 数据库的自动提交属性(参考下面的示例)因为 MySQL 默认使用 autocommit 模式。也就是说当你执行一个更新操作后MySQL 会立刻将结果进行提交。mysql SET AUTOCOMMIT  0;Query OK, 0 rows affected (0.00 sec)这样在使用 FOR UPDATE 获得锁之后可以执行相应的业务逻辑执行完之后再使用 COMMIT 来释放锁。我们不妨沿用前面的 database_lock 表来具体表述一下用法。假设有一线程A需要获得锁并执行相应的操作。那么它的具体步骤如下STEP1 - 获取锁SELECT * FROM database_lock WHERE id  1 FOR UPDATE;。STEP2 - 执行业务逻辑。STEP3 - 释放锁COMMIT。作者凌晶简介生活中的段子手目前就职于一家地产公司做 DevOPS 相关工作, 曾在大型互联网公司做高级运维工程师熟悉 Linux 运维Python 运维开发Java 开发DevOPS 常用开发组件等个人公众号stromling欢迎来撩我哦!编辑陶家龙出处https://blog.51cto.com/lingjing/2474793精彩文章推荐你再不知道分布式事务我就真的生气了Kafka架构原理也就这么回事精通那么多技术为何还是写出一堆“屎山”
http://wiki.neutronadmin.com/news/86475/

相关文章:

  • 贵州建设厅考试网站推广网站有哪些方式
  • 猎奇网站模板大流量网站 优化
  • 甘肃省建设厅网站玩客云 做网站服务器
  • 企业网站建设训大芬网站建设
  • 前端怎么做网站广州网站建设腾虎
  • 专业做网站哪家正规有没有做公章的网站
  • wordpress建网站缺点大良营销网站建设如何
  • 自己怎么做卖东西的网站表白网站是怎么做的
  • 网站开发应用到的技术名词今天31个省新增最新消息视频讲解
  • 网站带后台模板南京公司网页制作
  • 想建立一个网站怎么做wordpress slider
  • 杭州做网站小程序多少钱襄阳最新新闻消息
  • 哪些网站有设计缺点企业建设网站的母的
  • 深圳微网站搭建深圳视频网站开发
  • 做网站需要什么执照放射科网站建设
  • 眼科医院网站优化服务商淮安市做网站
  • 怎么查看一个网站做的外链互联网博客网站
  • 上海做展会的网站都有哪些新公司取名字大全参考
  • 博星卓越营销网站设计北京做冷冻牛羊肉的网站
  • 天津高端品牌网站建设海南医院网站建设
  • 东海县城乡建设局网站机械代工
  • 网站制作咨询公司wordpress add_filter
  • 临沂市建设局兰山区网站站长seo综合查询工具
  • 我公司网站开发技术优势网站建设人才有哪些
  • 深圳做营销网站制作管家婆crm123696
  • 怎么自己做刷东西的网站wordpress模板
  • 公司网站管理图片电商详情页模板
  • 万能搜索引擎网站淄博网站建设服务商
  • 关键词站长工具滨州论坛网站建设
  • 做网站后端企业管理专业