Rails 3应用从MySQL迁移至PostgreSQL后Solr启动失败:无法开启JMX监控
问题分析与解决方案
问题背景
Rails 3.2.8应用从MySQL迁移到PostgreSQL后,本地Mac环境下Solr(通过rake sunspot:solr:start启动)运行正常,索引和搜索功能无问题。但部署到运行Solr 5.4.1的Ubuntu 16.04 AWS实例时,Solr无法加载,核心错误为无法启动JMX监控,具体日志如下(已翻译为中文):
1081 INFO (coreLoadExecutor-6-thread-2) [ ] o.a.s.c.CoreContainer 创建SolrCore 'uncat',使用实例目录/mnt/ebs/solr/data/uncat中的配置 1081 INFO (coreLoadExecutor-6-thread-1) [ ] o.a.s.c.CoreContainer 创建SolrCore 'staging',使用实例目录/mnt/ebs/solr/data/staging中的配置 1097 INFO (coreLoadExecutor-6-thread-2) [ x:uncat] o.a.s.c.SolrCore 使用solr.NRTCachingDirectoryFactory 1097 INFO (coreLoadExecutor-6-thread-1) [ x:staging] o.a.s.c.SolrCore 使用solr.NRTCachingDirectoryFactory 1104 INFO (coreLoadExecutor-6-thread-2) [ x:uncat] o.a.s.c.SolrCore [[uncat] ] 在[/mnt/ebs/solr/data/uncat]打开新的SolrCore,dataDir=[null] 1104 INFO (coreLoadExecutor-6-thread-1) [ x:staging] o.a.s.c.SolrCore [[staging] ] 在[/mnt/ebs/solr/data/staging]打开新的SolrCore,dataDir=[null] 1128 ERROR (coreLoadExecutor-6-thread-1) [ x:staging] o.a.s.c.CoreContainer 创建核心[staging]失败:无法启动JMX监控 java.lang.RuntimeException: 无法启动JMX监控 at org.apache.solr.core.JmxMonitoredMap.<init>(JmxMonitoredMap.java:129) at org.apache.solr.core.SolrCore.initInfoRegistry(SolrCore.java:960) at org.apache.solr.core.SolrCore.<init>(SolrCore.java:744) at org.apache.solr.core.SolrCore.<init>(SolrCore.java:665) at org.apache.solr.core.CoreContainer.create(CoreContainer.java:746) at org.apache.solr.core.CoreContainer$1.call(CoreContainer.java:466) at org.apache.solr.core.CoreContainer$1.call(CoreContainer.java:457) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at org.apache.solr.common.util.ExecutorUtil$MDCAwareThreadPoolExecutor$1.run(ExecutorUtil.java:232) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) Caused by: java.io.IOException: 无法绑定到URL [rmi://127.0.0.1:56411/vultest]: javax.naming.ServiceUnavailableException [根异常是java.rmi.ConnectException: 连接被拒绝到主机: 127.0.0.1; 嵌套异常是: java.net.ConnectException: Connection refused (Connection refused)] at javax.management.remote.rmi.RMIConnectorServer.newIOException(RMIConnectorServer.java:827) at javax.management.remote.rmi.RMIConnectorServer.start(RMIConnectorServer.java:432) at org.apache.solr.core.JmxMonitoredMap.<init>(JmxMonitoredMap.java:124) ... 11个更多异常 Caused by: javax.naming.ServiceUnavailableException [根异常是java.rmi.ConnectException: 连接被拒绝到主机: 127.0.0.1; 嵌套异常是: java.net.ConnectException: Connection refused (Connection refused)] at com.sun.jndi.rmi.registry.RegistryContext.bind(RegistryContext.java:161) at com.sun.jndi.toolkit.url.GenericURLContext.bind(GenericURLContext.java:228) at javax.naming.InitialContext.bind(InitialContext.java:425) at javax.management.remote.rmi.RMIConnectorServer.bind(RMIConnectorServer.java:644) at javax.management.remote.rmi.RMIConnectorServer.start(RMIConnectorServer.java:427) ... 12个更多异常 Caused by: java.rmi.ConnectException: 连接被拒绝到主机: 127.0.0.1; 嵌套异常是: java.net.ConnectException: Connection refused (Connection refused) at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:623) at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216) at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202) at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:343) at sun.rmi.registry.RegistryImpl_Stub.bind(RegistryImpl_Stub.java:65) at com.sun.jndi.rmi.registry.RegistryContext.bind(RegistryContext.java:155) ... 16个更多异常 Caused by: java.net.ConnectException: Connection refused (Connection refused) at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) at java.net.Socket.connect(Socket.java:607) at java.net.Socket.connect(Socket.java:556) at java.net.Socket.<init>(Socket.java:452) at java.net.Socket.<init>(Socket.java:229) at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:40) at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:148) at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:617) ... 21个更多异常
核心原因
Solr启动时尝试绑定JMX的RMI端口到127.0.0.1,但连接被拒绝,通常由以下原因导致:
- JMX默认配置未正确设置,无法启动RMI注册表
- 系统防火墙或权限限制阻止了本地端口绑定
- RMI注册表未提前启动
解决方案
方案1:禁用JMX监控(快速解决)
如果不需要JMX监控,直接在Solr配置文件中禁用:
- 编辑Ubuntu实例上的Solr配置文件
/etc/default/solr.in.sh - 添加或修改以下配置:
SOLR_JMX="-Dsolr.jmx.enabled=false" - 重启Solr服务:
sudo service solr restart
方案2:配置JMX固定端口(保留监控)
若需要JMX监控,指定固定RMI端口并确保本地访问权限:
- 编辑
/etc/default/solr.in.sh,添加:SOLR_JMX="-Dcom.sun.management.jmxremote=true \ -Dcom.sun.management.jmxremote.port=18983 \ -Dcom.sun.management.jmxremote.rmi.port=18983 \ -Dcom.sun.management.jmxremote.local.only=true \ -Dcom.sun.management.jmxremote.authenticate=false \ -Dcom.sun.management.jmxremote.ssl=false" - 检查端口18983是否被占用:
netstat -tulpn | grep 18983 - 确保防火墙允许本地访问该端口(Ubuntu下可通过
ufw allow from 127.0.0.1 to any port 18983配置) - 重启Solr服务
方案3:手动启动RMI注册表
临时解决可手动启动RMI注册表后再启动Solr:
rmiregistry 56411 & sudo service solr start
注意:这种方式重启系统后需要重新启动注册表,建议用配置文件方式持久化。
方案4:检查系统网络与权限
- 测试回环接口连通性:
ping 127.0.0.1,确保回环正常 - 检查Solr运行用户(通常是
solr)是否有绑定端口的权限,避免权限不足导致绑定失败
内容的提问来源于stack exchange,提问作者DSadaka
相关产品推荐
相关产品推荐

