同一Jetty服务器中能否创建多个BayeuxServer实例?
实现Jetty上多实例BayeuxServer的方案
可以实现,核心是避开CometDServlet默认的ServletContext单例绑定逻辑,通过自定义Servlet来创建独立的BayeuxServer实例,分别配置扩展或保持纯净。
1. 自定义Servlet绕过单例限制
默认CometDServlet会将创建的BayeuxServer实例存储在ServletContext的org.cometd.bayeux属性中,导致后续Servlet复用同一个实例。我们可以继承CometDServlet,重写初始化和实例获取逻辑,让每个Servlet持有自己独立的BayeuxServer:
public class CustomCometDServlet extends CometDServlet { private BayeuxServer _bayeux; @Override protected void init() throws ServletException { // 跳过ServletContext共享逻辑,直接创建当前实例专属的BayeuxServer _bayeux = newBayeuxServer(); // 根据Servlet名称区分配置:给需要的实例添加扩展 if ("ExtendedCometDServlet".equals(getServletName())) { _bayeux.addExtension(new YourCustomExtension1()); _bayeux.addExtension(new YourCustomExtension2()); } // 复制原CometDServlet中的其他初始化逻辑(比如处理init参数) // 可参考原类的init()方法实现,确保参数配置生效 configureBayeux(_bayeux); } @Override protected BayeuxServer getBayeux() { // 返回当前Servlet持有的独立实例 return _bayeux; } }
2. 在web.xml中配置两个独立Servlet
注册两个自定义Servlet实例,指定不同的访问路径和初始化参数,确保它们各自启动独立的BayeuxServer:
<!-- 带扩展的CometD实例 --> <servlet> <servlet-name>ExtendedCometDServlet</servlet-name> <servlet-class>com.yourpackage.CustomCometDServlet</servlet-class> <init-param> <param-name>timeout</param-name> <param-value>60000</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>ExtendedCometDServlet</servlet-name> <url-pattern>/cometd/extended/*</url-pattern> </servlet-mapping> <!-- 无扩展的纯净CometD实例 --> <servlet> <servlet-name>PlainCometDServlet</servlet-name> <servlet-class>com.yourpackage.CustomCometDServlet</servlet-class> <init-param> <param-name>timeout</param-name> <param-value>30000</param-value> </init-param> <load-on-startup>2</load-on-startup> </servlet> <servlet-mapping> <servlet-name>PlainCometDServlet</servlet-name> <url-pattern>/cometd/plain/*</url-pattern> </servlet-mapping>
3. 关键注意事项
- 确保两个BayeuxServer实例的配置(超时、通道规则等)相互独立,避免因共享资源导致冲突。
- 若使用Spring等框架整合,可通过
@Bean分别创建两个不同配置的BayeuxServer实例,再绑定到对应的Servlet路径。 - 针对CometD 5版本,需确认
newBayeuxServer()和configureBayeux()方法的访问权限,若为protected可直接调用,若有调整需适配新版本API。
内容的提问来源于stack exchange,提问作者jesantana
相关产品推荐
相关产品推荐

