Slide 1

Slide 1 text

Spring Boot 2.3ͷ Liveness & Readiness Probes ରԠ ʹ͍ͭͯௐ΂ͯΈͨ 2020/07/30ʮJSUGษڧձ 2020೥ͦͷ6 LTେձʂʯ#jsug @otty_375

Slide 2

Slide 2 text

ࣗݾ঺հ • ͍͚(@otty_375) • WebΤϯδχΞ • ۀ຿ͰSpringΛ࢖ͬͯ·͢

Slide 3

Slide 3 text

Liveness & Readiness Probes ରԠͷ֓ཁ • ΞϓϦέʔγϣϯͷՄ༻ੑͷঢ়ଶΛ؅ཧ͢Δ࢓૊Έ͕ಋೖ͞Εͨ • LivenessɿΞϓϦέʔγϣϯͷ಺෦ঢ়ଶ͕ਖ਼ৗ͔ • ReadinessɿτϥϑΟοΫΛॲཧͰ͖Δ४උ͕׬͍ྃͯ͠Δ͔ • Spring Boot ActuatorͷϔϧενΣοΫͰঢ়ଶΛऔಘͰ͖Δ • Kubernetes؀ڥʹݶΒͣଞͷσϓϩΠ؀ڥͰ΋Livenessͱ Readinessͷ֓೦ࣗମ͸׆༻Ͱ͖Δ

Slide 4

Slide 4 text

ΞϓϦέʔγϣϯىಈϑΣʔζ ʹ͓͚ΔՄ༻ੑͷঢ়ଶ ΞϓϦέʔγϣϯͷ ىಈϑΣʔζ LivenessState ReadinessState ϔϧενΣοΫ݁Ռ starting BROKEN REFUSING_TRAFFIC DOWN started CORRECT REFUSING_TRAFFIC OUT_OF_SERVICE ready CORRECT ACCEPTING_TRAFFIC UP • LivenessState: CORRECT / BROKEN • ReadinessState: ACCEPTING_TRAFFIC / REFUSING_TRAFFIC

Slide 5

Slide 5 text

ΞϓϦέʔγϣϯىಈ࣌ͷ ঢ়ଶ͕มΘΔλΠϛϯά 1. ApplicationStartingEventɿΞϓϦέʔγϣϯىಈ࣌ͷॲཧͷ։࢝લ 2. ApplicationEnvironmentPreparedEventɿར༻͢ΔEnvironment͕ಛఆ͞Εͨޙ 3. ApplicationContextInitializedEventɿApplicationContext͕༻ҙ͞Εͨޙ 4. ApplicationPreparedEventɿBeanఆ͕ٛϩʔυ͞Εͨޙ 5. ApplicationStartedEventɿApplicationContext͕ϦϑϨογϡ͞Εͨޙ 6. AvailabilityChangeEvent (LivenessState.CORRECT)ɿApplicationStartedEventͷޙ 7. ApplicationReadyEventɿApplicationRunnerͱCommandLineRunner͕ݺ͹Εͨޙ 8. AvailabilityChangeEvent (ReadinessState.ACCEPTING_TRAFFIC)ɿ ApplicationReadyEventͷޙ

Slide 6

Slide 6 text

ϔϧενΣοΫ༗ޮԽઃఆํ๏ • Kubernetes؀ڥɿࣗಈͰ༗ޮʹͳΔ • ͦΕҎ֎ͷ؀ڥɿҎԼͷ͍ͣΕ͔ͷઃఆΛ௥Ճ # NEW! Spring Boot 2.3.2 ͔Β͸ίϨ management.endpoint.health.probes.enabled=true # Spring Boot 2.3.1·Ͱ management.health.probes.enabled=true # ໌ࣔతʹKubernetes؀ڥͩͱࢦఆ͢Δύλʔϯ spring.main.cloud-platform=kubernetes

Slide 7

Slide 7 text

ࢼͯ͠Έͨ • ༻ҙͨ͠αϯϓϧΞϓϦέʔγϣϯ • Spring Boot 2.3.2 • Dependencies: Web, Actuator • σϑΥϧτͷϔϧενΣοΫର৅͸diskSpace, pingͷΈ • ApplicationEventͷϦεφʔΛ௥Ճ͠ϩάʹॻ͖ग़͢ • ΞϓϦέʔγϣϯىಈதʹϔϧενΣοΫΤϯυϙΠϯτΛୟ͍ͯ ͲͷλΠϛϯάͰεςʔλε͕มΘΔ͔Λ֬ೝ

Slide 8

Slide 8 text

ࢼͯ͠Έͨʢઃఆͳ͠ͷ৔߹ʣ ࣌ࠁ ग़དྷࣄ 23:42:42.381 SpringApplicationىಈॲཧ։࢝ 23:42:48.308 ϔϧενΣοΫεςʔλε͕UPͰฦͬͯ͘ΔΑ͏ʹͳΔ ʢνΣοΫର৅ͷdiskSpace, ping͕UPεςʔλεͰฦͬͯདྷΔͨΊʣ 23:42:48.395 ApplicationStartedEventൃੜ 23:42:48.498 AvailabilityChangeEventൃੜ livenessState͕CORRECTʹมΘΔ 23:42:48.502 ApplicationReadyEventൃੜ 23:42:48.503 AvailabilityChangeEventൃੜ readinessState͕ACCEPTING_TRAFFICʹมΘΔ ΞϓϦέʔγϣϯ͸·ͩ SFBEZͳঢ়ଶͰ͸ͳ͍͕ ϔϧενΣοΫ͸61ʹͳΔ

Slide 9

Slide 9 text

ࢼͯ͠Έͨʢઃఆ͋Γͷ৔߹ʣ ࣌ࠁ ग़དྷࣄ 23:21:58.839 SpringApplicationىಈॲཧ։࢝ 23:22:05.789 ϔϧενΣοΫεςʔλε͕DOWNͰฦͬͯ͘ΔΑ͏ʹͳΔ ʢlivenessState͕DOWN, readinessState͕OUT_OF_SERVICEʣ 23:22:05.877 ApplicationStartedEventൃੜ 23:22:06.030 AvailabilityChangeEventൃੜ livenessState͕CORRECTʹมΘΔ 23:22:06.034 ApplicationReadyEventൃੜ 23:22:06.039 AvailabilityChangeEventൃੜ readinessState͕ACCEPTING_TRAFFICʹมΘΔ 23:22:06.110 ϔϧενΣοΫεςʔλε͕UPͰฦͬͯ͘ΔΑ͏ʹͳΔ ʢlivenessState͕UP, readinessState͕UPʣ ΞϓϦέʔγϣϯ͕SFBEZͳ ঢ়ଶʹͳ͔ͬͯΒ ϔϧενΣοΫ͕61ʹͳΔ

Slide 10

Slide 10 text

ίʔυΛ௥ͬͯΈͨ ʢ2.3.2.RELEASEʣ ΞϓϦέʔγϣϯىಈ࣌ͷॲཧΛ௥ͬͨ 1. αϯϓϧΞϓϦέʔγϣϯͷmainϝιου 2. SpringApplicationͷrunϝιου 3. SpringApplicationRunListenersͷstarted, runningϝιου 4. EventPublishingRunListenerͷstarted, runningϝιουͰ AvailabilityChangeEventΠϕϯτൃߦ 5. ApplicationAvailabilityBeanͷonApplicationEventϝιουͰΠϕϯτݕ஌

Slide 11

Slide 11 text

1. αϯϓϧΞϓϦέʔγϣϯͷ mainϝιου @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } • Application.java

Slide 12

Slide 12 text

2. SpringApplicationͷ runϝιου • SpringApplication.javaʢҰ෦ൈਮʣ public ConfigurableApplicationContext run(String... args) { // লུʢΞϓϦέʔγϣϯىಈ࣌ͷॲཧ͕ॱʹߦΘΕ͍ͯΔʣ SpringApplicationRunListeners listeners = getRunListeners(args); // … try { // … listeners.started(context); // … } // … try { listeners.running(context); } // … return context; }

Slide 13

Slide 13 text

3. SpringApplicationRunListenersͷ started, runningϝιου • SpringApplicationRunListeners.javaʢҰ෦ൈਮʣ private final List listeners; void started(ConfigurableApplicationContext context) { for (SpringApplicationRunListener listener : this.listeners) { listener.started(context); } } void running(ConfigurableApplicationContext context) { for (SpringApplicationRunListener listener : this.listeners) { listener.running(context); } }

Slide 14

Slide 14 text

4. EventPublishingRunListenerͷ started, runningϝιου • EventPublishingRunListener.javaʢҰ෦ൈਮʣ public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered { @Override public void started(ConfigurableApplicationContext context) { context.publishEvent(new ApplicationStartedEvent(this.application, this.args, context)); AvailabilityChangeEvent.publish(context, LivenessState.CORRECT); } @Override public void running(ConfigurableApplicationContext context) { context.publishEvent(new ApplicationReadyEvent(this.application, this.args, context)); AvailabilityChangeEvent.publish(context, ReadinessState.ACCEPTING_TRAFFIC); } } "WBJMBCJMJUZ$IBOHF&WFOUΛൃߦ

Slide 15

Slide 15 text

5. ApplicationAvailabilityBeanͷ onApplicationEventϝιου • ApplicationAvailabilityBean.javaʢҰ෦ൈਮʣ public class ApplicationAvailabilityBean implements ApplicationAvailability, ApplicationListener> { private final Map, AvailabilityChangeEvent>> events = new HashMap<>(); @Override public void onApplicationEvent(AvailabilityChangeEvent> event) { Class extends AvailabilityState> stateType = getStateType(event.getState()); this.events.put(stateType, event); } @Override public S getState(Class stateType, S defaultState) { Assert.notNull(stateType, "StateType must not be null"); Assert.notNull(defaultState, "DefaultState must not be null"); S state = getState(stateType); return (state != null) ? state : defaultState; } // … } ΠϕϯτΛݕ஌͠ ಺෦Ͱঢ়ଶΛอ࣋

Slide 16

Slide 16 text

ঢ়ଶͷऔಘ • ApplicationAvailability.javaʢҰ෦ൈਮʣ public interface ApplicationAvailability { default LivenessState getLivenessState() { return getState(LivenessState.class, LivenessState.BROKEN); } default ReadinessState getReadinessState() { return getState(ReadinessState.class, ReadinessState.REFUSING_TRAFFIC); } S getState(Class stateType, S defaultState); S getState(Class stateType); AvailabilityChangeEvent getLastChangeEvent(Class stateType); }

Slide 17

Slide 17 text

ঢ়ଶͷऔಘʢྫʣ • ApplicationAvailabilityΛDIͯ͠औಘ • private final ApplicationAvailability applicationAvailability; public void sample() { applicationAvailability.getLivenessState(); applicationAvailability.getReadinessState(); }

Slide 18

Slide 18 text

ঢ়ଶͷมߋʢྫʣ • AvailabilityChangeEventΛൃߦ • private final ApplicationEventPublisher publisher; public void sample() { try { // Կ͔͠Βͷॲཧ } catch (SampleException e) { AvailabilityChangeEvent.publish(publisher, e,ReadinessState.REFUSING_TRAFFIC); } }

Slide 19

Slide 19 text

·ͱΊˍײ૝ • ΞϓϦέʔγϣϯͷՄ༻ੑͷঢ়ଶΛ؅ཧ͢Δ࢓૊Έ͕ಋೖ͞Εͨ • LivenessStateͱReadinessStateΛϔϧενΣοΫʹؚΊΔʹ͸ɹ ࣗಈ΋͘͠͸1ߦઃఆΛ௥Ճ͢Δ͚ͩͰOK • ΞϓϦέʔγϣϯىಈ࣌ͷঢ়ଶมߋͷλΠϛϯάΛ஌Δʹ͸ɹɹ ॲཧͷྲྀΕΛཧղ͢Δ͜ͱ͕େ੾ • ΄ͱΜͲͷ৘ใ͸ެࣜυΩϡϝϯτʹॻ͍ͯ͋Δ͕ɺɹɹɹɹɹ ϩάΛॻ͖ग़ͨ͠ΓίʔυΛ௥͏͜ͱͰཧղ͕ਂ·ͬͨ

Slide 20

Slide 20 text

ࢀߟࢿྉ • Liveness and Readiness Probes with Spring Boot • https://spring.io/blog/2020/03/25/liveness-and-readiness-probes-with-spring-boot • Spring Boot 2.3.2 available now • https://spring.io/blog/2020/07/24/spring-boot-2-3-2-available-now • Application Availability • https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot- features.html#boot-features-application-availability • Kubernetes Probes • https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready- features.html#production-ready-kubernetes-probes

Slide 21

Slide 21 text

ऴΘΓ