关于tomcat无法启动问题详解

  1. 云栖社区>
  2. 博客>
  3. 正文

关于tomcat无法启动问题详解

youcongtech 2018-08-01 21:26:00 浏览1198
展开阅读全文

通常情况tomcat无法启动,有这么几个原因?
(1)代码有问题;

(2)tomcat有问题;

(3)端口被占;

(4)动态web项目为3.0;

(5)java环境运行内存不足;

这是比较常见的问题。解决方案基本都可以在网上找的到。但是我们有的时候不仅仅要学会通过恰当的关键字得到有效的信息,同时再面对问题的时候,也要知道该问题为什么会发生,知道问题的产生原因,比直接解决问题,更让人成长。当然了,这里也不能一昧地说,解决问题不重要。我在此想表达的意思是,知道问题产生的原因,可以制定更好的策略避免问题的发生,从源头上减少不必要的或让人抓狂的Bug。

 

针对(1),代码有问题的时候,启动项目会报错,会有一个提示框,比如很久之前我写的一个博客系统,其中就有一个关于发邮件,不过这个不是单单发邮件,加上了相关的业务逻辑。当时加上这个发邮件,tomcat启动就报错,去除了这个发邮件就好了,因此当时我只能将其归类于代码有问题,而且拿Servlet来或,<servlet-name></servlet-name>不能存在一摸一样的名字,否则就会和SpringMVC那样,当@RequestMapping中的url相同时,会报错,也会导致启动失败,还有比如Spring,很多人,不管是在校的大学生也好,还是培训机构专门学Java的,或者是一些工作比较长的开发者们,都会或多或少遇到过这个问题,通常这个问题出现的原因,基本上可以将错误信息复制,放到搜索引擎上,直接百度,即可找到答案,但是为什么会出现这个原因呢?因为比如使用SSM框架开发一个项目,其中你的一个类专门放业务方法,但是你并没有加上@Service注解。这个注解的主要作用:

<context:component-scan base-package="cn.blog"/>
    

与@ComponentScan注解,效果是一致的。

这里简单说下,通过该配置内容就可以扫描对应的@Service注解,从而完成自动扫描管理对象。

 

针对(2),tomcat问题,通常比较常见的如图:

这个问题在于Tomcat的默认配置问题,默认Tomcat中,启动一个项目需要耗时为45秒,而关闭一个项目需要耗时为15秒,一旦超过这个设定时间就会报错,这个是为了TomCat的性能而着想,但是实际上,稍微大一点的项目,在本地45秒是真的有点少的,所以我们需要把这个45和15改成450和150比较合适。

上面是引用该链接:

https://jingyan.baidu.com/article/cbcede0765ceb502f50b4d4e.html

 

不过,我个人的话,没有遇到通过将45改450这样解决问题,通常从情况下,一个tomcat运行一个比较大的项目是没有问题的,如果是混合项目,我一般将其划分为不同的tomcat,让其运行,或者是比如使用SpringBoot的内嵌Servlet容器,其实也不存在这样的问题。

我遇到比较常见的是,最为奇怪的是,一个项目没有错误,一点都没改动,突然就报错了,就无法启动了,然后将其删除,再重新添加就可以启动了。

因此,当时我只好将其归于tomcat自身某种原因,这种原因我现在还没有找到是什么原因。比如maven项目,有的时候tomcat无法启动时,只需update maven即可解决,

但是为什么会出现这种原因呢?因为maven多模块项目或者是单体maven项目,比如使用git更新了其他小伙伴的代码,或者自己在修改某个模块时,Eclipse反应不过来,无法检测你已经修改了代码,但是tomcat是一个,十分心细的小女孩,它能轻易的检测你的变化,这里也从中凸显(1)的原因,冲突导致tomcat无法启动。update project的目的在于,Eclipse有的时候无法检测你的代码变化,而必须通过手动点击update project来完成更新pom及其相关结构和配置,从而达到检测修改的代码或者是git pull其他小伙伴的代码。

 

针对(3),解决办法可采用修改端口的方式,修改tomcat下的config文件夹下的server.xml,找到对应的端口,修改为其他端口,比如tomcat默认端口8080,你可以修改为1515,1616等。当然了,如果你一定要这个端口运行该服务,而其他服务却占用该端口,你所要做的是找到这个端口进程,并杀死这个进程。比如在linux中可以通过lsof-i:端口号 查看那个进程占用该端口。可以通过kill 进程ID或者kill -9 进程ID进行强制杀死该进程。

端口是用来干什么的?为什么要有端口?

端口是用来干什么的,简单的说,端口是用来区分服务的。不同的服务对应不同的进程,不同的进程占用不同的端口。确保IP+不同的端口是一个服务,这样一来相同的IP+不同的端口,就可以构成许多许多服务。这里的服务指软件,比如nginx和apache所占端口为80,redis占用端口为6379,tomcat占用端口8080,这些软件的端口,就一开始下载该软件,端口就是这个,所以又称默认端口。

解释了端口是用来干什么的,这里也同样解释了为什么要有端口。这里要说下IP地址,我个人理解,在公民生活中身份证是区别于该人在该国家的唯一标识,

比如,一个人要结婚,要办公司或者是要入学,户口或者身份证是必须的,比如入学来说,必须要在当地有户口,而户口记录你的身份证号码,这个身份证就代表是你,在当今国内,很多很多都与你的身份证息息相关,比如银行办卡,通信办卡等等,没有身份证,你就办不成这些事情。

而IP地址在虚拟的网络世界中,同现实世界一样,道理基本是一样的。

综合IP+端口,你可以轻松的明白,为什么要有端口,为什么要有IP,它们的作用是什么。我想这里我讲的比较通俗易懂。

 

针对(4),有的时候会因为是3.0而无法启动成功

我下面这个红色标记只要将其修改为2.5即可解决

 

 如果发现其为3.0就会导致tomcat无法启动

 

当然了,也可以通过找到如图文件:

该文件内容为:

<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
    <fixed facet="wst.jsdt.web" />
    <installed facet="jst.web" version="2.5" />
    <installed facet="wst.jsdt.web" version="1.0" />
    <installed facet="java" version="1.8" />
</faceted-project>

目前是为2.5,属于正常值,如果为3.0,很有可能导致tomcat启动失败,只要将其修改为2.5即可。

我这里所强调的tomcat启动,是指项目在该tomcat上,并启动。而不是指tomcat上没有任何项目,直接启动。tomcat没有任何项目直接启动,除非端口被占用,或者该tomcat软件有问题,否则通常情况都百分百是没有问题的,是可以通过浏览器访问看见Tom猫的。

 

为什么会出现3.0必须降为2.5,tomcat才能正常启动?

原因是,tomcat7通常对应servlet的版本,同时对应jdk7,大家都知道,不论是windows上的tomcat还有Linux上的tomcat,必须要先安装jdk才能安装tomcat。

因为tomcat运行需要jre。而jdk中包含jre。jre是java运行环境。

比如以jsp为例,jsp又称java server page ,中文翻译过来为java 服务 页面,既然是java开头的服务界面,通常可以嵌套java代码,java代码运行需要jre。

在这里,我想大家也就明白了为什么安装tomcat,必先安装jdk的原因了。

当然了,jdk不是必须的,jdk只是专门为开发者使用的,这里强调的jdk里面通常包含jre。比如window来说,通常在官方网站上下载jdk时,通常会随身附带jre。

如图:

通过我的解释,我想大家应该也明白了。

 

 针对(5),通常的问题和解决办法如下:

1. java.lang.OutOfMemoryError: PermGen space

PermGen space的全称是Permanent Generation space,是指内存的永久保存区域OutOfMemoryError: PermGen space。从文字上看就是内存溢出,解决方法是加大内存。为什么会内存溢出,这是由于这块内存主要是被JVM存放Class和Meta信息的,Class在被Load的时候被放入PermGen space区域,它和存放Instance的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的APP会LOAD很多CLASS的话,就很可能出现PermGen space错误。这种错误常见在web服务器对JSP进行pre compile的时候。如果你的WEB APP下都用了大量的第三方jar, 其大小超过了jvm默认的大小(4M)那么就会产生此错误信息了。
解决方法: 手动设置MaxPermSize大小

 

a.如果tomcat是以bat方式启动的,则如下设置:

修改TOMCAT_HOME/bin/catalina.sh
在echo "Using CATALINA_BASE: $CATALINA_BASE"上面加入以下行:
JAVA_OPTS="-server -XX:PermSize=64M -XX:MaxPermSize=128m" 

 

b.如果tomcat是注册成了windows服务,以services方式启动的,则需要修改注册表中的相应键值。

打开注册表,找到目录HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\Procrun 2.0\htfty\Parameters\Java,其中目录地址中红色标注的(如htfty)需要根据不同情况作修改,为tomcat服务注册成windows服务的名称。 可以看到JvmMs和JvmMx项,其中JvmMs设置最小的内存使用参数,JvmMx设置最大的内存使用参数。设置好JvmMs和JvmMx项的值,重启tomcat服务器即可生效。
建议:将相同的第三方jar文件移置到tomcat/shared/lib目录下,这样可以达到减少jar 文档重复占用内存的目的。

 

2. java.lang.OutOfMemoryError: Java heap space

JVM堆的设置是指java程序运行过程中JVM可以调配使用的内存空间的设置。JVM在启动的时候会自动设置Heap size的值,其初始空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)是物理内存的1/4。可以利用JVM提供的-Xmn -Xms -Xmx等选项可进行设置。Heap size 的大小是Young Generation 和Tenured Generaion 之和。在JVM中如果98%的时间是用于GC且可用的Heap size 不足2%的时候将抛出此异常信息。
解决方法:手动设置Heap size

 

a.如果tomcat是以bat方式启动的,则如下设置:

修改TOMCAT_HOME/bin/catalina.sh
在“echo "Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行:
JAVA_OPTS="-server -Xms800m -Xmx800m -XX:MaxNewSize=256m"

 

b.如果tomcat是注册成了windows服务,以services方式启动的,则需要修改注册表中的相应键值。

打开注册表,找到目录HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\Procrun 2.0\htfty\Parameters\Java,其中目录地址中红色标注的(如htfty)需要根据不同情况作修改,为tomcat服务注册成windows服务的名称。 可以看到JvmMs和JvmMx项,其中JvmMs设置最小的内存使用参数,JvmMx设置最大的内存使用参数。设置好JvmMs和JvmMx项的值,重启tomcat服务器即可生效。

提示:Heap Size 最大不要超过可用物理内存的80%,一般的要将-Xms和-Xmx选项设置为相同,而-Xmn为1/4的-Xmx值。

 

上述虽说是window例子解决,但是也可以用于linux,比如:

修改TOMCAT_HOME/bin/catalina.sh
在“echo "Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行:
JAVA_OPTS="-server -Xms800m -Xmx800m -XX:MaxNewSize=256m"

 通过这种方式,可以解决这个问题。

参考链接为:https://blog.csdn.net/tiantang_1986/article/details/76977635

 

小结:关于tomcat无法启动问题,我已经说明了五种情况和对应的五种解决方案。这五种在实际开发和部署中,十分常见,基本每个Java开发者们或多或少都会预见。

 

网友评论

登录后评论
0/500
评论
youcongtech
+ 关注