dubbo的注冊中心和zookeeper里都有jetty的成分,jetty的默認端口又是8080,當二者與springboot進行整合時,springboot內嵌的tomcat的端口8080就會被jetty占用。
如果嘗試使用命令來殺死8080所在進程,那殺死的可能是zookeeper的服務。
為了解決jetty占用8080端口的問題,需要對dubbo注冊中心配置文件、zookeeper的配置文件進行修改。
dubbo的注冊中心路徑:
dubbo-admin\incubator-dubbo-ops-master\dubbo-monitor-simple
從最開始使用注冊中心說起
通過使用dubbo注冊中心的常規操作,來看一下注冊中心里的jetty是怎么占用端口號:
需要來到dubbo-monitor-simple文件夾下,接着cmd進入命令模式:
這時會生成target文件夾
打開target
解壓dubbo-monitor-simple-2.0.0的壓縮包產生dubbo-monitor-simple-2.0.0,
之后復制dubbo-monitor-simple-2.0.0到incubator-dubbo-ops-master文件夾下
打開dubbo-monitor-simple-2.0.0,找到conf配置文件,jetty原本的端口號是8080,所以造成注冊中心對8080的占用。因此修改jetty服務器的端口號為8081,如下:
這樣就可以避免注冊中心啟動jetty時與tomcat8080端口沖突。
接下來修改zookeeper
通過反復操作發現zookeeper服務占用了8080端口,因為提供服務的應用點擊運行總是被提示這樣的信息:
The Tomcat connector configured to listen on port 8080 failed to start. The port may already be in use or the connector may be misconfigured.
Description: The Tomcat connector configured to listen on port 8080 failed to start. The port may already be in use or the connector may be misconfigured. Action: Verify the connector's configuration, identify and stop any process that's listening on port 8080, or configure this application to listen on another port.
我每次用命令先查看8080的進程
接着殺死進程
可是每次關閉進程后,zookeeper的服務也被關閉了,不知道為什么會這樣,一開始認為zookeeper沒有道理占用8080端口。
但一想到8080端口,又使我想起一件怪事,就是之前dubbo里監控台所用的jetty端口號被改成8081后可以訪問。而訪問8080端口時,顯示8080在仍然被jetty占用。
這就是奇怪的地方,jetty分明端口號已經不再是8080,卻顯示jetty在占用8080。
如圖jetty可以在8081訪問:
如下圖:這里仍然顯示8080被jetty占用,那這個jetty又是怎么回事兒??我終於開始懷疑zookeeper了......
於是查了百度,有人給出了答案,就是zookeeper里從某個版本開始內置了jetty,所以是zookeeper里還有jetty在占用8080端口,而我當前的版本是最新版——3.6.0。
解決方法,修改zookeeper的配置文件zoo.cfg:
添加一條配置信息:admin.serverPort=8008
修改之后看看效果:
首先關閉之前的zookeeper服務(關閉終端),之后通過命令重新啟動zkServer.cmd
再次訪問8080端口:
很好,無法訪問說明zookeeper里的jetty不再占用8080端口號了,看來一切都因為自己安裝最新版的zookeeper的緣故。
那我的提供者是否恢復、可以通過tomcat的8080端口啟動了呢?
如圖,啟動提供者應用后,訪問監控中心顯示已經有提供者了,所以tomcat終於啟動了。
再看jetty被改成的8008端口:
也沒問題。
只是我還有疑問就是在消費者應用里,application.properties里指定tomcat的server.port時,期間發生了什么,為什么就直接改變了tomcat的端口號。
之前指定server.port是為了tomcat與jetty避免沖突,那現在已經不沖突了,所以我覺得,這里已經不需要指定server.port了,默認8080即可。
終於可以為我的應用通過地址欄傳參:
springboot內嵌的tomcat端口號占用問題解決方案
jetty的問題解決了,但是真是一波未平呀,springboot里內嵌tomcat又來搗亂了。
還是端口號占用問題,消費者每次啟動,tomcat的端口只能用一次,第二次產出端口占用,因此由於tomcat的限制,每次只能產生一個服務提供者了。
那么有沒有什么辦法讓tomcat的端口號可以重復使用呢?
除了換成外部tomcat以外,暫時沒有辦法。如果不解決端口占用的問題,雖然可以手動更改application.properties里server.port,但還是有些麻煩。
不過還有一種方法可以簡化開發過程,尤其springboot與dubbo相結合的時候大概比較完美:
很多時候dubbo自身的端口號20880也存在占用的情況,處理這種問題,我使用其中一種方案是將application.properties中的端口號設為-1
這樣做可以產生從20880開始遞增的端口號,比如下一個就會生成20881...
由此可以想象得到可以自己定義的一個tomcat端口號,
很簡單,在springboot的啟動類上添加一段代碼即可:
package com.changping.mall; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo; @SpringBootApplication @EnableDubbo public class SpringbootUserserviceProviderApplication implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> { public static void main(String[] args) { SpringApplication.run(SpringbootUserserviceProviderApplication.class, args); } @Override public void customize(ConfigurableServletWebServerFactory factory) { factory.setPort(getRandomPort()); } // 獲得8000到9999隨機端口號 public static int getRandomPort() { int a = 8000; int b = 10000; int randomPort = (int) (Math.random() * (b - a)) + a; return randomPort; } }
高亮的部分是后加的一段代碼,功能是給內嵌tomcat定義隨機的端口號,這樣,就不會產生端口占用的現象了。
啟動springboot項目,控制台可以看到端口號為8171:
Tomcat started on port(s): 8171 (http) with context path '' SpringbootUserserviceProviderApplication : Started SpringbootUserserviceProviderApplication in 17.489 seconds (JVM running for 19.357)
這樣就達到了我的最終目的——連續啟動三次毫無阻礙:
如果想看端口占用的情況鍵入命令即可:netstat -ano
就這樣吧,雖然花了點時間,但還是小有收獲,我的springboot+dubbo+zookeeper搭建也進入了尾聲>>>