为了更新我用于服务器的SSL证书,我有一个代码可以执行我需要的import \ export和验证。
效果很好,但为了让更改生效,我必须重新启动tomcat 我希望避免重启,并在不使用外部工具(例如keytool)的情况下更新它 我查找了一些类似的问题,并找到了解决方案 - 重新启动443连接器。我能够这样做,连接器正在停止并启动,但证书没有更新。只有服务器重启才会实际更新它
我是否缺少一些连接器初始化程序? 一些系统缓存或我应该清除的对象?
这是我用来重新启动连接器的代码:
MBeanServer mbeanServer = null;
ObjectName objectName = null;
final ObjectName objectNameQuery = new ObjectName("*:type=Connector,port=443,*");
for (final MBeanServer server : (ArrayList<MBeanServer>) MBeanServerFactory.findMBeanServer(null)) {
if (server.queryNames(objectNameQuery, null).size() > 0) {
mbeanServer = server;
objectName = (ObjectName) server.queryNames(objectNameQuery,null).toArray()[0];
break;
}
}
mbeanServer.invoke(objectName, "stop", null, null);
Thread.sleep(1000);
mbeanServer.invoke(objectName, "start", null, null);
我在tomcat日志中看到连接器重启的以下痕迹:
23-Apr-2017 15:42:00.292 INFO [BG-Task RestartTomcatConnector] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["http-nio-443"]
23-Apr-2017 15:42:01.349 INFO [BG-Task RestartTomcatConnector] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-443"]
答案 0 :(得分:0)
问题解决了,这些是组件:
server.xml必须包含bindOnInit =“false”。这是我使用的配置
<Connector protocol="org.apache.coyote.http11.Http11NioProtocol" port="443" SSLEnabled="true" maxThreads="150" acceptCount="2000" scheme="https" secure="true" ciphers="TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_DHE_RSA_WITH_AES_256_CBC_SHA" keystoreFile="webapps/ServerKeyStore" keystorePass="***" clientAuth="false" sslProtocol="TLS" sslEnabledProtocols="TLSv1.1,TLSv1.2" compression="on" compressableMimeType="text/html,text/xml,application/xml,application/json,application/javascript,text/css,text/plain" server="Portal" useSendfile="false" compressionMinSize="1024" bindOnInit="false"/>
连接器重启的Java代码:
public class TomcatConnectorRestarter implements Callable {
private final int waitSeconds = 3;
private final static ReentrantLock rl = new ReentrantLock();
@Override
public Boolean call() throws Exception {
restartConnector();
return true;
}
protected void restartConnector() throws Exception {
try {
if (tryLock()){
mLogger.info("Acquired lock");
try {
HTTPSConnectorMBean httpsConnector = null;
MBeanServer mbeanServer = null;
ObjectName objectName = null;
final ObjectName objectNameQuery = new ObjectName("*:type=Connector,port=443,*");
for (final MBeanServer server : (ArrayList<MBeanServer>) MBeanServerFactory.findMBeanServer(null)) {
if (server.queryNames(objectNameQuery, null).size() > 0) {
mbeanServer = server;
objectName = (ObjectName) server.queryNames(objectNameQuery, null).toArray()[0];
httpsConnector = new HTTPSConnectorMBean(objectName, mbeanServer);
break;
}
}
if (Objects.nonNull(httpsConnector)) {
mLogger.info("Stopping connector");
httpsConnector.stop();
mLogger.info("Waiting "+waitSeconds+" seconds after "+"stop"+" ...");
Thread.sleep(waitSeconds*1000);
mLogger.info("Starting connector");
httpsConnector.start();
}
else {
mLogger.error("Could not find connector object");
}
}
catch (Exception e) {
mLogger.error("Failed restarting connector",e);
}
}
else {
mLogger.warn("Operation is in process");
}
}
finally {
unlock();
}
}
private void unlock() {
if (rl.isHeldByCurrentThread()) {
mLogger.debug("Releasing lock");
rl.unlock();
}
}
private boolean tryLock() {
return !rl.isHeldByCurrentThread() && rl.tryLock();
}
private enum MBeanConnectorAction {
start,stop,getState;
}
private abstract class MBeansObjectAction {
private final ObjectName on;
private final MBeanServer server;
public MBeansObjectAction(ObjectName on, MBeanServer server) {
this.on = on;
this.server = server;
}
protected Object invoke(MBeanConnectorAction cmd) throws InstanceNotFoundException, ReflectionException, MBeanException {
return server.invoke(on, cmd.toString(), null, null);
}
}
private class HTTPSConnectorMBean extends MBeansObjectAction {
public HTTPSConnectorMBean(ObjectName on, MBeanServer server) {
super(on, server);
}
public void start() throws InstanceNotFoundException, ReflectionException, MBeanException {
invoke(MBeanConnectorAction.start);
}
public void stop() throws InstanceNotFoundException, ReflectionException, MBeanException {
invoke(MBeanConnectorAction.stop);
}
public Object status() throws InstanceNotFoundException, ReflectionException, MBeanException {
return invoke(MBeanConnectorAction.getState);
}
}
}