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

北京网站开发公司有哪些百度 竞价排名

北京网站开发公司有哪些,百度 竞价排名,网站的运作方式,会员管理系统开发Java技术栈 —— Redis的雪崩、穿透与击穿 〇、实验的先导条件#xff08;NginxJmeter#xff09;一、Redis缓存雪崩、缓存穿透、缓存击穿1.1 雪崩1.2 穿透1.3 击穿 二、Redis应用场景——高并发2.1 单机部署的高并发问题与解决#xff08;JVM级别锁#xff09;2.2 集群部署… Java技术栈 —— Redis的雪崩、穿透与击穿 〇、实验的先导条件NginxJmeter一、Redis缓存雪崩、缓存穿透、缓存击穿1.1 雪崩1.2 穿透1.3 击穿 二、Redis应用场景——高并发2.1 单机部署的高并发问题与解决JVM级别锁2.2 集群部署的高并发问题与解决分布式锁2.2.1 代码1(存在非原子操作与释放问题)2.2.2 代码2(finally块中存在释放其它线程锁的可能性)2.2.3 代码3(redisson)2.2.3.1 Java中嵌入Lua脚本 2.2.4 对代码3的性能优化、redis主从架构锁失效问题的解决方案2.2.4.1 性能优化的解决(分段锁重要)2.2.4.2 主从架构锁失效问题的解决2.2.4.2.1 zookeeper2.2.4.2.2 redis的RedLock 三、Redis与数据库的数据一致性 〇、实验的先导条件NginxJmeter 首先你需要掌握Nginx负载均衡与Jmeter压测工具搭建过程与使用方式见参考文章。 参考文章或视频链接[1] 《Java技术栈 —— Nginx的使用》[2] 2 ways to install Apache JMeter on Ubuntu 22.04 LTS Linux 一、Redis缓存雪崩、缓存穿透、缓存击穿 关于雪崩、穿透与击穿的原理可以先看本节的参考文章[1]代码以后再写到文章中。 1.1 雪崩 1.2 穿透 1.3 击穿 一、参考文章或视频链接[1] 【什么是Redis缓存雪崩、穿透、击穿十分钟给你讲的明明白白】- bilibili 二、Redis应用场景——高并发 高并发导致的问题本质就是资源争抢。 在操作系统中这类问题的雏形有哲学家用餐问题、进程争夺计算资源相关解决机制有信号量机制所以道理都是相通的高并发在计算机领域并不是什么新鲜事只是落地到应用场景会有一些其它考量。就像古代兵符印信或是倚天屠龙记中说的“武林至尊宝刀屠龙号令天下莫敢不从倚天不出谁与争锋”听谁的问题的解决方法啊就是象征物在谁手上就听谁的包括抢职位争权力也可以理解为一种并发谁坐到了那个位置才有号令的权力但是权力是致命毒药要小心哦 首先导入jedis依赖从而可以用java程序包操纵redis以下是完整依赖。 dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-jdbc/artifactId/dependencydependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion8.0.28/version/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-thymeleaf/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactId/dependencydependencygroupIdorg.mybatis.spring.boot/groupIdartifactIdmybatis-spring-boot-starter/artifactIdversion3.0.3/version/dependency!--实现分布式锁redisson--dependencygroupIdorg.redisson/groupIdartifactIdredisson/artifactIdversion3.6.5/version/dependency !-- 也可以手动引入Jedis不用SpringBoot提供的spring-boot-starter-data-redis--dependencygroupIdredis.clients/groupIdartifactIdjedis/artifactIdversion5.1.0/version/dependency!--如果你导入了下面的SpringBoot父依赖会自带Jedis不过版本不一定最新而已并且有些-- !-- parentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion3.2.1/versionrelativePath/ /parent用SpringBoot提供的Jedis版本dependencygroupIdredis.clients/groupIdartifactIdjedis/artifactId/dependency --然后我们开始复现高并发问题。首先是假设你已经搭建了一个简单的SpringBoot项目架构并且相关的Nginx配置也已配置好可以看 参考文章[5] 《Java技术栈 —— Nginx的使用》第3.1节那正是我为本文而写项目demo搭好了port号也初步定为9998。 二、参考文章或视频链接[1] Java guide(Jedis) - Redis Offical Website[2] Intro to Jedis – the Java Redis Client Library[3] Redis可视化工具 RedisInsight | The best Redis GUI[4] 示例代码来源图灵诸葛老师讲的确实很好 【这可能是目前讲的最好的Redis高并发架构教程堪称Redis架构实战的天花板】[5] 《Java技术栈 —— Nginx的使用》 2.1 单机部署的高并发问题与解决JVM级别锁 1先在redis中设置缓存好一个键值对键的名字为store这是我们要高并发的对象。 $ redis-cli 127.0.0.1:6379 SETNX store 2000 127.0.0.1:6379 get store 20002写一段操作redis获取store值的代码完整项目代码最后会附上开源地址。 RestController public class demoController {public static int count 0;RequestMapping(deduct_stock_then_get_stock)public Integer deductStock(){Jedis jedis new Jedis(127.0.0.1, 6379);int currentStock Integer.parseInt(jedis.get(stock));if (currentStock 0){currentStock--;jedis.set(stock, String.valueOf(currentStock));System.out.println(扣减成功剩余库存currentStock);}else{System.out.println(扣减失败库存不足);}return currentStock;} }启动项目并访问http://127.0.0.1:9998/deduct_stock_then_get_stock让我们先看看效果慢慢迭代好的现在浏览器上已经返回了当前库存数量显示是199不要在意这个数字随时可以在redis中修改。 然后我们用Jmeter模拟多个用户同时访问 http://127.0.0.1:9998/deduct_stock_then_get_stock上面这段Java代码会出什么问题呢简单来说就是会出现超卖问题。按下面的过程配置并点击绿色的启动箭头就开启了压测。 这是控制台输出的结果果然出现了超卖问题这说明会有多个用户都看到了相同的1999库存很明显是有问题的这是因为多个用户同时进入了相同段代码的执行过程并且都拿到了一个currentStock变量作为副本而这个变量在获取的时候出现了值相同的情况。 RestController public class demoController { //方法(2)以函数为单位上锁写成 public synchronized Integer deductStock(){RequestMapping(deduct_stock_then_get_stock)public Integer deductStock(){Jedis jedis new Jedis(127.0.0.1, 6379);synchronized (this){ //方法(1)以对象为单位上锁int currentStock Integer.parseInt(jedis.get(stock)); //上一段未加synchronized的代码问题出在这里都获取到了一样的值那么再进行currentStock--就是1999了if (currentStock 0){currentStock--;jedis.set(stock, String.valueOf(currentStock));System.out.println(扣减成功剩余库存currentStock);}else{System.out.println(扣减失败库存不足);}return currentStock;}}}只加了一个锁问题解决那么到目前为止单机部署的高并发问题可以算解决了如果集群部署的话上面这段代码还有用吗 2.2 集群部署的高并发问题与解决分布式锁 根据参考视频[4]所说上面的代码也只是解决了单机部署下的高并发问题如果是集群部署启动了多个服务分别部署在不同机器上呢这个时候Nginx会分发请求到不同服务实例上还会出现上面的超卖现象吗答案是会的这相当于线程A在服务A上执行扣库存线程B在服务B上执行扣库存这两个线程压根不归同一个JVM虚拟机进程管是没办法用上面的加synchronized关键字去限制的具体可以看视频讲解。但是只要思想不滑坡办法总比困难多请看。PS你能想象其实12306是全世界最能抗高并发的软件吗总有些东西在微不足道的角落里熠熠生辉独自发热。 还是刚刚那段在单机部署上解决了高并发问题的代码我们来多启动一个服务只是端口不同。 由于在参考文章[5]中我已经配置了Nginx所以我们的Jmeter测试地址应该改为http://127.0.0.1:8011/deduct_stock_then_get_stock看下面的两张截图和视频[5]里说的一样确实在集群部署时会出现超卖问题。 下面是加上分布式锁的解决方法 但是仍然存在问题。 2.2.1 代码1(存在非原子操作与释放问题) RestController public class demoController {RequestMapping(deduct_stock_then_get_stock)public Integer deductStock(){String lockKey product_100;Jedis jedis new Jedis(127.0.0.1, 6379);long result jedis.setnx(lockKey,xxx); // 获取分布式锁if(result 0){System.out.println(争抢分布式锁失败); /*注意这里实际使用会有问题不应该return只是作为示例争抢分布式锁失败的话也应该程门立雪三顾茅庐不可半途而返半途而返会导致许多业务请求被扼杀*/ return 500; }//*****重要思维*****//业务逻辑可能出异常导致分布式锁无法释放永远要考虑系统的业务逻辑被某种不可抗力因素停止不管是运维还是什么程序要具备健壮性。int currentStock Integer.parseInt(jedis.get(stock));if (currentStock 0) {currentStock--;jedis.set(stock, String.valueOf(currentStock));System.out.println(扣减成功剩余库存 currentStock);} else {System.out.println(扣减失败库存不足);}jedis.del(lockKey); //释放分布式锁return currentStock;}}2.2.2 代码2(finally块中存在释放其它线程锁的可能性) 下面的代码对上面的代码做了两处改进 (1)将获取与设置超时时间这两步组合成原子操作不可分离。 (2)增加clientID保证释放的是自己加的锁但在释放仍旧可能存在问题视频中提到用redisson进行解决见 redisson - github wikiredisson与jedis区别在于jedis只是提供一些原生命令的实现redisson可以提供分布式锁的实现能力。 RequestMapping(deduct_stock_then_get_stock) public Integer deductStock(){ //集群版//(1)获得分布式锁String lockKey product_100;Jedis jedis new Jedis(127.0.0.1, 6379);String clientID UUID.randomUUID().toString(); //唯一ID加锁人的身份// String result jedis.setex(lockKey, 10, clientID); //该命令是原子命令将获取与设置超时时间这两步组合成原子操作不可分离但还是存在问题如业务逻辑执行较慢锁已经超时释放了业务逻辑还没执行完又导致了并发Boolean result stringRedisTemplate.opsForValue().setIfAbsent(lockKey, clientID, 10, TimeUnit.SECONDS); //该命令是原子命令将获取与设置超时时间这两步组合成原子操作不可分离但还是存在问题如业务逻辑执行较慢锁已经超时释放了业务逻辑还没执行完又导致了并发stringRedisTemplate.opsForValue().get(lockKey);if(result Boolean.FALSE){System.out.println(争抢分布式锁失败); // 分布式锁争抢失败应该等待而不应该直接returnreturn 500;}try{//*****重要思维*****//(2)执行业务逻辑可能出异常导致分布式锁无法释放永远要考虑系统的业务逻辑被某种不可抗力因素停止不管是运维还是什么要具备健壮性。//此处可能存在的异常有// (2.1)业务逻辑执行失败但finally可以正常释放分布式锁// (2.2)应用被重启连finally都无法执行那么就需要令分布式锁自动过期int currentStock Integer.parseInt(jedis.get(stock));if (currentStock 0) {currentStock--;jedis.set(stock, String.valueOf(currentStock));System.out.println(扣减成功剩余库存 currentStock);} else {System.out.println(扣减失败库存不足);}return currentStock;}finally{//(3)出异常时释放分布式锁,这里释放分布式锁可能存在问题if (clientID.equals(jedis.get(lockKey))){//自己加的锁才能释放中间还可能存在执行时间的间隔开一个分线程将分布式锁加时检测这把分布式锁还是否加载在该主线程中加时到直到业务逻辑执行完成为止jedis.del(lockKey);}}}2.2.3 代码3(redisson) RequestMapping(deduct_stock_then_get_stock_cluster_redisson) public Integer deductStock3(){ //集群redisson版//(1)获得分布式锁String lockKey product_100;Jedis jedis new Jedis(127.0.0.1, 6379);RLock redissonLock redisson.getLock(lockKey); //获取RLock对象try{redissonLock.lock(); //(2)上锁底层调用redis命令时用到了lua脚本//(3)业务逻辑int currentStock Integer.parseInt(jedis.get(stock));if (currentStock 0) {currentStock--;jedis.set(stock, String.valueOf(currentStock));System.out.println(扣减成功剩余库存 currentStock);} else {System.out.println(扣减失败库存不足);}return currentStock;}finally{//(4)释放锁redissonLock.unlock();} }redisson是一种Redis Java client上述redisson的使用方法也是大厂在生产环境会用到的但上面的代码还有两个问题 (1)性能问题虽然没有超卖但会导致系统性能问题需要开始性能优化。 (2)redis主从架构下锁失效问题。比如Master同步给Slave分布式锁时Master正好挂掉然后重新选举的Master正好没有同步到这把锁就失效了。 2.2.3 参考文章或视频链接[1] 1. Overview of Redisson - GitHub 2.2.3.1 Java中嵌入Lua脚本 什么是Lua脚本我第一次听说Lua是在敖丙解说B站出事那次最后定位到一段Lua写的gcd()代码久闻大名却未上手实操过。请看本节参考文章[1]。 2.2.3.1 参考文章或视频链接[1] Lua:about - Offical Website 2.2.4 对代码3的性能优化、redis主从架构锁失效问题的解决方案 2.2.4.1 性能优化的解决(分段锁重要) 先了解下并发编程集合类ConcurrentHashMap这是一个高并发的Java集合类且线程安全其保证线程安全的原理是使用分段锁。受此启发性能优化也可以用分段加锁每个线程去不同的段位请求锁即可。 2.2.4.1 参考文章或视频链接[1] 《详解ConcurrentHashMap》- CSDN 2.2.4.2 主从架构锁失效问题的解决 Zookeeper集群是CP架构。Redis单机是CP架构Redis集群是AP架构。[5] CA - 单点集群满足一致性可用性的系统通常在可扩展性上不太强大。 CP - 满足一致性分区容忍性的系统通常性能不是特别高。 AP - 满足可用性分区容忍性的系统通常可能对一致性要求低一些。 CAP理论 2.2.4.2 参考文章或视频链接[1] Redis persistence and CAP theorem-From Zero to Hero -part II[2] 《架构设计之「 CAP 定理 」》- CSDN[3] 《CAP定理一文带你速解通俗易懂图文并茂》- CSDN推荐优先阅读[4] 《NoSQL 简介》- 菜鸟教程[5] 《redis是CA还是CP呢》- 腾讯云 2.2.4.2.1 zookeeper 使用zookeeperzookeeper解决主从架构锁失效问题更合适但会牺牲一点性能。 2.2.4.2.1 参考文章或视频链接[1] What is Apache ZooKeeper?[2] Welcome to Apache ZooKeeper[3] 《2.0 Zookeeper 安装配置》- 菜鸟[4] 《zookeeper快速入门一zookeeper安装与启动》 2.2.4.2.2 redis的RedLock 要超过半数redis节点加锁成功才算成功这样的原理又回到了zookeeper还是会损失加锁的性能所以RedLock实现的是否完善依旧存在争议。 三、Redis与数据库的数据一致性 (1)要保证的是数据的最终一致性而不是强一致性若要保证数据强一致性会损失性能这违背了使用Redis的初衷。 (2)删除Redis缓存而不是更新Redis缓存。 (3)先更新数据库数据。 三、 参考文章或视频链接[1] 《字节二面redis如何保证缓存和数据库的一致性》
http://www.tj-hxxt.cn/news/227843.html

相关文章:

  • 网站开发一般用什么开发语言电商网站开发哪里好
  • 网站建设哪家不错领地免费网站
  • 网站建设实验代码商城网站设计服务商
  • 商城网站设计配色思想旅游网站开发实现开题报告
  • pc端网站开发淄博企业网站建设公司
  • 网站建设选择数据库网页游戏广告平台网站建设
  • 北京 网站开发 大兴网站视频超链接怎么做
  • 北京建设监理协会官方网站响应式网站 产品轮播代码
  • 西安app网站开发太原百度网站建设
  • 长沙个人做网站排名网站建设怎么进行一级域名申请
  • 石家庄网站建设公司哪家好做管理信息的网站
  • 网站建设与管理题目青岛做网站皆赴青岛博采网络
  • 学校网站模板htmlwordpress数据库名
  • 网站cms是什么意思小说网站开发的看书软件
  • 外贸网站建设定制开发东莞网络网站建设
  • 移动网站开发源代码广告资源网
  • 怎么对网站的数据库做管理wordpress修改成中文字体
  • 制造网站建设wordpress文件权限设置
  • a站是什么帝国cms怎么做网站声明
  • 网站建站服务公司无锡企业网站制作哪家比较好
  • 深圳商城网站建设网站运营方案ppt
  • 建设一个网站需要哪些方面的开支大型网站建设兴田德润实惠
  • 九江的网站建设公司百度微信网站
  • 江苏网站建设哪家好推荐优秀的企业网站设计
  • 外贸平台哪个网站最好浙江网站建设情况
  • 网站前台图片设置二手设备回收做哪个网站好
  • 营销网站建设有哪些公司网络服务电话
  • 我要找个做网站的公司学做网站要学多久
  • 做设计.不抠图网站产品结构设计
  • 做设计素材网站有哪些网址导航网站怎样做