如何做自己的服务监控?spring boot 2.x服务监控揭秘
Actuator
是spring boot
项目中非常强大一个功能,有助于对应用程序进行监视和管理,通过 restful api
请求来监管、审计、收集应用的运行情况,针对微服务而言它是必不可少的一个环节。
spring 2.x actuator相对于spring 1.x actuator做了较大的改变。
如何做自己的服务监控?spring boot 1.x服务监控揭秘
****提供了更多的endpoint管理
ID | Description | Enabled by default |
---|---|---|
|
Exposes audit events information for the current application. |
Yes |
|
Displays a complete list of all the Spring beans in your application. |
Yes |
|
Exposes available caches. |
Yes |
|
Shows the conditions that were evaluated on configuration and auto-configuration classes and the reasons why they did or did not match. |
Yes |
|
Displays a collated list of all |
Yes |
|
Exposes properties from Spring’s |
Yes |
|
Shows any Flyway database migrations that have been applied. |
Yes |
|
Shows application health information. |
Yes |
|
Displays HTTP trace information (by default, the last 100 HTTP request-response exchanges). |
Yes |
|
Displays arbitrary application info. |
Yes |
|
Shows the Spring Integration graph. |
Yes |
|
Shows and modifies the configuration of loggers in the application. |
Yes |
|
Shows any Liquibase database migrations that have been applied. |
Yes |
|
Shows ‘metrics’ information for the current application. |
Yes |
|
Displays a collated list of all |
Yes |
|
Displays the scheduled tasks in your application. |
Yes |
|
Allows retrieval and deletion of user sessions from a Spring Session-backed session store. Not available when using Spring Session’s support for reactive web applications. |
Yes |
|
Lets the application be gracefully shutdown. |
No |
|
Performs a thread dump. |
Yes |
If your application is a web application (Spring MVC, Spring WebFlux, or Jersey), you can use the following additional endpoints:
ID | Description | Enabled by default |
---|---|---|
|
Returns an |
Yes |
|
Exposes JMX beans over HTTP (when Jolokia is on the classpath, not available for WebFlux). |
Yes |
|
Returns the contents of the logfile (if |
Yes |
|
Exposes metrics in a format that can be scraped by a Prometheus server. |
Yes |
********更多的metrics
JVM metrics, report utilization of:
- Various memory and buffer pools
- Statistics related to garbage collection
- Threads utilization
- Number of classes loaded/unloaded
- CPU metrics
- File descriptor metrics
- Kafka consumer metrics
- Log4j2 metrics: record the number of events logged to Log4j2 at each level
- Logback metrics: record the number of events logged to Logback at each level
- Uptime metrics: report a gauge for uptime and a fixed gauge representing the application’s absolute start time
- Tomcat metrics
- Spring Integration metrics
*********内部实现也发生了较大的变化,使用micrometer第三方工具来完成metric的实现。下面我们就亲自看看吧!
1.准备源码
https://github.com/tjanusz-personal/springbootrestdemo/tree/master/src/main/java/com/demo/springbootrestdemo
2.导入并启动项目
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \\\/ ___)| |_)| | | | | || (_| | ) ) ) )' |____| .__|_| |_|_| |_\__, | / / / /=========|_|==============|___/=/_/_/_/:: Spring Boot :: (v2.0.4.RELEASE)2019-01-17 11:20:39.076 INFO 5180 --- [ main] c.d.s.SpringbootrestdemoApplication : Starting SpringbootrestdemoApplication on DESKTOP-405G2C8 with PID 5180 (E:\document\springbootrestdemo\build\classes\java\main started by dell in E:\document\springbootrestdemo) 2019-01-17 11:20:39.080 INFO 5180 --- [ main] c.d.s.SpringbootrestdemoApplication : No active profile set, falling back to default profiles: default 2019-01-17 11:20:39.147 INFO 5180 --- [ main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@6f01b95f: startup date [Thu Jan 17 11:20:39 CST 2019]; root of context hierarchy WARNING: An illegal reflective access operation has occurred WARNING: Illegal reflective access by org.springframework.cglib.core.ReflectUtils$1 (file:/D:/gradle/caches/modules-2/files-2.1/org.springframework/spring-core/5.0.8.RELEASE/dc39c49e3246cdf73d3786ac41119140aed3fa08/spring-core-5.0.8.RELEASE.jar) to method java.lang.ClassLoader.defineClass(java.lang.Stri ng,byte[],int,int,java.security.ProtectionDomain) WARNING: Please consider reporting this to the maintainers of org.springframework.cglib.core.ReflectUtils$1 WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations WARNING: All illegal access operations will be denied in a future release 2019-01-17 11:20:40.341 INFO 5180 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.hateoas.config.HateoasConfiguration' of type [org.springframework.hateoas.config.HateoasConfiguration$$EnhancerBySpringCGLIB$$ecf2a812] is not eligible for getting processed by a ll BeanPostProcessors (for example: not eligible for auto-proxying) 2019-01-17 11:20:40.982 INFO 5180 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http) 2019-01-17 11:20:41.015 INFO 5180 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2019-01-17 11:20:41.016 INFO 5180 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.32 2019-01-17 11:20:41.029 INFO 5180 --- [ost-startStop-1] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [D:\software\jdk11\bin;C:\Windows\Sun\Java\bin;C:\Windows\sys tem32;C:\Windows;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;D:\software\jdk11\bin;D:\software\TortoiseGit\bin;D:\software\Git\cmd;D:\software\apache-maven-3.5.4\bin;D:\software\gradle-4.10.2\bin;D:\software\go\bin;D:\s oftware\ant\bin;D:\software\anaconda;D:\software\anaconda\Scripts;D:\software\anaconda\Library\bin;C:\Users\dell\AppData\Local\Microsoft\WindowsApps;;.] 2019-01-17 11:20:41.162 INFO 5180 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2019-01-17 11:20:41.168 INFO 5180 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 2035 ms 2019-01-17 11:20:41.832 INFO 5180 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*] 2019-01-17 11:20:41.832 INFO 5180 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'webMvcMetricsFilter' to: [/*] 2019-01-17 11:20:41.832 INFO 5180 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpTraceFilter' to: [/*] 2019-01-17 11:20:41.833 INFO 5180 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Servlet dispatcherServlet mapped to [/] 2019-01-17 11:20:41.960 INFO 5180 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/saveUrl],methods=[POST],consumes=[application/json;charset=UTF-8 || application/x-www-form-urlencoded],produces=[application/json;charset=UTF-8 || application/xml]}" onto public com.demo.spring bootrestdemo.domain.response.SaveUrlResponse com.demo.springbootrestdemo.web.DemoController.saveUrl(com.demo.springbootrestdemo.domain.request.SaveUrlRequest,java.lang.String,java.lang.String) 2019-01-17 11:20:41.961 INFO 5180 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/alive],methods=[GET]}" onto public com.demo.springbootrestdemo.domain.response.DemoPingResponse com.demo.springbootrestdemo.web.DemoController.alive() 2019-01-17 11:20:41.964 INFO 5180 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http .HttpServletRequest,javax.servlet.http.HttpServletResponse) 2019-01-17 11:20:41.964 INFO 5180 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.err or(javax.servlet.http.HttpServletRequest) 2019-01-17 11:20:42.038 INFO 5180 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@6f01b95f: startup date [Thu Jan 17 11:20:39 CST 2019]; root of context hierar chy 2019-01-17 11:20:42.087 INFO 5180 --- [ main] .m.m.a.ExceptionHandlerExceptionResolver : Detected @ExceptionHandler methods in restResponseEntityExceptionHandler 2019-01-17 11:20:42.529 INFO 5180 --- [ main] o.s.b.a.e.web.EndpointLinksResolver : Exposing 14 endpoint(s) beneath base path '/actuator' 2019-01-17 11:20:42.538 INFO 5180 --- [ main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/auditevents],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.serv let.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2019-01-17 11:20:42.539 INFO 5180 --- [ main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/beans],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.Ab stractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2019-01-17 11:20:42.539 INFO 5180 --- [ main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/health],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.A bstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2019-01-17 11:20:42.540 INFO 5180 --- [ main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/conditions],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servl et.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2019-01-17 11:20:42.540 INFO 5180 --- [ main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/configprops],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.serv let.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2019-01-17 11:20:42.540 INFO 5180 --- [ main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/env/{toMatch}],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.se rvlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2019-01-17 11:20:42.541 INFO 5180 --- [ main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/env],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.Abst ractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2019-01-17 11:20:42.541 INFO 5180 --- [ main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/info],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.Abs tractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2019-01-17 11:20:42.541 INFO 5180 --- [ main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/loggers/{name}],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.s ervlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2019-01-17 11:20:42.542 INFO 5180 --- [ main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/loggers/{name}],methods=[POST],consumes=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web. servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2019-01-17 11:20:42.542 INFO 5180 --- [ main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/loggers],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet. AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2019-01-17 11:20:42.543 INFO 5180 --- [ main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/heapdump],methods=[GET],produces=[application/octet-stream]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$Op erationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2019-01-17 11:20:42.543 INFO 5180 --- [ main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/threaddump],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servl et.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2019-01-17 11:20:42.543 INFO 5180 --- [ main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/metrics],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet. AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2019-01-17 11:20:42.544 INFO 5180 --- [ main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/metrics/{requiredMetricName}],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate. endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2019-01-17 11:20:42.544 INFO 5180 --- [ main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/scheduledtasks],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.s ervlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2019-01-17 11:20:42.544 INFO 5180 --- [ main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/httptrace],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servle t.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2019-01-17 11:20:42.545 INFO 5180 --- [ main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/mappings],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet .AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>) 2019-01-17 11:20:42.546 INFO 5180 --- [ main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto protected java.util.Map<java.lang.String, java.util.Map<java.lang.String, org.springfr amework.boot.actuate.endpoint.web.Link>> org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping.links(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) 2019-01-17 11:20:42.590 INFO 5180 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup 2019-01-17 11:20:42.641 INFO 5180 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2019-01-17 11:20:42.648 INFO 5180 --- [ main] c.d.s.SpringbootrestdemoApplication : Started SpringbootrestdemoApplication in 4.008 seconds (JVM running for 4.517) <=========----> 75% EXECUTING [25s] > :bootRun
3.获取EndPoint
3.0 来源
"webEndpointServletHandlerMapping": {"aliases": [],"scope": "singleton","type": "org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping","resource": "class path resource [org/springframework/boot/actuate/autoconfigure/endpoint/web/servlet/WebMvcEndpointManagementContextConfiguration.class]","dependencies": [ "webEndpointDiscoverer","servletEndpointDiscoverer","controllerEndpointDiscoverer","endpointMediaTypes","management.endpoints.web.cors-org.springframework.boot.actuate.autoconfigure.endpoint.web.CorsEndpointProperties","management.endpoints.web-org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties"]}
spring.factories定义了
org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration=\ org.springframework.boot.actuate.autoconfigure.endpoint.web.ServletEndpointManagementContextConfiguration,\ org.springframework.boot.actuate.autoconfigure.endpoint.web.reactive.WebFluxEndpointManagementContextConfiguration,\ org.springframework.boot.actuate.autoconfigure.endpoint.web.servlet.WebMvcEndpointManagementContextConfiguration,\ org.springframework.boot.actuate.autoconfigure.endpoint.web.jersey.JerseyWebEndpointManagementContextConfiguration,\ org.springframework.boot.actuate.autoconfigure.web.jersey.JerseyManagementChildContextConfiguration,\ org.springframework.boot.actuate.autoconfigure.web.reactive.ReactiveManagementChildContextConfiguration,\ org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementChildContextConfiguration,\ org.springframework.boot.actuate.autoconfigure.web.servlet.WebMvcEndpointChildContextConfiguration
3.1 映射
@Bean@ConditionalOnMissingBeanpublicWebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(WebEndpointsSupplier webEndpointsSupplier,ServletEndpointsSupplier servletEndpointsSupplier,ControllerEndpointsSupplier controllerEndpointsSupplier,EndpointMediaTypes endpointMediaTypes, CorsEndpointProperties corsProperties,WebEndpointProperties webEndpointProperties) {List<ExposableEndpoint<?>> allEndpoints = new ArrayList<>(); Collection<ExposableWebEndpoint> webEndpoints =webEndpointsSupplier.getEndpoints();allEndpoints.addAll(webEndpoints);allEndpoints.addAll(servletEndpointsSupplier.getEndpoints());allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints());EndpointMapping endpointMapping= newEndpointMapping(webEndpointProperties.getBasePath());return newWebMvcEndpointHandlerMapping(endpointMapping, webEndpoints,endpointMediaTypes, corsProperties.toCorsConfiguration(),newEndpointLinksResolver(allEndpoints,webEndpointProperties.getBasePath()));}
3.2 获取EndPoint
3.2.1 EndPoint定义
/*** Identifies a type as being an actuator endpoint that provides information about the* running application. Endpoints can be exposed over a variety of technologies including* JMX and HTTP.* <p>* Most {@code@Endpoint} classes will declare one or more* {@linkReadOperation @ReadOperation}, {@linkWriteOperation @WriteOperation},* {@linkDeleteOperation @DeleteOperation} annotated methods which will be automatically* adapted to the exposing technology (JMX, Spring MVC, Spring WebFlux, Jersey etc.).* <p>* {@code@Endpoint} represents the lowest common denominator for endpoints and* intentionally limits the sorts of operation methods that may be defined in order to* support the broadest possible range of exposure technologies. If you need deeper* support for a specific technology you can either write an endpoint that is* {@linkFilteredEndpoint filtered} to a certain technology, or provide* {@linkEndpointExtension extension} for the broader endpoint.**@authorAndy Wilkinson*@authorPhillip Webb*@since2.0.0*@seeEndpointExtension*@seeFilteredEndpoint*@seeEndpointDiscoverer*/
使用了@Endpoint注解的类
3.2.2 获取所有的EndPoint
@Overridepublic final Collection<E>getEndpoints() {if (this.endpoints == null) {this.endpoints =discoverEndpoints();}return this.endpoints;}private Collection<E>discoverEndpoints() {Collection<EndpointBean> endpointBeans =createEndpointBeans();addExtensionBeans(endpointBeans);returnconvertToEndpoints(endpointBeans);}private Collection<EndpointBean>createEndpointBeans() {Map<EndpointId, EndpointBean> byId = new LinkedHashMap<>(); String[] beanNames= BeanFactoryUtils.beanNamesForAnnotationIncludingAncestors(this.applicationContext, Endpoint.class);for(String beanName : beanNames) {if (!ScopedProxyUtils.isScopedTarget(beanName)) {EndpointBean endpointBean=createEndpointBean(beanName);EndpointBean previous=byId.putIfAbsent(endpointBean.getId(),endpointBean);Assert.state(previous== null,()-> "Found two endpoints with the id '" +endpointBean.getId()+ "': '" + endpointBean.getBeanName() + "' and '"+ previous.getBeanName() + "'");}}returnbyId.values();}privateEndpointBean createEndpointBean(String beanName) {Object bean= this.applicationContext.getBean(beanName);return newEndpointBean(beanName, bean);}private void addExtensionBeans(Collection<EndpointBean>endpointBeans) {Map<EndpointId, EndpointBean> byId =endpointBeans.stream().collect(Collectors.toMap(EndpointBean::getId, Function.identity()));String[] beanNames=BeanFactoryUtils.beanNamesForAnnotationIncludingAncestors(this.applicationContext, EndpointExtension.class);for(String beanName : beanNames) {ExtensionBean extensionBean=createExtensionBean(beanName);EndpointBean endpointBean=byId.get(extensionBean.getEndpointId());Assert.state(endpointBean!= null,()-> ("Invalid extension '" +extensionBean.getBeanName()+ "': no endpoint found with id '"+ extensionBean.getEndpointId() + "'"));addExtensionBean(endpointBean, extensionBean);}}
3.3 WebMvcEndpointHandlerMapping
3.3.0 spring mvc的流程复习
其中:
第2步获取HandlerMapping,其层次结构
其中RequestMappingHandlerMapping用来处理@RequestMapping注解
privateRequestMappingInfo createRequestMappingInfo(AnnotatedElement element) {RequestMapping requestMapping= AnnotatedElementUtils.findMergedAnnotation(element, RequestMapping.class);RequestCondition<?> condition = (element instanceof Class ?getCustomTypeCondition((Class<?>) element) : getCustomMethodCondition((Method) element));return (requestMapping != null ? createRequestMappingInfo(requestMapping, condition) : null);}
第3步获取HandlerAdapter,其层次结构
默认handlerMapping和handlerAdapter定义在DispatcherServlet.properties
org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMappingorg.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
3.3.1 获取WebMvcEndpointHandlerMapping
/*** Creates a new {@codeWebMvcEndpointHandlerMapping} instance that provides mappings* for the given endpoints.*@paramendpointMapping the base mapping for all endpoints*@paramendpoints the web endpoints*@paramendpointMediaTypes media types consumed and produced by the endpoints*@paramcorsConfiguration the CORS configuration for the endpoints or {@codenull}*@paramlinksResolver resolver for determining links to available endpoints*/publicWebMvcEndpointHandlerMapping(EndpointMapping endpointMapping,Collection<ExposableWebEndpoint>endpoints,EndpointMediaTypes endpointMediaTypes, CorsConfiguration corsConfiguration,EndpointLinksResolver linksResolver) {super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration);this.linksResolver =linksResolver;setOrder(-100);}
父类实现了initHandlerMethods()
@Overrideprotected voidinitHandlerMethods() {for (ExposableWebEndpoint endpoint : this.endpoints) {for(WebOperation operation : endpoint.getOperations()) {registerMappingForOperation(endpoint, operation);}}if (StringUtils.hasText(this.endpointMapping.getPath())) {registerLinksMapping();}}
将endpoint的Operation映射到Method级别,类似于@RequestMapping
private voidregisterMappingForOperation(ExposableWebEndpoint endpoint,WebOperation operation) {ServletWebOperation servletWebOperation=wrapServletWebOperation(endpoint,operation,newServletWebOperationAdapter(operation));registerMapping(createRequestMappingInfo(operation),new OperationHandler(servletWebOperation), this.handleMethod);}/*** Hook point that allows subclasses to wrap the {@linkServletWebOperation} before* it's called. Allows additional features, such as security, to be added.*@paramendpoint the source endpoint*@paramoperation the source operation*@paramservletWebOperation the servlet web operation to wrap*@returna wrapped servlet web operation*/protectedServletWebOperation wrapServletWebOperation(ExposableWebEndpoint endpoint,WebOperation operation, ServletWebOperation servletWebOperation) {returnservletWebOperation;}privateRequestMappingInfo createRequestMappingInfo(WebOperation operation) {WebOperationRequestPredicate predicate=operation.getRequestPredicate();PatternsRequestCondition patterns=patternsRequestConditionForPattern(predicate.getPath());RequestMethodsRequestCondition methods= newRequestMethodsRequestCondition(RequestMethod.valueOf(predicate.getHttpMethod().name()));ConsumesRequestCondition consumes= newConsumesRequestCondition(StringUtils.toStringArray(predicate.getConsumes()));ProducesRequestCondition produces= newProducesRequestCondition(StringUtils.toStringArray(predicate.getProduces()));return new RequestMappingInfo(null, patterns, methods, null, null, consumes,produces,null);}
3.3.2 获取ServletWebOperationAdapter
AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle
@OverridepublicObject handle(HttpServletRequest request,@RequestBody(required= false) Map<String, String>body) {Map<String, Object> arguments =getArguments(request, body);try{returnhandleResult(this.operation.invoke(newInvocationContext(newServletSecurityContext(request), arguments)),HttpMethod.valueOf(request.getMethod()));}catch(InvalidEndpointRequestException ex) {throw newBadOperationRequestException(ex.getReason());}}
4.触发机制
If you add a @Bean
annotated with @Endpoint
, any methods annotated with@ReadOperation
, @WriteOperation
, or @DeleteOperation
are automatically exposed over JMX and, in a web application, over HTTP as well. Endpoints can be exposed over HTTP using Jersey, Spring MVC, or Spring WebFlux.
if you need access to web-framework-specific functionality, you can implement Servlet or Spring @Controller
and @RestController
endpoints at the cost of them not being available over JMX or when using a different web framework.
EndpointDiscoverer
@Overridepublic final Collection<E>getEndpoints() {if (this.endpoints == null) {this.endpoints =discoverEndpoints();}return this.endpoints;}private Collection<E>discoverEndpoints() {Collection<EndpointBean> endpointBeans =createEndpointBeans();addExtensionBeans(endpointBeans);returnconvertToEndpoints(endpointBeans);}
调用 @ReadOperation
, @WriteOperation
, or @DeleteOperation方法
private void addOperations(MultiValueMap<OperationKey, O>indexed, EndpointId id,Object target,booleanreplaceLast) {Set<OperationKey> replacedLast = new HashSet<>();Collection<O> operations = this.operationsFactory.createOperations(id, target);for(O operation : operations) {OperationKey key=createOperationKey(operation);O last=getLast(indexed.get(key));if (replaceLast && replacedLast.add(key) && last != null) {indexed.get(key).remove(last);}indexed.add(key, operation);}}
其中DiscoveredOperationsFactory定义了@ReadOperation
, @WriteOperation
, or @DeleteOperation方法
private static final Map<OperationType, Class<? extends Annotation>>OPERATION_TYPES;static{Map<OperationType, Class<? extends Annotation>> operationTypes = new EnumMap<>(OperationType.class);operationTypes.put(OperationType.READ, ReadOperation.class);operationTypes.put(OperationType.WRITE, WriteOperation.class);operationTypes.put(OperationType.DELETE, DeleteOperation.class);OPERATION_TYPES=Collections.unmodifiableMap(operationTypes);}private finalParameterValueMapper parameterValueMapper;private final Collection<OperationInvokerAdvisor>invokerAdvisors;DiscoveredOperationsFactory(ParameterValueMapper parameterValueMapper,Collection<OperationInvokerAdvisor>invokerAdvisors) {this.parameterValueMapper =parameterValueMapper;this.invokerAdvisors =invokerAdvisors;}public Collection<O>createOperations(EndpointId id, Object target) {returnMethodIntrospector.selectMethods(target.getClass(),(MetadataLookup<O>) (method) ->createOperation(id, target, method)).values();}privateO createOperation(EndpointId endpointId, Object target, Method method) {returnOPERATION_TYPES.entrySet().stream().map((entry)->createOperation(endpointId, target, method,entry.getKey(), entry.getValue())).filter(Objects::nonNull).findFirst().orElse(null);}
总结:
1.若一个Bean在类上使用@Endpoint注解,并且在方法上使用@ReadOperation
, @WriteOperation
, or @DeleteOperation注解,那么自动可以使用jmx或者http访问,http提供服务的可以是Jersey, Spring MVC或者Spring WebFlux.
2.http提供服务的基本机制
2.1 使用HandlerMapping映射请求2.2 使用HandlerAdapter(自定义)聚合EndPoint,并代理EndPoint的请求。
参考文献
【1】https://terasolunaorg.github.io/guideline/1.0.x/en/Overview/SpringMVCOverview.html
【2】https://docs.spring.io/spring-boot/docs/2.1.2.RELEASE/reference/htmlsingle/#production-ready-enabling
转载于:https://www.cnblogs.com/davidwang456/p/10281420.html
如何做自己的服务监控?spring boot 2.x服务监控揭秘相关推荐
- SpringCloud(8)微服务监控Spring Boot Admin
1.简介 Spring Boot Admin 是一个管理和监控Spring Boot 应用程序的开源软件.Spring Boot Admin 分为 Server 端和 Client 端,Spring ...
- 服务监控 Spring Boot Actuator 介绍
服务监控 Spring Boot Actuator 介绍 1. 概述 在本文中,我们将介绍Spring Boot Actuator.首先介绍一些Actuator的基础知识,然后详细讨论Spring B ...
- 《深入理解 Spring Cloud 与微服务构建》第十五章 微服务监控 Spring Boot Admin
<深入理解 Spring Cloud 与微服务构建>第十五章 微服务监控 Spring Boot Admin 文章目录 <深入理解 Spring Cloud 与微服务构建>第十 ...
- 高级版的 jvisualvm :Spring Boot Admin 监控 Spring Boot 微服务项目
前奏:先说一下 Java VisualVM Java VisualVM 是一个能够监控 JVM 的 jdk 自带的图形化工具: 在 $JAVA_HOME/bin 目录下,可直接运行它. 要想监控远程服 ...
- springboot 创建地址_使用 SpringBoot Admin监控Spring Boot 服务
简介 SpringBoot-Amind是什么?Spring Boot Admin 是一个管理和监控 Spring Boot 应用程序的开源软件.,可监控的信息包含:应用状态.内存.线程.堆栈等等,比较 ...
- Spring Boot之程序性能监控
转载自 Spring Boot之程序性能监控 Spring Boot特别适合团队构建各种可快速迭代的微服务,同时为了减少程序本身监控系统的开发量,Spring Boot提供了actuator模块,可以 ...
- Spring微服务实战第2章 使用Spring Boot构建微服务
第2章 使用Spring Boot构建微服务 基于微服务的架构具有以下特点. 有约束的--微服务具有范围有限的单一职责集.微服务遵循UNIX的理念,即应用程序是服务的集合,每个服务只做一件事,并只做好 ...
- 使用Spring Boot构建微服务(文末福利)
本文主要内容 学习微服务的关键特征 了解微服务是如何适应云架构的 将业务领域分解成一组微服务 使用Spring Boot实现简单的微服务 掌握基于微服务架构构建应用程序的视角 学习什么时候不应该使用微 ...
- Spring boot、微服务、OAuth、OpenID的爱恨情仇!
在本文中,我们学习如何使用Spring boot轻松配置和部署微服务,然后使用OAuth和OpenID保护它们. 在微服务体系架构中,其中较大的应用程序由多个较小的服务组成,每个服务都有自己的目标,它 ...
最新文章
- 数据库的查询,添加,修改,删除
- Replication Controller、Replica Set
- DHCP和DNS的概念—Vecloud微云
- node+Mysql,数据库时区显示正确,查询时却显示另一个时区
- 老师“鬼话”全曝光!哈哈哈哈哈哈全国的老师都这样吗?
- matlab 计算汉明距_matlab实现滑动平均滤波
- css选择器按功能分,CSS 选择器
- C++ STL 一个简单的文件输入输出示例
- SecureCRT+SecureFX 7.1.1.264整合版 - SSH和SFTP客户端
- vscode生成vue模板快捷键_vscode之快速生成vue模板
- 程序员的超大文件下载方法
- Tungsten Fabric中文社区介绍
- js摇号程序_车管所怎么摇号流程及查询
- 远程办公和分布式协作的区别
- 《数字图像处理》题库5:计算题 ①
- 帮忙写一篇关于消防化工指挥作战系统的设计报告
- 古典微分几何 近代微分几何资料
- python基础day-15:time、hash、json
- Shell 字符串转数组的三种方式
- 家电类CCC认证流程
热门文章
- Leetcode114二叉树转链表-树中修改
- spring mybatis 整合jar 包冲突问题
- mysql 日志的存放形式_mysql日志详细解析
- 软件生成目录没有图框_图纸目录和编号
- python如何下载tushare_安装tushare
- php上传图文,php+ajax实现异步上传图文功能详解
- iview select选中值取值_完美解决iview 的select下拉框选项错位的问题
- c语言输入r1 r2垫片的面积,2011学生C语言上机实验
- android Too many open files 解决
- VC包含目录、附加依赖项、库目录及具体设置