部分问题合集

问题合集

1.雪花id

        雪花id是什么:snowflake是Twitter开源的分布式ID生成算法,结果是64bit的Long类型的ID,有着全局唯一和有序递增的特点。

缺点是强依赖机器时钟,如果机器上的时钟回拨,有可能会导致主键重复的问题

2、redis数据持久性

   (1 RDB持久化,生产某个时间点的快照文件

执行rdb持久化时,redis会fork出一个子进程,子进程将内存中数据写入到一个紧凑的文件中,因此它保存的是某个时间点的完整数据。

redis启动时会从rdb文件中恢复数据到内存,因此回复数据时只需要将redis关闭后,将备份的rdb文件替换当前的rdb文件,再启动redis即可。

        优点

  • rdb文件体积小,适合备份及传输

  • 性能比aof好(aof需要写入日志文件)

  • rdb恢复要比aof快

  • 缺点

  • 服务器故障时会丢失最后一次备份之后的数据

  • redis保存rdb时,fork子进程的这个操作期间,redis服务会停止响应,但如果数据量大且cpu时间紧张,则停止响应的时间可能长大1秒

(2 AOF持久化(append only file):日志追加模式(redis协议格式保存)

        aof就是将客户端每一次操作记录追加到指定的aof(日志)文件中,在aof文件体积多大时可以自动在后台重写aof文件(不会影响正常服务,中途磁盘写满或者停机导致失败也不会丢失数据)

aof持久化的fsync策略支持:

fsync:同步内存中所有已经修改的文件数据到存储设备

aof文件过大时会触发自动重写,重写后的新aof文件包含了恢复当前数据集所需最少的命令集合

优点

  • 充分保证数据的持久化,正确的配置一般最多丢失1s的数据

  • aof文件内容是以redis协议格式保存,易读

缺点

  • aof文件通常大于rdb文件

  • 速度慢于rdb

  • 重新启动redis时会以极低的概率导致无法将数据集恢复成保存时的原样

3、redis缓存雪崩

        redis缓存可以理解为:由于原有的缓存失效,新缓存未到期间,原本应该访问缓存的请求都去查询数据库了,而对数据库cpu和内存造成的巨大压力,严重的会造成数据库宕机,从而形成一系列的连锁反应,造成整个系统崩溃。

解决办法

        加锁(参考链接:(redis分布式锁的原理及代码实现_风幕浦的博客-CSDN博客))或者队列的方式保证不会有大量的线程对数据库一次性进行读写,从而避免失效时大量的请求并发到底层存储系统上。或者就是将缓存失效时间分散开。

4、redis缓存穿透

        指用户查询数据,数据库没有,在缓存中也没有。这样导致用户查询时,缓存找不到,每次都要去数据库查询一遍,然后返回null,这样请求就会绕过缓存直接查数据库。

解决方法

        最常见的就是使用布隆过滤器,将所有可能存在的数据哈希到一个大的bitmap中,一个不存在的数据就会被拦截掉,从而避免了对底层的压力。

​         或者把这个空结果进行缓存,但过期时间短,最长不超过5分钟。直接把默认值放在缓存,这样第二次缓存中获取就会有值了,而不会访问数据库。

5、redis缓存击穿

        redis中一个热点key在失效时,大量的请求过来,从而全部到达数据库,压垮数据库

解决方法

(1 设置热点数据永不过期

​         对于某个频繁获取的信息,缓存在redis中,并且设置永不过期。但并不使用所有场景。

(2 定时更新

        假如这个数据设定过期时间为1小时,那么每到59分时,通过定时任务去更新这个数据的key,并重新设置过期时间。

(3 互斥锁

这是比较常用的方法

        在redis根据key获取的value值为空时,先锁上,然后从数据库加载,加载完毕猴,释放锁,如果其他线程也在请求该key时,发现获取锁失败,则会睡眠一段时间后重试。

6、reids常用的数据类型

String

        常规的set/get操作,value可以是String也可以是数字。一般做一些复杂的计数功能的缓存。

hash

        这里value存放的是结构化的对象,比较方便的就是操作其中的某个字段。博主在做单点登录的时候,就是用这种数据结构存储用户信息,以cookieId作为key,设置30分钟为缓存过期时间,能很好的模拟出类似session的效果。

list

        使用List的数据结构,可以做简单的消息队列的功能。另外还有一个就是,可以利用lrange命令,做基于redis的分页功能,性能极佳,用户体验好。本人还用一个场景,很合适—取行情信息。就也是个生产者和消费者的场景。LIST可以很好的完成排队,先进先出的原则。

set

        因为set堆放的是一堆不重复值的集合。所以可以做全局去重的功能。为什么不用JVM自带的Set进行去重?因为我们的系统一般都是集群部署,使用JVM自带的Set,比较麻烦,难道为了一个做一个全局去重,再起一个公共服务,太麻烦了。另外,就是利用交集、并集、差集等操作,可以计算共同喜好,全部的喜好,自己独有的喜好等功能。

sorted set

        sorted set多了一个权重参数score,集合中的元素能够按 score进行排列。可以做排行榜应用,取TOP N操作。

7、redis过期策略

redis采用的是定期删除+惰性删除策略。

        定期删除,redis默认每100ms检查(不是全部检查,而是随机抽查),是否有过期的key,有则删除。因此会导致很多key没有删除掉,于是就使用惰性删除,在你获取某个key时,redis会先检查是否过期,如果过期了就会删除。

8、跨域的常用解决方案

        (1 JSONP(JSON with Padding):JSONP是一种使用<script>标签发起跨域请求的技术。通过动态创建<script>标签,将需要访问的数据作为回调函数的参数传递,从而实现跨域请求。

        (2 CORS(跨域资源共享):CORS是一种由服务器端实现的跨域解决方案。通过在服务器的响应头中添加特定的CORS标头,告知浏览器允许特定域名的跨域请求。例如,在响应头中设置"Access-Control-Allow-Origin"标头来指定允许访问的域名。

        (3 代理服务器:使用代理服务器是一种常见的跨域解决方案。将跨域请求发送到同源的服务器,然后由服务器代理请求目标资源,并将结果返回给客户端。这种方法需要在服务器端进行配置,但对于客户端来说是透明的。

        (4 iframe跨域通信:通过在页面中嵌入隐藏的iframe,来实现跨域通信。通过修改iframe的URL、使用postMessage等方式,可以在不同域名下的页面之间进行数据传递和通信。

        (5 WebSocket:WebSocket是一种在单个TCP连接上进行全双工通信的协议,它不受同源策略的限制。通过使用WebSocket,可以在不同域名之间实现实时的双向数据传输。

9、JWT 和 session 的区别

session

        因为http的无状态我们并不能知道是哪个用户发出的请求,所以为了让我们的应用能识别是哪个用户发出的请求。我们只能在服务器存储一份用户登录的信息,这份登录信息会在响应时传递给浏览器并告诉其保存为cookie,以便下次请求时发送给我们的应用,这样我们的应用就能识别请求来自哪个用户了

session的缺点

        第一对服务器的压力大:因为每个用户经过服务器认证之后,服务器都要做一次记录,通常这些记录都是保存在内存中,而随着认证用户的增多,服务器开销会明显增大。

    第二程序扩展性变差:用户认证后,服务器做认证记录,如果认证的记录被保存在内存中的话,这意味着用户下次请求还必须在这台服务器上才能拿到授权的资源,这样在分布式的应用上,相应的限制了负载均衡器的能力,也就意味着限制了扩展的能力。

    第三安全性偏低:因为是基于cookie来进行用户识别的,cookie如果被截获,用户就会很容易受到跨站请求伪造(CSRF)的攻击。

JWT

        jwt也是基于token的一种方式。为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准,可实现无状态、分布式的Web应用授权(。JWT只需要保存在客户端即可,减少了对服务器的压力。

                 jwt由三部分组成: Header:头部分通常有两部分组成,一个是使用到的签名算法("HS256"是JWT官方比较推荐的签名算法)一个是令牌的类型(这里目前就一种类型JWT)。

        Payload:负载用来存放信息,官网介绍有三部分,这里就先大致理解为存放的是我们需要传递的内容信息,比如“userId, username, age ”之类的信息。

        Signature:创建签名,我们在header中指定了一个秘钥,作用就是用来在创建签名的时候进行加密的。

10、JWT的优点

(1 可拓展性好

应用程序分布式部署的情况下,session需要多机共享数据,通常可以存在数据库或者redis里,而jwt不需要。

(2 无状态

jwt不在服务端存储任何状态,RESTful API的原则之一是无状态,发出请求 时,总会返回带有参数的响应,不会产生附加影响。用户的认证状态引入这种附加影响,则破坏了这一原则。另外jwt的载荷中可以存储一些常用信息,用于交换信息。

11、SpringCache的常用注解

1、@EnableCaching

开启spring Cache框架支持。解析对应的注解,实现缓存读写访问

2、@CacheConfig

缓存配置,可以配置当前类型中所用缓存注解的通用信息

3、@Cacheable

表示要对方法返回值进行缓存

例:

//执行方法时,返回结果做缓存 
@Cacheable(cacheNames="cache:prefix",key = "'all:values'")
​
//方法参数id 作为key的一部分,做缓存
@CachePut(key = "'TestServiceImpl:getById:'+#id")
​
//方法参数id 作为key的一部分,做缓存,方法返回结果为null时,不做缓存 
@Cacheable(key = "'testUnless('+#id+')'",unless = "#result==null")
​
//方法参数id大于0时 作为key的一部分,做缓存
@Cacheable(key = "'TestServiceImpl:getById:'+#id", condition = "#id > 0")

4、@CacheEvict

淘汰缓存注解

//执行方法时,根据key删除缓存
@CacheEvict(allEntries = true)

5、@CachePut

更新缓存,如果key存在覆盖缓存数据。key不存在,新增数据缓存

//方法参数id 作为key的一部分,根据key更新缓存
@CachePut(key = "'TestServiceImpl:getById:'+#id")

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值