Share
Embed
Transcript
33 slides
-
3 ࣗݾհ • ໊લ : ٢ా ๎ / @sinsengumi •
৬ۀ : ιϑτΣΞΤϯδχΞ Web σβΠφʔ ==> ΤϯδχΞ ͖ͳݴޠ Java ! • ॴଐ : ΤϜεϦʔגࣜձࣾ • JJUG 2016 Spring Ͱ Spring Boot ͷΛͨ͠ͷͰɺ ͦͪΒݟ͚ͯΔͱخ͍͠Ͱ͢ʂ https://speakerdeck.com/sinsengumi/spring-boot-application-infrastructure M3 tech meetup! #1 -
4 ࣍ 1. Spring Boot Actuator ʹ͍ͭͯ 2. Spring Boot
Actuator ͷΧελϚΠζํ๏ 3. Spring Boot Actuator ΛΘͣʹγεςϜใΛՄࢹԽ͢Δ 4. Spring Boot Admin M3 tech meetup! #1 -
5 Spring Boot Actuator ʹ͍ͭͯ Spring Boot ͕ Production-ready feature
ͱݺΜͰ͍Δػೳɻ ΞϓϦέʔγϣϯͷঢ়ଶΛϞχλɺཧͰ͖ΔΑ͏ʹͳΔɻ HTTP, JMX, SSH ΛͬͯΞΫηε͕Ͱ͖Δɻ <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> ಋೖ jar ΛೖΕΔ͚ͩʢAuto-configurationʣ M3 tech meetup! #1 -
11 Spring Boot Actuator ͷΧελϚΠζํ๏ • application.properties • endpoints.* Ͱɺ֤
Endpoint ͷઃఆ • management.* ͰɺηΩϡϦςΟઃఆ • Endpoint ΛՃ͢Δ • Endpoint ΠϯλϑΣʔεΛ࣮͢Δ • health Endpoint ʹใΛՃ͢Δ • HealthIndicator ΠϯλϑΣʔεΛ࣮͢Δ • info Endpoint ʹใΛՃ͢ΔʢSpring Boot 1.4.0 ͔Βɻઆ໌ׂѪʣ • InfoContributor ΠϯλϑΣʔεΛ࣮͢Δ M3 tech meetup! #1 -
12 application.propertiesʢ1ʣ M3 tech meetup! #1 # env ༻ෆՄ endpoints.env.enabled=false
# mappings ͷ PATH มߋ endpoints.mappings.id=routers # shutdown ػೳΛ ON endpoints.shutdown.enabled=true # actuator ͷ context-path Λมߋ management.context-path=/api/management # actuator ͷ port Λมߋ management.port=8081 http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/ #common-application-properties -
13 Endpoint ΛՃ͢Δʢ1ʣ M3 tech meetup! #1 EndpointʢAbstractEndpoint<T>ʣΛ࣮͢Δɻ @Component public
class BatchEndpoint extends AbstractEndpoint<List<Map<String, String>>> { public BatchEndpoint() { super("batch"); } @Override public List<Map<String, String>> invoke() { String taskPackage = "net.sinsengumi.springboot.notactuator.task"; ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(true); return provider.findCandidateComponents(taskPackage).stream() .map(bean -> classForName(bean.getBeanClassName())) .flatMap(clazz -> Stream.of(clazz.getDeclaredMethods())) .filter(method -> method.getAnnotation(Scheduled.class) != null) .map(method -> { Scheduled scheduled = method.getAnnotation(Scheduled.class); return ImmutableMap.of( "method", method.toGenericString(), "cron", scheduled.cron()); }) .collect(Collectors.toList()); } } -
14 Endpoint ΛՃ͢Δʢ2ʣ M3 tech meetup! #1 2016-05-29 22:33:07,401 INFO
[restartedMain] o.s.b.a.e.m.EndpointHandlerMapping (534) - Mapped "{[/api/ management/info || /api/management/info.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke() 2016-05-29 22:33:07,402 INFO [restartedMain] o.s.b.a.e.m.EndpointHandlerMapping (534) - Mapped "{[/api/ management/batch || /api/management/batch.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke() 2016-05-29 22:33:07,402 INFO [restartedMain] o.s.b.a.e.m.EndpointHandlerMapping (534) - Mapped "{[/api/ management/autoconfig || /api/management/autoconfig.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke() 2016-05-29 22:33:08,462 INFO [restartedMain] o.s.b.a.e.j.EndpointMBeanExporter (674) - Located managed bean 'batchEndpoint': registering with JMX server as MBean [org.springframework.boot:type=Endpoint,name=batchEndpoint] 2016-05-29 22:33:08,498 INFO [restartedMain] o.s.b.a.e.j.EndpointMBeanExporter (674) - Located managed bean 'requestMappingEndpoint': registering with JMX server as MBean [org.springframework.boot:type=Endpoint,name=requestMappingEndpoint] 2016-05-29 22:33:08,504 INFO [restartedMain] o.s.b.a.e.j.EndpointMBeanExporter (674) - Located managed bean 'environmentEndpoint': registering with JMX server as MBean [org.springframework.boot:type=Endpoint,name=environmentEndpoint] 2016-05-29 22:33:08,508 INFO [restartedMain] o.s.b.a.e.j.EndpointMBeanExporter (674) - Located managed bean 'healthEndpoint': registering with JMX server as MBean [org.springframework.boot:type=Endpoint,name=healthEndpoint] -
17 health Endpoint ʹใΛՃ͢Δʢ1ʣ M3 tech meetup! #1 HealthIndicatorʢAbstractHealthIndicatorʣΛ࣮͢Δɻ @Component
@ConditionalOnProperty(prefix = "management.health.userAccountService", name = "enabled", matchIfMissing = true) public class UserAccountServiceHealthIndicator extends AbstractHealthIndicator { @Autowired private UserAccountService userAccountService; @Override protected void doHealthCheck(Builder builder) throws Exception { if (userAccountService.healthy()) { builder.up().withDetail("version", "1.0.0"); } else { builder.down().withDetail("version", "1.0.0"); } } } -
18 health Endpoint ʹใΛՃ͢Δʢ2ʣ M3 tech meetup! #1 Bean ໊͔Β
“healthIndicator” ΛΓऔͬͨͷ -
19 Spring Boot Actuator ΛΘͣʹՄࢹԽ͢Δ • Spring Boot Actuator ͕ग़Δલʢࢲ͕Βͳ͔͚͔ͬͨͩʣ͔Βɺ
ΦϨΦϨ࣮Ͱ͍ͬͯͨͷͰհ͍͚ͨͩ͠Ͱ͢ɾɾɾ • URL ͱ͔ Play ͷ routers ϑΝΠϧతʹҰཡͰݟ͍ͨ • DI Container ͬͯΔͳΒొ͞ΕͯΔ Bean ͷใݟ͍ͨ • ซͤͯɺSpring Boot Actuator ͕෦Ͱ͍ͬͯΔ͜ͱݟ͍ͯ͘ɻ • ΦϨΦϨ࣮Ͱ͍ͬͯͨ࣌ͱͷࠩ M3 tech meetup! #1 -
@Controller public class RouterController { @Autowired RequestMappingHandlerMapping handlerMapping; @RequestMapping(value =
"/admin/system/router", method = RequestMethod.GET) public String routers(Model model) { model.addAttribute("requestMappingInfos", OriginalRequestMappingInfo.of(handlerMapping)); return "screen/admin/system/router"; } @Data public static class OriginalRequestMappingInfo implements Serializable { private Site site; private Set<RequestMethod> methods; private Set<String> patterns; // লུ public static List<OriginalRequestMappingInfo> of(RequestMappingHandlerMapping handlerMapping) { List<OriginalRequestMappingInfo> result = new ArrayList<OriginalRequestMappingInfo>(); for (Entry<RequestMappingInfo, HandlerMethod> e : handlerMapping.getHandlerMethods().entrySet()) { RequestMappingInfo requestMappingInfo = e.getKey(); // লུ result.add(o); } return result; } } } ΦϨΦϨ࣮ 20 URL ͷՄࢹԽʢ1ʣ M3 tech meetup! #1 άάͬͨΒɺRequestMappingHandlerMapping ͱ͍͏ͷʹ RequestMapping ͷҰཡ͕ೖ͍ͬͯΔΒ͍͠ɻ -
21 URL ͷՄࢹԽʢ2ʣ M3 tech meetup! #1 Actuator ͷ Endpoint
ͷ URL ͱ͔ɺ੩తϦιʔεͷ URL ͱ͔ग़͖ͯͯͳ͍ɻ Actuator ͷ mappings Endpoint Ͱશ෦ग़͍ͯͨɻ ͳΜ͔Γͳ͍ɾɾʁʁ -
22 URL ͷՄࢹԽʢ3ʣ M3 tech meetup! #1 @ConfigurationProperties(prefix = "endpoints.mappings")
public class RequestMappingEndpoint extends AbstractEndpoint<Map<String, Object>> implements ApplicationContextAware { private List<AbstractUrlHandlerMapping> handlerMappings = Collections.emptyList(); private List<AbstractHandlerMethodMapping<?>> methodMappings = Collections.emptyList(); @Override public Map<String, Object> invoke() { Map<String, Object> result = new LinkedHashMap<String, Object>(); extractHandlerMappings(this.handlerMappings, result); extractHandlerMappings(this.applicationContext, result); extractMethodMappings(this.methodMappings, result); extractMethodMappings(this.applicationContext, result); return result; } protected void extractHandlerMappings(// লུ) { // লུ } protected void extractMethodMappings(// লུ) { // লུ } } Actuator ͷ࣮ΛݟͯΈΔʢRequestMappingEndpointʣ -
23 URL ͷՄࢹԽʢ4ʣ M3 tech meetup! #1 Spring MVC ͷ
URL ͱ Controller HandlerMapping Ͱؔ࿈͚ΒΕ͍ͯΔɻ ܧঝؔҎԼɻ ΦϨΦϨΫϥεͰ Inject ͍ͯͨ͠ͷ RequestMappingEndpoint Ͱ List ͱͯ͠ Inject ͍ͯͨ͠ͷ -
24 URL ͷՄࢹԽʢ5ʣ M3 tech meetup! #1 Actuator ͷ HandlerMapping
ΦϨΦϨΫϥεͰ Inject ͍ͯͨ͠ͷɻ ͜ͷ bean ʹࣗͰఆٛͨ͠ @RequestMapping ͕ೖΔ ΦϨΦϨͰ RequestMappingHandlerMapping Λ୯ମͰ Injection ͍ͯͨ͠ҝɺ Actuator ͷ URLʢEndpointHandlerMappingʣ͕ग़ͯ͜ͳ͔ͬͨʢผ Beanʣ List<RequestMappingHandlerMapping> Ͱ Inject ͢Δͱग़ͯ͘Δɻ ʢSpring DI ͷॊೈ͞ͱڧྗ͞ʂʂʣ ※ management.port Ͱผϙʔτʹ͍ͯ͠ΔͱऔಘͰ͖ͳ͍ɻ -
@Controller public class ContextController { @Autowired private ApplicationContext applicationContext; @RequestMapping(value
= "/admin/system/context", method = RequestMethod.GET) public String context(Model model) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) applicationContext.getAutowireCapableBeanFactory(); Map<String, BeanDefinition> beanDefinitions = new LinkedHashMap<>(); for (String bd : registry.getBeanDefinitionNames()) { beanDefinitions.put(bd, registry.getBeanDefinition(bd)); } model.addAttribute("context", applicationContext); model.addAttribute("beanDefinitions", beanDefinitions); return "screen/admin/system/context"; } } ΦϨΦϨ࣮ 26 Bean ͷՄࢹԽʢ1ʣ M3 tech meetup! #1 ApplicationContext ͔Β bean ͷఆٛʢBeanDefinitionʣΛऔಘͰ͖Δɻ ApplicationContext Injection Ͱ͖Δɻ -
[~] curl http://localhost:8080/api/management/beans | grep '"bean"' | wc -l 287
28 Bean ͷՄࢹԽʢ3ʣ M3 tech meetup! #1 ͋ΕɺͳΜ͔͕ҧ͏ɾɾʁʁ Actuator ͷ beans Endpoint ͷํ͕গͳ͍ɻ Կ͔ϑΟϧλ͞Ε͍ͯΔɾɾʁ Actuator ͷ beans Endpoint ΛݟͯΈΔɻ -
29 Bean ͷՄࢹԽʢ4ʣ M3 tech meetup! #1 Actuator ͷ࣮ΛݟͯΈΔʢBeansEndpoint ->
LiveBeansView.generateJsonʣ protected String generateJson(Set<ConfigurableApplicationContext> contexts) { for (Iterator<ConfigurableApplicationContext> it = contexts.iterator(); it.hasNext();) { ConfigurableApplicationContext context = it.next(); // লུ ConfigurableListableBeanFactory bf = context.getBeanFactory(); String[] beanNames = bf.getBeanDefinitionNames(); for (String beanName : beanNames) { BeanDefinition bd = bf.getBeanDefinition(beanName); if (isBeanEligible(beanName, bd, bf)) { // লུ } } // লུ } return result.toString(); } protected boolean isBeanEligible(String beanName, BeanDefinition bd, ConfigurableBeanFactory bf) { return (bd.getRole() != BeanDefinition.ROLE_INFRASTRUCTURE && (!bd.isLazyInit() || bf.containsSingleton(beanName))); } Role.INFRASTRUCTURE ͱ͔ @Lazy ͱ͔ͰϑΟϧλ͞Ε͍ͯΔ -
30 Bean ͷՄࢹԽʢ5ʣ M3 tech meetup! #1 ͱ͍͏͜ͱͰɺΦϨΦϨͱ Actuator Ͱඍົͳࠩҟ͕͋Δ͜ͱ͕Θ͔Γ·ͨ͠ɻ
Actuator Ͱ Role.INFRASTRUCTURE (= 2 ) ͕ϑΟϧλ͞Ε͍ͯͨ -
31 Spring Boot Admin υΠπͷ codesentric ͱ͍͏ձ͕ࣾ࡞͍ͬͯΔɻ ෳͷ Spring Boot
ΞϓϦΛཧ͢Δ UI Λఏڙͯ͘͠ΕΔɻ https://github.com/codecentric/spring-boot-admin M3 tech meetup! #1 -
33 ·ͱΊ M3 tech meetup! #1 • Spring Boot Actuator
ศརɻΞϓϦͷ͜ͱΞϓϦʹฉ͘ͷ͕Ұ൪ɻ URL Ұཡͱ͔ͷ Excel ͍ΒΜ͔ͬͨΜɻ • த DI ίϯςφ͔ΒใΛऔͬͯ͘Δͱ͍͏ Spring Β͍͠Γํͱɺ Auto-configuration Ͱ࣮͞Ε͍ͯΔɻ • Spring Boot ΞϓϦͷ্ཱ͕ͪ͛؆୯ա͗ΔͷͰɺ Spring Boot Admin ͱ͍͏ཧΞϓϦग़͖ͯͨɻ