经验分享一箩筐,今后不再入坑

01. 聊 啥面试


世人都说路不齐、别人骑马我骑驴、回头看看推车汉、比上不足下有余!
数据库


你骑马来我骑驴,看看眼前我不如;回头一看推车汉,比上不足比下余。apache


回头总结一下以往填过的坑,感受本身还真挺牛掰。缓存


今天不闲聊,主题不跑偏,就想送大家一箩筐经验,预防大家再入坑。
安全


吃个核桃,坐稳,扶好,咱们开始。bash


02. 聊 开服务器


经验一:CPU 长期利用率为 100%多线程


问题现象:并发

多用户并发状况下,CPU 利用率长期为100%,DUMP 线程信息,发现 CPU 利用率高的线程都与 HashMap 操做相关。异步


缘由分析:

  • 在并发状况下选择非线程安全的容器是没有保障的,HashMap是非线程安全的;

  • HashMap 在多线程状况下,进行扩容很容易致使死循环,最终致使 CPU 利用率 100%。


解决方法:

  • 在并发场景下,避免使用 hashMap;

  • 在并发场景下,若必定要使用 HashMap,使用同步锁或者使用 ConcurrentHashMap 替代 HashMap。


经验二:数据库访问至关的慢


问题现象:

数据库请求次数多,响应慢。


缘由分析:

在索引具有的前提下,数据库分配链接数少,且缺乏缓存。


解决方法:

  • 对于须要链接到数据库的应用,要考虑查询的结果是否能够复用;

  • 对于查询结果时效性不高并且须要屡次调用的请求,作缓存每每能够节省数据库的资源,也使应用自己效率大大提升。


经验三:系统链接数巨多


问题现象:

系统链接数巨多


缘由分析:

Tomcat 容器默认的通信方式为 TCP/IP + BIO,这种模式每每不适合大并发的状况,BIO 模式生成 Socket 会消耗过多的本地资源,Socket 链接的创建通常比较慢,能支持的链接数有限。


通常都采起 accept 获取 Socket 之后采用一个 thread 来处理,one connection one thread,不管链接是否有真正数据请求,都须要独占一个 thread。


若是咱们 server 端须要支持大量链接,但这些链接同时发送请求的峰值不会不少,通常建议替换成 NIO 模式。


解决方法:

替换成 TCP/IP+NIO,NIO 模型是内置的,调用很方便,只须要修改配置文件conf/server.xml文件,将配置文件中 protocol 修改为 org.apache.coyote.http11.Http11NioProtocol,重启便可生效。


下面的配置是已经改过了的,默认 protocol 是HTTP/1.1

<Connector port="8080"	protocol="org.apache.coyote.http11.Http11NioProtocol"  	connectionTimeout="20000"  	redirectPort="8443"   	maxThreads="500"   	minSpareThreads="20"  	acceptCount="100" 	disableUploadTimeout="true" 	enableLookups="false"   	URIEncoding="UTF-8" />复制代码

经验四:使用HttpClient的版本问题


问题现象:

不是每一个请求都能正确返回,可能遇到 The remote server returned an error.(417) Unkown


缘由分析:

系统使用的是 4.0.3 版本,该版本发布时 Expect:100-continue 默认为开启状态,即客户端每次与服务器通信过程,每次先向服务器发送一个请求,看服务器是否能处理这个请求,通常应用在上传一些特殊的文件或者比较大数据量的交互上,有时候会造 time_wait 不少。


该问题在 HttpClient 4.1 版本中解决,默认为关闭该功能。


解决方法:

升级到 4.1 以上版本,默认为关闭该功能。


经验五:使用 log4j 日志性能的问题


问题现象:

日志 IO 占用大量的系统资源,CPU 利用率高,TPS 偏低,热点方法在

org.apache.log4j.Category.callAppenders
ch.qos.logback.core.OutputStreamAppender.subAppend() 复制代码

等与日志相关的方法。

缘由分析:

日志量过大,IO 频繁。日志对系统性能的影响程度主要体如今如下几方面

  • 日志输出的选项设置,有些选项极慢, 例如 C/class、 F/file 、L/line 、l 、M/method速度极慢,尽可能避免使用;

  • 日志输出双份,某些应用一般将业务日志同时输出到控制台和另一个文件或者日志信息在同一份文件中输出两次;

  • 日志输出的目的地,输出到控制台的速度比输出到文件系统的速度要慢;

  • 日志输出格式不同对性能也会有影响,如简单输出布局(SimpleLayout)比格式化输出布局(PatternLayout)输出速度要快。能够根据须要尽可能采用简单输出布局格式输出日志信息;

  • 日志级别越低输出的日志内容就越多,对系统系能影响很大;

  • 日志输出方式的不一样,对系统系能也是有必定影响的,采用异步输出方式比同步输出方式性能要高;

  • 每次接收到日志输出事件就打印一条日志内容比当日志内容达到必定大小时打印性能要低。


解决方法:

  • 精简日志输出内容,合理设置日志输出格式,避免使用那些极慢的选项;

  • 设置日志缓存,以及缓存大小;

  • 将业务日志仅输出到文件系统,且仅输出一份(以log4j为例,对于日志输出多份的状况举例以下):

同一份日志输出到两个文件的状况
log4j.rootLogger=DEBUG, stdout, system 
表示将等级为 DEBUG 的日志信息输出到 stdout 和 system 这两个目的地,
此配置将使得日志输出两份,将此行改为 
log4j.rootLogger=DEBUG, system;
表示将日志只输出到 system 这一个目的地;复制代码

经验六:logback 比 log4j 拥有更好的性能


使用 logback 和 log4j 日志组件进行日志打印。

当日志级别为 debug 时,系统平均 tps 比为 logback:log4j=1.31:1

当日志级别为 info 时,系统平均 tps 比为 logback:log4j=1.03:1


日志输出量越大时,使用 logback 日志组件进行日志打印比 log4j 方式在处理速度方面的优点越为明显,实验过程当中 logback 比之 log4j 系统处理能力提高幅度为 3%~30%。


经验七:已经分享一箩筐了,再分享箩筐也装不下,惟恐聪明的大家也消化不动了。(有缘再续)


03. 聊 毕


过往从事研发中的点滴经验,送给大家,预防大家再入坑,另外大家也能够在面试的时候吹吹牛啦(哈哈)。


若是大家感受稍微有点意思,不用赞扬,就点击右下角的“在看”,或者多多分享转发给大家的朋友就很感激。

相关文章
相关标签/搜索