Slide 1

Slide 1 text

M3 tech meetup! #1 Spring Boot ΞϓϦͷγεςϜ৘ใΛ ՄࢹԽ͢Δʢnot Actuatorʣ ٢ా ๎໵ʢΤϜεϦʔגࣜձࣾʣ

Slide 2

Slide 2 text

M3 tech meetup! #1 ຊ೔͸ M3 tech meetup! ʹ ͓ӽ͠௖͖ɺ੣ʹ͋Γ͕ͱ͏͍͟͝·͢ʂ

Slide 3

Slide 3 text

3 ࣗݾ঺հ • ໊લ : ٢ా ๎໵ / @sinsengumi • ৬ۀ : ιϑτ΢ΣΞΤϯδχΞ
 Web σβΠφʔ ==> ΤϯδχΞ
 ޷͖ͳݴޠ͸ Java ! • ॴଐ : ΤϜεϦʔגࣜձࣾ • JJUG 2016 Spring Ͱ Spring Boot ͷ࿩Λͨ͠ͷͰɺ
 ͦͪΒ΋ݟͯ௖͚Δͱخ͍͠Ͱ͢ʂ
 https://speakerdeck.com/sinsengumi/spring-boot-application-infrastructure M3 tech meetup! #1

Slide 4

Slide 4 text

4 ໨࣍ 1. Spring Boot Actuator ʹ͍ͭͯ 2. Spring Boot Actuator ͷΧελϚΠζํ๏ 3. Spring Boot Actuator Λ࢖ΘͣʹγεςϜ৘ใΛՄࢹԽ͢Δ 4. Spring Boot Admin M3 tech meetup! #1

Slide 5

Slide 5 text

5 Spring Boot Actuator ʹ͍ͭͯ Spring Boot ͕ Production-ready feature ͱݺΜͰ͍Δػೳɻ ΞϓϦέʔγϣϯͷঢ়ଶΛϞχλɺ؅ཧͰ͖ΔΑ͏ʹͳΔɻ HTTP, JMX, SSH Λ࢖ͬͯΞΫηε͕Ͱ͖Δɻ org.springframework.boot spring-boot-starter-actuator ಋೖ͸ jar ΛೖΕΔ͚ͩʢAuto-configurationʣ M3 tech meetup! #1

Slide 6

Slide 6 text

6 Endpoints : mappings @RequestMapping ͷҰཡΛදࣔ͢Δɻ M3 tech meetup! #1

Slide 7

Slide 7 text

7 Endpoints : beans Spring Bean ͷҰཡΛදࣔ͢Δɻ M3 tech meetup! #1

Slide 8

Slide 8 text

8 Endpoints : env ϓϩύςΟͷҰཡΛදࣔ͢Δɻ M3 tech meetup! #1

Slide 9

Slide 9 text

9 Endpoints : health ϔϧενΣοΫͷ৘ใΛදࣔ͢Δɻ M3 tech meetup! #1 ϛυϧ΢ΣΞ΋ରԠ͍ͯ͠Δ΋ͷ͕͋Ε͹ɺ ࣗಈͰ௥Ճͯ͘͠ΕΔɻ

Slide 10

Slide 10 text

10 M3 tech meetup! #1

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

13 Endpoint Λ௥Ճ͢Δʢ1ʣ M3 tech meetup! #1 EndpointʢAbstractEndpointʣΛ࣮૷͢Δɻ @Component public class BatchEndpoint extends AbstractEndpoint>> { public BatchEndpoint() { super("batch"); } @Override public List> 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()); } }

Slide 14

Slide 14 text

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]

Slide 15

Slide 15 text

15 Endpoint Λ௥Ճ͢Δʢ3ʣ M3 tech meetup! #1

Slide 16

Slide 16 text

16 Endpoint Λ௥Ճ͢Δʢ4ʣ M3 tech meetup! #1

Slide 17

Slide 17 text

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"); } } }

Slide 18

Slide 18 text

18 health Endpoint ʹ৘ใΛ௥Ճ͢Δʢ2ʣ M3 tech meetup! #1 Bean ໊͔Β “healthIndicator” Λ੾Γऔͬͨ΋ͷ

Slide 19

Slide 19 text

19 Spring Boot Actuator Λ࢖ΘͣʹՄࢹԽ͢Δ • Spring Boot Actuator ͕ग़Δલʢࢲ͕஌Βͳ͔͚͔ͬͨͩ΋ʣ͔Βɺ
 ΦϨΦϨ࣮૷Ͱ΍͍ͬͯͨͷͰ঺հ͍͚ͨͩ͠Ͱ͢ɾɾɾ • URL ͱ͔ Play ͷ routers ϑΝΠϧతʹҰཡͰݟ͍ͨ • DI Container ࢖ͬͯΔͳΒొ࿥͞ΕͯΔ Bean ͷ৘ใݟ͍ͨ • ซͤͯɺSpring Boot Actuator ͕಺෦Ͱ΍͍ͬͯΔ͜ͱ΋ݟ͍ͯ͘ɻ • ΦϨΦϨ࣮૷Ͱ΍͍ͬͯͨ࣌ͱͷࠩ෼ M3 tech meetup! #1

Slide 20

Slide 20 text

@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 methods; private Set patterns; // লུ public static List of(RequestMappingHandlerMapping handlerMapping) { List result = new ArrayList(); for (Entry e : handlerMapping.getHandlerMethods().entrySet()) { RequestMappingInfo requestMappingInfo = e.getKey(); // লུ result.add(o); } return result; } } } ΦϨΦϨ࣮૷ 20 URL ͷՄࢹԽʢ1ʣ M3 tech meetup! #1 άάͬͨΒɺRequestMappingHandlerMapping ͱ͍͏ͷʹ RequestMapping ͷҰཡ͕ೖ͍ͬͯΔΒ͍͠ɻ

Slide 21

Slide 21 text

21 URL ͷՄࢹԽʢ2ʣ M3 tech meetup! #1 Actuator ͷ Endpoint ͷ URL ͱ͔ɺ੩తϦιʔεͷ URL ͱ͔ग़͖ͯͯͳ͍ɻ Actuator ͷ mappings Endpoint Ͱ͸શ෦ग़͍ͯͨɻ ͳΜ͔଍Γͳ͍ɾɾʁʁ

Slide 22

Slide 22 text

22 URL ͷՄࢹԽʢ3ʣ M3 tech meetup! #1 @ConfigurationProperties(prefix = "endpoints.mappings") public class RequestMappingEndpoint extends AbstractEndpoint> implements ApplicationContextAware { private List handlerMappings = Collections.emptyList(); private List> methodMappings = Collections.emptyList(); @Override public Map invoke() { Map result = new LinkedHashMap(); 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ʣ

Slide 23

Slide 23 text

23 URL ͷՄࢹԽʢ4ʣ M3 tech meetup! #1 Spring MVC ͷ URL ͱ Controller ͸ HandlerMapping Ͱؔ࿈෇͚ΒΕ͍ͯΔɻ ܧঝؔ܎͸ҎԼɻ ΦϨΦϨΫϥεͰ Inject ͍ͯͨ͠΋ͷ RequestMappingEndpoint Ͱ List ͱͯ͠ Inject ͍ͯͨ͠΋ͷ

Slide 24

Slide 24 text

24 URL ͷՄࢹԽʢ5ʣ M3 tech meetup! #1 Actuator ͷ HandlerMapping ΦϨΦϨΫϥεͰ Inject ͍ͯͨ͠΋ͷɻ ͜ͷ bean ʹ͸ࣗ෼Ͱఆٛͨ͠ @RequestMapping ͕ೖΔ ΦϨΦϨͰ͸ RequestMappingHandlerMapping Λ୯ମͰ Injection ͍ͯͨ͠ҝɺ Actuator ͷ URLʢEndpointHandlerMappingʣ͕ग़ͯ͜ͳ͔ͬͨʢผ Beanʣ List Ͱ Inject ͢Δͱग़ͯ͘Δɻ ʢSpring DI ͷॊೈ͞ͱڧྗ͞ʂʂʣ ※ management.port Ͱผϙʔτʹ͍ͯ͠ΔͱऔಘͰ͖ͳ͍ɻ

Slide 25

Slide 25 text

25 URL ͷՄࢹԽʢ6ʣ M3 tech meetup! #1 ͱ͍͏͜ͱͰɺΦϨΦϨ͸࿙Ε͕͋Δ͜ͱ͕Θ͔Γ·ͨ͠ɻ

Slide 26

Slide 26 text

@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 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 Ͱ͖Δɻ

Slide 27

Slide 27 text

27 Bean ͷՄࢹԽʢ2ʣ M3 tech meetup! #1 309ݸ

Slide 28

Slide 28 text

[~] 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 ΛݟͯΈΔɻ

Slide 29

Slide 29 text

29 Bean ͷՄࢹԽʢ4ʣ M3 tech meetup! #1 Actuator ͷ࣮૷ΛݟͯΈΔʢBeansEndpoint -> LiveBeansView.generateJsonʣ protected String generateJson(Set contexts) { for (Iterator 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 ͱ͔ͰϑΟϧλ͞Ε͍ͯΔ

Slide 30

Slide 30 text

30 Bean ͷՄࢹԽʢ5ʣ M3 tech meetup! #1 ͱ͍͏͜ͱͰɺΦϨΦϨͱ Actuator Ͱඍົͳࠩҟ͕͋Δ͜ͱ͕Θ͔Γ·ͨ͠ɻ Actuator Ͱ͸ Role.INFRASTRUCTURE (= 2 ) ͕ϑΟϧλ͞Ε͍ͯͨ

Slide 31

Slide 31 text

31 Spring Boot Admin υΠπͷ codesentric ͱ͍͏ձ͕ࣾ࡞͍ͬͯΔɻ ෳ਺ͷ Spring Boot ΞϓϦΛ؅ཧ͢Δ UI Λఏڙͯ͘͠ΕΔɻ https://github.com/codecentric/spring-boot-admin M3 tech meetup! #1

Slide 32

Slide 32 text

32 Spring Boot Admin σϞ M3 tech meetup! #1 ʢ͕࣌ؒ͋Ε͹ʣ

Slide 33

Slide 33 text

33 ·ͱΊ M3 tech meetup! #1 • Spring Boot Actuator ศརɻΞϓϦͷ͜ͱ͸ΞϓϦʹฉ͘ͷ͕Ұ൪ɻ
 URL Ұཡͱ͔ͷ Excel ͸͍ΒΜ͔ͬͨΜ΍ɻ • த਎͸ DI ίϯςφ͔Β৘ใΛऔͬͯ͘Δͱ͍͏ Spring Β͍͠΍Γํͱɺ
 Auto-configuration Ͱ࣮૷͞Ε͍ͯΔɻ • Spring Boot ΞϓϦͷ্ཱ͕ͪ͛؆୯ա͗ΔͷͰɺ
 Spring Boot Admin ͱ͍͏؅ཧΞϓϦ΋ग़͖ͯͨɻ