[轉載]Java使用Jedis操作Redis併發時遇到的坑記錄
Java在使用jedis操作redis資料時,遇到坑,各種查資料解決了將近1天才實現結果。
坑1:
直接在Idea裡面,建TestNG的Test類時,
裡面的多執行緒程式碼,一直會提示報錯,沒有任何提示,直接就test任務結束。
解決方案:使用main建入口的方式進行測試,千萬不要使用testng的@Test註解這種方式進行測試。
原因,估計是多執行緒引起的。怎麼弄還不明白,只能換成main方法裡面去執行多執行緒。
坑2:
多執行緒併發會造成衝突,會報各種錯。
解決方法:使用JRedisPool建立執行緒池。
而且在操作時,使用synchronized把操作方法進行封裝。否則依然會報錯。
坑3 :
超出執行緒池容量。1000個執行緒,會報大量的錯。
解決方法:
JedisPoolConfig裡面設定
//Redis伺服器IP
private static String ADDR_ARRAY = "127.0.0.1";
//Redis的埠號
private static int PORT = 6379;
//訪問密碼
private static String AUTH = "";
//可用連線例項的最大數目,預設值為8;
//如果賦值為-1,則表示不限制;如果pool已經分配了maxActive個jedis例項,則此時pool的狀態為exhausted(耗盡)。
private static int MAX_ACTIVE = 500;
//控制一個pool最多有多少個狀態為idle(空閒的)的jedis例項,預設值也是8。
private static int MAX_IDLE = 100;
//等待可用連線的最大時間,單位毫秒,預設值為-1,表示永不超時。如果超過等待時間,則直接丟擲JedisConnectionException;
private static int MAX_WAIT = 10 * 1000;
private static int TIMEOUT = 10 * 1000;//超時時間
//在borrow一個jedis例項時,是否提前進行validate操作;如果為true,則得到的jedis例項均是可用的;
private static boolean TEST_ON_BORROW = true;
private static JedisPool jedisPool = null;
/**
* 初始化Redis連線池
*/
private static void initialPool() {
try {
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(MAX_ACTIVE);
config.setMaxIdle(MAX_IDLE);
config.setMaxWaitMillis(MAX_WAIT);
config.setTestOnBorrow(TEST_ON_BORROW);//使用時進行掃描,確保都可用
config.setTestWhileIdle(true);//Idle時進行連線掃描
config.setTestOnReturn(true);//還回執行緒池時進行掃描
//
////表示idle object evitor兩次掃描之間要sleep的毫秒數
// config.setTimeBetweenEvictionRunsMillis(30000);
//
////表示idle object evitor每次掃描的最多的物件數
// config.setNumTestsPerEvictionRun(10);
//
////表示一個物件至少停留在idle狀態的最短時間,然後才能被idle object evitor掃描並驅逐;這一項只有在timeBetweenEvictionRunsMillis大於0時才有意義
// config.setMinEvictableIdleTimeMillis(60000);
if (StringUtils.isNotBlank(AUTH)) {
jedisPool = new JedisPool(config, ADDR_ARRAY.split(",")[0], PORT, TIMEOUT, AUTH);
} else {
jedisPool = new JedisPool(config, ADDR_ARRAY.split(",")[0], PORT, TIMEOUT);
}
} catch (Exception e) {
logger.error("First create JedisPool error : " + e);
try {
//如果第一個IP異常,則訪問第二個IP
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(MAX_ACTIVE);
config.setMaxIdle(MAX_IDLE);
config.setMaxWaitMillis(MAX_WAIT);
config.setTestOnBorrow(TEST_ON_BORROW);
jedisPool = new JedisPool(config, ADDR_ARRAY.split(",")[1], PORT, TIMEOUT, AUTH);
} catch (Exception e2) {
logger.error("Second create JedisPool error : " + e2);
}
}
}
/**
* 在多執行緒環境同步初始化
*/
private static synchronized void poolInit() {
if (jedisPool == null) {
initialPool();
}
}
/**
* 同步獲取Jedis例項
*
* @return Jedis
*/
public synchronized static Jedis getJedis() {
if (jedisPool == null) {
poolInit();
}
Jedis jedis = null;
try {
if (jedisPool != null) {
jedis = jedisPool.getResource();
}
} catch (Exception e) {
logger.error("Get jedis Error : " + e.getMessage(), e);
} finally {
returnResource(jedis);//歸還到Redis池裡面
}
return jedis;
}
/**
* 釋放jedis資源
*
* @param jedis
*/
public static void returnResource(final Jedis jedis) {
if (jedis != null && jedisPool != null) {
jedisPool.returnResource(jedis);
}
}
/**
* 關閉連線池
*/
public static void closePool() {
if (jedisPool != null) {
jedisPool.close();
}
}
/**
* 設定 String
*
* @param key
* @param value
*/
public synchronized static void setString(String key, String value) {
try {
value = StringUtils.isEmpty(value) ? "" : value;
getJedis().set(key, value);
} catch (Exception e) {
logger.error("Set key error : " + e);
}
}
/**
* 設定 過期時間
*
* @param key
* @param seconds 以秒為單位
* @param value
*/
public synchronized static void setString(String key, int seconds, String value) {
try {
value = StringUtils.isEmpty(value) ? "" : value;
getJedis().setex(key, seconds, value);
} catch (Exception e) {
logger.error("Set keyex error : " + e);
}
}
/**
* 獲取String值
*
* @param key
* @return value
*/
public synchronized static String getString(String key) {
if (getJedis() == null || !getJedis().exists(key)) {
return null;
}
return getJedis().get(key);
}
}
相關推薦
[轉載]Java使用Jedis操作Redis併發時遇到的坑記錄
Java在使用jedis操作redis資料時,遇到坑,各種查資料解決了將近1天才實現結果。 坑1: 直接在Idea裡面,建TestNG的Test類時, 裡面的多執行緒程式碼,一直會提示報錯,沒有任何提示,直接就test任務結束。 解決方案:使用m
python遇坑記錄-json.loads() :JSONDecodeError: Invalid escape
key 結果 sys ref pen ket cape sel port 環境:python3.6 json文件: { "src_dir" : "C:\\Users\\admin\\Desktop\\99\\apkobb", "buc
google支付遇坑記錄
google支付備忘 : 一.In-app billing error: Null data in IAB activity result (-1002 xxxxx) 接入google的支付sdk,不會顯示google的支付介面小視窗。 問題:手機把Google Play商
asp.net core 2.1 Mysql 資料庫遷移,遇坑記錄
首先來一段錯誤immodeMacBook-Pro:tz.efcontext immo$ dotnet ef database update Unable to create an object of type 'AppDbContext'. Add an implementa
前端遇坑記錄(三)——axios請求的引數自動拼接到url後面
遇坑如題,這東西搞了我大半天。google 百度 StackOverflow 一通找,就是搞不定。 我秉承一個原則,問題在網上線索寥寥,要麼就是問題難+小眾,沒幾個人分享。 要麼就是問題太簡單,沒人會問。 我相信我這個是後者。 所以,我最後才想到去看axios的文件.
Mac 升級pip 9.0.1到10.0.1遇坑記錄
首先你要pip安裝某一個工具的時候遇到下面類似的錯誤 Traceback (most recent call last): File "/Users/finaris/PycharmProjects/test/test/test.py", line 14
Spring Data操作Redis時,發現key值出現 xacxedx00x05tx00 b
成了 內存 format string obj 但是 tail 就是 urn 原文鏈接:http://blog.csdn.net/yunhaibin/article/details/9001198 最近在研究redis,以及spring data對redis的支持發現了
使用Redis和jackson操作json中遇到的坑
表數據 谷歌 這樣的 進行 結構 length 找到 sql 報道 前言(可以略過) 最近在開發一個智能電表的管理系統,與常規的面向業務的系統不同。智能電表特點是每30分鐘會向服務器發一次請求,報道自己目前的電表情況。然後服務器根據電表情況統計此電表的電量使用情況
PostgreSQL+REDIS_FDW詳細記錄踩坑過程之遠端操作redis(三)
準備: redis 以及pg都開啟並都能遠端訪問 1.redis 開啟遠端訪問 修改Redis配置檔案/etc/redis/redis.conf,找到bind那行配置: # bind 127.0.0.1 2.去掉#註釋並改為:
多執行緒,高併發的情況下操作redis當中的資料,如何加鎖?
多個執行緒同時去操作Redis當中的資料,假如不加鎖的情況下,會出現資料重複的問題。假如需要每次都只有一條執行緒去操作Redis當中的資料,需要給操作加上鎖。 但是去網上一搜,網上給Redis加鎖的機制都是利用Redis的setnx自身的方法去加鎖,但是這樣
SQL Server併發操作單個表時發生在page頁面級的死鎖
最近遇到的死鎖問題都發生在併發操作單張表上,比較有意思,就模擬了重現了一下。根據非聚集索引為條件,刪除某一個表的資料,類似於這麼一個語句,delete from table where nocluster_index in (x,y,z,m,n……)in裡面的內容不同,併發執行某些情況下,可能會引發死鎖,
在redis中優化頻繁操作redis產生多次連結引發的網路延時
在程式中可能存在頻繁操作redis,每次操作redis都需要產生網路連結,雖然每次操作的返回處理非常快(幾十甚至幾毫米),但是非常多的redis操作在超高的併發請求中,還是有必要優化的,那麼php中如何避免產生多次操作,每次都連結一次redis呢?其實和上篇文章的方法是一
Spring Cloud: 使用kill命令優雅關閉微服務, 解決退出時Eureka取消註冊操作耗時過長的坑
關於Spring Cloud服務優雅關閉的方案有很多種了,這裡介紹一下使用kill命令優雅關閉的方案,並解決會出現的問題。 所謂的優雅指兩方面,一是程式在退出時要主動向Eureka取消註冊自己,二是完成資源清理工作。比如我的程式裡用到了執行緒池來非同步執行一些
Spring Data操作Redis時,發現key值出現 \xac\xed\x00\x05t\x00\tb
最近在研究redis,以及spring data對redis的支援發現了一個奇怪的現象 先說現象吧,通過redisTemplate下的opsForHash方法儲存hash型別的值,操作成功以後,去redis控制檯顯示keys * 的時候,發現一個奇怪的現象,插入的has
實現專案下載需求時遇過的那些坑
導語 當前市面上的APP,凡有涉及到視訊、期刊、或其它大型檔案傳輸、瀏覽等用途的,新增下載或快取至本地的功能以避免網速的限制及依賴,毫無疑問都將給使用者帶來更好的體驗。而談到下載技術,就又不得不牽扯到了斷點續傳,佇列任務等老生常談的問題。這不,本人當前的專案,就恰好遇到了
AFNetworking實現專案下載需求時遇過的那些坑
導語 當前市面上的APP,凡有涉及到視訊、期刊、或其它大型檔案傳輸、瀏覽等用途的,新增下載或快取至本地的功能以避免網速的限制及依賴,毫無疑問都將給使用者帶來更好的體驗。而談到下載技術,就又不得不牽扯到了斷點續傳,佇列任務等老生常談的問題。這不,本人當前的專案,就恰好遇到了
操作redis時出現 DENIED Redis is running in protected mode
在操作redis時,出現DENIED Redis is running in protected mode這說明redis是執行在保護模式開啟redis的redis.conf 檔案通過/ 找到 protected-mode yes將yes 改成no 即可。友情提示:通過 :n
Redis 叢集時 踩過的坑
建立完成redis例項後,使用redis-trib.tb來新建叢集 redis-trib.rb create --replicas 1 127.0.0.1:7379 127.0.0.1:7380 127.0.0.1:7381 127.0.0.1:7382 127.0.0.
redis 之 使用java操作redis
main print 數據庫 cli 防火墻 images enc png red 1. 在java操作redis需要使用jedis插件,並且linux要開啟相關的防火墻。 重啟防火墻服務 : 2. 新建maven項目: 3.添加項目依賴: <dependenc
redis--(六)java操作redis
技術分享 http ges 分享 .cn -1 -- edi image Java操作redis集群 redis--(六)java操作redis