黑马点评项目遇到的部分问题

目录

  • 1. Invalid default value for ‘begin_time‘报错
  • 2. [ThreadLocal](https://blog.csdn.net/u010445301/article/details/111322569)
  • 3. 悲观锁实现单体一人一单超卖问题
  • 4. redisson
  • 5. 回顾秒杀优化
  • 6. Nginx 负载均衡

1. Invalid default value for ‘begin_time‘报错

  • mysql⽇期时间设置默认0000-00-0000:00:00出错。
    • DEFAULT ‘0000-00-00 00:00:00’(零时间戳),这不满足sql_mode中的NO_ZERO_DATE而报错。
    • sql_mode有两种,一种是空值,一种是严格模式,会给出很多默认设置。在MySQL5.7之后默认使用严格模式。
    • NO_ZERO_DATE:若设置该值,MySQL数据库不允许插入零日期,插入零日期会抛出错误而不是警告。
    • 在命令行中设置sql_mode:
      SET SESSION sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';

2. ThreadLocal

  • remove 方法,直接将 ThreadLocal 对应的值从当前线程 Thread 中的 ThreadLocalMap 中删除。为什么要删除,这涉及到内存泄漏的问题。
  • ThreadLocalMap 中使用的 key 为 ThreadLocal 的弱引用, 弱引用的特点是,如果这个对象只存在弱引用,那么在下一次垃圾回收的时候必然会被清理掉。
  • 所以如果 ThreadLocal 没有被外部强引用的情况下,在垃圾回收的时候会被清理掉的,这样一来 ThreadLocalMap中使用这个 ThreadLocal 的 key 也会被清理掉。但是, value 是强引用,不会被清理,这样一来就会出现 key 为 null 的 value。

3. 悲观锁实现单体一人一单超卖问题

  • 乐观锁适合判断数据更新问题,而当前是判断是否存在,所以可以使用悲观锁解决。

  • 锁的范围尽量小, synchronized尽量锁代码块而不是方法,锁的范围越大性能越低。

  • 锁的对象一定是一个不变的值,不能直接锁 Long 类型的 userId,每请求一次都会创建一个新的 userId 对象,synchronized 要锁不变的值, 所以要将 Long 类型的 userId 通过 toString() 方法转成 String 类型的 userId, toString底层是直接 new 一个新的 String 对象,还是在变, 所以要用 intern() 方法从常量池中寻找与当前字符串值一致的字符串对象, 这样就能保障一个用户发送多次请求,每次请求的 userId 都是不变的,从而完成锁的效果。

  • 要锁整个事务,而不是锁事务内部的代码。如果我们锁住事务内部的代码会导致其它线程能够进入事务,当我们事务还未提交,锁一旦释放,仍然会存在超卖问题。

  • Spring 的 @Transactional 注解要想事务生效,必须使用动态代理。在同一个类中,一个方法调用另外一个有注解(比如@Async,@Transational)的方法,注解是不会生效的,所以我们需要创建一个代理对象,使用代理对象来调用方法。

    • spring 在扫描bean的时候会扫描方法上是否包含@Transactional注解,如果包含,spring会为这个bean动态地生成一个子类(即代理类,proxy),代理类是继承原来那个bean的。此时,当这个有注解的方法被调用的时候,实际上是由代理类来调用的,代理类在调用之前就会启动transaction。然而,如果这个有注解的方法是被同一个类中的其他方法调用的,那么该方法的调用并没有通过代理类,而是直接通过原来的那个bean,所以就不会启动transaction,我们看到的现象就是@Transactional注解无效。

    • 让代理对象生效的步骤:

      • 引入 AOP 依赖,动态代理是AOP 的常见实现之一
      <dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId>
      </dependency>
      
      • 暴露动态代理对象,默认是关闭的
      	@EnableAspectJAutoProxy(exposeProxy = true)
      
  • 对于集群下一人一单的并发安全问题,由于每个tomcat 都有一个属于自己的 jvm,此时这个synchronized锁会失效,synchronized是本地锁,只能提供线程级别的同步,每个JVM中都有一把synchronized锁,不能跨 JVM 进行上锁,当一个线程进入被 synchronized 关键字修饰的方法或代码块时,它会尝试获取对象的内置锁(也称为监视器锁)。如果该锁没有被其他线程占用,则当前线程获得锁,可以继续执行代码;否则,当前线程将进入阻塞状态,直到获取到锁为止。而现在我们是创建了两个节点,也就意味着有两个JVM,所以synchronized会失效! 原文链接

  • try…finally…确保发生异常时锁能够释放,注意这给地方不要使用catch,A事务方法内部调用B事务方法,A事务方法不能够直接catch,否则会导致事务失效。

        // 3、创建订单(使用分布式锁)Long userId = ThreadLocalUtls.getUser().getId();SimpleRedisLock lock = new SimpleRedisLock(stringRedisTemplate, "order:" + userId);boolean isLock = lock.tryLock(1200);if (!isLock) {// 索取锁失败,重试或者直接抛异常(这个业务是一人一单,所以直接返回失败信息)return Result.fail("一人只能下一单");}try {// 索取锁成功,创建代理对象,使用代理对象调用第三方事务方法, 防止事务失效IVoucherOrderService proxy = (IVoucherOrderService) AopContext.currentProxy();return proxy.createVoucherOrder(userId, voucherId);} finally {lock.unlock();}

4. redisson

  • 可重入:利用hash 结构记录线程id 和重入次数
  • 可重试:利用信号量和 PubSub 功能实现等待、唤醒、获取锁失败的重试机制
  • 超时续约:利用 watchDog ,每个一段时间(releaseTime / 3) 重置超时时间
    获取锁,根据订阅发的通知,在自己获取锁时,判断自己的剩余时间,去监听获取。
    避免业务未完成锁超时释放发问题,采用看门狗的机制,每过一段时间去重置有效期.
  • 主从一致性问题:利用 Redission 的 multiLock ,多个独立的 Redis 节点, 必须在所有节点都获取重入锁,才算获取锁成功

5. 回顾秒杀优化

遇到自增 ID 问题,通过实现分布式ID解决了问题;后面我们在单体系统下遇到了一人多单超卖问题,我们通过乐观锁解决了;我们对业务进行了变更,将一人多单变成了一人一单,结果在高并发场景下同一用户发送相同请求仍然出现了超卖问题,我们通过悲观锁解决了;由于用户量的激增,我们将单体系统升级成了集群,结果由于锁只能在一个JVM中可见导致又出现了,在高并发场景下同一用户发送下单请求出现超卖问题,我们通过实现分布式锁成功解决集群下的超卖问题;由于我们最开始实现的分布式锁比较简单,会出现超时释放导致超卖问题,我们通过给锁添加线程标识成功解决了;但是释放锁时,判断锁是否是当前线程 和 删除锁两个操作不是原子性的,可能导致超卖问题,我们通过将两个操作封装到一个Lua脚本成功解决了;为了解决锁的不可重入性,我们通过将锁以hash结构的形式存储,每次释放锁都value-1,获取锁value+1,从而实现锁的可重入性,并且将释放锁和获取锁的操作封装到Lua脚本中以确保原子性。最最后,我们发现可以直接使用现有比较成熟的方案Redisson来解决上诉出现的所有问题,不可重试、不可重入、超时释放、原子性等问题Redisson都提供相对应的解决方法。
原文链接

6. Nginx 负载均衡

搭建集群环境时,修改 Nginx 配置后要重启。 nginx.exe -s reload

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

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

相关文章

Java设计模式_概述(设计模式类型和基本原则)

一、设计模式 设计模式&#xff08;Design pattern&#xff09;代表了最佳的实践&#xff0c;是软件开发人员在软件开发过程中面临一般问题的解决方案&#xff0c;是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。是优秀程序猿的经验结晶。 但不推荐刚入门的开…

如何删除.gitignore文件中指定的所有被忽略的文件

要删除.gitignore文件中指定的所有被忽略的文件&#xff0c;你可以使用git rm命令结合-r选项。以下是一些步骤&#xff1a; 查看将要删除的文件&#xff1a;首先&#xff0c;你可以使用git ls-files命令来列出被git忽略的文件&#xff0c;以确保你想要删除的文件列表是正确的。…

LeetCode 热题 100 Day06

矩阵相关题型 Leetcode 48. 旋转图像【中等】 题意理解&#xff1a; 将一个矩阵顺时针旋转90度&#xff0c;返回旋转后的矩阵。 要求&#xff1a; 在原地修改&#xff0c;不借助额外的空间 如果可以使用辅助数组来实现转置,则有 matrix_new[i][j]matrix[j][row-i-1]; 解…

Kubernetes学习-核心概念篇(三) 核心概念和专业术语

&#x1f3f7;️个人主页&#xff1a;牵着猫散步的鼠鼠 &#x1f3f7;️系列专栏&#xff1a;Kubernetes渐进式学习-专栏 &#x1f3f7;️个人学习笔记&#xff0c;若有缺误&#xff0c;欢迎评论区指正 1. 前言 在前面两篇文章我们简单介绍了什么是K8S&#xff0c;以及K8S的…

mysql服务器无法启动问题处理

一台hlr服务器用网管软件登录失败&#xff0c;查找原因&#xff0c;发现网关软件连接服务器的tcp的10002端口失败&#xff0c;超时无应答&#xff0c;导致连接失败。 用户反馈核心网hlr&#xff0c;smc无法登录&#xff0c;putty登录服务器&#xff0c;发现hlr10002端口没有打…

【保姆级讲解下gateway基本配置】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

STM32与OLED显示屏通信(四针脚和七阵脚)

系列文章目录 STM32单片机系列专栏 C语言术语和结构总结专栏 文章目录 1. 单片机调试 2. OLED简介 3. 接线 4. OLED驱动函数 4.1 四针脚版本 OLED.c OLED.h OLED_Font.h 4.2 七针脚版本 引脚连接 OLED.c OLED.h OLED_Font.h 5. 主函数 工程文件模板 1. 单片机…

Android 当存在双卡时,移动网络默认为SIM卡1

文章目录 一、当Android设备中存在双卡时&#xff0c;移动网络默认为SIM卡1二、下面是完整的代码路径和修改点 一、当Android设备中存在双卡时&#xff0c;移动网络默认为SIM卡1 完成这个需求有以下两个修改点&#xff1a; 下面依旧是Android13 MTK平台&#xff0c;在MtkMulti…

SoC如何开机自动运行脚本程序?

目录 1、通过启动加载程序执行脚本 2、通过Linux init 系统 2.1、/etc/init.d目录中的脚本 2.2、修改/etc/rc.local文件 在Linux SoC开发中&#xff0c;实现SoC启动时执行特定脚本的方法主要取决于你使用的启动加载程序&#xff08;Bootloader&#xff09;以及Linux内核的配置。…

unity中压缩文件与解压文件

今天研究了一下在unity中 把文件压缩后转二进制发送到服务器并从服务器下载后解压使用文件&#xff0c;废话不多说直接上代码&#xff0c;zip压缩插件是用的dotnetzip插件&#xff0c;网上可以搜索下载这个dll private static void GetPathMeshData_ZIP(Milling_ProjectData da…

(Snowflake Algorithm)雪花算法Java的简单使用

概述 雪花算法&#xff08;Snowflake Algorithm&#xff09;最初是由Twitter开源的&#xff0c;用于生成一个64位的长整型数字作为全局唯一的ID。这个算法是用Scala语言编写的&#xff0c;并且在Twitter内部得到了广泛应用。由于其简单、高效和分布式友好的特性&#xff0c;雪…

Fiddlers使用

下载 FiddlerClassic&#xff0c;是免费的&#xff0c;不过只能在Windows上使用。 使用 如何使用Fiddler进行手机端抓包 手机抓包&#xff0c;如果使用有线WindowsPC共享Wifi热点&#xff0c;子网络ip地址段与PC不一致&#xff0c;再添PC ip地址&#xff08;8888&#xff09…

JMeter的下载安装与使用(Mac)

1、下载地址​​​​​​https://jmeter.apache.org/download_jmeter.cgi 2、下载Binaries 下的apache-jmeter5.5.tgz 3、解压 4、启动 在bin目录下打开终端&#xff0c;输入sh jmeter 出现jmeter首页界面&#xff0c;即为成功。 5、使用 5.1 语言选择 option选项卡&am…

揭秘!七大副业赚钱秘籍,让你轻松实现财务自由!

以下是七种赚钱的副业推荐&#xff1a; 1&#xff0c;自媒体运营 自媒体运营是当下非常火热的副业之一。通过在微博、微信公众号、抖音、B站等自媒体平台上发布原创内容&#xff0c;吸引粉丝关注&#xff0c;进而实现流量变现。自媒体运营的核心在于内容创作和粉丝互动&#…

java解析PDF、WORD获取其中的表格以及文本内容

近期因工作需要需要解析PDF&#xff0c;需要把PDF中的文本和表格分离&#xff0c;最终要实现的目标是PDF中的文本内容放一块&#xff0c;表格内容放一块&#xff0c;以list的形式存储。解析PDF的技术有很多&#xff0c;经过多次尝试发现使用AdobeAcrobat可以实现表格和文本分离…

06 华三防火墙的如何进入web页面?

1 AI 思路 要进入华三防火墙的Web页面,你需要按照以下步骤操作: 确定防火墙的IP地址:首先,你需要知道你的华三防火墙的IP地址。通常,你可以从网络管理员或者设备本身获取这个信息。 打开浏览器:在你的电脑上打开一个网页浏览器,例如Chrome、Firefox或者Edge等。 输入UR…

系统服务(22年国赛)—— DHCPDHCP Relay(中继)

前言&#xff1a;原文在我的博客网站中&#xff0c;持续更新数通、系统方面的知识&#xff0c;欢迎来访&#xff01; 系统服务&#xff08;22年国赛&#xff09;—— DHCP&&DHCP Relay(中继)https://myweb.myskillstree.cn/94.html 目录 一、题目 DHCP AppSrv 二…

Linux学习之路 -- 进程篇 -- 自定义shell的编写

前面介绍了进程程序替换的相关知识&#xff0c;接下来&#xff0c;我将介绍如何基于前面的知识&#xff0c;编写一个简单的shell&#xff0c;另外本文的所展示的shell可能仅供参考。 目录 <1>获取用户的输入和打印命令行提示符 <2>切割字符串 <3>执行这个…

第 4 篇 : Netty客户端互发图片和音/视频

说明 因为图片和音/视频不能确定其具体大小, 故引入MinIO。客户端之间只发送消息, 通过上传/下载来获取额外信息 1. MinIO搭建(参考前面文章), 并启动 2. 登录MinIO创建3个Bucket: image、voice、video 3. 客户端改造 3.1 修改 pom.xml <?xml version"1.0" …

苍穹外卖绕过微信支付

经过以下改动可实现&#xff1a; 1、不用微信支付端口 2、弹出支付成功的界面 3、数据库修改支付成功后的数据 #在OrderServiceImpl.java里加入Autowiredprivate OrderService orderService; #在OrderServiceImpl.java里的payment函数做以下改动 #图片里有&#xff0c;红色为原…