1、Tomcat启动错误

1.1、JDK环境变量缺失

  • 问题描述:

报错日志提示:The JAVA_HOME environment variable is not defined This environment variable is needed to run this program;

  • 问题原因:

启动时未检测到JDK环境变量,导致启动失败。

  • 解决方案:

在/etc/profile或~/.bash_profile中设置环境变量JAVA_HOME,参考如下:

  1. JAVA_HOME=/home/tomcat/j2sdk1.4.2_08(具体值要以实际的jdk安装路径为准)
  2. export JAVA_HOMECLASSPATH=/home/tomcat/j2sdk1.4.2_08/lib/tools.jar:/home/tomcat/j2sdk1.4.2_08/lib/dt.jar
  3. export CLASSPATH

1.2、Tomcat端口占用

  • 问题描述:

Tomcat启动失败,报错日志显示:Address already in use

  • 问题原因:

Tomcat默认监听端口为8080,如进程没有停止重复启动或启动两个Tomcat实例则可能会出现端口冲突问题。

  • 解决方案:
    • 重复启动情况:

通过ps -ef |grep tomcat或jps查看是否已经有Tomcat进程启动,如果已经有进程启动,则使用kill命令停止此进程后再次启动Tomcat。

  • 需启动多个Tomcat实例情况:

如需在一台服务器启动多个Tomcat实例,则需要保证两个实例不能监听相同端口,修改端口方式如下:

  1. $ vim tomcat/conf/server.xml
  2. # 将下面的8080修改为其他端口
  3. <Connector port="8080" protocol="HTTP/1.1"
  4. connectionTimeout="20000"
  5. redirectPort="8443" />
  6. # 将下面的AJP端口修改为其他端口
  7. <Connector port=”8009 enableLookups=”false redirectPort=”8443 debug=”0
  8. protocol=”AJP/1.3 />
  9. # 将管理端口修改为其他端口
  10. <Server port=”8005 shutdown=”SHUTDOWN debug=”0”>

2、后端服务连接异常

2.1、数据库连接异常

  • 问题描述:

Tomcat在启动或者运行过程中,出现异常,日志报错显示:Could not create connection to database server.或 Could not get JDBC Connection

  • 问题原因:

此异常一般为Tomcat应用服务器无法连接数据库或没有数据库权限导致,出现此问题一般会导致应用不可用。

  • 解决方案:

首先要排查问题原因,可通过以下方式排查

  1. # 查看数据库端口是否监听,登录数据库服务器
  2. $ ss -ntpl |grep 3306
  3. # 在应用服务器查看是否可以连通数据库
  4. $ telnet test.mysql.com 3306
  5. # 在应用服务器使用mysql客户端尝试连接mysql
  6. $ mysql -uapp -htest.mysql.com -p
  7. # 登录成功后,切换到需要操作的库,验证是否对目标库有操作权限
  8. $ use TABLESNAME;
  9. $ create tables ...;

排查后如果是网络不通,则需要开通网络访问权限,如果是没有操作数据库权限,则需要联系数据库管理员开通权限。

2.2、连接缓存服务异常

  • 问题描述:

Tomcat在启动或者运行过程中,出现异常,日志报错显示:redis.clients.jedis.exceptions.JedisConnectionException: java.net.ConnectException: Connection refused: connect

  • 问题原因:

此异常一般为Tomcat应用服务器无法连接Redis服务器。

  • 解决方案:

首先要排查问题原因,可通过以下方式排查

  1. # 查看redis服务器端口是否监听,登录数据库服务器
  2. $ ss -ntpl |grep 6379
  3. # 在应用服务器查看是否可以连通redis
  4. $ telnet test.redis.com 6379

排查后如果是网络不通,则需要开通网络访问权限。

3、Tomcat内存泄漏

  • 问题描述:

Tomcat运行过程中,出现报错:Java.lang.OutOfMemeoryError:GC overhead limit exceeded

  • 问题原因:

出现此异常一般为Tomcat内存不足或程序代码存在漏洞。

  • 解决方案:
    • 内存不足

内存不足的情况需要查看配置文件中Tomcat应用的JVM配置是否合理,一般将Tomcat内存配置为服务器内存的70左右。

  1. $ vim tomcat/bin/catalina.sh
  2. JAVA_OPTS="-Xms2048m -Xmx4096m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/log/oom.hprof"

-Xms2048m jvm启动时初始内存为2G
-Xmx4096m jvm最大可占用内存为4G
-XX:+HeapDumpOnOutOfMemoryError 参数表示当JVM发生OOM时,自动生成DUMP文件
-XX:HeapDumpPath=${目录} 参数表示生成DUMP文件的路径,可以指定文件名称

4、重启后首次访问很慢

  • 问题描述:

在centos上部署了tomcat应用,每次重启tomcat服务后,首次访问一个接口时都非常慢,差不多需要2分钟时间。

  • 问题原因:

导致访问很慢的接口有个功能是生成随机数。tomcat7上的随机数主要通过java.security.SecureRandom生成随机数来实现,随机数算法使用的是”SHA1PRNG”,而这个随机算法/dev/urandom 则是一个非阻塞的发生器。

  • 解决方案: ```bash

    修改java.security文件

    打开$JAVA_PATH/jre/lib/security/java.security这个文件,找到下面的内容:securerandom.source=file:/dev/urandom 替换成securerandom.source=file:/dev/./urandom

或者修改catalina.sh

if [[ “$JAVA_OPTS” != -Djava.security.egd= ]]; then JAVA_OPTS=”$JAVA_OPTS -Djava.security.egd=file:/dev/./urandom” fi

  1. <a name="uDwL4"></a>
  2. ### 5、站点无法中文搜索
  3. - 问题描述:
  4. Tomcat启动成功后,在站点内输入中文无法正常搜索。
  5. - 问题原因
  6. Tomcat7以及之前的版本,默认编码为ISO8559-1,直到Tomcat8之后才默认变为UTF-8
  7. - 解决方案:
  8. 修改tomcat编码
  9. ```bash
  10. $ vim conf/server.xml
  11. # 增加URIEncoding="UTF-8"
  12. <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8" />

6、JVM故障处理思路

6.1、查看CPU或内存占用较高的进程和线程

  1. top
  2. top -Hp [进程ID]

6.2、根据线程ID,将线程ID转换为16进制,执行jstack打印当前java进程堆栈信息

  1. jstack [进程ID] > jstack.log

然后在jstack.log中搜索线程id为16进制的堆栈信息。

6.3、查看当前JVM分区GC的情况

  1. jstat -gcutil [进程id] 1000

每1000ms打印一次gc信息。
返回信息的含义如下:

  1. S0 年轻代中第一个survivor(幸存区)已使用的占当前容量百分比
  2. S1 年轻代中第二个survivor(幸存区)已使用的占当前容量百分比
  3. E 年轻代中Eden(伊甸园)已使用的占当前容量百分比
  4. O old代已使用的占当前容量百分比
  5. P perm代已使用的占当前容量百分比
  6. YGC 从应用程序启动到采样时年轻代中gc次数
  7. YGCT 从应用程序启动到采样时年轻代中gc所用时间(s)
  8. FGC 从应用程序启动到采样时old代(全gc)gc次数
  9. FGCT 从应用程序启动到采样时old代(全gc)gc所用时间(s)
  10. GCT 从应用程序启动到采样时gc用的总时间(s)

6.4、查看堆内存信息

  1. jmap -histo [进程id] > jmap.txt

该命令可以查看当前jvm内存里对象的实例数和占用内存数

6.5、导出堆内存信息

  1. jmap -dump:format=b,file=dump.bin [进程ID]

将dump.bin文件导入到MAT工具具体分析。