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

黄山市住房城乡建设厅网站金昌百度seo

黄山市住房城乡建设厅网站,金昌百度seo,四川建设网官网入口,wordpress简单的验证码1、为什么要使用分布式锁 锁是多线程代码中的概念#xff0c;只有多任务访问同一个互斥的共享资源时才需要锁。单机应用开发时一般使用synchronized或lock。多线程的运行都是在同一个JVM之下。应用是分布式集群#xff0c;属于多JVM的工作环境#xff0c;JVM之间已经无法通过…1、为什么要使用分布式锁 锁是多线程代码中的概念只有多任务访问同一个互斥的共享资源时才需要锁。单机应用开发时一般使用synchronized或lock。多线程的运行都是在同一个JVM之下。应用是分布式集群属于多JVM的工作环境JVM之间已经无法通过多线程的锁解决同步问题。 2、分布式锁的几种方式 分布式锁的核心思路是借助外力 解决多JVM进程操作共享数据时需要使用互斥锁的问题。 常见的方式 有 mysql数据库分布式锁zookeeper分布式锁redis分布式锁 3、搭建测试分布式锁的环境 【1】创建工程distributed-lock-study pom如下 父工程 ?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersionparentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion2.7.6/versionrelativePath/ !-- lookup parent from repository --/parentgroupIdcom.lyx/groupIdartifactIddistributed-lock-study/artifactIdversion0.0.1-SNAPSHOT/versionpackagingpom/packagingnamedistributed-lock-study/namedescriptiondistributed-lock-study/descriptionmodulesmodulemoduleA/modulemodulemoduleB/module/modulespropertiesjava.version8/java.versiondubbo.starter2.7.6/dubbo.starterdubbo.registry.zookeeper2.7.6/dubbo.registry.zookeepermysql-connection.version8.0.26/mysql-connection.versiondruid.version1.2.1/druid.versionmybatis-plus.version3.5.2/mybatis-plus.versionhutool.version5.7.17/hutool.version/properties dependencyManagementdependencies!-- Dubbo 依赖 --dependencygroupIdorg.apache.dubbo/groupIdartifactIddubbo-spring-boot-starter/artifactIdversion${dubbo.starter}/version/dependency!-- zookeeper 注册中心 依赖 --dependencygroupIdorg.apache.dubbo/groupIdartifactIddubbo-registry-zookeeper/artifactIdversion${dubbo.registry.zookeeper}/version/dependencydependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion${mysql-connection.version}/versionscoperuntime/scope/dependency!--druid连接池--dependencygroupIdcom.alibaba/groupIdartifactIddruid-spring-boot-starter/artifactIdversion${druid.version}/version/dependency!--mybatis-plus依赖--dependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-boot-starter/artifactIdversion${mybatis-plus.version}/version/dependency!--hutool--dependencygroupIdcn.hutool/groupIdartifactIdhutool-all/artifactIdversion${hutool.version}/version/dependency/dependencies/dependencyManagement/project【2】创建moduleA和moduleB两个模块 依赖 ?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersionparentgroupIdcom.lyx/groupIdartifactIddistributed-lock-study/artifactIdversion0.0.1-SNAPSHOT/version/parentgroupIdorg.example/groupIdartifactIdmoduleA/artifactIdpropertiesmaven.compiler.source8/maven.compiler.sourcemaven.compiler.target8/maven.compiler.targetproject.build.sourceEncodingUTF-8/project.build.sourceEncoding/propertiesdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdoptionaltrue/optional/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency!--mybatis-plus依赖--dependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-boot-starter/artifactId/dependencydependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdscoperuntime/scope/dependency!--druid连接池--dependencygroupIdcom.alibaba/groupIdartifactIddruid-spring-boot-starter/artifactId/dependency!--redis依赖--dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactId/dependency!--common-pool--dependencygroupIdorg.apache.commons/groupIdartifactIdcommons-pool2/artifactId/dependency!-- Redisson分布式锁使用--dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactId/dependencydependencygroupIdorg.redisson/groupIdartifactIdredisson-spring-boot-starter/artifactIdversion3.14.0/version/dependency!--基于Curator 客户端zookeeper的实现分布式锁 --dependencygroupIdorg.apache.curator/groupIdartifactIdcurator-framework/artifactIdversion4.0.1/version/dependencydependencygroupIdorg.apache.curator/groupIdartifactIdcurator-recipes/artifactIdversion4.0.1/version/dependency/dependenciesbuildpluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactIdconfigurationexcludesexcludegroupIdorg.projectlombok/groupIdartifactIdlombok/artifactId/exclude/excludes/configuration/plugin/plugins/build/project 【3】在两个模块中编写application.yml spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/lock_db?useUnicodetruecharacterEncodingutf-8serverTimezoneAsia/Shanghaiusername: rootpassword: 123456redis:host: 192.168.184.200port: 6379lettuce:pool:max-active: 8max-idle: 8min-idle: 0max-wait: 100ms server:port: 1111 # 两个模块的端口号不一样其他一样【4】编写启动类 SpringBootApplication MapperScan(top.psjj.ma.mapper) public class ModuleAApplication {public static void main(String[] args) {SpringApplication.run(ModuleAApplication.class,args);} }【5】准备数据库local_db,并出入下张表 SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS 0;-- ---------------------------- -- Table structure for t_goods -- ---------------------------- DROP TABLE IF EXISTS t_goods; CREATE TABLE t_goods (id int(0) NOT NULL AUTO_INCREMENT COMMENT 主键,goods varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL,count int(0) NULL DEFAULT NULL,PRIMARY KEY (id) USING BTREE ) ENGINE InnoDB CHARACTER SET utf8 COLLATE utf8_unicode_ci ROW_FORMAT Dynamic;-- ---------------------------- -- Records of t_goods -- ---------------------------- INSERT INTO t_goods VALUES (1, 手机, -1); INSERT INTO t_goods VALUES (2, 笔记本, 100);SET FOREIGN_KEY_CHECKS 1; 【6】编写po 、mapper 、service 、controller,两个模块代码完全一样 Data AllArgsConstructor NoArgsConstructor TableName(t_goods) public class Goods implements Serializable {Serialprivate static final long serialVersionUID -9084934747907815210L;TableId(type IdType.AUTO)private Integer id;private String goods;private Integer count; } public interface GoodsMapper extends BaseMapperGoods {Update(update t_goods set count count-1 where id#{id})void subCount(Integer id); }public interface GoodsService extends IServiceGoods {void updateGoodsCount(Integer id); }Service public class GoodsServiceImpl extends ServiceImplGoodsMapper, Goods implements GoodsService {Overridepublic void updateGoodsCount(Integer id) {Goods goods this.baseMapper.selectById(id);Integer count goods.getCount();if(count0){try {Thread.sleep(5000);} catch (InterruptedException e) {throw new RuntimeException(e);}this.baseMapper.subCount(id);}} } RestController RequestMapping(/goods) public class GoodsController {Autowiredprivate GoodsService goodsService;RequestMapping(/update)public String updateGoodsCount(Integer id){goodsService.updateGoodsCount(id);return ok;} }4、基于Mysql实现的分布式锁 4.1 mysql实现分布式锁原理 首先单独分离出一台mysql数据库所有服务要想操作文件共享资源那么必须先在mysql数据库中插入一个标志插入标志的服务就持有了锁并对文件进行操作 。操作完成后主动删除标志进行锁释放其余服务会一直查询数据库看是否标志有被占用直到没有标志占用时自己才能写入标志获取锁。 4.2  问题 如果服务jvm1宕机或者卡顿了会一直持有锁未释放造成死锁。因此需要一个监视锁进程时刻监视锁的状态如果超过一定时间未释放就要进行主动清理锁标记然后供其他服务继续获取锁。如果监视锁字段进程和jvm1同时挂掉依旧不能解决死锁问题于是又增加一个监视锁字段进程这样一个进程挂掉还有另一个监视锁字段进程可以对锁进行管理。但是又诞生一个新的问题两个监视进程必须进行同步否则对于过期的情况管理存在不一致问题。 因此存在以下问题并且方案变得很复杂 监视锁字段进程对于锁的监视时间周期过短仍旧会造成多售jvm1还没处理完其持有的锁就被主动销毁造成多个服务同时持有锁进行操作。 监视锁字段进程对于锁的监视时间周期过长会造成整个服务卡顿过长吞吐低下。 多个监视锁字段进程间的同步问题。 当一个jvm持有锁的时候其余服务会一直访问数据库查看锁会造成其余jvm的资源浪费。 4.2 基于update实现分布锁特殊情况 关于分布式锁因为代码直接执行语句有数据库行级锁不会产生超卖问题。 mysql行锁解决分布锁问题演示修改的代码  ServiceImpl中 //mysql行锁解决分布锁问题 try {Thread.sleep(5000); } catch (InterruptedException e) {throw new RuntimeException(e); } this.baseMapper.subCount2(goods); mapper中  Update(update t_goods set countcount-1 where id#{id} and count0) void subCount2(Goods goods); 5、基于Redis实现分布式锁 5.1 Redis实现分布式锁优点 1Redis有很高的性能  2Redis命令对此支持较好实现起来比较方便 命令介绍: setnx SETNX key val当且仅当key不存在时set一个key为val的字符串返回1若key存在则什么都不做返回0。 expire : expire key timeout为key设置一个超时时间单位为second超过这个时间锁会自动释放避免死锁。 delete :  delete key删除key 在使用Redis实现分布式锁的时候主要就会使用到这三个命令。 5.2 Redis实现分布式锁原理 获取锁的时候使用setnx加锁并使用expire命令为锁添加一个超时时间超过该时间则自动释放锁锁的value值为一个随机生成的UUID通过此在释放锁的时候进行判断。获取锁的时候还设置一个获取的超时时间若超过这个时间则放弃获取锁。释放锁的时候通过UUID判断是不是该锁若是该锁则执行delete进行锁释放。 5.3 Redisson分布式锁使用 1)引入依赖 !-- Redisson分布式锁使用-- dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactId /dependencydependencygroupIdorg.redisson/groupIdartifactIdredisson-spring-boot-starter/artifactIdversion3.14.0/version /dependency2)配置文件 spring:redis:host: 192.168.220.110port: 6379 3)代码实现 //创建锁 RLock lock redissonClient.getLock(goods- id); //加锁 try {lock.lock();Goods goods this.baseMapper.selectById(id);Integer count goods.getCount();if(count0){try {Thread.sleep(5000);} catch (InterruptedException e) {throw new RuntimeException(e);}this.baseMapper.subCount(id);} } catch (RuntimeException e) {throw new RuntimeException(超卖了); } finally {//释放锁lock.unlock(); } 5.4 总结 可以使用缓存代替数据库实现分布式锁性能根号。同时多数缓存服务时集群部署可以避免单点问题。 很多缓存服务提供了实现分布式锁的方法和对数据过期自动删除的支持如Tair的put方法redis 的setnx方法(Redisson是Redis官方推荐的Java版的Redis客户端) 。可以设置超时时间控制锁的释放。 使用缓存实现分布式锁的优点性能好实现起来较为方便。 使用缓存实现分布式锁的缺点 通过超时时间来控制所得失效时间不靠谱。 6、 基于Zookeeper实现的分布式锁 6.1 Zookeeper的特点 Zookeeper的每一个节点都是一个天然的顺序发号器zookeeper有以下特点 维护了一个有层次的数据节点类似文件系统。 有临时节点持久节点临时有序节点分布式锁实现基于的数据节点) 持久有序节点。 zookeeper可以和client客户端通过心跳机制保持长连接断开连接自动删除临时节点。 zookeeper的节点上可以注册上用户事件(自定义)节点数据删除等事件都可以触发自定义事件。 zookeeper保持了统一视图各服务对于状态信息获取满足一致性。 创建有序节点会有编号 6.2 Zookeeper实现分布式锁原理 创建一个目录mylock 线程A想获取锁就在mylock目录下创建临时顺序节点 获取mylock目录下所有的子节点然后获取比自己小的兄弟节点如果不存在则说明当前线程顺序号最小获得锁 线程B获取所有节点判断自己不是最小节点设置监听比自己小的节点 线程A处理完删除自己的节点线程B监听到变更事件判断自己是不是最小的节点如果是则获得锁。 6.3 Zookeeper解决的问题 锁无法释放 在创建锁的时候客户端会在ZK中创建一个临时节点一旦客户端获取到锁之后突然挂掉Session连接断开那么这个临时节点就会自动删除掉。锁就会释放。 非阻塞锁 客户端可以通过在ZK中创建顺序节点并且在节点上绑定监听器一旦节点有变化Zookeeper会通知客户端客户端可以检查自己创建的节点是不是序号最小如果是那么自己就获取到锁。 不可重入   客户端在创建节点的时候把当前客户端的主机信息和线程信息直接写入到节点中下次想要获取锁的时候和当前最小的节点中的数据比对。如果信息一样直接获取到锁如果不一样就再创建一个临时的顺序节点参与排队。 单点问题 ZK是集群部署的只要集群中有半数以上的机器存活就可以对外提供服务。   6.4 基于Curator 客户端实现分布式锁 Curator Framework提供了简化使用zookeeper更高级的API接口。它包涵很多优秀的特性主要包括以下三点 自动连接管理自动处理zookeeper的连接和重试存在一些潜在的问题可以watch NodeDataChanged event和获取updateServerList;Watches可以自动被Cruator recipes删除 更干净的API简化raw zookeeper方法事件等提供现代流式API接口 Recipe实现leader选举分布式锁path缓存和watcher,分布式队列等。 依赖 dependencygroupIdorg.apache.curator/groupIdartifactIdcurator-framework/artifactIdversion4.0.1/version /dependency dependencygroupIdorg.apache.curator/groupIdartifactIdcurator-recipes/artifactIdversion4.0.1/version /dependency 代码 //zookeeper 分布式锁解决超卖问题 //1.创建zookeeper连接 RetryPolicy retryPolicy new ExponentialBackoffRetry(1000, 3); CuratorFramework client CuratorFrameworkFactory.newClient(192.168.184.200:2181, retryPolicy); client.start(); //创建分布式锁 InterProcessMutex interProcessMutex new InterProcessMutex(client,/ordersettinglock); //加锁 try {interProcessMutex.acquire();Goods goods this.baseMapper.selectById(id);Integer count goods.getCount();if(count0){try {Thread.sleep(5000);} catch (InterruptedException e) {throw new RuntimeException(e);}this.baseMapper.subCount(id);} } catch (Exception e) {throw new RuntimeException(超卖了); } finally {//释放锁try {interProcessMutex.release();} catch (Exception e) {throw new RuntimeException(e);} } 6.5 总结 优点: 有效的解决单点问题、不可重入问题、非阻塞问题、锁无法释放问题。实现起来简单。 缺点 性能上不如使用缓存实现分布式锁。需要对ZK的原理有所了解比较复杂 。 7、分布式锁总结 上面几种方式哪种方式都无法做到完美。就像CAP一样在复杂性、可靠性、性能等方面无法同时满足所以根据不同的应用场景选择最适合自己的才是王道。 理解难易程度 数据库缓存redis) zookeeper. 复杂性 zookeeper  缓存 数据库 性能 缓存 zookeeper 数据库 可靠性 zookeeper 缓存 数据库
http://www.zqtcl.cn/news/197367/

相关文章:

  • 商城网站备案要求wordpress插件 手机版
  • 北京市网站备案查询石家庄建设信息网必须交费吗
  • 北京优化网站方法四川省建设局网站
  • 怎么做网站能快速赚钱重庆快速建站
  • 河南专业网站建设公司首选培训心得简短200字
  • 销售网站开发业务高端建网站多少钱
  • 几个做ppt的网站知乎青岛高品质网站制作
  • 网站seo插件wordpress模板中文版
  • 夹江移动网站建设手机网站微信登陆
  • 浏阳做网站网易企业邮箱注册官网
  • 东莞网站建设是什么意思自己怎么做企业网站建设
  • 免费的网站申请泰州网站整站优化
  • 毕业设计做企业门户网站过期域名网站
  • 网站建设和风险分析简单网页制作代码模板
  • 照片展示网站那个网站可以做攻略
  • 优秀网站设计赏析万网网站备案多久
  • 网站维护服务有哪些电商网站
  • 部门网站建设总结鼎城网站建设
  • 制作网站的模板下载大型商城购物平台开发
  • wordpress 分类文章置顶整站优化推广品牌
  • 网站手机验证码如何做官方网站在家做兼职
  • 东莞三合一网站制作网站建设 千助
  • 114网站做推广怎么样江苏建设培训网站
  • 如何让网站做网页适配网站上的产品五星怎样做优化
  • 怎么做网站排名优化免费jq网站模板
  • 源码时代培训机构官网自己建网站怎么做seo
  • 宜都网站制作济南比较大的网站制作公司
  • 怎么用电脑做网站主机假网站怎么制作
  • 网站 微信网络营销方案设计心得
  • 淘宝客 wordpress网站wordpress类似的工具