我们为什么要优化?
linux作为服务器,当socket运行高并发TCP程序时,通常会出现连接建立到一定个数后不能再建立连接的情况
生产环境下,多次测试,发现每次连接建立到1000左右时,再也不能建立tcp连接,为什么呢?
这是因为在Linux平台上,无论编写客户端程序还是服务端程序,在进行高并发TCP连接处理时,
最高的并发数量都要受到系统对用户单一进程同时可打开文件数量的限制(这是因为系统为每个TCP连接都要创建一个socket句柄,
每个socket句柄同时也是一个文件句柄)。为了调大TCP最大连接数,必须修改用户进程可打开文件数限制
我的Linux优化就基于Centos的,如果是其他操作系统,可能参数会有变化,大家就自行去了解一下就好了
优化最大连接数
一、使用以下命令查看当前最大连接数:
ulimit -n
然后我们默认应该都是1024,所以我们需要把它调大
二、修改以下配置文件:
编辑/etc/security/limits.conf
vi /etc/security/limits.conf
在配置文件中添加以上内容
* soft nofile 65535
* hard nofile 65535
* soft nproc 65535
* hard nproc 65535
第1个参数指定修改root用户的打开文件数限制,可用'*'号表示修改所有用户的限制;
第2个参数soft或hard指定要修改软限制还是硬限制;
第3个参数65535则指定了想要修改的新的限制值,即最大打开文件数(请注意软限制值要小于或等于硬限制)
nofile有上限,不是无穷大,nofile 65535即上限为65535
文件内容修改后,重启系统,再执行第一步操作,发现打开的文件数限制已变为:65535
有的Linux操作系统,如(Ubuntu)不允许配置 * ,ubuntu的root用户必须写出来,其它用户可用*代替
三、保证/etc/pam.d/login文件中session required pam_limits.so被打开
编辑/etc/pam.d/login
vi /etc/pam.d/login
把以下内容添加上
session required pam_limits.so
然后我们重启虚拟机,再次输入 ulimit -n
四、查看Linux系统级的最大打开文件数限制,使用如下命令,我们的最大数是不能大于它的
cat /proc/sys/fs/file-max
这是根据你电脑配置来的,每个人都不一样
这表明这台Linux系统最多允许同时打开(即包含所有用户打开文件数总和)这么多个文件,是Linux系统级硬限制,所有用户级的打开文件数限制都不应超过这个数值。通常这个系统级硬限制是Linux系统在启动时根据系统硬件资源状况计算
出来的最佳的最大同时打开文件数限制,如果没有特殊需要,不应该修改此限制,除非想为用户级打开文件数限制设置超过此限制的值
Linux系统优化-TCP/IP内核参数优化
一、修改/etc/sysctl.conf文件,在文件最后添加如下行:
net.core.rmem_default = 256960
net.core.rmem_max = 513920
net.core.wmem_default = 256960
net.core.wmem_max = 513920
net.core.netdev_max_backlog = 65535
net.core.somaxconn = 65535
net.core.optmem_max = 81920
net.ipv4.tcp_mem = 131072 262144 524288
net.ipv4.tcp_rmem = 8760 256960 4088000
net.ipv4.tcp_wmem = 8760 256960 4088000
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_sack = 1
net.ipv4.tcp_fack = 1
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 15
net.ipv4.ip_local_port_range = 1024 65535
net.ipv4.tcp_max_syn_backlog = 20000
参数具体的意思自己去看博客:参数详情
二、执行sysctl命令,让改动配置立即生效
sysctl -p
如果系统没有错误提示,就表明对TCP/IP内核参数修改成功
Tomcat在各位JavaWeb从业者常常就是默认的开发环境,但是Tomcat的默认配置作为生产环境,
尤其是内存和线程的配置,默认都很低,容易成为性能瓶颈.幸好Tomcat还有很多的提升空间.
我们主要将从性能优化与安全设置这两个方面入手,对Tomcat进行设置。
springboot因为是内嵌tomcat,所以我们如果想要修改它的Tomcat配置,只需要在它的application.yml中配置即可
在优化Tomat的前提是你java的环境变量是配置好的,这里就不说了,不会配置的去看我以前的博客
javascript:void(0)
我们先需要上传一个tomcat,然后解压。
tar -zxvf apache-tomcat-8.5.20.tar.gz
修改tomcat远程控制
vi conf/tomcat-users.xml
配置我们进入tomcat的用户
<role rolename="manager"/>
<role rolename="manager-gui"/>
<role rolename="admin"/>
<role rolename="admin-gui"/>
<role rolename="manager-script"/>
<role rolename="manager-jmx"/>
<role rolename="manager-status"/>
<user username="admin" password="password" roles="admin-gui,admin,manager-gui,manager,manager-script,manager-jmx,manager-status"/>
cd webapps/manager/META-INF/
vi context.xml
将下面配置注释掉
<Context antiResourceLocking="false" privileged="true" >
将这行配置注释
<!-- <Valve className="org.apache.catalina.valves.RemoteAddrValve"
allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" /> -->
<Manager sessionAttributeValueClassNameFilter="java\.lang\.(?:Boolean|Integer|Long|Number|String)|org\.apache\.catalina\.filters\.CsrfPreventionFilter\$LruCache(?:\$1)?|java\.util\.(?:Linked)?HashMap"/>
</Context>
配置好之后,我们就能查看服务状态
我们还能直接在Manager App中直接发布项目
tomcat默认情况下JVM只分配128MB
此环境变量JAVA_OPTS要添加在tomca的bin下catalina.sh里,位置cygwin=false前
JAVA_OPTS="-server -Xms2048m -Xmx2048m -Xmn768m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m -Djava.awt.headless=true"
参数说明:
#-server :启用jdk的server版,一定要作为第一个参数,在多个CPU时性能佳
#-Xms2048m :设置JVM最大可用内存为2048MB
#-Xmx2048m :设置JVM初始可用内存为2048MB,
:Xms与Xmx普遍选择配置相同的大小,可以根据实际情况由小向大增加,建议设为物理内存的一半。不可超过物理内存。
#-Xmn768m :年轻代内存大小,Sun官方推荐配置为整个堆的3/8,即:2048*3/8=768
#-XX:PermSize=128m :设置堆栈永久区起始大小为128m
#-XX:MaxPermSize=256m :设置堆栈永久区最大大小为256m
:在JDK1.8中,取消了PermGen,取而代之的是Metaspace,所以PermSize和MaxPermSize参数失效,
:取而代之的是-XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m
#-Djava.awt.headless=true :linux下处理图片时需加上(windows上不会出问题),否则抛异常:Exception in thread "main" Java.lang.InternalError: Can't connect to X11 window server using ':0.0' as the value of the DISPLAY variable
Tomcat并发优化(即Tomcat线程优化)
修改conf/server.xml添加Executor,然后在Connector元素添加此线程池的引用
先在server.xml查找被注释的Executor元素,取消注释后修改成如下内容
<Executor name="tomcatThreadPool"
namePrefix="catalina-exec-"
prestartminSpareThreads="true"
maxThreads="800"
maxQueueSize="100"
minSpareThreads="50"
maxIdleTime="12000"
threadPriority="5"
/>
属性说明:
name="tomcatThreadPool" # 配置TOMCAT共享线程池,NAME为名称
namePrefix="catalina-exec-" # 线程的名字前缀,用于标记线程名称
prestartminSpareThreads="true" # executor启动时,是否开启最小的线程数
maxThreads="800" # 最大并发连接数,不配置时默认200,一般建议设置500~ 800
maxQueueSize="100" # 任务队列上限
minSpareThreads="50" # 最小的保持活跃的线程数量,默认是25.这个要根据负载情况自行调整了。太小了就影响反应速度,太大了白白占用资源
maxIdleTime="12000" # 线程空闲时间,超过该时间后,空闲线程会被销毁,默认值为6000(1分钟),单位毫秒
threadPriority="5" # 线程池中线程优先级,默认值为5,值从1到10
修改Connector元素,添加Connectorexecutor属性,tomcatThreadPool即上面配置的线程池
<Connector port="8080"
protocol="org.apache.coyote.http11.Http11NioProtocol"
...
executor="tomcatThreadPool"
/>
Tomcat的IO优化
即修改Tomcat Connector运行模式,Tomcat Connector(Tomcat连接器)有bio、nio、apr三种运行模式
BIO
同步阻塞IO
每个请求都要创建一个线程来处理,线程开销比较大。缺点:并发量高时,线程数较多,浪费资源。
Tomcat7或以下,在Linux系统中默认使用这种方式
NIO
异步非阻塞IO
利用Java的异步IO处理,可以通过少量的线程处理大量的请求。
Tomcat8在Linux系统中默认使用这种方式。
Tomcat7必须修改Connector的protocol属性配置来启动:
<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
connectionTimeout="20000" redirectPort="8443"/>
APR
大杀器APR,即Apache Portable Run-time libraries,从操作系统层面解决io阻塞问题。apr也是在Tomcat上运行高并发应用的首选模式
Tomcat7或Tomcat8在Win7或以上的系统中启动默认使用这种方式。
Linux如果安装了apr和native,Tomcat直接启动就支持apr。
APR安装所需软件(也可以通过apt-get网上直接下载)
apr-1.6.5.tar.gz
apr-iconv-1.2.2.tar.gz
apr-util-1.6.1.tar.gz
openssl-1.0.2q.tar.gz(新版本的ubuntu系统中已安装openssl)
tomcat-native(tomcat自带、bin目录下)
APR安装步骤
1. 上传软件
pscp -r d:/temp/apr root@192.168.199.129:/usr/local/java #将包含安装软件的文件夹apr传至/usr/local/java目录下
2. 解压安装文件
cd /usr/local/java/apr
tar -zxvf apr-1.6.5.tar.gz
tar -zxvf apr-iconv-1.2.2.tar.gz
tar -zxvf apr-util-1.6.1.tar.gz
注1:linux命令可以可以分开执行,也可以通过&&符号放到一起执行
tar -zxvf apr-1.6.5.tar.gz && tar -zxvf apr-iconv-1.2.2.tar.gz && tar -zxvf apr-util-1.6.1.tar.gz
3. 安装apr需要依赖安装
#ubuntu的依赖安装
apt-get install -y libtool libapr1 make gcc libexpat1-dev
注1:#centos的依赖安装
yum install -y apr-devel openssl-devel gcc make expat-devel libtool
4. 安装apr基础包
cd /usr/local/java/apr/apr-1.6.5 #进入apr解压后的目录
./configure --prefix=/usr/local/apr && make && make install
注1:--prefix参数用于指定apr的安装路径,默认值就是“/usr/local/apr”,所以上面的命令也可以写成如下格式:
./configure && make && make install
5. 安装apr-iconv包
cd /usr/local/java/apr/apr-iconv-1.2.2
./configure --prefix=/usr/local/apr-iconv --with-apr=/usr/local/apr && make && make install
注1:--prefix参数用于指定apr-iconv的安装路径
注2:--with-apr告知apr-iconv配置的时候apr的路径在什么地方
6. 安装apr-util包
cd /usr/local/java/apr/apr-util-1.6.1
./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr --with-apr-iconv=/usr/local/apr-iconv/bin/apriconv && make && make install
注1:--prefix参数用于指定apr-util的安装路径
注2:--with-apr告知apr-util配置的时候apr的路径在什么地方
注2:--with-apr-iconv告知apr-util配置的时候apr-iconv的路径在什么地方
7. 安装openssl(此步骤可省略,ubuntu16.04已安装openssl)
注:Ubuntu可通过如下命令查看OpenSSL相关情况
openssl version -a
8. 安装tomcat-native
cd /usr/local/apache-tomcat-8.5.20/bin
tar -zxvf tomcat-native.tar.gz # 解压tomcat-native.tar.gz
cd tomcat-native-1.2.12-src/native/ # 进入解压后目录下的目录native
./configure --with-apr=/usr/local/apr --with-java-home=$JAVA_HOME && make && make install
# 安装tomcat-native
9. 修改配置server.xml添加apr支持
cd /usr/local/apache-tomcat-8.5.20/conf
vim server.xml
#将配置中的
Connector port="8080" protocol="HTTP/1.1"
改成
Connector port="8080" protocol="org.apache.coyote.http11.Http11AprProtocol"
将配置中的
Connector port="8009" protocol="AJP/1.3" redirectPort="8443"
改成
Connector port="8009" protocol="org.apache.coyote.ajp.AjpAprProtocol" redirectPort="8443"
注1:8009端口,负责和其他的HTTP服务器建立连接,如果单独使用tomcat而不与其它的http集成
可以将<Connector port="8009"...>注释掉而不使用
10. 配置apr相关环境变量
vim /etc/profile
#在文件的最后增加以下内容
export JAVA_HOME=/usr/local/java/jdk1.8.0_151
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$JAVA_HOME/bin:$PATH #此3行内容在之前linux课程已配置
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/apr/lib
export LD_RUN_PATH=$LD_RUN_PATH:/usr/local/apr/lib
source /etc/profile #设置环境变量立即生效
11. 进行启动测试
cd /usr/local/apache-tomcat-8.5.20/bin
./startup.sh
tail -100f logs/catalina.out 实时查看日志文件 后一百行
Tomcat启动的时候,可以通过log看到Connector使用的是哪一种运行模式:
Starting ProtocolHandler ["http-bio-8080"]
Starting ProtocolHandler ["http-nio-8080"]
Starting ProtocolHandler ["http-apr-8080"]
也可以进入tomcat欢迎页面,点击Server Status,再进行查看
设置tomcat自动启动
在创建tomcat自动启动脚本时,除了要添加之前的两个环境变量,还要将LD_LIBRARY_PATH和LD_RUN_PATH添加进来,
注意:多了export关键字,并且JAVA_HOME和CATALINA_HOME中是没有变量引用的
cp /usr/local/apache-tomcat-8.5.20/bin/catalina.sh /etc/init.d
cd /etc/init.d
mv catalina.sh tomcat
chmod a+x tomcat
vim /etc/init.d/tomcat 修改更名后的文件tomcat,添加如下两个环境变量的配置,请加到#!/bin/sh后面,修改完成后如下
#!/bin/sh
JAVA_HOME=/usr/local/jdk1.8.0_151
CATALINA_HOME=/usr/local/apache-tomcat-8.5.20
export LD_LIBRARY_PATH=/usr/local/apr/lib
export LD_RUN_PATH=/usr/local/apr/lib
end…