文章目录
- 1、密集索引和稀疏索引的区别
- 2、意向锁
- 3、Redis集群
- 4、DNS解析的流程
- 5、Spring Bean生命周期
- 6、Spring编程式事务和声明式事务
- 7、堆外内存
- 8、Https
- 9、接口限流方法
1、密集索引和稀疏索引的区别
- 密集索引文件中的搜索码都对应一个索引值
- 稀疏索引文件中只会为某些索引码的某些值建立索引项
2、意向锁
产生的原因:解决表锁与之前可能存在的行锁冲突,避免为了判断表是否存在行锁而去扫描全表的系统消耗。
作用:一种快速判断表锁与之前可能存在的行锁冲突的机制。(数据库会帮我们自动加)。行锁在加锁前要先加意向锁。意向锁是一种表锁。
3、Redis集群
Redis有三种集群,分别是主从复制,哨兵模式,集群模式
详情见此篇文章,Pipeline及主从同步模式和哨兵模式
4、DNS解析的流程
- 在浏览器中输入www.qq.com域名,操作系统会先检查自己本地的hosts文件是否有这个网址映射关系,如果有,就先调用这个IP地址映射,完成域名解析。
- 如果hosts里没有这个域名的映射,则查找本地DNS解析器缓存,是否有这个网址映射关系,如果有,直接返回,完成域名解析。
- 如果hosts与本地DNS解析器缓存都没有相应的网址映射关系,首先会找TCP/ip参数中设置的首选DNS服务器,在此我们叫它本地DNS服务器,此服务器收到查询时,如果要查询的域名,包含在本地配置区域资源中,则返回解析结果给客户机,完成域名解析,此解析具有权威性。
- 如果要查询的域名,不由本地DNS服务器区域解析,但该服务器已缓存了此网址映射关系,则调用这个IP地址映射,完成域名解析,此解析不具有权威性。
- 如果本地DNS服务器本地区域文件与缓存解析都失效,则根据本地DNS服务器的设置(是否设置转发器)进行查询,如果未用转发模式,本地DNS就把请求发至13台根DNS,根DNS服务器收到请求后会判断这个域名(.com)是谁来授权管理,并会返回一个负责该顶级域名服务器的一个IP。本地DNS服务器收到IP信息后,将会联系负责.com域的这台服务器。这台负责.com域的服务器收到请求后,如果自己无法解析,它就会找一个管理.com域的下一级DNS服务器地址(qq.com)给本地DNS服务器。当本地DNS服务器收到这个地址后,就会找qq.com域服务器,重复上面的动作,进行查询,直至找到www.qq.com主机。
- 如果用的是转发模式,此DNS服务器就会把请求转发至上一级DNS服务器,由上一级服务器进行解析,上一级服务器如果不能解析,或找根DNS或把转请求转至上上级,以此循环。不管是本地DNS服务器用是是转发,还是根提示,最后都是把结果返回给本地DNS服务器,由此DNS服务器再返回给客户机。
5、Spring Bean生命周期
容器创建之后会解析,并且创建出来bean,Spring Bean的生命周期主要有创建和销毁:
创建Bean:
- 实例化Bean对象,以及设置Bean属性;
- 通过使用各种Aware接口,注入Bean对容器基础设施的依赖,让容器感知到Bean的存在;
- 紧接着调用BeanPostProcessor的前置初始化方法postProcessBeforeInitialization,主要是在Spring Bean完成初始化实例之后,添加一些自定义的处理逻辑;
- 如果实现InitializingBean.afterPropertiesSet,会针对自定义初始化的Bean去做一些自定义的事情;
- 之后定义Bean init,初始化Bean;
- 调用BeanPostProcessor的后置初始化方法postProcessAfterInitialization,做一些Bean初始化实例之后的自定义工作,最后就成功创建了Bean。
销毁Bean:
- 如果Bean实现了DisposableBean接口,就会调用destroy方法;
- 如果配置了destroy-method属性,则会调用其配置的销毁方法。
6、Spring编程式事务和声明式事务
spring支持编程式事务管理和声明式事务管理两种方式:
- 编程式事务使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,spring推荐使用TransactionTemplate
- 声明式事务是建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。声明式事务最大的优点就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明(或通过基于@Transactional注解的方式),便可以将事务规则应用到业务逻辑中
7、堆外内存
堆外内存就是把内存对象分配在Java虚拟机的堆以外的内存,这些内存直接受操作系统管理(而不是虚拟机),这样做的结果就是能够在一定程度上减少垃圾回收对应用程序造成的影响。
在JAVA中,JVM内存指的是堆内存。
机器内存中,不属于堆内存的部分即为堆外内存。
堆外内存也被称为直接内存
Netty使用的也是堆外内存。
使用堆外内存的优点:
- 减少垃圾回收:因为垃圾回收会暂停其他的工作。
- 加快复制速度:堆内在flush到远程时,会先复制到直接内存(非堆内存),然后在发送;而堆外内存相当于省略掉了这个工作。
8、Https
一个HTTPS请求实际上包含了两次HTTP传输,可以细分为8步:
- 客户端向服务器发起HTTPS请求,连接到服务器的443端口
- 服务器端有一个密钥对,即公钥和私钥,是用来进行非对称加密使用的,服务器端保存着私钥,不能将其泄露,公钥可以发送给任何人。
- .服务器将自己的公钥发送给客户端。
- 客户端收到服务器端的证书之后,会对证书进行检查,验证其合法性,如果发现发现证书有问题,那么HTTPS传输就无法继续。严格的说,这里应该是验证服务器发送的数字证书的合法性,关于客户端如何验证数字证书的合法性,下文会进行说明。如果公钥合格,那么客户端会生成一个随机值,这个随机值就是用于进行对称加密的密钥,我们将该密钥称之为client key,即客户端密钥,这样在概念上和服务器端的密钥容易进行区分。然后用服务器的公钥对客户端密钥进行非对称加密,这样客户端密钥就变成密文了,至此,HTTPS中的第一次HTTP请求结束。
- 客户端会发起HTTPS中的第二个HTTP请求,将加密之后的客户端密钥发送给服务器。
- 服务器接收到客户端发来的密文之后,会用自己的私钥对其进行非对称解密,解密之后的明文就是客户端密钥,然后用客户端密钥对数据进行对称加密,这样数据就变成了密文。
- 服务器将加密后的密文发送给客户端
- 客户端收到服务器发送来的密文,用客户端密钥对其进行对称解密,得到服务器发送的数据。这样HTTPS中的第二个HTTP请求结束,整个HTTPS传输完成。
9、接口限流方法
常见的限流算法有:令牌桶、漏桶、Redis计数器。
令牌桶算法(Token Bucket)
令牌桶大小固定,系统会以一个恒定的速度往桶里放入令牌,而如果请求需要被处理,则需要先从桶里获取一个令牌,当桶里没有令牌可取时,则拒绝服务。如果令牌不被消耗,或者被消耗的速度小于产生的速度,令牌就会不断地增多,直到把桶填满。后面再产生的令牌就会从桶中溢出。最后桶中可以保存的最大令牌数永远不会超过桶的大小。
令牌桶的另外一个好处是可以方便的改变速度. 一旦需要提高速率,则按需提高放入桶中的令牌的速率. 一般会定时(比如100毫秒)往桶中增加一定数量的令牌, 有些变种算法则实时的计算应该增加的令牌的数量.
** 漏桶算法(Leaky Bucket)**
水(请求)先进入到漏桶里,漏桶以一定的速度出水(接口有响应速率),当水流入速度过大会直接溢出(访问频率超过接口响应速率),然后就拒绝请求,可以看出漏桶算法能强行限制数据的传输速率。
可见这里有两个变量,一个是桶的大小,支持流量突发增多时可以存多少的水(burst),另一个是水桶漏洞的大小(rate)。
因为漏桶的漏出速率是固定的参数,所以,即使网络中不存在资源冲突(没有发生拥塞),漏桶算法也不能使流突发(burst)到端口速率.因此,漏桶算法对于存在突发特性的流量来说缺乏效率.
基于Redis计数功能的实现
一秒内访问某一个接口的次数不能超过60次(即QPS),每秒在Redis中创建一个键,并且设置键的过期时间为2秒(边界问题),每一个用户对此服务接口的访问就把键值加1,在1秒内当键值增加到60的时候,就禁止访问服务接口。在某种场景中添加访问时间间隔还是很有必要的,也可用于每分钟、每小时访问次数。