如何做自己的服务监控?spring boot 2.x服务监控揭秘
Actuator是spring boot項(xiàng)目中非常強(qiáng)大一個功能,有助于對應(yīng)用程序進(jìn)行監(jiān)視和管理,通過?restful api請求來監(jiān)管、審計(jì)、收集應(yīng)用的運(yùn)行情況,針對微服務(wù)而言它是必不可少的一個環(huán)節(jié)。
spring 2.x actuator相對于spring 1.x actuator做了較大的改變。
如何做自己的服務(wù)監(jiān)控?spring boot 1.x服務(wù)監(jiān)控揭秘
?****提供了更多的endpoint管理
| auditevents | Exposes audit events information for the current application. | Yes |
| beans | Displays a complete list of all the Spring beans in your application. | Yes |
| caches | Exposes available caches. | Yes |
| conditions | Shows the conditions that were evaluated on configuration and auto-configuration classes and the reasons why they did or did not match. | Yes |
| configprops | Displays a collated list of all?@ConfigurationProperties. | Yes |
| env | Exposes properties from Spring’s?ConfigurableEnvironment. | Yes |
| flyway | Shows any Flyway database migrations that have been applied. | Yes |
| health | Shows application health information. | Yes |
| httptrace | Displays HTTP trace information (by default, the last 100 HTTP request-response exchanges). | Yes |
| info | Displays arbitrary application info. | Yes |
| integrationgraph | Shows the Spring Integration graph. | Yes |
| loggers | Shows and modifies the configuration of loggers in the application. | Yes |
| liquibase | Shows any Liquibase database migrations that have been applied. | Yes |
| metrics | Shows ‘metrics’ information for the current application. | Yes |
| mappings | Displays a collated list of all?@RequestMapping?paths. | Yes |
| scheduledtasks | Displays the scheduled tasks in your application. | Yes |
| sessions | 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 |
| shutdown | Lets the application be gracefully shutdown. | No |
| threaddump | 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:
| heapdump | Returns an?hprof?heap dump file. | Yes |
| jolokia | Exposes JMX beans over HTTP (when Jolokia is on the classpath, not available for WebFlux). | Yes |
| logfile | Returns the contents of the logfile (if?logging.file?or?logging.path?properties have been set). Supports the use of the HTTP?Range?header to retrieve part of the log file’s content. | Yes |
| prometheus | 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
*********內(nèi)部實(shí)現(xiàn)也發(fā)生了較大的變化,使用micrometer第三方工具來完成metric的實(shí)現(xiàn)。下面我們就親自看看吧!
1.準(zhǔn)備源碼
https://github.com/tjanusz-personal/springbootrestdemo/tree/master/src/main/java/com/demo/springbootrestdemo
2.導(dǎo)入并啟動項(xiàng)目
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \\\/ ___)| |_)| | | | | || (_| | ) ) ) )' |____| .__|_| |_|_| |_\__, | / / / /=========|_|==============|___/=/_/_/_/:: 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] > :bootRun3.獲取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@ConditionalOnMissingBeanpublic WebMvcEndpointHandlerMapping 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 = new EndpointMapping(webEndpointProperties.getBasePath());return new WebMvcEndpointHandlerMapping(endpointMapping, webEndpoints,endpointMediaTypes, corsProperties.toCorsConfiguration(),new EndpointLinksResolver(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* {@link ReadOperation @ReadOperation}, {@link WriteOperation @WriteOperation},* {@link DeleteOperation @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* {@link FilteredEndpoint filtered} to a certain technology, or provide* {@link EndpointExtension extension} for the broader endpoint.** @author Andy Wilkinson* @author Phillip Webb* @since 2.0.0* @see EndpointExtension* @see FilteredEndpoint* @see EndpointDiscoverer*/使用了@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);return convertToEndpoints(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() + "'");}}return byId.values();}private EndpointBean createEndpointBean(String beanName) {Object bean = this.applicationContext.getBean(beanName);return new EndpointBean(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的流程復(fù)習(xí)
其中:
?第2步獲取HandlerMapping,其層次結(jié)構(gòu)
其中RequestMappingHandlerMapping用來處理@RequestMapping注解
private RequestMappingInfo 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,其層次結(jié)構(gòu)
?
默認(rèn)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.RequestMappingHandlerAdapter3.3.1 獲取WebMvcEndpointHandlerMapping
/*** Creates a new {@code WebMvcEndpointHandlerMapping} instance that provides mappings* for the given endpoints.* @param endpointMapping the base mapping for all endpoints* @param endpoints the web endpoints* @param endpointMediaTypes media types consumed and produced by the endpoints* @param corsConfiguration the CORS configuration for the endpoints or {@code null}* @param linksResolver resolver for determining links to available endpoints*/public WebMvcEndpointHandlerMapping(EndpointMapping endpointMapping,Collection<ExposableWebEndpoint> endpoints,EndpointMediaTypes endpointMediaTypes, CorsConfiguration corsConfiguration,EndpointLinksResolver linksResolver) {super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration);this.linksResolver = linksResolver;setOrder(-100);}父類實(shí)現(xiàn)了initHandlerMethods()
@Overrideprotected void initHandlerMethods() {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 void registerMappingForOperation(ExposableWebEndpoint endpoint,WebOperation operation) {ServletWebOperation servletWebOperation = wrapServletWebOperation(endpoint,operation, new ServletWebOperationAdapter(operation));registerMapping(createRequestMappingInfo(operation),new OperationHandler(servletWebOperation), this.handleMethod);}/*** Hook point that allows subclasses to wrap the {@link ServletWebOperation} before* it's called. Allows additional features, such as security, to be added.* @param endpoint the source endpoint* @param operation the source operation* @param servletWebOperation the servlet web operation to wrap* @return a wrapped servlet web operation*/protected ServletWebOperation wrapServletWebOperation(ExposableWebEndpoint endpoint,WebOperation operation, ServletWebOperation servletWebOperation) {return servletWebOperation;}private RequestMappingInfo createRequestMappingInfo(WebOperation operation) {WebOperationRequestPredicate predicate = operation.getRequestPredicate();PatternsRequestCondition patterns = patternsRequestConditionForPattern(predicate.getPath());RequestMethodsRequestCondition methods = new RequestMethodsRequestCondition(RequestMethod.valueOf(predicate.getHttpMethod().name()));ConsumesRequestCondition consumes = new ConsumesRequestCondition(StringUtils.toStringArray(predicate.getConsumes()));ProducesRequestCondition produces = new ProducesRequestCondition(StringUtils.toStringArray(predicate.getProduces()));return new RequestMappingInfo(null, patterns, methods, null, null, consumes,produces, null);}?3.3.2?獲取ServletWebOperationAdapter?
AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle
@Overridepublic Object handle(HttpServletRequest request,@RequestBody(required = false) Map<String, String> body) {Map<String, Object> arguments = getArguments(request, body);try {return handleResult(this.operation.invoke(new InvocationContext(new ServletSecurityContext(request), arguments)),HttpMethod.valueOf(request.getMethod()));}catch (InvalidEndpointRequestException ex) {throw new BadOperationRequestException(ex.getReason());}}4.觸發(fā)機(jī)制
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);return convertToEndpoints(endpointBeans);}調(diào)用?@ReadOperation,?@WriteOperation, or?@DeleteOperation方法
private void addOperations(MultiValueMap<OperationKey, O> indexed, EndpointId id,Object target, boolean replaceLast) {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 final ParameterValueMapper 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) {return MethodIntrospector.selectMethods(target.getClass(),(MetadataLookup<O>) (method) -> createOperation(id, target, method)).values();}private O createOperation(EndpointId endpointId, Object target, Method method) {return OPERATION_TYPES.entrySet().stream().map((entry) -> createOperation(endpointId, target, method,entry.getKey(), entry.getValue())).filter(Objects::nonNull).findFirst().orElse(null);}總結(jié):
1.若一個Bean在類上使用@Endpoint注解,并且在方法上使用@ReadOperation,?@WriteOperation, or?@DeleteOperation注解,那么自動可以使用jmx或者h(yuǎn)ttp訪問,http提供服務(wù)的可以是Jersey, Spring MVC或者Spring WebFlux.
2.http提供服務(wù)的基本機(jī)制
2.1 使用HandlerMapping映射請求2.2 使用HandlerAdapter(自定義)聚合EndPoint,并代理EndPoint的請求。
參考文獻(xiàn)
【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
轉(zhuǎn)載于:https://www.cnblogs.com/davidwang456/p/10281420.html
總結(jié)
以上是生活随笔為你收集整理的如何做自己的服务监控?spring boot 2.x服务监控揭秘的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: web框架的前生今世--从servlet
- 下一篇: 经济学人使用Golang构建微服务历程回