tomcat性能调优
1、JVM参数调优:-Xms
2. 禁用DNS查询 :DNS查询需要占用网络,并且包括可能从很多很远的服务器或者不起作用的服务器上去获取对应的IP的过程,这样会消耗一定的时间。为了消除DNS查询对性能的影响我们可以关闭DNS查询,
3、通过应用程序的连接器(Connector)进行性能控制的的参数是创建的处理请求的线程数
通过listener入口,核心是在AbstractApplicationContext的refresh方法,在此处进行装载bean工厂,bean,创建bean实例,拦截器,后置处理器等。
ClassPathXmlApplicationContext实现beanFactory接口,是一个具体的实例化工厂。服务器启动时,解析xml配置文件
将对应文件中每个bean的id作为key,属性封装到beandefinition作为value,封装到一个ConCurrentHashMap容器A中。
同时,还有一个ConCurrentHashMap容器B存储bean的实例化对象,默认是空。当有一个请求时,首先去B中,查找。如果
B容器没有,则访问A容器,如果是单例,则创建之后,仍要保存到B中,下次可以使用。如果是非单例的,则直接创建,并不
在B中保存副本。
说说对spring的理解
spring生命周期
1. BeanFactoyPostProcessor实例化
2. Bean实例化,然后通过某些BeanFactoyPostProcessor来进行依赖注入
3. BeanPostProcessor的调用.Spring内置的BeanPostProcessor负责调用Bean实现的接口: BeanNameAware, BeanFactoryAware, ApplicationContextAware等等,等这些内置的BeanPostProcessor调用完后才会调用自己配置的BeanPostProcessor
4. Bean销毁阶段
spring AOP实现原理
主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。
1、横切关注点
对哪些方法进行拦截,拦截后怎么处理,这些关注点称之为横切关注点
2、切面(aspect)
类是对物体特征的抽象,切面就是对横切关注点的抽象
3、连接点(joinpoint)
被拦截到的点,因为Spring只支持方法类型的连接点,所以在Spring中连接点指的就是被拦截到的方法,实际上连接点还可以是字段或者构造器
4、切入点(pointcut)
对连接点进行拦截的定义
5、通知(advice)
所谓通知指的就是指拦截到连接点之后要执行的代码,通知分为前置、后置、异常、最终、环绕通知五类
入口是web.xml中配置的ds,ds继承了HttpServletBean,FrameworkServlet,通过其中的init方法进行初始化装载bean和实例,initServletBean是实际完成上下文工作和bean初始化的方法。
阻塞式io,非阻塞io,io复用模型,信号驱动io模型,异步io模型。
Ls,find,tar,tail,cp,rm,vi,grep,ps,pkill等等
https://yq.aliyun.com/articles/69417?spm=5176.100240.searchblog.18.Zrbh9R
Tail -n 5 filename
ps -ef|grep Java
Linux 实现并没有区分这两个概念(进程和线程)
1. 进程:程序的一次执行
2. 线程:CPU的基本调度单位
一个进程可以包含多个线程。
实现runable接口,继承thread类。
在拥有共享数据的多条线程并行执行的程序中,线程安全的代码会通过同步机制保证各个线程都可以正常且正确的执行,不会出现数据污染等意外情况。
volatile 的原理,作用,能代替锁么。
Volatile利用内存栅栏机制来保持变量的一致性。不能代替锁,其只具备数据可见性一致性,不具备原子性
线程的生命周期状态
新建,可运行,运行中, 睡眠,阻塞,等待,死亡。
sleep 和 wait 的区别。
Sleep是休眠线程,wait是等待,sleep是thread的静态方法,wait则是object的方法。
Sleep依旧持有锁,并在指定时间自动唤醒。wait则释放锁。
Lock 与 Synchronized 的区别。
首先两者都保持了并发场景下的原子性和可见性,区别则是synchronized的释放锁机制是交由其自身控制,且互斥性在某些场景下不符合逻辑,无法进行干预,不可人为中断等。
而lock常用的则有ReentrantLock和readwritelock两者,添加了类似锁投票、定时锁等候和可中断锁等候的一些特性。此外,它还提供了在激烈争用情况下更佳的性能。
newCache 和 newFixed 有什么区别,他们的原理简单概括下
newFixedThreadPool返回一个包含指定数目线程的线程池,如果任务数量多于线程数目,那么没有没有执行的任务必须等待,直到有任务完成为止。
newCachedThreadPool根据用户的任务数创建相应的线程来处理,该线程池不会对线程数目加以限制,完全依赖于JVM能创建线程的数量,可能引起内存不足。
什么是线程池
多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力。
为什么要用线程池:
1.减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。
2.可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为消耗过多的内存,而把服务器累趴下(每个线程需要大约1MB内存,线程开的越多,消耗的内存也就越大,最后死机)。
线程池的关闭方式有几种
清空工作队列,终止线程池中各个线程,销毁线程池
spring 的 controller 是单例还是多例,怎么保证并发的安全。
单例
通过单例工厂 DefaultSingletonBeanRegistry实现单例
通过保AsyncTaskExecutor持安全
ThreadLocal 用过么,用途是什么,原理是什么,用的时候要注意什么。
Threadlocal底层是通过threadlocalMap进行存储键值 每个ThreadLocal类创建一个Map,然后用线程的ID作为Map的key,实例对象作为Map的value,这样就能达到各个线程的值隔离的效果。
ThreadLocal的作用是提供线程内的局部变量,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或者组件之间一些公共变量的传递的复杂度。
谁设置谁负责移除
讲讲 java 同步机制的 wait 和 notify。
首先这两个方法只能在同步代码块中调用,wait会释放掉对象锁,等待notify唤醒。
TCP 三次握手和四次挥手的流程,为什么断开连接要 4 次,如果握手只有两次,会出现什么。
第一次握手(SYN=1, seq=x):
指明客户端打算连接的服务器的端口
发送完毕后,客户端进入 SYN_SEND
状态。
第二次握手(SYN=1, ACK=1, seq=y, ACKnum=x+1):
服务器发回确认包(ACK)应答。
发送完毕后,服务器端进入 SYN_RCVD
状态。
第三次握手(ACK=1,ACKnum=y+1)
客户端再次发送确认包(ACK),SYN 标志位为0,ACK 标志位为1,
TIME_WAIT状态就是用来重发可能丢失的ACK报文。
TIME_WAIT 表示主动关闭,CLOSE_WAIT 表示被动关闭。
1xx:信息,请求收到,继续处理
2xx:成功,行为被成功地接受、理解和采纳
3xx:重定向,为了完成请求,必须进一步执行的动作
4xx:客户端错误,请求包含语法错误或者请求无法实现
5xx:服务器错误,服务器不能实现一种明显无效的请求
200 ok 一切正常
302 Moved Temporatily 文件临时移出
404 not found
加密方式是tls/ssl,底层是通过对称算法,非对称,hash算法实现
客户端发起HTTPS请求 –》2. 服务端的配置 –》
3. 传送证书 —》4. 客户端解析证书 5. 传送加密信息 6. 服务段解密信息 7. 传输加密后的信息 8. 客户端解密信息
Dns解析–>端口分析–>tcp请求–>服务器处理请求–>服务器响应–>浏览器解析—>链接关闭
一个HTTP请求报文由请求行(request line)、请求头部(header)、空行和请求数据4个部分组成
HTTP响应也由三个部分组成,分别是:状态行、消息报头、响应正文。
首先分布式锁实现常见的有数据库锁(表记录),缓存锁,基于zk(临时有序节点可以实现的)的三种
Redis适用于对性能要求特别高的场景。redis可以每秒执行10w次,内网延迟不超过1ms
缺点是数据存放于内存,宕机后锁丢失。
锁无法释放?使用Zookeeper可以有效的解决锁无法释放的问题,因为在创建锁的时候,客户端会在ZK中创建一个临时节点,一旦客户端获取到锁之后突然挂掉(Session连接断开),那么这个临时节点就会自动删除掉。其他客户端就可以再次获得锁。
非阻塞锁?使用Zookeeper可以实现阻塞的锁,客户端可以通过在ZK中创建顺序节点,并且在节点上绑定监听器,一旦节点有变化,Zookeeper会通知客户端,客户端可以检查自己创建的节点是不是当前所有节点中序号最小的,如果是,那么自己就获取到锁,便可以执行业务逻辑了。
不可重入?使用Zookeeper也可以有效的解决不可重入的问题,客户端在创建节点的时候,把当前客户端的主机信息和线程信息直接写入到节点中,下次想要获取锁的时候和当前最小的节点中的数据比对一下就可以了。如果和自己的信息一样,那么自己直接获取到锁,如果不一样就再创建一个临时的顺序节点,参与排队。
单点问题?使用Zookeeper可以有效的解决单点问题,ZK是集群部署的,只要集群中有半数以上的机器存活,就可以对外提供服务。
分布式事务就是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。以上是百度百科的解释,简单的说,就是一次大的操作由不同的小操作组成,这些小的操作分布在不同的服务器上,且属于不同的应用,分布式事务需要保证这些小操作要么全部成功,要么全部失败。本质上来说,分布式事务就是为了保证不同数据库的数据一致性。
分布式事务,本质上是对多个数据库的事务进行统一控制,按照控制力度可以分为:不控制、部分控制和完全控制。不控制就是不引入分布式事务,部分控制就是各种变种的两阶段提交,包括上面提到的消息事务+最终一致性、TCC模式,而完全控制就是完全实现两阶段提交。部分控制的好处是并发量和性能很好,缺点是数据一致性减弱了,完全控制则是牺牲了性能,保障了一致性,具体用哪种方式,最终还是取决于业务场景。作为技术人员,一定不能忘了技术是为业务服务的,不要为了技术而技术,针对不同业务进行技术选型也是一种很重要的能力!
分布式事务优缺点
优点是可以管理多机事务,拥有无线扩展性 缺点是易用性难,承担延时风险
一致性hash是一种分布式hash实现算法。满足平衡性 单调性 分散性 和负载。
一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
(1)每一个URI代表一种资源;
(2)客户端和服务器之间,传递这种资源的某种表现层;
(3)客户端通过四个HTTP动词,对服务器端资源进行操作,实现"表现层状态转化"。
说说你知道的几种 HASH 算法,简单的也可以。
哈希(Hash)算法,即散列函数。 它是一种单向密码体制,即它是一个从明文到密文的不可逆的映射,只有加密过程,没有解密过程。 同时,哈希函数可以将任意长度的输入经过变化以后得到固定长度的输出
MD4 MD5 SHA
什么是 zab 协议。
ZAB 是 Zookeeper 原子广播协议的简称
整个ZAB协议主要包括消息广播和崩溃恢复两个过程,进一步可以分为三个阶段,分别是:
发现 Discovery
同步 Synchronization
广播 Broadcast
组成ZAB协议的每一个分布式进程,都会循环执行这三个阶段,将这样一个循环称为一个主进程周期。
一个在线文档系统,文档可以被编辑,如何防止多人同时对同一份文档进行编辑更新。
点击编辑的时候,利用redis进行加锁setNX完了之后 expire 一下
也可以用版本号进行控制
Dubbo 的原理,数据怎么流转的,怎么实现集群,负载均衡,服务注册和发现。重试转发,快速失败的策略是怎样的。
Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。简单的说,dubbo就是个服务框架,如果没有分布式的需求,其实是不需要用的,只有在分布式的时候,才有dubbo这样的分布式服务框架的需求,并且本质上是个服务调用的东东,说白了就是个远程服务调用的分布式框架
其核心部分包含:
1. 远程通讯: 提供对多种基于长连接的NIO框架抽象封装,包括多种线程模型,序列化,以及“请求-响应”模式的信息交换方式。
2. 集群容错: 提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持。3. 自动发现: 基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方可以平滑增加或减少机器。
Dubbox—负载均衡
在集群负载均衡时,Dubbo提供了多种均衡策略,缺省为random随机调用。 可以自行扩展负载均衡策略,参见:负载均衡扩展
Random LoadBalance 随机,按权重设置随机概率。 在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。
RoundRobin LoadBalance 轮循,按公约后的权重设置轮循比率。存在慢的提供者累积请求问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。
LeastActive LoadBalance最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。 使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。
ConsistentHash LoadBalance 一致性Hash,相同参数的请求总是发到同一提供者。 当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。 缺省只对第一个参数Hash,如果要修改,请配置
一次 RPC 请求的流程是什么。
1)服务消费方(client)调用以本地调用方式调用服务;
2)client stub接收到调用后负责将方法、参数等组装成能够进行网络传输的消息体;
3)client stub找到服务地址,并将消息发送到服务端;
4)server stub收到消息后进行解码;
5)server stub根据解码结果调用本地的服务;
6)本地服务执行并将结果返回给server stub;
7)server stub将返回结果打包成消息并发送至消费方;
8)client stub接收到消息,并进行解码;
9)服务消费方得到最终结果。
RPC概念及分类
RPC全称为Remote Procedure Call,翻译过来为“远程过程调用”。目前,主流的平台中都支持各种远程调用技术,以满足分布式系统架构中不同的系统之间的远程通信和相互调用。远程调用的应用场景极其广泛,实现的方式也各式各样。
从通信协议的层面,大致可以分为:
基于HTTP协议的(例如基于文本的SOAP(XML)、Rest(JSON),基于二进制Hessian(Binary))
基于TCP协议的(通常会借助Mina、Netty等高性能网络框架)
常见的几种通信方式
1. 远程数据共享(例如:共享远程文件,共享数据库等实现不同系统通信)
2. 消息队列
3. RPC(远程过程调用)
异步模式的用途和意义。
异步模式使用与服务器多核,并发严重的场景
可提高服务吞吐量大,不容易受到冲击,可以采用并发策略,提高响应时间
缓存数据过期后的更新如何设计。
失效:应用程序先从cache取数据,没有得到,则从数据库中取数据,成功后,放到缓存中。
命中:应用程序从cache中取数据,取到后返回。
更新:先把数据存到数据库中,成功后,再让缓存失效。
数据库隔离级别有哪些,各自的含义是什么,MYSQL 默认的隔离级别是是什么。
·未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据
提交读(Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)
可重复读(Repeated Read):可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读
串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞
MYSQL默认是RepeatedRead级别
序列化/反序列化
只有二进制数据才能在网络中传输,序列化和反序列化的定义是:
将对象转换成二进制流的过程叫做序列化,
将二进制流转换成对象的过程叫做反序列化。
高并发下,如何做到安全的修改同一行数据。
使用悲观锁 悲观锁本质是当前只有一个线程执行操作,结束了唤醒其他线程进行处理。
也可以缓存队列中锁定主键。
乐观锁和悲观锁是什么,INNODB 的行级锁有哪 2 种,解释其含义。
乐观锁是设定每次修改都不会冲突,只在提交的时候去检查,悲观锁设定每次修改都会冲突,持有排他锁。
行级锁分为共享锁和排他锁两种 共享锁又称读锁 排他锁又称写锁
优化SQL语句的一般步骤
1.通过show status命令了解各种SQL的执行频率
2.定位执行效率较低的SQL语句
3.通过explain分析低效SQL的执行计划
4.确定问题并采取相应的优化措施
数据库会死锁吗
产生死锁的原因主要是:
(1)系统资源不足。
(2) 进程运行推进的顺序不合适。
(3)资源分配不当等。
mysql 怎么解决死锁。
1)重启数据库(谁用谁知道)
2)杀掉抢资源的进程:
先查哪些进程在抢资源:SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;
杀掉它们:Kill trx_mysql_thread_id;
聚集索引和非聚集索引的区别。
“聚簇”就是索引和记录紧密在一起。
非聚簇索引 索引文件和数据文件分开存放,索引文件的叶子页只保存了主键值,要定位记录还要去查找相应的数据块。
ACID 是什么。
A,atomic,原子性,要么都提交,要么都失败,不能一部分成功,一部分失败。
C,consistent,一致性,事物开始及结束后,数据的一致性约束没有被破坏
I,isolation,隔离性,并发事物间相互不影响,互不干扰。
D,durability,持久性,已经提交的事物对数据库所做的更新必须永久保存。即便发生崩溃,也不能被回滚或数据丢失。
mysql 中 in 和 exists 区别。
如果查询的两个表大小相当,那么用in和exists差别不大。
如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in:
not in 和not exists如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;而not extsts 的子查询依然能用到表上的索引。所以无论那个表大,用not exists都比not in要快。
1.EXISTS只返回TRUE或FALSE,不会返回UNKNOWN。
2.IN当遇到包含NULL的情况,那么就会返回UNKNOWN。
索引是什么
mysql索引: 是一种帮助mysql高效的获取数据的数据结构,这些数据结构以某种方式引用数据,这种结构就是索引。可简单理解为排好序的快速查找数据结构。如果要查“mysql”这个单词,我们肯定需要定位到m字母,然后从下往下找到y字母,再找到剩下的sql。
单值索引:一个索引包含1个列 create index idx_XX on table(f1) 一个表可以建多个。
唯一索引: 索引列的值必须唯一,但允许有空值 create unique index idx_XX on table(f1)
复合索引: 一个索引包含多个列 如:create index idx_XX on table(f1,f2,..)
全文索引:文本字段上(text)如果建立的是普通索引,那么只有对文本的字段内容前面的字符进行索引,其字符大小根据索引建立索引时申明的大小来规定.
(三)使用索引的优点
1.可以通过建立唯一索引或者主键索引,保证数据库表中每一行数据的唯一性.
2.建立索引可以大大提高检索的数据,以及减少表的检索行数
3.在表连接的连接条件 可以加速表与表直接的相连
4.在分组和排序字句进行数据检索,可以减少查询时间中 分组 和 排序时所消耗的时间(数据库的记录会重新排序)
5.建立索引,在查询中使用索引 可以提高性能
(四)使用索引的缺点
1.在创建索引和维护索引 会耗费时间,随着数据量的增加而增加
2.索引文件会占用物理空间,除了数据表需要占用物理空间之外,每一个索引还会占用一定的物理空间
3.当对表的数据进行 INSERT,UPDATE,DELETE 的时候,索引也要动态的维护,这样就会降低数据的维护速度,(建立索引会占用磁盘空间的索引文件。一般情况这个问题不太严重,但如果你在一个大表上创建了多种组合索引,索引文件的会膨胀很快)。