記錄Redis事故影響API性能-下篇

背景

  • 線上服務報大量的Redis,相關依賴這個服務的其餘產品線服務也報出一樣的日誌。
"Could not get a resource from the pool  org.springframework.data.redis.RedisConnectionFailureException: Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool" 和 "Connect timed out」 
複製代碼
  • 截圖線上日誌

image

爲何要寫這篇文章

  • 在個人上篇文章中 《記錄Redis事故影響API性能-上篇》 因爲時間的問題遺留了一個問題沒有解釋清楚
  • 咱們在解決線上問題時如何能快速的定位問題和如何根據相關日誌思考問題是如何發生的-經過個人理解嘗試解釋一下這個問題

由於我我的的能力和精力有限,若是有任何不對或者須要完善的地方,請幫忙指出!java

分析

《記錄Redis事故影響API性能-上篇》 這篇文章中解決方法中第一個想到的是和運維確認redis 問題和拋出了若是咱們哨兵模式當中若是一個節點掛掉會不會出現 獲取不到鏈接池和超時呢?redis

  • 咱們先來分析一下節點掛掉會不會出現問題,我經過分析jedis 源碼 答案是 即便掛掉一個節點不會出現鏈接池獲取不到和超時,下面咱們一步一步來分析:spring

    • 第一步:咱們的redis 環境是基於哨兵模式,因此咱們只看JedisSentinelPool 這個類文件就能夠了,先看鏈接哨兵的初始化邏輯。架構

      image

    • 第二步:咱們從源碼中能夠看到在初始化哨兵節點啓了一個線程來作監聽的,下面咱們看看這塊的源碼運維

      • 我縮了一下代碼,總體看一下這個內部類 MasterListener 源碼微服務

        image

      • 在看一下run 方法 具體實現post

        image

      • 好,你們仔細看一下咱們第二步的兩個截圖,咱們經過假設論證的方法來論證咱們的假設是否成立。性能

      1. 假設個人三個哨兵節點,其中有一個節點掛掉了,會影響服務而且報timeout 和 獲取不到鏈接池資源,但經過咱們查看源碼 這個假設一眼就看的出來 拋出的Exception 和咱們的假設步一致,若是是某一個節點掛掉了會報 下面Excetpion 中的一種,因此假設不成立學習

        if (running.get()) {
          log.log(Level.SEVERE, "Lost connection to Sentinel at " + host + ":" + port
              + ". Sleeping 5000ms and retrying.", e);
          try {
            Thread.sleep(subscribeRetryWaitTimeMillis);
          } catch (InterruptedException e1) {
            log.log(Level.SEVERE, "Sleep interrupted: ", e1);
          }
        } else {
          log.fine("Unsubscribing from Sentinel at " + host + ":" + port);
        }
        複製代碼
      2. 咱們在找運維的時候,運維也不肯定Redis 是否有問題,就重啓了一個哨兵節點,應用報了一個錯誤 而後瞬間就行了,好的當時截圖留了一個證據,如今分析來看 這個錯誤日誌能給我很大的啓示可是咱們錯過了,若是你對jedis 有深刻的瞭解的話。spa

        image

總結:

1. 經過上面的分析咱們能夠得出 哨兵模式 即便某一個哨兵節點掛掉了不會報出 一下問題

"Could not get a resource from the pool org.springframework.data.redis.RedisConnectionFailureException: Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool"
複製代碼
"Could not get a resource from the pool org.springframework.data.redis.RedisConnectionFailureException: Connect timed out; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Connect timed out"
複製代碼

2. 咱們在此次的故障中,處理問題的時候想法太單一,在加上線上服務問題心態上有些變化,着急了,沒有經過事物的本質去思考問題,從如今總結來看,這個問題當時細心一點就應該得出是什麼問題致使的。

3 . 多覆盤多總結 ,考慮事情須要從事物的本質去思考問題。一份耕耘,一份收穫,不留戀過去,不懼將來。

  • 對於如何定位線上問題和能準確並快速肯定問題的根因的方法論和原則

    • 基於服務
      • 服務故障都須要第一時間恢復,不管能不能找到根因。【基於用戶爲中心指導原則】
      • 若是你的架構是基於微服務,必定要搭建基於微服務的服務治理系統。
      • 全部線上服務運行的日誌必定要保留,方便後期找根因。
      • 搭建服務的監控系統。
    • 基於人
      • 在處理線上服務,沉穩冷靜, 不放過任何有用的信息
      • 大膽假設,邏輯清晰,當心求證。
      • 時刻保持謙卑的心,終身學習。

關聯文章

《記錄Redis事故影響API性能-上篇》

做者:易企秀工程師 henry_chen

相關文章
相關標籤/搜索