記一次由 jedis 引發的離譜選學問題

背景

我的應用中,使用 jedis 作為連接 redis 的客戶端,一直在用的好好的,后來有一個新的組件,也需要使用 redis,但是組件是內部封裝的,我只能提供一個 StringReidsTempalte,所以我基于應用本身構造的 factory,又重新構建了一個新的 template。

使用版本

springboot: 3.0.6
jedis: 4.3.2
redis 安裝版本: 7.0.11
jdk: 17

現狀

當時的現狀就是這樣的:

有一個統一的factory 構造器,構造一個 factory,并將這個 factory 交由 spring 管理。

應用內部統一使用的緩存客戶端,由自定義構造一個 RedisTemplate,而新的組件,使用 factory 構造一個新的 StringRedisTemplate。

表象

我在本地啟動的時候,沒有任何問題,正常和 redis 交互。

部署到服務器啟動的時候,會在實際和 redis 交互的底層邏輯處,報出異常。

報錯位置1:

org.springframework.data.redis.connection.jedis.JedisStringCommands#set(byte[], byte[], org.springframework.data.redis.core.types.Expiration, org.springframework.data.redis.connection.RedisStringCommands.SetOption)

img在這個地址執行的時候,invoke 方法沒問題,執行到 from 的時候,debug 執行,會報上面構建的 SetParams 這個類找不到。(只有 debug 會報,正常執行該堆棧打印不出)

通過解包,找到實際服務器的 jar 包中的 lib,發現對應的jar 包是有的,也存在這個類。

后面我就不管這個,果然就繼續執行了,這個地方并無卡點。

執行到 getOrElse 的時候,就會報另外一個異常,也就是服務器會打印出來的異常,Unknown redis exception.

堆棧信息中,大概得處理邏輯就是從cgLib 中獲取客戶端的時候,會有一些地方有卡點,不過太過深入,沒有繼續追,肯定不是底層邏輯的 bug,只能是我的客戶端構造的有問題。

于是我就開始仔細看我構造出來的客戶端,和我正常的客戶端比較。

然而這個也沒有什么異常的情況。

我的自己構建的客戶端連接池,正常使用,用了很久了,一直沒問題,實際到底層的時候,都是在一個地方使用的,應該是沒啥問題。

通過網上找關于 jedis 客戶端的使用 demo,幾乎和我的沒差別,只是調優參數不一樣。

jedis 報錯:Unknown redis exception 的幾種常見問題

  1. Redis 服務未啟動或者未連接:在程序連接 Redis 時,如果 Redis 服務未啟動或者程序無法連接到 Redis,就會出現這個異常。確保 Redis 服務已啟動,且連接信息配置正確。
  2. Redis 服務故障:Redis 服務本身發生故障導致連接斷開,也會引起這個異常。這時可以檢查 Redis 服務是否正常,以及網絡連接是否正常。
  3. Redis 客戶端版本問題:Spring Data Redis 依賴于 lettuce 和 Jedis 客戶端來訪問 Redis。如果使用了不兼容的客戶端版本,就會出現這個異常。確保 Spring Data Redis、lettuce 和 Jedis 的版本匹配。
  4. Redis 操作出錯:使用 Redis 進行操作時,可能會遇到一些錯誤情況,如 key 不存在,操作類型不匹配等。這時檢查 Redis 的操作是否合規,可以幫助解決這個異常。

針對這些可能產生該異常的情況,可以分別進行如下處理:

  1. 確認 Redis 服務已啟動,并檢查網絡連接和連接信息是否正確。
  2. 檢查 Redis 服務是否正常,以及網絡連接是否正常。
  3. 選擇適合的 Spring Data Redis、lettuce 和 Jedis 版本,確保版本匹配。
  4. 確認 Redis 的操作是否合規,以及檢查 Redis key 是否存在。

解決問題

最終發現,根本無法下手,因為我本地是好的,java 版本都沒問題。

最終嘗試使用 lettuce。

問題解決,正常使用。

如果有各位大佬知道具體原因,歡迎交流!不勝感激!

拓展

lettuce 和 jedis比較

spring boot 本身默認使用的就是 lettuce,所以個人覺得直接使用 lettuce 會更好一些。

lettuce 是 jedis 的后起之秀,相較于 jedis 來說,lettuce 有如下優點

  • 線程安全(jedis 線程非安全)
  • 基于 Netty 框架的事件驅動通信,可以異步(jedis 為同步阻塞 IO,不支持異步)
  • 基于異步+線程安全,所以更適合分布式緩存。
    • ps:我的應用就是分布式的,考慮到有可能是線程安全導致的問題,所以嘗試使用 lettuce,結果就解決問題了。(只是猜測可能是線程安全問題導致,并沒有實際驗證,雖然解決,可能只是誤打誤撞)

相較于 jedis,lettuce 的缺點也有

  • jedis 提供了更為全面的 reidis 操作特性的 api。
  • jedis 的 api 基本和 redis 的指令一一對應,使用簡單,更容易理解。而 lettuce 的api 更抽象一些,學習成本會更高一些。

lettuce 使用

和 jedis 相比,lettuce 使用更簡單,因為 lettuce 并不需要配置連接池,因為 lettuce 單鏈接的性能就很好,線程池數量太低,會導致性能降低,太高和單鏈接性能差異不大,但是資源消耗更多。

所以簡單配置即可。

spring boot 3之后,也移除了直接配置連接池的入口。只需要簡單配置 redis 的鏈接方式即可。

    @Bean("lettuceConnectionFactory")public RedisConnectionFactory lettuceConnectionFactory(CacheConfiguration configuration) {logger.info("開始構建 redis factory...{}", JedisConnectionFactory.class.getName());
//        GenericObjectPoolConfig<RedisProperties.Lettuce> poolConfig = getLettucePoolConfig();
//
//        LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder()
//                .build();RedisStandaloneConfiguration redisConfig = getRedisConfiguration(configuration);
//        LettuceConnectionFactory factory = new LettuceConnectionFactory(redisConfig, clientConfig);LettuceConnectionFactory factory = new LettuceConnectionFactory(redisConfig);factory.afterPropertiesSet();return factory;}

注意:lettuce 的 factory 創建完成之后,一定要調用afterPropertiesSet方法,否則在實際使用的時候就會報錯。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/206666.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/206666.shtml
英文地址,請注明出處:http://en.pswp.cn/news/206666.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java 多線程之 LockSupport (阻塞和喚醒線程)

文章目錄 一、概述二、使用方法三、測試示例1四、測試示例2 一、概述 LockSupport 是Java并發包中的一個工具類&#xff0c;用于線程的阻塞和喚醒。它提供了一種基于線程的許可&#xff08;permit&#xff09;的方式來實現線程的阻塞和喚醒&#xff0c;而不需要顯式地使用鎖。例…

【無線網絡技術】——無線廣域網(學習筆記)

&#x1f4d6; 前言&#xff1a;無線廣域網(WWAN)是指覆蓋全國或全球范圍內的無線網絡&#xff0c;提供更大范圍內的無線接入&#xff0c;與無線個域網、無線局域網和無線城域網相比&#xff0c;它更加強調的是快速移動性。典型的無線廣域網&#xff1a;蜂窩移動通信系統和衛星…

Linux UUCP命令教程:如何在Linux系統中進行文件復制(附實例詳解和注意事項)

Linux UUCP命令介紹 UUCP&#xff08;Unix-to-Unix Copy&#xff09;是一套允許遠程執行命令和傳輸文件的程序。UUCP命令是該套件中的一個程序&#xff0c;它為請求文件復制操作提供了用戶界面。UUCP套件還包括uux&#xff08;遠程命令執行的用戶界面&#xff09;、uucico&…

Java期末復習題之抽象類、接口

點擊返回標題->23年Java期末復習-CSDN博客 第1題. 首先設計一個學生抽象類Student&#xff0c;其數據成員有name(姓名)、age(年齡)和degree(學位)&#xff0c;以及一個抽象方法show()。然后由Student類派生出本科生類Undergraduate和研究生類Graduate&#xff0c;本科生類Un…

js moment計算當前時間到24:00:00的剩余時間

2023.12.7今天我學習了如何計算當前的時間到24:00:00剩下的時間&#xff0c;https://momentjs.cn/ const now moment(); // 獲取當前時間const endOfDay moment().endOf(day); // 設置當天的 23:59:59const duration moment.duration(endOfDay.diff(now)); // 計算剩余時間的…

第 7 部分 — 增強 LLM 安全性的策略:數學和倫理框架

一、說明 增強大型語言模型 (LLM) 安全性的追求是技術創新、道德考慮和實際應用的復雜相互作用。這項努力需要一種深入而富有洞察力的方法&#xff0c;將先進的數學模型與道德原則和諧地融合在一起&#xff0c;以確保LLM的發展不僅在技術上穩健&#xff0c;而且在道德上合理且對…

C#winform點擊按鈕下載數據庫中表的字段到Excel上

C#winform點擊按鈕下載數據庫中表的字段到Excel上 需求&#xff1a;C#winform點擊按鈕下載數據庫中表的字段到Excel&#xff0c;并計算下載消耗的時間以及文件存放位置。 C#實現 using System; using System.Data; using System.Data.OleDb; using System.Data.SqlClient; u…

Flutter 如何更新showModalBottomSheet 中的數據

showDialog(context: context,builder: (context) {String label test;//StatefulBuilderreturn StatefulBuilder(//在這里為了區分&#xff0c;在構建builder的時候將setState方法命名為了setDialogState。builder: (context, setDialogState) {print(label $label);return …

【LeetCode】268. 丟失的數字

268. 丟失的數字 難度&#xff1a;簡單 題目 給定一個包含 [0, n] 中 n 個數的數組 nums &#xff0c;找出 [0, n] 這個范圍內沒有出現在數組中的那個數。 示例 1&#xff1a; 輸入&#xff1a;nums [3,0,1] 輸出&#xff1a;2 解釋&#xff1a;n 3&#xff0c;因為有 3…

[Makefile] include 關鍵字

在 Makefile 中&#xff0c;include 關鍵字的作用是引入其他文件的內容&#xff0c;通常用于將其他 Makefile 文件&#xff08;通常是頭文件&#xff09;的內容包含到當前的 Makefile 中。這樣可以實現模塊化管理和代碼重用。 include使用 使用 include 關鍵字的語法如下&…

網絡攻擊(一)--安全滲透簡介

1. 安全滲透概述 目標 了解滲透測試的基本概念了解滲透測試從業人員的注意事項 1.1. 寫在前面的話 在了解滲透測試之前&#xff0c;我們先看看&#xff0c;信息安全相關的法律是怎么樣的 中華人民共和國網絡安全法 《中華人民共和國網絡安全法》由全國人民代表大會常務委員會…

Spring Cloud切換內嵌Tomcat為寶蘭德Application Server

目錄 替換Tomcat中間件Tomcat是什么Spring Cloud剔除tomcat引入寶蘭德Application Server打包運行授權導入 替換Tomcat中間件 Tomcat是什么 Spring Cloud剔除tomcat <!--集成springmvc框架 --><dependency><groupId>org.springframework.boot</groupId&…

Boost:asio多io_service,多線程run

多io_service,多線程run,相當于多個線程分別處理注冊在不同io_service上的回調,也就是每個線程排某個io_service的異步處理: //mio_mth.cpp #include <boost/asio.hpp> #include <boost/date_time/posix_time/posix_time_types.hpp> #include <iostream>…

MAC PHP版本安裝問題

安裝php 7.4版本不成功 Error: php7.4 has been disabled because it is a versioned formula! 因為php7.4官方已經不再維護&#xff0c;所以Hombrew將該php版本移出了repository&#xff0c;所以安裝不了。 解決辦法 從第三方倉庫中安裝 //將第三方倉庫加入brew brew tap sh…

7.1 C++11指針空值—nullptr

一、NULL和nullptr區別 NULL是宏定義&#xff0c;nullptr是關鍵字。 #ifndef NULL#ifdef __cplusplus#define NULL 0#else#define NULL ((void *)0)#endif #endif nullptr可以隱式轉換為任意指針類型&#xff0c;而NULL需要顯示轉換 void func(char *) {std::cout <<…

Java安全之Commons Collections6分析

CC6分析 import org.apache.commons.collections.*; import org.apache.commons.collections.functors.ChainedTransformer; import org.apache.commons.collections.functors.ConstantTransformer; import org.apache.commons.collections.functors.InvokerTransformer; impo…

Flask 動態路由、請求數據接收、視圖函數返回值詳解

一、動態路由 在前面的博客中&#xff0c;我們學習了如何創建基本的 Flask 應用&#xff0c;并定義了一些簡單的路由。但有時候&#xff0c;我們需要更加靈活的路由&#xff0c;能夠根據用戶請求的不同來動態生成響應。Flask 提供了動態路由的功能&#xff0c;使我們能夠輕松處…

上網監控軟件——安全與隱私的平衡

網絡已經成為人們生活和工作中不可或缺的一部分。然而&#xff0c;隨著網絡使用的普及&#xff0c;網絡安全問題也日益突出。上網監控軟件作為網絡安全領域的一個重要組成部分&#xff0c;在保護企業和家庭網絡安全方面發揮著重要作用。 本文將探討上網監控軟件的背景、功能、優…

我的Android播放器封裝經驗

近段時間&#xff0c;電視家不能用了&#xff0c;好吧&#xff0c;自己開發一個APP。其實也不是開發&#xff0c;而是基于現有的播放器核心自己封裝一個&#xff0c;只要能夠非常方便操作觀看電視就好。 當然&#xff0c;前提是要有節目源&#xff0c;這個我早已完成&#xff…

1-2算法基礎-常用庫函數

1.排序 sort(first,last,cmp) first指向要排序范圍的第一個元素&#xff0c;從0起 last指向要排序范圍的最后一個元素的下一個位置 cmp&#xff08;可選&#xff09;&#xff0c;自定義函數&#xff0c;默認從小到大 評測系統 #include <iostream> #include<algorith…