<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          給 SpringBoot 服務(wù)添加健康檢查

          共 4025字,需瀏覽 9分鐘

           ·

          2021-11-14 19:49

          引子


          公司的后端服務(wù)基于 SpringBoot 開發(fā),部署在 K8S 集群中。在平時開發(fā)過程中,由于部署頻繁,經(jīng)常導(dǎo)致服務(wù)隊(duì)對外表現(xiàn)為 502 不可用,非常影響前端開發(fā)體驗(yàn)。

          如果服務(wù)長時間不可用,那么前端只能啟用 mock 模式進(jìn)行開發(fā)了。具體做法可以參見《前后端分離開發(fā)中前端需要克服的挑戰(zhàn)》一文。


          盡管前端有辦法,但是作為后端服務(wù),還是得保證服務(wù)的可用性,不能隨意找借口搪塞。



          實(shí)際上,公司的 dev 環(huán)境也在 AWS 集群上,配置并不低,而且需要的話可以繼續(xù)調(diào)高配置。在部署時,觀察 pod 的狀態(tài),的確是滾動更新的。


          之所以在部署時服務(wù)會不可用,是因?yàn)闆]有配置服務(wù)就緒探針,K8S 沒有辦法獲取 pod 里應(yīng)用的狀態(tài),只能檢查 pod 的狀態(tài)。只要 pod 起來了,流量就會路由給它,但這時如果應(yīng)用并未啟動完畢,就會導(dǎo)致對外表現(xiàn)為 502 Bad Gateway。


          因此,要解決這個問題,實(shí)現(xiàn)服務(wù)無宕機(jī)更新,就只需要配置好探針就行了。


          給 SpringBoot 應(yīng)用添加 actuator


          測試


          第一步,先把測試寫好,文檔化我們期待的行為:

          import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.availability.ApplicationAvailability;import org.springframework.boot.availability.AvailabilityChangeEvent;import org.springframework.boot.availability.LivenessState;import org.springframework.boot.availability.ReadinessState;import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.context.ApplicationContext;import org.springframework.test.context.ActiveProfiles;import org.springframework.test.context.junit4.SpringRunner;import org.springframework.test.web.servlet.MockMvc;

          import static org.assertj.core.api.Assertions.assertThat;import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

          @RunWith(SpringRunner.class)@ActiveProfiles("test")@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)@AutoConfigureMockMvcpublic class HealthCheckControllerTest { @Autowired private ApplicationAvailability applicationAvailability; @Autowired private MockMvc mockMvc;

          @Autowired private ApplicationContext context;

          @Test public void testHealthCheck() throws Exception { assertThat(applicationAvailability.getLivenessState()) .isEqualTo(LivenessState.CORRECT);

          mockMvc.perform(get("/healthz/liveness")) .andExpect(status().isOk()) .andExpect(jsonPath("$.status.code").value("UP"));

          AvailabilityChangeEvent.publish(context, ReadinessState.REFUSING_TRAFFIC);

          assertThat(applicationAvailability.getReadinessState()) .isEqualTo(ReadinessState.REFUSING_TRAFFIC); mockMvc.perform(get("/healthz/readiness")) .andExpect(status().isServiceUnavailable()) .andExpect(jsonPath("$.status.code").value("OUT_OF_SERVICE"));

          }}


          添加依賴


          以 maven 項(xiàng)目為例,在 pom 文件中添加:


          <dependency>  <groupId>org.springframework.bootgroupId>  <artifactId>spring-boot-starter-actuatorartifactId>dependency>


          配置項(xiàng)目


          可以在 bootstrap.yml 中增加這樣的配置:


          management:  endpoint:    health:      probes:        enabled: true      livenessState:        enabled: true      readinessState:        enabled: true  endpoints:    web:      base-path: /      path-mapping:        health: healthz


          這時測試可以通過了。也可以本地啟動進(jìn)行手動端到端驗(yàn)證。先啟動:


          mvn clean install && mvn spring-boot:run -pl your-representation-layer


          執(zhí)行:


          curl http://localhost:your-port/healthz/liveness

          curl http://localhost:your-port/healthz/readiness



          在 deployment 文件里配置探針


          在 deployment 文件中增加如下配置項(xiàng):




          readinessProbe: httpGet: path: /healthz/readiness port: 8080 initialDelaySeconds: 30 timeoutSeconds: 10 livenessProbe: httpGet: path: /healthz/liveness port: 8080 initialDelaySeconds: 130 timeoutSeconds: 10


          大功告成,提交本次改動,后面的服務(wù)更新就不會影響前端開發(fā)了。當(dāng)然,這只從運(yùn)維層解決了服務(wù)的可用。對于開發(fā)層面,一定要注意,作為服務(wù)提供者,對于接口的修改,必須保證向前兼容。永遠(yuǎn)不要假設(shè)和要求前端和你同時更新(根本做不到,比如對于微信小程序,發(fā)布后,仍然有最長 24 小時的更新延遲;如果是原生 APP,用戶不一定自動更新的)。


          總結(jié)


          監(jiān)控和可觀測性對于分布式系統(tǒng)至關(guān)重要,這兩點(diǎn)要求系統(tǒng)在運(yùn)行時提供健康檢查機(jī)制。假如現(xiàn)有的系統(tǒng)沒有這個機(jī)制,那么可以參考《利用 Vector 從日志創(chuàng)建指標(biāo)來提高系統(tǒng)的可觀測性》一文,從日志的角度來彌補(bǔ)。然而,正如本文開頭提到的,這依然會影響平時的開發(fā)體驗(yàn),所以,本文詳細(xì)介紹了如何在 SpringBoot 應(yīng)用中增加健康檢查機(jī)制,一來解決了開發(fā)體驗(yàn)問題,二來為后續(xù)捕獲有用的健康指標(biāo)從而與流行的工具集成以提高系統(tǒng)的可觀測性打下了基礎(chǔ)。


          瀏覽 77
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  操鼻免费素材网站 | 亚洲视频欧美视频视频一区 | 五月婷婷网站导航 | 青娱乐在线观看 | 亚洲精品一二三四区 |