最近在项目中采用dubbo来管理服务,但是数据库连接池这一块采用druid,网上配置druid sql监控的都是基于web.xml配置,需要servlet容器支持,但是dubbo项目服务端这边一般不是web项目,所以启动这一块用不到servlet容器,一般dubbo项目启动都是采用shell脚本,java命令行,eclipse开发时直接main函数启动。出现了这问题后网上找方案,比较少,庆幸前辈记录的好,通俗易懂,依葫芦画瓢搞出来了,在此也特别记录下。
解决思想:
dubbo提供的容器有SpringContainer、Log4jContainer、JettyContainer、JavaConfigContainer、LogbackContainer
其中jetty大家都熟悉,更轻量级的servlet容器。dubbo里面内置了JettyContainer,可以提供汇报一些dubbo的执行状态。但是我们无法直接配置druid的sql监听器,所以必须借助于dubbo启动jetty容器的形式,自己进行JettyContainer扩展,而同时dubbo启动服务时可以指定多个容器,所以我们启动时指定启动spring容器与我们扩展的JettyContainer容器,完成druid监控。
1.添加jetty依赖
<dependency> <groupId>org.mortbay.jetty</groupId> <artifactId>jetty</artifactId> <version>6.1.26</version> </dependency>
2.更改JettyContainer
先下载JettyContainer代码下来,或者拷贝我的
将下载下来的JettyContainer添加到项目/src/main/java/自定义包下,再添加druid监听servlet代码
public class JettyContainer implements Container { private static final Logger logger = LoggerFactory.getLogger(JettyContainer.class); public static final String JETTY_PORT = "dubbo.jetty.port"; public static final String JETTY_DIRECTORY = "dubbo.jetty.directory"; public static final String JETTY_PAGES = "dubbo.jetty.page"; public static final int DEFAULT_JETTY_PORT = 8090; //jetty容器端口 SelectChannelConnector connector; public void start() { String serverPort = ConfigUtils.getProperty(JETTY_PORT); int port; if (serverPort == null || serverPort.length() == 0) { port = DEFAULT_JETTY_PORT; } else { port = Integer.parseInt(serverPort); } connector = new SelectChannelConnector(); connector.setPort(port); ServletHandler handler = new ServletHandler(); String resources = ConfigUtils.getProperty(JETTY_DIRECTORY); if (resources != null && resources.length() > 0) { FilterHolder resourceHolder = handler.addFilterWithMapping(ResourceFilter.class, "/*", Handler.DEFAULT); resourceHolder.setInitParameter("resources", resources); } ServletHolder pageHolder = handler.addServletWithMapping(PageServlet.class, "/*"); pageHolder.setInitParameter("pages", ConfigUtils.getProperty(JETTY_PAGES)); pageHolder.setInitOrder(2); //这里是新添加的,作用于druid日志监控系统的 handler.addServletWithMapping(StatViewServlet.class, "/druid/*"); Server server = new Server(); server.addConnector(connector); server.addHandler(handler); try { server.start(); } catch (Exception e) { throw new IllegalStateException("Failed to start jetty server on " + NetUtils.getLocalHost() + ":" + port + ", cause: " + e.getMessage(), e); } } public void stop() { try { if (connector != null) { connector.close(); connector = null; } } catch (Throwable e) { logger.error(e.getMessage(), e); } } }
3.更改duboo启动时加载容器配置
在src/main/resources/META-INF 下面创建dubbo文件夹,再添加文件com.alibaba.dubbo.container.Container
文件内容
myjetty=自定义包.JettyContainer
4.更改或添加dubbo.properties内容
说明:dubbo加载spring容器时,默认加载src/main/resources/META-INF/spring 文件夹里面的配置文件。
此处更改内容也是更改spring配置加载位置,指定dubbo加载哪些容器,配置日志
#配置spring配置加载位置 dubbo.spring.config=classpath*:spring-*.xml #配置传入要加载的容器 dubbo.container=spring,myjetty,log4j #配置日志文件路径 dubbo.log4j.file=/logs/dubbo-jzy-provider.log #配置日志级别 dubbo.log4j.level=WARN #配置日志子目录,用于多进程启动,避免冲突 dubbo.log4j.subdirectory=20880
5.启动发布服务
说明: com.alibaba.dubbo.container.Main 是dubbo服务启动的主类,指定启动spring容器和修改后的myjetty 容器。
public class JettyContainerStart { public static void main(String[] args) { args = new String[] { "spring", "myjetty" }; com.alibaba.dubbo.container.Main.main(args); } }
6.druid sql监控页面
参考网上解决方案,感谢