参考:
https://blog.csdn.net/liyiliyi/article/details/1188641
http://issues.apache.org/bugzilla/show_bug.cgi?id=36976
问题描述
为了方便使用JMX管理tomcat,监控服务性能等状况,对tomcat服务器bin/catalina.sh(window下是catalina.bat)做了如下改动:
#java虚拟机启动参数追加如下配置信息
JAVA_OPTS="$JAVA_OPTS -Djava.rmi.server.hostname=ip地址 -Dcom.sun.management.jmxremote.port=端口1090 -Dcom.sun.management.jmxremote.rmi=端口1090 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false"
修改完成后,启动服务,查看配置的1090端口的占用。无任何异常,且本地也可以使用jmx连接远程服务进行指标监控。
#可以使用如下命令查看端口信息
netstat -aon|grep 1090
但是在关闭服务shutdown时,报如下错误:
...
Error: Exception thrown by the agent : java.rmi.server.ExportException: Port already in use: 1090; nested exception is:
java.net.BindException: Address already in use (Bind failed)
jdk.internal.agent.AgentConfigurationError: java.rmi.server.ExportException: Port already in use: 1090; nested exception is:
java.net.BindException: Address already in use (Bind failed)
at jdk.management.agent/sun.management.jmxremote.ConnectorBootstrap.startRemoteConnectorServer(ConnectorBootstrap.java:491)
at jdk.management.agent/jdk.internal.agent.Agent.startAgent(Agent.java:447)
at jdk.management.agent/jdk.internal.agent.Agent.startAgent(Agent.java:599)
Caused by: java.rmi.server.ExportException: Port already in use: 1090; nested exception is:
java.net.BindException: Address already in use (Bind failed)
at java.rmi/sun.rmi.transport.tcp.TCPTransport.listen(TCPTransport.java:335)
at java.rmi/sun.rmi.transport.tcp.TCPTransport.exportObject(TCPTransport.java:243)
at java.rmi/sun.rmi.transport.tcp.TCPEndpoint.exportObject(TCPEndpoint.java:412)
at java.rmi/sun.rmi.transport.LiveRef.exportObject(LiveRef.java:147)
at java.rmi/sun.rmi.server.UnicastServerRef.exportObject(UnicastServerRef.java:234)
at java.rmi/sun.rmi.registry.RegistryImpl.setup(RegistryImpl.java:220)
at java.rmi/sun.rmi.registry.RegistryImpl.<init>(RegistryImpl.java:180)
at jdk.management.agent/sun.management.jmxremote.SingleEntryRegistry.<init>(SingleEntryRegistry.java:49)
at jdk.management.agent/sun.management.jmxremote.ConnectorBootstrap.exportMBeanServer(ConnectorBootstrap.java:836)
at jdk.management.agent/sun.management.jmxremote.ConnectorBootstrap.startRemoteConnectorServer(ConnectorBootstrap.java:479)
... 2 more
Caused by: java.net.BindException: Address already in use (Bind failed)
at java.base/java.net.PlainSocketImpl.socketBind(Native Method)
at java.base/java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:436)
at java.base/java.net.ServerSocket.bind(ServerSocket.java:381)
at java.base/java.net.ServerSocket.<init>(ServerSocket.java:243)
at java.base/java.net.ServerSocket.<init>(ServerSocket.java:135)
at java.rmi/sun.rmi.transport.tcp.TCPDirectSocketFactory.createServerSocket(TCPDirectSocketFactory.java:45)
at java.rmi/sun.rmi.transport.tcp.TCPEndpoint.newServerSocket(TCPEndpoint.java:670)
at java.rmi/sun.rmi.transport.tcp.TCPTransport.listen(TCPTransport.java:324)
... 11 more
问题分析
这是什么错误呢?
经过百度,发现问题是:
如上述配置时,tomcat在shutdown关闭时,会绑定jmx配置的端口1090,由于1090在tomcat启动时已经被绑定了,所以就产生报错了。
解决方案
根据问题分析,就明确了如何解决。即在tomcat启动时,jmx参数才有效;tomcat关闭时,不设置jmx参数。
但是,如何在catalina.sh执行时判断tomcat是启动还是关闭,这里我没有具体取百度。
而是,看了下catalina.sh脚本,在下边发现了启动时,会判断传入参数进行不同处理,所以就尝试了一下,在增加jvm的jmx参数前增加对启动参数的判断。
这样经过修改后,再次尝试启动/关闭tomcat,发现问题已经解决。
if [ "$1" = "start" ] ; then
JAVA_OPTS="$JAVA_OPTS -Djava.rmi.server.hostname=ip地址 -Dcom.sun.management.jmxremote.port=端口1090 -Dcom.sun.management.jmxremote.rmi=端口1090 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false"
fi