最近做一个项目,需要动态添加与移除servlet容器的http端口,并且启动都是嵌入式的。因此,果断选择了Jetty。
在模块化方面,Jetty是做的相当给力的一个容器,对于端口的动态增删能力,动态启停等都来源于这种强大的模块化设计。
- 动态增删端口
一般在嵌入式Jetty中,都会通过一个handlerCollection来负责接收所有的接入请求。为了做到动态添加与移除的效果,做了如下权衡。
1.启动之初
启动之初,只将server启动,并且加入一个空的handlerCollection。此时,有一点要注意,
/* ------------------------------------------------------------ */public HandlerCollection(){ _mutableWhenRunning=false;} /* ------------------------------------------------------------ */public HandlerCollection(boolean mutableWhenRunning){ _mutableWhenRunning=mutableWhenRunning;
}
无参构造函数默认的不允许在运行期间加入新的实例。因此,必须初始化填true。
private HandlerCollection handlers = new HandlerCollection(true);
2.动态加端口
List<Handler> handlerList = new LinkedList<>();if (handlers.getHandlers() != null) { for(Handler temp : handlers.getHandlers()) { handlerList.add(temp); }} MockHandler handler = new MockHandler(port, sysCode, mockDao);handler.setServer(server);handler.start();handlerList.add(handler);handlers.setHandlers(handlerList.toArray(new MockHandler[0])); Connector connector = getConnector(port);server.addConnector(connector);connector.start();
private ServerConnector getConnector(int port) { ServerConnector connector = new ServerConnector(server); connector.setPort(port); return connector;}
每添加一个handler,必须先启动,让其先准备好,然后再替换之前的handler集合。
3.动态移除端口
for (Connector connector : server.getConnectors()) { ServerConnector serverConnector = (ServerConnector) connector; if (codePort == serverConnector.getPort()) { connector.stop(); server.removeConnector(connector); List<Handler> mockHandlers = new LinkedList<>(); for(Handler tempHandler : handlers.getHandlers()) { MockHandler mockTempHandler = (MockHandler) tempHandler; if (!mockTempHandler.getSysCode().equals(sysCode)) { mockHandlers.add(tempHandler); } else { mockTempHandler.stop(); } } handlers.setHandlers(mockHandlers.toArray(new MockHandler[0])); break; } else { continue; }}
移除之前,先要停止此handler工作,避免继续接入新的请求,但是处理者已经消失导致未知异常。
- 动态启停
关于动态启停,这归属于Jetty的嵌入式使用方式,有一点要注意的就是,启动Jetty将会hold住当前线程,因此可能需要一个独立线程来启动server。
@Overridepublic void destroy() throws Exception { if (server != null) { server.stop(); server.destroy(); }} @Overridepublic void afterPropertiesSet() throws Exception { new Thread() { @Override public void run() { server = new Server(); server.setHandler(handlers); try { server.start(); server.join(); } catch (Exception e) { e.printStackTrace(); } } }.start();}
时间: 2024-10-12 22:47:23