Redis.java 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. package zs.payment.utils;
  2. import org.slf4j.Logger;
  3. import org.slf4j.LoggerFactory;
  4. import redis.clients.jedis.Jedis;
  5. import redis.clients.jedis.JedisPool;
  6. import redis.clients.jedis.JedisPoolConfig;
  7. import java.util.Random;
  8. import java.util.concurrent.ConcurrentHashMap;
  9. import java.util.regex.Pattern;
  10. public class Redis {
  11. private static final Logger log = LoggerFactory.getLogger(Redis.class);
  12. @FunctionalInterface
  13. public interface RedisCallback<V> {
  14. V execute(Jedis jedis) throws Exception;
  15. }
  16. /**
  17. * 主从模式
  18. * @param ipPort Redis server address
  19. * @param callback Redis callback
  20. * @return callback result
  21. */
  22. public static <V> V with(String ipPort, RedisCallback<V> callback) {
  23. JedisPool pool = pool(ipPort);
  24. Jedis jedis = null;
  25. V val = null;
  26. try {
  27. for (int i = 1; i <= 2; i++) {
  28. if (jedis == null) {
  29. if (i > 1) {
  30. Thread.sleep(200);
  31. }
  32. jedis = pool.getResource();
  33. }
  34. }
  35. if (callback != null) {
  36. val = callback.execute(jedis);
  37. }
  38. } catch (Exception e) {
  39. log.error("redis " + ipPort, e);
  40. returnResource(pool, jedis);
  41. } finally {
  42. returnResource(pool, jedis);
  43. }
  44. return val;
  45. }
  46. /**
  47. * 集群模式(指定数据库)
  48. * @param ipPorts Redis cluster addresses
  49. * @param db Redis database index
  50. * @param callback Redis callback
  51. * @return callback result
  52. */
  53. public static <V> V withClusterDb(String ipPorts, int db, RedisCallback<V> callback) {
  54. String[] ipPortArray = ipPorts.split(",");
  55. String ipPort = "";
  56. if (ipPortArray.length > 0) {
  57. Random random = new Random();
  58. int index = random.nextInt(ipPortArray.length);
  59. ipPort = ipPortArray[index];
  60. }
  61. JedisPool pool = poolClusterDb(ipPort, db);
  62. Jedis jedis = null;
  63. V val = null;
  64. try {
  65. for (int i = 1; i <= 2; i++) {
  66. if (jedis == null) {
  67. if (i > 1) {
  68. Thread.sleep(200);
  69. }
  70. jedis = pool.getResource();
  71. }
  72. }
  73. if (callback != null) {
  74. val = callback.execute(jedis);
  75. }
  76. } catch (Exception e) {
  77. log.error("redis " + ipPort + " db" + db, e);
  78. returnResource(pool, jedis);
  79. } finally {
  80. returnResource(pool, jedis);
  81. }
  82. return val;
  83. }
  84. /**
  85. * 集群模式
  86. * @param ipPorts Redis cluster addresses
  87. * @param callback Redis callback
  88. * @return callback result
  89. */
  90. public static <V> V withCluster(String ipPorts, RedisCallback<V> callback) {
  91. String[] ipPortArray = ipPorts.split(",");
  92. String ipPort = "";
  93. if (ipPortArray.length > 0) {
  94. Random random = new Random();
  95. int index = random.nextInt(ipPortArray.length);
  96. ipPort = ipPortArray[index];
  97. }
  98. JedisPool pool = poolCluster(ipPort);
  99. Jedis jedis = null;
  100. V val = null;
  101. try {
  102. for (int i = 1; i <= 2; i++) {
  103. if (jedis == null) {
  104. if (i > 1) {
  105. Thread.sleep(200);
  106. }
  107. jedis = pool.getResource();
  108. }
  109. }
  110. if (callback != null) {
  111. val = callback.execute(jedis);
  112. }
  113. } catch (Exception e) {
  114. log.error("redis " + ipPort, e);
  115. returnResource(pool, jedis);
  116. } finally {
  117. returnResource(pool, jedis);
  118. }
  119. return val;
  120. }
  121. private static ConcurrentHashMap<String, JedisPool> pools = new ConcurrentHashMap<String, JedisPool>();
  122. private static JedisPoolConfig poolConfig = config();
  123. private static JedisPoolConfig poolConfigCluster = configCluster();
  124. private static JedisPoolConfig config() {
  125. JedisPoolConfig cfg = new JedisPoolConfig();
  126. cfg.setMaxTotal(500);
  127. cfg.setMinIdle(50);
  128. cfg.setMaxIdle(100);
  129. cfg.setMaxWaitMillis(5000);
  130. cfg.setTestOnBorrow(true);
  131. cfg.setTestOnReturn(true);
  132. cfg.setTestWhileIdle(true);
  133. cfg.setMinEvictableIdleTimeMillis(300000);
  134. cfg.setTimeBetweenEvictionRunsMillis(60000);
  135. cfg.setNumTestsPerEvictionRun(10);
  136. return cfg;
  137. }
  138. private static JedisPool pool(String ipPort) {
  139. JedisPool pool = pools.get(ipPort);
  140. if (pool == null) {
  141. String host = null;
  142. int port = 6379;
  143. String[] hp = ipPort.split(":");
  144. if (hp.length > 0) {
  145. host = hp[0];
  146. if (hp.length > 1 && Pattern.matches("[0-9]+", hp[1])) {
  147. port = Integer.parseInt(hp[1]);
  148. }
  149. }
  150. pool = new JedisPool(poolConfig, host, port);
  151. pools.put(ipPort, pool);
  152. }
  153. return pool;
  154. }
  155. /**
  156. * 集群配置
  157. * @return
  158. */
  159. private static JedisPoolConfig configCluster() {
  160. JedisPoolConfig cfg = new JedisPoolConfig();
  161. cfg.setMaxTotal(500);
  162. cfg.setMinIdle(50);
  163. cfg.setMaxIdle(100);
  164. cfg.setMaxWaitMillis(5000);
  165. cfg.setTestOnBorrow(true);
  166. cfg.setTestOnReturn(true);
  167. cfg.setTestWhileIdle(true);
  168. cfg.setMinEvictableIdleTimeMillis(300000);
  169. cfg.setTimeBetweenEvictionRunsMillis(60000);
  170. cfg.setNumTestsPerEvictionRun(10);
  171. return cfg;
  172. }
  173. private static JedisPool poolCluster(String ipPort) {
  174. JedisPool pool = pools.get(ipPort);
  175. if (pool == null) {
  176. String host = null;
  177. int port = 6379;
  178. String[] hp = ipPort.split(":");
  179. if (hp.length > 0) {
  180. host = hp[0];
  181. if (hp.length > 1 && Pattern.matches("[0-9]+", hp[1])) {
  182. port = Integer.parseInt(hp[1]);
  183. }
  184. }
  185. pool = new JedisPool(poolConfigCluster, host, port);
  186. pools.put(ipPort, pool);
  187. }
  188. return pool;
  189. }
  190. private static JedisPool poolClusterDb(String ipPort, int db) {
  191. String poolKey = ipPort + "#db" + db;
  192. JedisPool pool = pools.get(poolKey);
  193. if (pool == null) {
  194. String host = null;
  195. int port = 6379;
  196. String[] hp = ipPort.split(":");
  197. if (hp.length > 0) {
  198. host = hp[0];
  199. if (hp.length > 1 && Pattern.matches("[0-9]+", hp[1])) {
  200. port = Integer.parseInt(hp[1]);
  201. }
  202. }
  203. pool = new JedisPool(poolConfigCluster, host, port, 2000, null, db);
  204. pools.put(poolKey, pool);
  205. }
  206. return pool;
  207. }
  208. public static void returnResource(JedisPool jedisPool, Jedis jedis) {
  209. if (jedisPool != null && jedis != null) {
  210. jedisPool.returnResource(jedis);
  211. }
  212. }
  213. }