技术标签: 谷粒商城-心得笔记
https://blog.csdn.net/suchahaerkang/article/details/108561366
2021-05-29 14:10:28.509 WARN 18020 — [ioEventLoop-4-1] io.lettuce.core.protocol.CommandHandler : null Unexpected exception during request: io.netty.util.internal.OutOfDirectMemoryError: failed to allocate 46137344 byte(s) of direct memory (used: 58720256, max: 100663296)
使用58720256,需要释放空间46137344 ,但是最大内存100663296 (46137344 +58720256 >100663296 )
产生堆外内存溢出OutOfDirectMemoryError:
1)、springboot2.0以后默认使用lettuce操作redis的客户端,它使用netty进行与redis的网络通信
2)、lettuce的bug导致netty堆外内存溢出 -Xmx300m; netty如果没有指定堆外内存,默认使用-Xmx300m 可设置:
-Dio.netty.maxDirectMemory
解决方案:不能直接使用-Dio.netty.maxDirectMemory去调大堆外内存
当你调大 -Xmx300m运行内存空间时,只是减缓了OutOfDirectMemoryError异常出现的时间
1)、升级lettuce客户端。(项目推荐使用,需要手动解决该问题。lettuce在使用netty进行通信时,没有及时释放空间导致内存溢出,但是netty吞吐量达,新,所以推荐使用)
2)、切换使用jedis(比较老的版本)
穿透:查询一个永不存在的数据
雪崩:缓存key同一时间大面积失效
击穿:某一个单热点被高频访问,在前一点突然失效。解决方案:
1、空结果缓存:解决缓存穿透
2、设置过期时间(加随机值),解决缓存雪崩
3、加锁:解决缓存击穿
1. 本地锁
synchronized关键字:表明这是一个加锁的操作。
锁:其实就是一个对象。只要是同一把锁,就能锁住这个锁的所有线程换句话说就是只要是用同一个对象锁,那么调用这个锁对象的所有进程都能锁住。
本地锁只能是在单体应用可以使用,如果是高并发的情况下,假如10个机器,就有10把锁。
synchronized关键字修饰的锁和JUC(Lock)都是本地锁,只能锁住当前进程
锁时序问题
黑色框表示锁
2. 分布式锁
分布式的情况下,锁住所有的进程。
本地锁:当是单体应用的时候,使用的是本地锁,例如JUC,里面有各种锁,比如可重入锁等。
分布式锁:当是多个应用的时候,这个时候要锁住所有应用的进程,需要Redis提供的分布式锁,Redisson对各种锁进行封装,可以使用简单的代码进行加锁。
我们可以同时去一个地方“占坑”,如果占到,就执行逻辑。否则就必须等待,直到释放锁。占坑可以去Redis,也可以去数据库,可以去任何大家都可以访问到的地方。等待可以自旋的方式。
使用锁的过程中注意的方式:
1.加锁和设置时间保持原子性
2. 删除锁,保证删除自己的锁(1.去redis获取lock锁的值 2.将获取的值与当前uuid比较,相等则删除)
步骤1 + 步骤2 ==保持原子性 ,使用redis官方提供的脚本运行。
3.让锁能够自动续机:当业务执行代码时间过长,还没执行完业务代码,锁就到期了,需要自动续机。
解决方案:(1)设置锁的时间长一点,加上try(业务代码)finally{删锁},无论业务代码是否有问题,都要删锁。
(2) 。。。。
Canal是一个阿里开源的一个组件,用来解决缓存数据和数据库数据一致性问题而开发的
spring cache提供了对缓存技术的crud操作,缓存技术可以使用Redis,Map等等
1、引入依赖
spring-boot-starter-cache,spring-boot-starter-data-redis
2、写配置
2.1 自动配置了那些 (CacheAutoConfiguration 会导入 RedisCacheConfiguration,自动配好了缓存管理器)
2.2 配置使用Redis作为缓存 spring.cache.type=redis
3、使用缓存
3.1 在启动类上@EnableCaching 注解 开启缓存
3.2 使用相关Cache注解实现缓存操作
如果容器中的一个组件,只有一个构造器,那么其构造器的参数都是有容器提供的
自动配置类CacheAutoConfiguration —》 导入RedisCacheConfiguration 配置 —》自动配置了RedisCacheManager —》初始化所有缓存 —》每个缓存决定使用什么配置—》如果有redisCacheConfiguration就用已有的,没有就用默认配置 —》想改缓存配置,就给容器中放一个RedisCacheConfiguration即可 —》就会应用到当前RedisCacheManager 管理的所有的缓存分区中。
/**
* 每一个需要缓存的数据我们都来指定要放到那个名字的缓存。【缓存的分区(按照业务类型分)】
* 代表当前方法的结果需要缓存,如果缓存中有,方法都不用调用,如果缓存中没有,会调用方法。最后将方法的结果放入缓存
* 默认行为
* 如果缓存中有,方法不再调用
* key是默认生成的: 缓存的名字::SimpleKey::[] (自动生成key值),配置文件指定前缀的话,则是:前缀SimpleKey::[]
* 缓存的value值,默认使用jdk序列化机制,将序列化的数据存到redis中
* 默认时间是 -1:永不过期
*
* 自定义操作:key的生成
* 指定生成缓存的key:key属性指定,接收一个Spel表达式
* 指定缓存的数据的存活时间:配置文档中修改存活时间
* 将数据保存为json格式:保证如果使用的是PHP语言等也能使用,自定义自己的配置文件MyCacheConfig
* 1.缓存的自动配置CacheAutoConfiguration
* 2.RedisCacheConfigration
*
*
* 4、Spring-Cache的不足之处:
* 1)、读模式
* 缓存穿透:查询一个null数据。解决方案:缓存空数据
* 缓存击穿:大量并发进来同时查询一个正好过期的数据。解决方案:加锁 ? 默认是无加锁的;使用sync = true来解决击穿问题
* 缓存雪崩:大量的key同时过期。解决:加随机时间。加上过期时间
* 2)、写模式:(缓存与数据库一致)
* 1)、读写加锁。
* 2)、引入Canal,感知到MySQL的更新去更新Redis
* 3)、读多写多,直接去数据库查询就行
*
* 总结:
* 常规数据(读多写少,即时性,一致性要求不高的数据,完全可以使用Spring-Cache):写模式(只要缓存的数据有过期时间就足够了)
* 特殊数据:特殊设计
*
* 原理:
* CacheManager(RedisCacheManager)->Cache(RedisCache)->Cache负责缓存的读写
*
*/
4、Spring-Cache的不足之处:
* 1)、读模式
* 缓存穿透:查询一个null数据。解决方案:缓存空数据 ==》配置文件:spring.cache.redis.cache-null-values=true
* 缓存击穿:大量并发进来同时查询一个正好过期的数据。解决方案:加锁 ? 默认是无加锁的;使用sync = true来解决击穿问题
* 缓存雪崩:大量的key同时过期。解决:加随机时间。加上过期时间
* 2)、写模式:(缓存与数据库一致)
* 1)、读写加锁。
* 2)、引入Canal,感知到MySQL的更新去更新Redis
* 3)、读多写多,直接去数据库查询就行
*
* 总结:
* 常规数据(读多写少,即时性,一致性要求不高的数据,完全可以使用Spring-Cache):写模式(只要缓存的数据有过期时间就足够了)
* 特殊数据:特殊设计
*
* 原理:
* CacheManager(RedisCacheManager)->Cache(RedisCache)->Cache负责缓存的读写
这里讲述一些初学者学习C51的一些误区和注意事项。高手的特别应用不包括在内。1)C忌讳绝对定位。常看见初学者要求使用_at_,这是一种谬误,把C当作ASM看待了。在C中变量的定位是编译器的事情,初学者只要定义变量和变量的作用域,编译器就把一个固定地址给这个变量。怎么取得这个变量的地址?要用指针。比如unsigned char data x;后,x的地址就是&x,你只要查看这个参数,就可以在...
/** * hex字符串转出字符串 *TODO *@param s *@return * @throws UnsupportedEncodingException */ public static String hexToString(String s) { byte[] bytes =
1. 找源码,在hisdk 里面就有zlib 的源码:zlib-1.2.8.tar.gz2. 解压,然后:cd zlib-1.2.8 3. ./configure --prefix=/work/opensource/zlib/zlib-1.2.8/_install ,然后修改MakefileCROSS=arm-hisiv500-linux-CC=$(CROSS)gccL
文章目录安装相关库原理简述代码效果实现今天教大家一个有趣的玩法,如何利用Python+opencv3实现简单的手势识别。当然网上也有相关教程,但绝大多数给出的代码拿来之后你是不能直接用的,这对于拿来主义的同学来说简直太“禽兽”了。所以今天我也会给出所有代码,只要配置好环境就可以运行。话不多说接下来就进入正题。安装相关库这个安装库的重要性就不用我多说了,但凡是想直接用人家的代码,就要安装人家运行所需的全部库。pip install opencv-pythonpip install opencv
整理不易,冲冲冲……后期继续更YUVPlayer下载地址:http://www.yuvplayer.com/YUV 文件下载地址:http://trace.eas.asu.edu/yuv/index.html注意:用YUVPlayer播放时请记住下载视频对应的长和宽的数值,播放时需要自己手动填入,否则会出现播放不正确的情况。...
工欲善其事必先利其器,趁手的工具会使我们开发事半功倍。市面上的编辑器我用过许多,编辑器使用经历Notepad++,(开源)这个应该是最轻量级的吧,查看代码还好,编辑代码就算了官网地址:https://notepad-plus-plus.org/Brackets,(开源)这个也不错,github-star:30k了,上次发布版本是6月...
#问题:nginx部署的vue项目中接入了第三方接口 在IE浏览器中出现了 Access-Control-Allow-Headers 列表中不存在请求标头 x-access-token。 其他浏览器正常#解决:在nginx中配置反向代理解决跨域
sql server死锁 In this article, we will talk about the deadlocks in SQL Server, and then we will analyze a real deadlock scenario and discover the troubleshooting steps. 在本文中,我们将讨论SQL Server中的死锁,然...
2.4; s+ v0 B. B. W1 P' ]( j基金管理(资金预算)上一章介绍的是资金管理中的资金头寸管理,流动性预测和公司总部资金平衡。本章介绍的模块是管理资金预算的。由于本模块在公共部门(如政府等)是特别重要的模块,...
mainActivity :package com.example.he.toby.otademo;import android.content.pm.PackageInfo;import android.content.pm.PackageManager;import android.support.v7.app.AppCompatActivity;import android
题目链接题意 求等比数列的和并对1e9+91e9+91e9+9取模。分析 S=a1(qlen−1)q−1S=a1(qlen−1)q−1S=\frac{a1(q^len -1)}{q-1},q=bk∗(inv(a))k(mod1e9+9),其中len=(n+1)/k,inv(a)为a的逆元q=bk∗(inv(a))k(mod1e9+9),其中len=(n+1)/k,inv(a)为a的逆元...
一、什么是高并发高并发(High Concurrency)是互联网分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计保证系统能够同时并行处理很多请求。高并发相关常用的一些指标有响应时间(Response Time),吞吐量(Throughput),每秒查询率QPS(Query Per Second),并发用户数等。响应时间:系统对请求做出响应的时间。例如系统处理一个HTTP请求需要200ms,这个200ms就是系统的响应时间。吞吐量:单位时间内处理的请求数量。QPS:每秒响应请求数。在互