1.1Java环境介绍
jdk java 开发工具包
jre
sdk
J2EE 企业版
J2SE 标准版
J2ME 手机开发
1.2Tomcat自动部署
通过saltstack来批量安装tomcat,详细如下。
主机名 |
IP |
描述 |
linux-node1.example.com |
192.168.56.11 |
salt-master、salt-minion、jdk、tomcat |
linux-node2.example.com |
192.168.56.12 |
salt-minion、jdk、tomcat |
下载JDK、Tomcat软件包
[root@linux-node1 ~]# cd /usr/local/src/ #进入源码安装路径,下载jdk、tomcat
[root@linux-node1 ~]# wget http://download.oracle.com/otn-pub/java/jdk/8u74-b02/jdk-8u74-linux-x64.tar.gz
[root@linux-node1 ~]# wget http://apache.fayea.com/tomcat/tomcat-8/v8.0.32/bin/apache-tomcat-8.0.32.tar.gz
linux-node1
[root@linux-node1 ~]# yum install -y salt-master salt-minion#安装salt-master和salt-minion
[root@linux-node1 ~]# vim /etc/salt/master #修改salt-master配置文件,指定file_roots目录
file_roots:
base:
- /srv/salt/
[root@linux-node1 ~]# sed -i '/#master: salt/amaster: 192.168.56.11' /etc/salt/minion #指定主saltIP地址
[root@linux-node1 ~]# systemctl start salt-master salt-minion #启动salt-master以及salt-minion
linux-node2
[root@linux-node2 ~]# yum install -y salt-minion #在linux-node2上面安装salt-minion即可
[root@linux-node2 ~]# sed -i '/#master: salt/amaster: 192.168.56.11' /etc/salt/minion #指定master端IP地址
[root@linux-node2 ~]# systemctl start salt-minion #启动salt-minion
salt-key
[root@linux-node1 ~]# salt-key #查看salt-minion状态
Accepted Keys:
Denied Keys:
Unaccepted Keys:
linux-node1.example.com
linux-node2.example.com
Rejected Keys:
[root@linux-node1 ~]# salt-key -A -y #将salt-minion加入管理
[root@linux-node1 local]# salt '*' test.ping #测试连同性
linux-node1.example.com:
True
linux-node2.example.com:
True
创建jdk、tomcat目录以及存放软件的files目录,做到解耦
[root@linux-node1 ~]# mkdir -p /srv/salt/{tomcat/files,jdk/files}/
拷贝/usr/local/src对应软件到对应的files目录下
[root@linux-node1 ~]# cp /usr/local/src/jdk-8u74-linux-x64.tar.gz /srv/salt/jdk/files/
[root@linux-node1 ~]# cp /usr/local/src/apache-tomcat-8.0.32.tar.gz /srv/salt/tomcat/files/
查看目录结构
[root@linux-node1 ~]# tree /srv/
/srv/
└── salt
├── jdk
│ ├── files
│ │ └── jdk-8u74-linux-x64.tar.gz
│ └── install.sls
├── tomcat
│ ├── files
│ │ └── apache-tomcat-8.0.32.tar.gz
│ └── install.sls
└── top.sls
编写jdk的sls模块
[root@linux-node1 ~]# cat /srv/salt/jdk/install.sls
jdk-install:
file.managed:
- name: /usr/local/src/jdk-8u74-linux-x64.tar.gz
- source: salt://jdk/files/jdk-8u74-linux-x64.tar.gz
- user: root
- group: root
- mode: 644
cmd.run:
- name: cd /usr/local/src && tar xf jdk-8u74-linux-x64.tar.gz && mv jdk1.8.0_74 /usr/local/ && ln -s /usr/local/jdk1.8.0_74 /usr/local/jdk && chown -R root:root /usr/local/jdk
- unless: test -d /usr/local/jdk
- require:
- file: jdk-install
jdk-config:
file.append:
- name: /etc/profile
- text:
- export JAVA_HOME=/usr/local/jdk
- export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
- export CLASSPATH=.$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$JAVA_HOME/lib/tools.jar
编写tomcat的sls模块
[root@linux-node1 ~]# cat /srv/salt/tomcat/install.sls
include:
- jdk.install
tomcat-install:
file.managed:
- name: /usr/local/src/apache-tomcat-8.0.32.tar.gz
- source: salt://tomcat/files/apache-tomcat-8.0.32.tar.gz
- user: root
- group: root
cmd.run:
- name: cd /usr/local/src && tar xf apache-tomcat-8.0.32.tar.gz && mv apache-tomcat-8.0.32 /usr/local/ && ln -s /usr/local/apache-tomcat-8.0.32 /usr/local/tomcat && chown -R root:root /usr/local/tomcat
- unless: test -d /usr/local/tomcat
- require:
- file: tomcat-install
tomcat-config:
file.append:
- name: /etc/profile
- text:
- export TOMCAT_HOME=/usr/local/tomcat
编写topfile总入口的sls模块
[root@linux-node1 salt]# pwd
/srv/salt
[root@linux-node1 salt]# cat top.sls
base:
'*':
- tomcat.install
执行salt高级状态
[root@linux-node1 ~]# salt '*' state.highstate
检查是否安装成功
[root@linux-node2 ~]# source /etc/profile #刷新环境变量
[root@linux-node2 ~]# java -version #查看java版本信息
java version "1.8.0_74"
Java(TM) SE Runtime Environment (build 1.8.0_74-b02)
Java HotSpot(TM) 64-Bit Server VM (build 25.74-b02, mixed mode)
[root@linux-node2 ~]# /usr/local/tomcat/bin/version.sh #查看tomcat是否安装成功
Using CATALINA_BASE: /usr/local/tomcat
Using CATALINA_HOME: /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME: /usr/local/jdk
Using CLASSPATH:/usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Server version: Apache Tomcat/9.0.0.M3
Server built: Feb 1 2016 20:52:49 UTC
Server number: 9.0.0.0
OS Name: Linux
OS Version: 3.10.0-229.el7.x86_64
Architecture: amd64
JVM Version: 1.8.0_74-b02
JVM Vendor: Oracle Corporation
1.3Tomcat配置管理
1.4Tomcat安全规范
1.4.1telnet管理端口保护(强制)
类别 |
配置内容及说明 |
标准配置 |
备注 |
telnet端口保护 |
1.修改默认的8005管理端口为不易猜测的端口(大于1024); 2.修改SHUTDOWN指令为其他字符串; |
<Server port="8527" shutdown="dangerous"> |
1.以上配置项的配置内容只是建议配置,可以按照服务实际情况进行合理配置,但要求端口配置在8000~8999之间; |
1.4.2禁用管理端(强制)
类别 |
配置内容及说明 |
标准配置 |
备注 |
禁用管理端 |
1. 删除默认的{Tomcat安装目录}/conf/tomcat-users.xml文件,重启tomcat后将会自动生成新的文件; 2. 删除{Tomcat安装目录}/webapps下默认的所有目录和文件; 3.将tomcat 应用根目录配置为tomcat安装目录以外的目录; |
<Context path="" docBase="/home/work/local/tomcat_webapps" debug="0" reloadable="false" crossContext="true"/> |
对于前段web模块,Tomcat管理端属于tomcat的高危安全隐患,一旦被攻破,黑客通过上传web shell的方式将会直接取得服务器的控制权,后果极其严重; |
1.4.3降权启动(强制)
类别 |
配置内容及说明 |
标准配置 |
备注 |
降权启动 |
1.tomcat启动用户权限必须为非root权限,尽量降低tomcat启动用户的目录访问权限; 2.如需直接对外使用80端口,可通过普通账号启动后,配置iptables规则进行转发; |
避免一旦tomcat 服务被入侵,黑客直接获取高级用户权限危害整个server的安全; |
1.4.4文件列表访问控制(强制)
类别 |
配置内容及说明 |
标准配置 |
备注 |
文件列表访问控制 |
1.conf/web.xml文件中default部分listings的配置必须为false; |
<init-param> <param-name>listings</param-name> <param-value>false</param-value> </init-param> |
false为不列出目录文件,true为允许列出,默认为false; |
1.4.5版本信息隐藏(强制)
类别 |
配置内容及说明 |
标准配置 |
备注 |
版本信息隐藏 |
1.修改conf/web.xml,重定向403、404以及500等错误到指定的错误页面; 2.也可以通过修改应用程序目录下的WEB-INF/web.xml下的配置进行错误页面的重定向; |
<error-page> <error-code>403</error-code> <location>/forbidden.jsp</location> </error-page> <error-page> <error-code>404</error-code> <location>/notfound.jsp</location> </error-page> <error-page> <error-code>500</error-code> <location>/systembusy.jsp</location> </error-page> |
在配置中对一些常见错误进行重定向,避免当出现错误时tomcat默认显示的错误页面暴露服务器和版本信息; 必须确保程序根目录下的错误页面已经存在; |
1.4.6Server header重写(推荐)
类别 |
配置内容及说明 |
标准配置 |
备注 |
Server header重写 |
在HTTP Connector配置中加入server的配置; |
server="webserver" |
当tomcat HTTP端口直接提供web服务时此配置生效,加入此配置,将会替换http 响应Server header部分的默认配置,默认是 |
1.4.7ajp连接端口保护(推荐)
类别 |
配置内容及说明 |
标准配置 |
备注 |
Ajp 连接端口保护 |
1.修改默认的ajp 8009端口为不易冲突的大于1024端口; 2.通过iptables规则限制ajp端口访问的权限仅为线上机器; |
<Connector port="8528" protocol="AJP/1.3" /> |
以上配置项的配置内容仅为建议配置,请按照服务实际情况进行合理配置,但要求端口配置在8000~8999之间;; 保护此端口的目的在于防止线下的测试流量被mod_jk转发至线上tomcat服务器; |
1.4.8起停脚本权限回收(推荐)
类别 |
配置内容及说明 |
标准配置 |
备注 |
起停脚本权限回收 |
去除其他用户对Tomcat的bin目录下shutdown.sh、startup.sh、catalina.sh的可执行权限; |
chmod -R 744 tomcat/bin/* |
防止其他用户有起停线上Tomcat的权限; |
1.4.9访问日志格式规范(推荐)
类别 |
配置内容及说明 |
标准配置 |
备注 |
访问日志格式规范 |
开启Tomcat默认访问日志中的Referer和User-Agent记录 |
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"prefix="localhost_access_log." suffix=".txt" pattern="%h %l %u %t %r %s %b %{Referer}i %{User-Agent}i %D" resolveHosts="false"/> |
开启Referer和User-Agent是为了一旦出现安全问题能够更好的根据日志进行问题排查; |
1.4.10访问限制(可选)
类别 |
配置内容及说明 |
标准配置 |
备注 |
访问限制 |
通过配置,限定访问的ip来源 |
<Context path="" docBase="/home/work/tomcat" debug="0" reloadable="false" crossContext="true"> <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="61.148.18.138,61.135.165.*" deny="*.*.*.*"/> </Context> |
通过配置信任ip的白名单,拒绝非白名单ip的访问,此配置主要是针对高保密级别的系统,一般产品线不需要; |
1.4.11建议配置及标准执行方案
配置部分(${ CATALINA_HOME }conf/server.xml)
<Server port="8527" shutdown=" dangerous">
<!-- Define a non-SSL HTTP/1.1 Connector on port 8080 -->
<Connector port="8080" server="webserver"/>
<!-- Define an AJP 1.3 Connector on port 8528 -->
<!--Define an accesslog -->
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs"prefix="localhost_access_log." suffix=".txt"
pattern="%h %l %u %t %r %s %b %{Referer}i %{User-Agent}i %D" resolveHosts="false"/>
<Connector port="8528" protocol="AJP/1.3" />
<Context path="" docBase="/home/work/local/tomcat_webapps" debug="0" reloadable="false" crossContext="true"/>
配置部分(${ CATALINA_HOME }conf/web.xml或者WEB-INF/web.xml)
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<error-page>
<error-code>403</error-code>
<location>/forbidden.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/notfound.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/systembusy.jsp</location>
</error-page>
删除如下tomcat的默认目录和默认文件
tomcat/webapps/*
tomcat/conf/tomcat-user.xml
去除其他用户对tomcat 起停脚本的执行权限
chmod 744 –R tomcat/bin/*
1.5Tomcat性能优化
1.5.1外部优化
操作系统
JVM
代理-Nginx
开启远程catalina.sh
CATALINA_OPTS="$CATALINA_OPTS
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=12345
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=192.168.56.11"
1.5.1.1JPS优化命令
用来查看基于HotSpot JVM里面所有进程的具体状态,包括进程ID,进程启动的路径等等。
与unix上的ps累死,用来显示本地有权限的java进程,可以查看本地运行着几个java程序,并显示他们的进程号。使用jps时,不需要传递进程号做为参数。
Jps也可以显示远程系统上的JAVA进程,这需要远程服务上开启了jstat服务,以及RMI注及服务,不过常用的都是对本地的JAVA进程的查看。
命令格式
jps [options] [hostid]
常用参数说明
-m 输出传递给main方法的参数,如果是内嵌的JVM则输出为null。
-l 输出应用程序主类的完整包名,或者是应用程序JAR文件的完整路径。
-v 输出传给JVM的参数。
1.5.1.2Jstack优化命令
如果java程序崩溃生成core文件,jstack工具可以用来获得core文件的java stack和native stack的信息,从而可以轻松地知道java程序是如何崩溃和在程序何处发生问题。另外,jstack工具还可以附属导正在运行的java程序中,看到当时运行的java程序的java stack和native stack的信息,如果现在运行的java程序呈现hung的状态,jstack是非常有用的。
命令格式
常用参数说明
-F:jstack [-l] pid无法响应时,强制打印堆栈
-l:长列表,打印关于锁的附加信息。
-m:混合模式输出(包括java和本地c/c++片段)堆栈。
pid:java应用程序的进程号,一般可以通过jps来获得。
executable:产生core dump的java可执行程序。
core:打印出的core文件。
remote-hostname-or-ip:远程debug服务器的名称或IP。
server-id:唯一id,假如一台主机上多个远程debug服务。
1.5.1.3Jmap优化命令
打印出某个java进程(使用pid)内存的所有’对象’的情况(如:产生那些对象,及其数量)。
可以输出所有内存中对象的工具,甚至可以将JVM中的heap,以二进制输出成文本。使用方法 jmap -histo pid。如果连用jmap -histo pid>a.log可以将其保存到文本中去,在一段时间以将3024进程的内存heap输出出来到outfile文件里,在配合MAT(内存分析工具Memory Analysis Tool)或与jhat(Java Heap Analysis Tool)一起使用,能够以图像的形式直观的展示当前内存是否有问题。
64位机上使用需要使用如下方式:
jmap -J-d64 -heap pid
命令格式
jmap [option] pid
jmap [option] executable core
jmap [option] [server-id@]remote-hostname-or-IP
1.5.2内部优化
禁用DNS查询
调整线程数
压缩
<Connector port="8080" protocol="HTTP/1.1"
URIEncoding="UTF-8"minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" disableUploadTimeout="true" connectionTimeout="20000"
acceptCount="300" maxThreads="300" maxProcessors="1000" minProcessors="5"
useURIValidationHack="false"
compression="on" compressionMinSize="2048"
compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
SSLEnabled="true"
scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="d:/tomcat2/conf/shnlap93.jks" keystorePass="aaaaaa"
/>
1.6Tomcat监控管理
1.7JVM故障排查思路
1.jps获取java进程的PID。
2.jstack pid >> java.txt 导出CPU占用高进程的线程栈。
3.top -H -p PID 查看对应进程的哪个线程占用CPU过高。
4. echo "obase=16;989"|bc 将线程的PID转换为16进制。
5.在第二步导出的java.txt中查找转换成为16进制的线程PID。找到对应的线程栈。
6.分析负载高的线程栈都是什么业务操作。优化程序并处理问题。
maxThreads="600" #最大线程数
minSpareThreads="100" #初始化时创建的线程数
maxSpareHtreads="500" #一旦创建的线程超过这个值,Tomcat就会关闭,不再需要的socket线程。
acceptCount="700" /> #指定当所有可以使用的处理请求的线程数量都被使用时,可以放到处理队列中的请求数,超过这个数的请求将不予处理。