在webflux+druid中 使用druid的监控页面

Published on with 0 views and 0 comments

在 webflux + druid 中使用druid的监控页面

  1. 使用tomcat作为web容器(druid版本1.2.8)
    1.1 添加依赖
    1.2 将filter赋值到tomcat的context 中
  2. 使用netty作为web容器. //TODO
    2.1 添加依赖 避免报错
    2.2 添加路由
  3. 使用tomcat作为web容器(druid版本1.2.8)
    如果能选择tomcat作为容器的话, 就非常好解决了. 只要配置一下filter就行 注意: druid版本必须 大于1.2.5

1.1 添加依赖

<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
            <exclusions>
                <!-- Exclude the reactor-netty dependency -->
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-reactor-netty</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </dependency>

1.2 将filter赋值到tomcat的context 中

@Configuration
@ConditionalOnProperty(name = "spring.datasource.druid.stat-view-servlet.enabled", havingValue = "true")
public class DruidStatViewConfig {
    @Autowired(required = false)
    FilterRegistrationBean webStatFilterRegistrationBean;
    @Autowired(required = false)
    ServletRegistrationBean statViewServletRegistrationBean;

    @Resource
    ApplicationContext applicationContext;

    /**
     * @author xmw
     * @date 2022/3/18 9:22
     * @param
     * @return org.springframework.boot.web.server.WebServerFactoryCustomizer<org.springframework.boot.web.embedded.tomcat.TomcatReactiveWebServerFactory>
     * @description : 使用tomcat 添加StatViewFilter
     */


    @Bean
    public WebServerFactoryCustomizer<TomcatReactiveWebServerFactory> customizer() {
        return factory -> {
            factory.addContextCustomizers(
                    context -> {
                        //监控页面 和sql监控功能
                        if(statViewServletRegistrationBean != null){
                            FilterDef filterDef = new FilterDef();
                            StatViewFilter filter = new StatViewFilter();
                            filterDef.setFilterName(filter.getClass().getName());
                            filterDef.setFilter(filter);
                            filterDef.setAsyncSupported("true");
                            //将DruidStatProperties的配置 赋值
                            filterDef.getParameterMap().putAll(statViewServletRegistrationBean.getInitParameters());
                            context.addFilterDef(filterDef);
                            FilterMap filterMap = new FilterMap();
                            filterMap.setFilterName(filter.getClass().getName());
                            filterMap.addURLPattern("/druid/*");
                            //filterMap.setDispatcher("REQUEST,FORWARD,INCLUDE,ASYNC");
                            context.addFilterMap(filterMap);
                        }
                        //监控url
                        if(webStatFilterRegistrationBean != null){
                            FilterDef webStatFilterDef = new FilterDef();
                            webStatFilterDef.setFilter(webStatFilterRegistrationBean.getFilter());
                            webStatFilterDef.setFilterName(webStatFilterRegistrationBean.getFilter().getClass().getName());
                            webStatFilterDef.setAsyncSupported("true");
                            webStatFilterDef.getParameterMap().putAll(webStatFilterRegistrationBean.getInitParameters());
                            context.addFilterDef(webStatFilterDef);

                            FilterMap webStatFilterMap = new FilterMap();
                            webStatFilterMap.setFilterName(webStatFilterRegistrationBean.getFilter().getClass().getName());
                            webStatFilterMap.addURLPattern("/*");
                            context.addFilterMap(webStatFilterMap);
                        }
                    }
            );
        };
    }
}

  1. 使用netty作为web容器. //TODO
    暂时没有找到特别完美的办法. 当前办法只能使用sql监控功能, 也就算是凑合用.
    该方法主要是通过 手动添加druid路由,来实现功能

2.1 添加依赖 避免报错

	<dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
        </dependency>

2.2 添加路由
让.json请求 路由到druidService方法中. 其他都是静态资源请求 转到druid方法即可

@Configuration
public class HandleConfig {

    @Bean
    public RouterFunction<ServerResponse> functionalRoutes(DruidHandler druidHandler) {
        return RouterFunctions
                .route(RequestPredicates.path("/druid/{url}.json")
                        , druidHandler::druidService)
                .andRoute(RequestPredicates.path("/druid/**")
                        , druidHandler::druid);
    }
}


@Component
public class DruidHandler {
  private static final MediaType TEXT_HTML_UTF8 = new MediaType("text", "html", StandardCharsets.UTF_8);
  @Resource
  ApplicationContext applicationContext;

  /**
   * Serves a plain_text
   */
  public Mono<ServerResponse> druidService(ServerRequest request) {
    String url = request.pathVariable("url");
    String query = request.uri().getQuery();
    url = "/"+url + ".json";
    if(StringUtil.isNotEmpty(query)){
      url = url + "?" +query;
    }

    String service = DruidStatService.getInstance().service(url);
    return ServerResponse.ok()
      .contentType(MediaType.APPLICATION_JSON)
      .body(
        Mono.just(service), String.class
      );
  }
  /**
   * Serves a JSON stream
   */
  public Mono<ServerResponse> druid(ServerRequest request) {
    String s = "classpath:support/http/resources" + request.path().replace("/druid","");
    org.springframework.core.io.Resource resource = applicationContext.getResource(s);
    return ServerResponse.ok().body(BodyInserters.fromResource(resource));
  }
}


标题:在webflux+druid中 使用druid的监控页面
作者:woyehua
地址:https://blog.stormbirds.cn/articles/2022/06/06/1654482909121.html