【监控】JavaMelody In Action

JavaMelody In Action

前言:
在项目的实际运行过程中,我们想知道项目具体运行情况到底是怎么样的,比如,我们关心java虚拟机使用的内存是多少?执行sql的数量及单个sql执行的时间是怎么样的?http 请求有没有错误?定时任务有没有按时触发 …等等,但是,大多数情况这些消息对我们是透明的,我们也很难根据项目的实际运行情况进行针对性的优化。这也就导入了我们今天的主题JavaMelody

JavaMelody

  • 什么是 JavaMelody
    JavaMelody是用来在QA和实际运行生产环境中监控Java或Java EE应用程序服务器的一个开源框架。主要基于请求的数据统计来演化图表。

在Spring Boot项目中使用JavaMelody

JavaMelody 已经对 Spring Boot 2 有了充分的集成(spring-boot-starter)的支持,但是对于Spring Boot 1 的工程,是不兼容的,不过使用方法与常规的spring项目一致。

  • Spring Boot 2 集成
    只需要在我们的pom文件里面添加上依赖
    <dependency>
    	<groupId>net.bull.javamelodygroupId>
    	<artifactId>javamelody-spring-boot-starterartifactId>
    	<version>1.77.0version>
    dependency>

然后我们就可以运行我们的项目,打开url:http://localhost:8080/monitoring 看到对应的监控记录了
我们可以进行对应的针对性的参数设置

     javamelody:
      # 是否自动装配,default: true
      enabled: true
      #排除哪些数据源
      excluded-datasources: secretSource,topSecretSource
      # 启动对service和controller的监控, default: true
      spring-monitoring-enabled: true
      # 初始化JavaMelody中的参数 
      # See: https://github.com/javamelody/javamelody/wiki/UserGuide#6-optional-parameters
      init-parameters:
        # log http requests:
        log: true
        # 排除对某些url的监控:
        #url-exclude-pattern: (/webjars/.*|/css/.*|/images/.*|/fonts/.*|/js/.*)
        # to aggregate digits in http requests:
        #http-transform-pattern: \d+
        # 添加基本的信息验证
        #authorized-users: admin:pwd
        # 设置存储地址:
        #storage-directory: /tmp/javamelody
        # 设置监控 "/monitoring" 地址:
        #monitoring-path: /admin/performance

具体参数请见: https://github.com/javamelody/javamelody/wiki/UserGuide#6-optional-parameters

  • 设置默认的url端口
    刚才我们谈到,默认的url是需要打开8080 端口进行映射的,那如果端口被占用或者我们想换个其他的端口来进行监控数据的话,该怎么做呢?
  1. pom文件添加依赖
<dependency>
   <groupId>org.springframework.bootgroupId>
   <artifactId>spring-boot-starter-actuatorartifactId>
dependency>
  1. 配置文件设置(yml或者properties文件),以yml文件为例
management.server.port: 8081
  1. 启用管理端点并在yml(或properties)中通过http进行端口暴露
management.endpoints.web.exposure.include: info,health,monitoring

javamelody:
  management-endpoint-monitoring-enabled: true
  1. 验证
    http://localhost:8081/actuator/monitoring

大概信息如下:下面有对应的明细记录
【监控】JavaMelody In Action_第1张图片

在Spring Boot 1.x 项目中使用JavaMelody

刚才介绍了在SpringBoot2.0项目中进行组件的集成,那么对于一般的普通Spring Boot 1.x的项目也很简单,所以由此也可以看出来,JavaMelody是一个无侵入性的非常优秀的监控框架

  • spring 项目的集成
    1)加入pom依赖

<dependency>
	<groupId>net.bull.javamelodygroupId>
	<artifactId>javamelody-coreartifactId>
	<version>1.77.0version>
dependency>

<dependency>
	<groupId>com.lowagiegroupId>
	<artifactId>itextartifactId>
	<version>2.1.7version>
	<exclusions>
		<exclusion>
			<artifactId>bcmail-jdk14artifactId>
			<groupId>bouncycastlegroupId>
		exclusion>
		<exclusion>
			<artifactId>bcprov-jdk14artifactId>
			<groupId>bouncycastlegroupId>
		exclusion>
		<exclusion>
			<artifactId>bctsp-jdk14artifactId>
			<groupId>bouncycastlegroupId>
		exclusion>
	exclusions>
dependency>

如果你想要导出xml或者json 的报告,需要这两个依赖(不是必须的)

<dependency>
	<groupId>com.thoughtworks.xstreamgroupId>
	<artifactId>xstreamartifactId>
	<version>1.4.10version>
dependency>
<dependency>
	<groupId>org.jrobingroupId>
	<artifactId>jrobinartifactId>
	<version>1.5.9version>
dependency>

2)复制下面的配置类

package hello;

import java.util.Arrays;
import java.util.EventListener;
import java.util.HashSet;
import java.util.Map;

import javax.servlet.DispatcherType;
import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import javax.sql.DataSource;

import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.aop.support.Pointcuts;
import org.springframework.aop.support.annotation.AnnotationMatchingPointcut;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import net.bull.javamelody.MonitoredWithAnnotationPointcut;
import net.bull.javamelody.MonitoredWithSpring;
import net.bull.javamelody.MonitoringFilter;
import net.bull.javamelody.MonitoringSpringAdvisor;
import net.bull.javamelody.Parameter;
import net.bull.javamelody.SessionListener;
import net.bull.javamelody.SpringContext;
import net.bull.javamelody.SpringDataSourceBeanPostProcessor;
import net.bull.javamelody.SpringRestTemplateBeanPostProcessor;

/**
 * Spring  configuration for JavaMelody.
 *
 */
@Configuration
@ConditionalOnWebApplication
public class JavaMelodyConfiguration {
	/**
	 * Name of the FilterRegistrationBean.
	 */
	public static final String REGISTRATION_BEAN_NAME = "javamelody-registration";

	/**
	 * Registers the JavaMelody {@link SessionListener}.
	 * @param servletContext ServletContext
	 * @return ServletListenerRegistrationBean
	 */
	@Bean
	public ServletListenerRegistrationBean<EventListener> monitoringSessionListener(
			ServletContext servletContext) {
		final ServletListenerRegistrationBean<EventListener> servletListenerRegistrationBean = new ServletListenerRegistrationBean<>(
				new SessionListener());
		if (servletContext.getFilterRegistration("javamelody") != null) {
			// if webapp deployed as war in a container with MonitoringFilter and SessionListener already added by web-fragment.xml,
			// do not add again
			servletListenerRegistrationBean.setEnabled(false);
		}
		return servletListenerRegistrationBean;
	}

	/**
	 * Registers the JavaMelody {@link MonitoringFilter}.
	 * @param servletContext ServletContext
	 * @return FilterRegistrationBean
	 */
	@Bean(name = REGISTRATION_BEAN_NAME)
	public FilterRegistrationBean monitoringFilter(ServletContext servletContext) {
		final FilterRegistrationBean registrationBean = new FilterRegistrationBean();

		// Create the monitoring filter and set its configuration parameters.
		final MonitoringFilter filter = new MonitoringFilter();
		filter.setApplicationType("Spring Boot");

		// Wrap the monitoring filter in the registration bean.
		registrationBean.setFilter(filter);
		registrationBean.setAsyncSupported(true);
		registrationBean.setName("javamelody");
		registrationBean.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.ASYNC);

		// Set the initialization parameter for the monitoring filter.
		// see the list of parameters:
		// https://github.com/javamelody/javamelody/wiki/UserGuide#6-optional-parameters
		registrationBean.addInitParameter(Parameter.LOG.getCode(), Boolean.toString(true));
		// to exclude images, css, fonts and js urls from the monitoring:
		// javaMelody.addInitParameter(Parameter.URL_EXCLUDE_PATTERN.getCode(), "(/webjars/.*|/css/.*|/images/.*|/fonts/.*|/js/.*)");
		// to add basic auth:
		// javaMelody.addInitParameter(Parameter.AUTHORIZED_USERS.getCode(), "admin:pwd");
		// to change the default storage directory:
		// javaMelody.addInitParameter(Parameter.STORAGE_DIRECTORY.getCode(), "/tmp/javamelody");

		// Set the URL patterns to activate the monitoring filter for.
		registrationBean.addUrlPatterns("/*");

		final FilterRegistration filterRegistration = servletContext
				.getFilterRegistration("javamelody");
		if (filterRegistration != null) {
			// if webapp deployed as war in a container with MonitoringFilter already added by web-fragment.xml,
			// do not try to add it again
			registrationBean.setEnabled(false);
			for (final Map.Entry<String, String> entry : registrationBean.getInitParameters()
					.entrySet()) {
				filterRegistration.setInitParameter(entry.getKey(), entry.getValue());
			}
		}
		return registrationBean;
	}

	// Note: if you have auto-proxy issues, you can add the following dependency in your pom.xml:
	// <dependency>
	//   <groupId>org.springframework.boot</groupId>
	//   <artifactId>spring-boot-starter-aop</artifactId>
	// </dependency> 
	@Bean
	@ConditionalOnMissingBean(DefaultAdvisorAutoProxyCreator.class)
	public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
		return new DefaultAdvisorAutoProxyCreator();
	}

	/**
	 * Monitoring of JDBC {@link DataSource}s
	 * @param excludedDatasources Comma separated list of excluded datasources
	 * @return SpringDataSourceBeanPostProcessor
	 */
	@Bean
	public SpringDataSourceBeanPostProcessor monitoringDataSourceBeanPostProcessor(
			@Value("${javamelody.excluded-datasources:}") String excludedDatasources) {
		final SpringDataSourceBeanPostProcessor processor = new SpringDataSourceBeanPostProcessor();
		if (excludedDatasources != null && excludedDatasources.trim().length() > 0) {
			processor.setExcludedDatasources(
					new HashSet<>(Arrays.asList(excludedDatasources.split(","))));
		}
		return processor;
	}

	/**
	 * Monitoring of beans and methods having the {@link MonitoredWithSpring} annotation.
	 * @return MonitoringSpringAdvisor
	 */
	@Bean
	public MonitoringSpringAdvisor monitoringSpringAdvisor() {
		return new MonitoringSpringAdvisor(new MonitoredWithAnnotationPointcut());
	}

	/**
	 * Monitoring of beans having the {@link Service} annotation.
	 * @return MonitoringSpringAdvisor
	 */
	@Bean
	public MonitoringSpringAdvisor monitoringSpringServiceAdvisor() {
		return new MonitoringSpringAdvisor(new AnnotationMatchingPointcut(Service.class));
	}

	/**
	 * Monitoring of beans having the {@link Controller} annotation.
	 * @return MonitoringSpringAdvisor
	 */
	@Bean
	public MonitoringSpringAdvisor monitoringSpringControllerAdvisor() {
		return new MonitoringSpringAdvisor(new AnnotationMatchingPointcut(Controller.class));
	}

	/**
	 * Monitoring of beans having the {@link RestController} annotation.
	 * @return MonitoringSpringAdvisor
	 */
	@Bean
	public MonitoringSpringAdvisor monitoringSpringRestControllerAdvisor() {
		return new MonitoringSpringAdvisor(new AnnotationMatchingPointcut(RestController.class));
	}

	/**
	 * Monitoring of beans or methods having the {@link Async} annotation.
	 * @return MonitoringSpringAdvisor
	 */
	@Bean
	public MonitoringSpringAdvisor monitoringSpringAsyncAdvisor() {
		return new MonitoringSpringAdvisor(
				Pointcuts.union(new AnnotationMatchingPointcut(Async.class),
						new AnnotationMatchingPointcut(null, Async.class)));
	}

	/**
	 * Monitoring of beans methods having the {@link Scheduled} or {@link Schedules} annotations.
	 * @return MonitoringSpringAdvisor
	 */
	//	@Bean
	//	public MonitoringSpringAdvisor monitoringSpringScheduledAdvisor() {
	//		return new MonitoringSpringAdvisor(
	//				Pointcuts.union(new AnnotationMatchingPointcut(null, Scheduled.class),
	//						new AnnotationMatchingPointcut(null, Schedules.class)));
	//	}

	/**
	 * Monitoring of {@link RestTemplate} beans.
	 * @return SpringRestTemplateBeanPostProcessor
	 */
	@Bean
	public SpringRestTemplateBeanPostProcessor monitoringRestTemplateBeanPostProcessor() {
		return new SpringRestTemplateBeanPostProcessor();
	}

	/**
	 * @return Reference to the Spring context.
	 */
	@Bean
	public SpringContext javamelodySpringContext() {
		return new SpringContext();
	}
}

正常情况下,这个时候已经能够正常运行了,如果不能运行,检查是否动态代理有问题,如果有问题的话添加aop包

<dependency>
	<groupId>org.springframework.bootgroupId>
	<artifactId>spring-boot-starter-aopartifactId>
dependency>

在Spring MVC 项目中使用JavaMelody

  • 整合到Spring 项目中
    1)添加POM依赖
  
        <dependency>
            <groupId>net.bull.javamelodygroupId>
            <artifactId>javamelody-coreartifactId>
            <version>1.74.0version>
        dependency>

2)在Spring-config.xml中导入配置

   
    <import resource="classpath:net/bull/javamelody/monitoring-spring.xml"/>
    <import resource="classpath:net/bull/javamelody/monitoring-spring-datasource.xml"/>
    <import resource="classpath:net/bull/javamelody/monitoring-spring-aspectj.xml"/>

启动项目,然后打开url:http://localhost:8080/monitoring 检验下结果吧!

参考:https://github.com/javamelody/javamelody

你可能感兴趣的:(微服务,监控,后台监控,javaMelody)