请注意:Spring Boot + Tomcat 8.5.8不可使用!

截止到2016年12月13日,最新版本的Spring Boot是1.4.2.RELEASE,如果默认配置,使用的Tomcat版本是8.5.6。通过SPRING INITIALIZR创建项目,可以轻松更改Tomcat的版本。

如果使用Maven作为构建工具,则只需要在属性中指定版本,如下所示。

<properties>
    <!-- ... -->
    <tomcat.version>8.5.8</tomcat.version>
</properties>

如果使用8.5.8会发生什么?

首先……如果使用默认的端口号(8080),Tomcat将无法启动。

错误内容是“地址已在使用中”。在某种意义上,这是一个常见的错误,当同时操作多个Spring Boot应用程序时,如果保持某一应用程序处于运行状态,可能会遇到这个错误。

...
2016-12-11 03:12:06.364 ERROR 20786 --- [           main] o.a.coyote.http11.Http11NioProtocol      : Failed to start end point associated with ProtocolHandler [http-nio-8080]

java.net.BindException: Address already in use
    at sun.nio.ch.Net.bind0(Native Method) ~[na:1.8.0_102]
    at sun.nio.ch.Net.bind(Net.java:433) ~[na:1.8.0_102]
...

但是这次我没有启动其他应用程序,也没有僵尸进程存在…。

那么,为什么会出现“地址已被使用”的问题呢?

不探究细节,使用Spring Boot上的内置Tomcat 8.5.8时,不小心会导致Tomcat的连接器重复2次的情况,这是问题的原因。默认情况下,两个连接器都使用8080端口,导致出现“Address already in use”错误。

尝试使用Spring Boot的属性将服务器端口号更改为18080,看看会发生什么….

server.port=18080

以下的日志会显示服务器启动。

以下的日志将输出并启动服务器。

...
2016-12-11 03:15:39.717  INFO 20842 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http) 18080 (http)
2016-12-11 03:15:39.721  INFO 20842 --- [           main] com.example.Tomcat858DemoApplication     : Started Tomcat858DemoApplication in 2.639 seconds (JVM running for 3.076)

尽管启动了,但是Tomcat已经启动并在8080端口(由Tomcat创建的连接器)和18080端口(由Spring Boot创建的连接器)等待请求。

如果您想了解更详细的原因,请……

Spring项目的项目成员和Spring Boot的核心贡献者Andy Wilkinson先生已经为我们报告了一个错误!

    https://bz.apache.org/bugzilla/show_bug.cgi?id=60368

下面的内容与此处介绍的内容相同,但在Spring Boot方面有一个问题,因此我将在此处附上链接。

    https://github.com/spring-projects/spring-boot/issues/7615

我该怎么办?

我认为使用Tomcat 8.5.6会更好,如果有某些理由需要使用较高版本而不是8.5.6的话,可以尝试使用8.5.9。总之,它会正常启动。虽然我没有看到原因,但是升级到8.5.9后,在Spring Boot的测试中出现了错误,所以在8.5.9版本中与Spring Boot结合可能会有一些地方无法正常工作。

总结

如果没有特殊原因,就直接使用Spring Boot所依赖的Tomcat吧。至少要使用过之前Spring Boot发布版本中使用的版本才行…这样,你就能意识到遇到严重的操作故障的风险增加,因此最好多注意一下。

请参考以下网站

    • https://bz.apache.org/bugzilla/show_bug.cgi?id=60368

 

    https://github.com/spring-projects/spring-boot/issues/7615
bannerAds