关于Linux环境调优(tomcat)

序言

首先需要了解服务器的内存和cpu情况.然后根据服务器的配置情况设置java的相关环境.并且可以查看各个进程中的使用情况

Linux相关命令

Free命令--内存(top命令也可以显示内存使用情况,但是不能设置单位)

free 命令显示系统使用和空闲的内存情况,包括物理内存、交互区内存(swap)和内核缓冲区内存。

命令 注释
free 以Kb为单位显示内存容量
free -m 以Mb为单位显示内存容量
free -g 已Gb为单位显示内存容量

系统根据不同的显示单位展示如下:

参数说明如下:

  • Mem:表示物理内存统计,如果机器剩余内存非常小,一般小于总内存的20%,则判断为系统物理内存不够
  • Swap: 表示硬盘上交换分区的使用情况,如剩余空间较小,需要留意当前系统内存使用情况及负载,当Swap的used值大于0时,则表示操作系统物理内存不够,已经开始使用硬盘内存了。
  • total:表示物理内存统计
  • used:表示总计分配给(包含buffers与cache)使用的数量,但其中可能部分缓存并未实际使用
  • free:表示未被分配的内存
  • shared:表示共享内存
  • buff/cache:表示系统分配但未被使用的buffers数量
  • available:表示系统分配但未被使用的available数量

        查看系统中各线程占用内存百分比的情况:(执行以上命令可查看各个程序进程内存使用的内存情况,如下图所示,第一列为进程占用的内存百分比,可以看到哪些应用程序占的内存比较多,用于排查问题)

# 如下的命令感觉比Top要好点,可以看执行命令的全路径,这样就比简写要好点.

ps -eo pmem,pcpu,rss,vsize,args | sort -k 1 -r | less


输入命令后显示如下的内容:

  • %MEM : 表示进程占用的内存百分比
  • %CPU : 表示进程占用的CPU百分比

Top命令--包括内存,cup,进程的使用情况

top 命令查看系统的实时负载, 包括进程、CPU负载、内存使用等等;

直接输入top命令,可以看到如下图所示的的信息.其中上半部分是内存的使用情况,下面是各个进程的使用情况.

上半部分--这部分感觉也很重要

上半部分如下图.主要届时下 %Cpu部分参数的意思.下面的就是free的部分可以看上面的free注释

  • us: 用户空间占用CPU百分比
  • sy: 内核空间占用CPU百分比
  • ni: 用户进程空间内改变过优先级的进程占用CPU百分比
  • id: 空闲CPU百分比
  • wa: 等待输入输出CPU时间百分比
  • hi: CPU服务于硬件中断所耗费的时间总额
  • si: CPU服务软中断所耗费的时间总额
  • st: Steal Time. 如果你想要部署虚拟环境(例如:Amazon EC2), steal time就是你想要关注的性能指标之一。 如果这个指标的数值很高,那么说明机器状态非常糟糕

下半部分--这部分比较简单

  • PID: 进程ID
  • User: 进程所有者
  • PR: 优先级
  • NI: nice值,负值表示高优先级,正直表示低优先级
  • VIRT: 进程使用的虚拟内存总量
  • RES: 进程使用的,未被换出的物理内存大小
  • SHR: 共享内存大小
  • S: 进程状态
  • %CPU: 上次更新到现在的CPU时间占用百分比
  • %MEM: 进程使用的物理内存百分比
  • TIME+: 进程使用CPU总时间
  • COMMAND:命令名,命令行

top命令其它

       进入top的实时界面后,默认按照CPU的使用率排序,通过“shift+m”按键将进程按照内存使用情况排序,可以查看哪些进程是当前系统中的内存开销“大户”。

       top命令中,按下 f 键,进入选择排序列的界面,这里可以选择要显示的信息列,要按照哪些信息列进行排序等,参照红框的说明来选择是否显示那些列就行,标*的就是显示

CUP个数与cpu内核数

  注意Netty的work默认2倍核心数,o密集型2倍核心数,计算密集型1倍核心数,避免线程上下文切换带来的开销。

# 总核数 = 物理CPU个数 X 每颗物理CPU的核数 
# 总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数


# 查看物理CPU个数
cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l


# 查看每个物理CPU中core的个数(即核数)
cat /proc/cpuinfo| grep "cpu cores"| uniq


# 查看逻辑CPU的个数
cat /proc/cpuinfo| grep "processor"| wc -l

tomcat参数优化

\bin\catalina.sh设置JAVA_OPTS

在catalina.sh的cygwin=false这句话之前加上Java_opts

JDK 1.8中 PermSize 和 MaxPermGen 已经无效。JDK 1.8 中已经不存在永久代的结论 而以 元空间 代替。

用例如下所示:

JAVA_OPTS="$JAVA_OPTS -server -Xms2048M -Xmx3072M -Xss1024k
-XX:+AggressiveOpts
-XX:+UseParallelGC -XX:+UseBiasedLocking"
  • -server:   一定要作为第一个参数,在多个 CPU 时性能佳,还有一种叫 -client 的模式,特点是启动速度比较快,但运行时性能和内存管理效率不高,通常用于客户端应用程序或开发调试,在 32 位环境下直接运行 Java 程序默认启用该模式。Server 模式的特点是启动速度比较慢,但运行时性能和内存管理效率很高,适用于生产环境,在具有 64 位能力的 JDK 环境下默认启用该模式,可以不配置该参数。

  • -Xms:  为初始化内存,直接与最大内存一致,这样可以避免内存重复分配,降低效率,直接上来就是最大的,jvm也不用再扩展内存了,节省时间。

  • -Xmx:  表示最大 Java 堆大小,当应用程序需要的内存超出堆的最大值时虚拟机就会提示内存溢出,并且导致应用服务崩溃,因此一般建议堆的最大值设置为可用内存的最大值的80%(也有说物理内存的一半)如何知道我的 JVM 能够使用最大值,使用 java -Xmx512M -version 命令来进行测试,然后逐渐的增大 512 的值,如果执行正常就表示指定的内存大小可用,否则会打印错误信息,默认值为物理内存的 1/4,默认(MinHeapFreeRatio参数可以调整)空余堆内存大于 70% 时,JVM 会减少堆直到-Xms 的最小限制
  • -Xmn:  新生代的内存空间大小,注意:此处的大小是(eden+ 2 survivor space)。与 jmap -heap 中显示的 New gen 是不同的。整个堆大小 = 新生代大小 + 老生代大小 + 永久代大小在保证堆大小不变的情况下,增大新生代后,将会减小老生代大小。    (此值对系统性能影响较大,Sun官方推荐配置为整个堆的 3/8。一般设置为Xmx的3、4分之一)
  • -Xss:   是每个线程所占用的内存,也就是每个线程的堆栈大小,太小了容易溢出,太大了会导致创建的线程数量减少,因为最大容量是有限的。这里最大内存为1280M,理论上可以创建1000个左右线程,差不多支持500个并发访问(是并发访问哦,也就是500个用户同一时刻点击),已经相当可以了。表示每个 Java 线程堆栈大小,JDK 5.0 以后每个线程堆栈大小为 1M,以前每个线程堆栈大小为 256K。根据应用的线程所需内存大小进行调整,在相同物理内存下,减小这个值能生成更多的线程,但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在 3000~5000 左右。一般小的应用, 如果栈不是很深, 应该是128k 够用的,大的应用建议使用 256k 或 512K,一般不易设置超过 1M,要不然容易出现out ofmemory。这个选项对性能影响比较大,需要严格的测试。

  • -XX:+AggressiveOpts:  作用如其名(aggressive),启用这个参数,则每当 JDK 版本升级时,你的 JVM 都会使用最新加入的优化技术(如果有的话)。
  • -XX:+UseParallelGC:  设置为并行收集器。此配置仅对年轻代有效。即年轻代使用并行收集,而年老代仍使用串行收集。
  • -XX:+UseBiasedLocking: 启用一个优化了的线程锁,我们知道在我们的appserver,每个http请求就是一个线程,有的请求短有的请求长,就会有请求排队的现象,甚至还会出现线程阻塞,这个优化了的线程锁使得你的appserver内对线程处理自动进行最优调配。
  • -XX:NewSize:设置新生代内存大小。
  • -XX:MaxNewSize:设置最大新生代新生代内存大小
  • -XX:PermSize:设置持久代内存大小.
  • -XX:MaxPermSize:设置最大值持久代内存大小,永久代不属于堆内存,堆内存只包含新生代和老年代。

通过Tomcat检查设置是否起效

  • 1.首先在conf/tomcat-users.xml文件里面,在</tomcat-users>前面添加如下代码
<role rolename="manager-gui"/>  

# username就是登陆账号 password就是密码

<user password="admin" roles="manager-gui" username="tomcat"/>  
  • 2. 修改/webapps/manager/META-INF/目录下context.xml文件,如下:

<Valve className="org.apache.catalina.valves.RemoteAddrValve"  
allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1|\d+\.\d+\.\d+\.\d+" />  

  • 4.查看确认所分配的内存

./conf/server.xml调优

连接池

打开被注释的默认连接池配置,并改成如下内容

<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"  
         maxThreads="150" 
         minSpareThreads="100"   
         prestartminSpareThreads="true" 
         maxQueueSize="100"/>   
  • name: 线程名称
  • namePrefix: 线程前缀
  • maxThreads : 最大并发连接数,不配置时默认200,一般建议设置500~ 800 ,要根据自己的硬件设施条件和实际业务需求而定。
  • minSpareThreads:Tomcat启动初始化的线程数,默认值25   
  • prestartminSpareThreads:在tomcat初始化的时候就初始化minSpareThreads的值, 不设置trueminSpareThreads  的值就没啥效果了 。
  • maxQueueSize: 最大的等待队列数,超过则拒绝请求

连接配置

修改连接配置并改成如下内容:

<Connector port="8080" protocol="HTTP/1.1"  
        connectionTimeout="20000"  
        redirectPort="8443"    
        executor="tomcatThreadPool"  
        enableLookups="false"   
        maxIdleTime="60000"
        acceptCount="100"   
        maxPostSize="10485760" 
        acceptorThreadCount="2"    
        disableUploadTimeout="true"   
        URIEncoding="utf-8"
        keepAliveTimeout ="6000"  
        maxKeppAliveRequests="500"  />  
  • port:连接端口。  
  • protocol:连接器使用的传输方式。  
  • executor: 连接器使用的线程池名称
  • enableLookups:禁用DNS  查询
  • maxIdleTime:线程空闲时间,超过该时间后,空闲线程会被销毁,默认值为6000(1分钟),单位毫秒。
  • acceptCount:指定当所有可以使用的处理请求的线程数都被使用时,可以放到处理队列中的请求数,超过这个数的请求将不予处理,默认设置 100 。
  • maxPostSize:限制 以FORM URL 参数方式的POST请求的内容大小,单位字节,默认是 2097152(2兆),10485760 为 10M。如果要禁用限制,则可以设置为 -1。
  • acceptorThreadCount: 用于接收连接的线程的数量,默认值是1。一般这个指需要改动的时候是因为该服务器是一个多核CPU,如果是多核 CPU 一般配置为 2。
  • disableUploadTimeOut:允许Servlet容器,正在执行使用一个较长的连接超时值,以使Servlet有较长的时间来完成它的执行,默认值为false
  • keepAliveTimeout - 表示在下次请求过来之前,tomcat保持该连接多久。这就是说假如客户端不断有请求过来,且未超过过期时间,则该连接将一直保持。
  • maxKeepAliveRequests -表示该连接最大支持的请求数。超过该请求数的连接也将被关闭(此时就会返回一个Connection: close头给客户端)。 (maxKeepAliveRequests="1"代表禁用长连接)(1表示禁用,-1表示不限制个数,默认100个。一般设置在100~200之间)

关于tomcat的压缩

      压缩会增加Tomcat负担,最好采用Nginx + Tomcat 或者 Apache + Tomcat 方式,压缩交由Nginx/Apache 去做。

      Tomcat 的压缩是在客户端请求服务器对应资源后,从服务器端将资源文件压缩,再输出到客户端,由客户端的浏览器负责解压缩并浏览。相对于普通的 浏览过程 HTML、CSS、Javascript和Text,它可以节省40% 左右的流量。更为重要的是,它可以对动态生成的,包括CGI、PHP、JSP、ASP、Servlet,SHTML等输出的网页也能进行压缩,压缩效率也很高。

Tomcat的IO优化

       即修改Tomcat Connector运行模式,Tomcat Connector(Tomcat连接器)有bionioapr三种运行模式。

  • 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如果安装了aprnative,Tomcat直接启动就支持apr.(这个详细的使用暂时,后面有空在写清楚点[email protected])

 

Linux的TCP

 Linux系统优化-调大TCP最大连接数

   linux作为服务器,当socket运行高并发TCP程序时,通常会出现连接建立到一定个数后不能再建立连接的情况生产环境下,多次测试,发现每次连接建立到1000左右时,再也不能建立tcp连接,为什么呢?

      这是因为在Linux平台上,无论编写客户端程序还是服务端程序,在进行高并发TCP连接处理时,最高的并发数量都要受到系统对用户单一进程同时可打开文件数量的限制(这是因为系统为每个TCP连接都要创建一个socket句柄,每个socket句柄同时也是一个文件句柄)。为了调大TCP最大连接数,必须修改用户进程可打开文件数限制。

查看系统允许当前用户进程打开的文件数限制

ulimit -n 

这表示当前用户的每个进程最多允许同时打开1024个文件,默认也是1024

修改/etc/security/limits.conf文件,在文件最后添加如下内容:
 

vim /etc/security/limits.conf

添加

root soft nofile 65535
root hard nofile 65535
* soft nofile 65535
* hard nofile 65535
  • 第1个参数指定修改root用户的打开文件数限制,可用’*'号表示修改所有用户的限制;
  • 第2个参数softhard指定要修改软限制还是硬限制;
  • 第3个参数65535则指定了想要修改的新的限制值,即最大打开文件数(请注意软限制值要小于 或等于硬限制) nofile有上限,不是无穷大,nofile 65535即上限为65535

        再次查看一下可以发现件数限制已变为:65535(有的Linux操作系统,如(Ubuntu)不允许配置 * ,ubuntu的root用户必须写出来,其它用户可用*代替)  这个需要重启系统后才能生效.

查看Linux系统级的最大打开文件数限制,使用如下命令

每台服务器有可能不一样,是Linux系统在启动时根据系统硬件资源状计算

cat /proc/sys/fs/file-max   #我的是584864 这个根据服务器硬件计算得出的

这表明这台Linux系统最多允许同时打开(即包含所有用户打开文件数总和)95288个文件,是Linux系统级硬限制,所有用户级的打开文件数限制都不应超过这个数值。通常这个系统级硬限制是Linux系统在启动时根据系统硬件资源状况计算出来的最佳的最大同时打开文件数限制,如果没有特殊需要,不应该修改此限制,除非想为用户级打开文件数限制设置超过此限制的值

 Linux系统优化-TCP/IP内核参数优化

修改 /etc/sysctl.conf
生效: sysctl -p

net.ipv4.tcp_mem = 196608  262144  393216  
#(4G 内存机器 使用,TCP连接最多约使用1.6GB内存 , 393216*4096/1024/1024=1.6G)
#内核分配给TCP连接的内存,单位是Page,1 Page = 4096 Bytes

net.ipv4.tcp_mem = 524288  699050  1048576  
#(8G 内存使用,TCP连接最多约使用4GB内存)         

#为每个TCP连接分配的读、写缓冲区内存大小,单位是Byte
net.ipv4.tcp_rmem = 4096      8192    4194304
net.ipv4.tcp_wmem = 4096      8192    4194304
#                  最小内存  缺省内存  最大内存
# 一般按照缺省值分配,上面的例子就是读写均为8KB,共16KB
#1.6G 内存服务器, TCP内存能容纳的连接数,约为  1600MB/16KB = 100K = 10万
#4.G TCP内存能容纳的连接数,约为  4000MB/16KB = 250K = 25万

net.core.somaxconn= 4000
#(端口最大的监听队列的长度)
#同时,修改下全局配置
# echo 4000 > /proc/sys/net/core/somaxconn 定义了系统中每一个端口最大的监听队列的长度,这是个全局的参数,默认值为128,

net.ipv4.tcp_syncookies = 1
#表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;

net.ipv4.tcp_tw_reuse = 1
#表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;

net.ipv4.tcp_tw_recycle = 1
#表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭;

net.ipv4.tcp_fin_timeout = 30
#修改系統默认的 TIMEOUT 时间。

net.ipv4.tcp_keepalive_time = 1200  
#表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为20分钟。

net.ipv4.ip_local_port_range = 10000 65000  
#表示用于向外连接的端口范围。缺省情况下很小:32768到61000,改为10000到65000。
#(注意:这里不要将最低值设的太低,否则可能会占用掉正常的端口!)

net.ipv4.tcp_max_syn_backlog = 8192
#表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。

net.ipv4.tcp_max_tw_buckets = 5000
#表示系统同时保持TIME_WAIT的最大数量,如果超过这个数字,TIME_WAIT将立刻被清除并打印警告信息。默 认为180000,改为5000。

net.ipv4.tcp_max_orphans = 65536
#当orphans达到32768个时,会报Out of socket memory,此时占用内存 32K*64KB=2048MB=2GB
#(每个孤儿socket可占用多达64KB内存),实际可能小一些

net.ipv4.tcp_orphan_retries = 1
#孤儿socket废弃前重试的次数,重负载web服务器建议调小,设置较小的数值,可以有效降低orphans的数量

net.ipv4.tcp_retries2
#活动TCP连接重传次数,超过次数视为掉线,放弃连接。缺省值:15,建议设为 2或者3.

net.ipv4.tcp_synack_retries
#TCP三次握手的syn/ack阶段,重试次数,缺省5,设为2-3

net.core.netdev_max_backlog = 2048
# 网络设备的收发包的队列大小
发布了70 篇原创文章 · 获赞 51 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/cuiyaonan2000/article/details/104695360