请注意: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