《后端服务性能优化指南》java
目录mysql
1、 服务器操做系统 2linux
2、 web服务器/反向代理服务器(nginx) 2nginx
3、 应用服务器(tomcat) 2web
4、 应用日志配置 2spring
5、 数据库(mysql) 3sql
6、 数据库链接池 3数据库
7、 Restfull服务调用 4apache
1、服务器操做系统后端
一、全局全部进程共享上限
查看系统配置最大句柄数 cat /proc/sys/fs/file-nr
修改: /etc/sysctl.conf
fs.file-max = 100000
net.ipv4.ip_conntrack_max = 100000
net.ipv4.netfilter.ip_conntrack_max = 100000
二、单进程最大句柄数
服务器默认配置为1024
查看最大进程数 ulimit -u
查看进程最大句柄数 ulimit -n
修改:/etc/security/limits.conf
* soft nofile = 32768
* hard nofile = 65536
对全部用户单线程最大可打开句柄,软限制32768,硬限制65536;
三、tcp链接存活时间,关闭链接时等待时间
修改/etc/sysctl.conf,添加以下几行:
#系統默认的TIMEOUT时间
net.ipv4.tcp_fin_timeout=30
#启重用,容许将TIME_WAIT sockets从新用于新的TCP链接 默认为0表示关闭
net.ipv4.tcp_tw_reuse=1
#开启TCP链接中TIME_WAIT sockets的快速回收 默认为0 表示关闭
net.ipv4.tcp_tw_recycle=1
四、使用uname -a命令查看系统内核版本,请确保linux系统内核版本高于2.6.28, 今后版本开始linux支持高效异步IO模型epoll,jdk的NIO开发包中含有对当 前操做系统版本号的判断(linux>2.6时调用epoll的native方法),java nio所 用的IO模型的实现方式由操做系统决定。
2、web服务器/反向代理服务器(nginx)
nginx.conf配置文件:
五、nginx单个工做进程最大创建外部链接数
worker_connections 16000
六、nginx进程最大可打开句柄数
worker_rlimit_nofile 65535
七、nginx工做进程数
worker_processes 8 [通常设置为CPU核数的双倍]
3、应用服务器(tomcat)
一、请将connector配置为NIO模式,并设置合适的最大链接数(springboot内嵌的tomcat默认就是NIO,最大链接数max-connections默认10000)
二、调整tomcat工做线程数与排队队列长度
server.tomcat.max-threads=800
server.tomcat.accept-count=200
4、应用日志配置
一、应用日志目前最佳实践为sl4j + logback,代码中应使用sl4j日志门面,禁止直接使用log4j等具体实现。
二、在某些高并发服务应考虑作日志异步优化,减小IO阻塞时间、提升CPU利用率:
<appender name="syslog"
class="ch.qos.logback.core.rolling.RollingFileAppender">
......
</appender>
<appender name="ASYNC_ROLLING_FILE" class="ch.qos.logback.classic.AsyncAppender">
<queueSize>256</queueSize>
<includeCallerData>true</includeCallerData>
<appender-ref ref="syslog"/>
</appender>
<root level="INFO">
<!-- <appender-ref ref="STDOUT"/> -->
<appender-ref ref="ASYNC_ROLLING_FILE"/>
</root>
Logback提供的AsyncAppender使用内置的队列实现异步日志输出,默认256,为保证性能,超过该长度80%则开始丢弃error以外的日志。
属性名 |
类型 |
默认值 |
描述 |
queueSize |
int |
256 |
内置BlockingQueue的最大容量 |
discardingThreshold |
int |
-1 |
默认状况下,当blockingQueue的容量高于阈值时(80%),会丢弃ERROR如下级别的日志,若是不但愿丢弃日志(既每次都是全量保存),那能够设置为0,可是若是队列满的时候,会丢弃全部插入队列的日志信息,因此建议设置为-1(默认值)。 如正常日志能够丢弃,那能够极大的提高性能,并保存关键的ERROR日志。
|
includeCallerData |
boolean |
false |
提取调用者数据的代价是至关昂贵的。为了提高性能,默认状况下,当event被加入到queue时,event关联的调用者数据不会被提取。默认状况下,只有"cheap"的数据,如线程名。好比日志中的代码行号若是须要输出则应将该值设为true。实测includeCallerData=true会带来必定性能降低,但高并发下仍远比同步日志方式的tps要高。 |
5、数据库(mysql)
在作压力测试的时候,发现了数据库链接数的限制,以及一些比较长慢查询,如下的配置主要解决这方面的问题
如下的数据库参数在/etc/my.cnf 中进行修改,数据库重启以后生效。
一、 数据库的最大链接数以及用户最大链接数的设置以下,
max_connections=1000(默认151)
max_user_connections=1000
2、查询过程当中生成的临时表的大小能够经过tmp_table_size进行设置, max_heap_table_size在作链接查询的时候用到。参数max_heap_table_size比tmp_table_size小时,则系统会把max_heap_table_size的值做为最大的内存临时表的上限,大于这个时,改写硬盘,增长heap表的大小,可达到提升联接查询速度的效果。
如:
tmp_table_size=200M(默认16M)
max_heap_table_size=500M(默认16M)
3、read_buffer_size:是MySQL读入缓冲区大小,对表进行顺序扫描的请求将分配一个读入缓冲区,MySQL会为它分配一段内存缓冲区。read_buffer_size变量控制这一缓冲区的大小。若是对表的顺序扫描请求很是频繁,而且如认为频繁扫描进行得太慢,能够经过增长该变量值以及内存缓冲区大小提升其性能。
以下的设置:
sort_buffer_size = 8M
read_buffer_size =8M
read_rnd_buffer_size = 8M
join_buffer_size,这个是跟join table 关联的,如:join_buffer_size = 8M。
6、数据库链接池
以tomcat-jdbc链接池为例,其余链接池如dbcp、c3p0、druid等相似;
一、core portal user identity几个应用的数据库链接池参数修改:user最大链接maxActive、最大空闲maxIdle 300,最小空闲minIdle、初始数initialSize 60;portal\core\identity:最大链接、最大空闲100, 最小空闲、初始数20;其余应用初始5最大20
二、在生产环境请关闭testOnBorrow和testOnReturn(设置为false),失效链接主要经过testWhileIdle保证。
7、 Restfull服务调用
一、热点服务不容许直接使用jdk自带的java.net.URLConnection进行http client调用
二、推荐使用apache httpclient,okhttp等链接池模式的http库进行rest服务调用,减小反复创建链接的开销。基于spring技术栈的应用比较好的实践方式是使用restTemplate来配置上述实现方式。
三、Apache HttpClient Fluent API底层实现基于自家的httpclient链接池模式,其中代码写死了maxTotal和maxPerRoute全部请求会使用一个公共的链接池,总共200链接,每一个destination最多100个链接。在高并发状况下会出现瓶颈,不推荐热点应用使用。