1,JedisPool的使用

<!-- 连接池的配置信息 --><beanid="jedisConfig"class="redis.clients.jedis.JedisPoolConfig"><!-- 说明一个pool可以有多少个Jedis实例 --><propertyname="maxActive"value="10" /><!-- 最大Idle--><propertyname="maxIdle"value="5" /><!-- 最小Idle --><propertyname="minIdle"value="1" /><!-- 获得一个jedis实例的时候是否检查连接可用性(ping()) --><propertyname="testOnBorrow"value="true" /><!-- return 一个jedis实例给pool时,是否检查连接可用性(ping()) --><propertyname="testOnReturn"value="true" /><!-- idle状态监测用异步线程evict进行检查, --><propertyname="testWhileIdle"value="true" /><!-- 一次最多evict的pool里的jedis实例个数 --><propertyname="numTestsPerEvictionRun"value="10" /><!-- test idle 线程的时间间隔 --><propertyname="timeBetweenEvictionRunsMillis"value="60000" /><!--最大等待wait时间--><propertyname="maxWait"value="3000" /><propertyname="whenExhaustedAction"value="" />
//WHEN_EXHAUSTED_FAIL = 0; 直接抛出异常throw new NoSuchElementException("Pool exhausted");
//WHEN_EXHAUSTED_BLOCK = 1;borrowObject()将会阻塞,直到有可用新的或者空闲的object为止,或者如果配置了maxWait,
//如果请求阻塞超时,将抛出NoSuchElementException.如果maxWait为负数,请求将会无限制的阻
//塞下去,默认配置。
//WHEN_EXHAUSTED_GROW = 2;borrowObject()将会继续创建新的对象,并返回,因此,pool维护的对像数将超出maxActive;
//
</bean>
 
 
public String set(String key, String value) {
Jedis jedis = null;
boolean success = true;
try {
jedis = this.pool.getResource();
return jedis.set(key, value);
}catch (JedisException e) {
success = false;
if(jedis != null){
pool.returnBrokenResource(jedis);
}
throw e;
}finally{
if(success && jedis != null){
this.pool.returnResource(jedis);
}
}
}

获取Jedis

pool.getResource();

这个可以直接看Pool的getResource方法,

最终还是GenericObjectPool的borrowObject()方法借用对象

@SuppressWarnings("unchecked")
public T getResource() {
try {
return (T) internalPool.borrowObject();
} catch (Exception e) {
throw new JedisConnectionException(
"Could not get a resource from the pool", e);
}
}

用完归还,调用的是GenericObjectPool的returnObject()方法

pool.returnResource(jedis)
//JedisPool.java
public void returnResource(final BinaryJedis resource) {
returnResourceObject(resource);
}
//Pool.java
publicvoid returnResourceObject(final Object resource) {
try {
internalPool.returnObject(resource);
} catch (Exception e) {
throw new JedisException(
"Could not return the resource to the pool", e);
}
}

出错,调用的是GenericObjectPool的invalidateObject()方法

最后在JedisFactory的destroyObject()中调用jedis.quit()请求Server关闭连接

pool.returnBrokenResource(jedis)
//JedisPool.java
public void returnBrokenResource(final BinaryJedis resource) {
returnBrokenResourceObject(resource);
}
//Pool.javaprotectedvoid returnBrokenResourceObject(final Object resource) {
try {
//失效
internalPool.invalidateObject(resource);
} catch (Exception e) {
thrownew JedisException(
"Could not return the resource to the pool", e);
}
}
//GenericObjectPool
publicvoid invalidateObject(Object obj)
throws Exception
{
try
{
if (this._factory != null)
this._factory.destroyObject(obj);
}
finally {
synchronized (this) {
this._numActive -= 1;
allocate();
}
}
}
//JedisFactory
publicvoid destroyObject(final Object obj) throws Exception {
if (obj instanceof Jedis) {
final Jedis jedis = (Jedis) obj;
if (jedis.isConnected()) {
try {
try {
jedis.quit();
} catch (Exception e) {
}
jedis.disconnect();
} catch (Exception e) { }
}
}
}

JedisPool源代码

package redis.clients.jedis;

import org.apache.commons.pool.BasePoolableObjectFactory;
import org.apache.commons.pool.impl.GenericObjectPool.Config; import redis.clients.util.Pool; publicclassJedisPoolextendsPool<Jedis> {public JedisPool(final Config poolConfig, final String host) {
this(poolConfig, host, Protocol.DEFAULT_PORT, Protocol.DEFAULT_TIMEOUT, null, Protocol.DEFAULT_DATABASE);
} public JedisPool(String host, int port) {
this(new Config(), host, port, Protocol.DEFAULT_TIMEOUT, null, Protocol.DEFAULT_DATABASE);
} public JedisPool(final String host) {
this(host, Protocol.DEFAULT_PORT);
} public JedisPool(final Config poolConfig, final String host, int port,
int timeout, final String password) {
this(poolConfig, host, port, timeout, password, Protocol.DEFAULT_DATABASE);
} public JedisPool(final Config poolConfig, final String host, finalint port) {
this(poolConfig, host, port, Protocol.DEFAULT_TIMEOUT, null, Protocol.DEFAULT_DATABASE);
} public JedisPool(final Config poolConfig, final String host, finalint port, finalint timeout) {
this(poolConfig, host, port, timeout, null, Protocol.DEFAULT_DATABASE);
} public JedisPool(final Config poolConfig, final String host, int port, int timeout, final String password,
finalint database) {
super(poolConfig, new JedisFactory(host, port, timeout, password, database));
} publicvoid returnBrokenResource(final BinaryJedis resource) {
returnBrokenResourceObject(resource);
} publicvoid returnResource(final BinaryJedis resource) {
returnResourceObject(resource);
} /**
* PoolableObjectFactory custom impl.
*/
privatestaticclassJedisFactoryextendsBasePoolableObjectFactory {privatefinal String host;
privatefinalint port;
privatefinalint timeout;
privatefinal String password;
privatefinalint database; public JedisFactory(final String host, finalint port,
finalint timeout, final String password, finalint database) {
super();
this.host = host;
this.port = port;
this.timeout = timeout;
this.password = password;
this.database = database;
} public Object makeObject() throws Exception {
final Jedis jedis = new Jedis(this.host, this.port, this.timeout); jedis.connect();
if (null != this.password) {
jedis.auth(this.password);
}
if( database != 0 ) {
jedis.select(database);
} return jedis;
} publicvoid destroyObject(final Object obj) throws Exception {
if (obj instanceof Jedis) {
final Jedis jedis = (Jedis) obj;
if (jedis.isConnected()) {
try {
try {
jedis.quit();
} catch (Exception e) {
}
jedis.disconnect();
} catch (Exception e) { }
}
}
} publicboolean validateObject(final Object obj) {
if (obj instanceof Jedis) {
final Jedis jedis = (Jedis) obj;
try {
return jedis.isConnected();/* && jedis.ping().equals("PONG");*/
} catch (final Exception e) {
returnfalse;
}
} else {
returnfalse;
}
}
}
}

其中JedisFactory继承自BasePoolableObjectFactory,只实现了3个方法

makeObject(),连接,new Socket()

destroyObject()--断开连接,

validateObject()--ping



Pool源代码

package redis.clients.util;

import org.apache.commons.pool.PoolableObjectFactory;
import org.apache.commons.pool.impl.GenericObjectPool; import redis.clients.jedis.exceptions.JedisConnectionException;
import redis.clients.jedis.exceptions.JedisException; publicabstractclassPool<T> {privatefinal GenericObjectPool internalPool; public Pool(final GenericObjectPool.Config poolConfig,
PoolableObjectFactory factory) {
this.internalPool = new GenericObjectPool(factory, poolConfig);
} @SuppressWarnings("unchecked")
public T getResource() {
try {
return (T) internalPool.borrowObject();
} catch (Exception e) {
thrownew JedisConnectionException(
"Could not get a resource from the pool", e);
}
} publicvoid returnResourceObject(final Object resource) {
try {
internalPool.returnObject(resource);
} catch (Exception e) {
thrownew JedisException(
"Could not return the resource to the pool", e);
}
} publicvoid returnBrokenResource(final T resource) {
returnBrokenResourceObject(resource);
} publicvoid returnResource(final T resource) {
returnResourceObject(resource);
} protectedvoid returnBrokenResourceObject(final Object resource) {
try {
//失效
internalPool.invalidateObject(resource);
} catch (Exception e) {
thrownew JedisException(
"Could not return the resource to the pool", e);
}
} publicvoid destroy() {
try {
internalPool.close();
} catch (Exception e) {
thrownew JedisException("Could not destroy the pool", e);
}
}
}

JedisPoolConfig源代码

publicclassJedisPoolConfigextendsConfig {public JedisPoolConfig() {
// defaults to make your life with connection pool easier :)
setTestWhileIdle(true);
setMinEvictableIdleTimeMillis(60000);
setTimeBetweenEvictionRunsMillis(30000);
setNumTestsPerEvictionRun(-1);
} publicint getMaxIdle() {
return maxIdle;
} publicvoid setMaxIdle(int maxIdle) {
this.maxIdle = maxIdle;
} publicint getMinIdle() {
return minIdle;
} publicvoid setMinIdle(int minIdle) {
this.minIdle = minIdle;
} publicint getMaxActive() {
return maxActive;
} publicvoid setMaxActive(int maxActive) {
this.maxActive = maxActive;
} publiclong getMaxWait() {
return maxWait;
} publicvoid setMaxWait(long maxWait) {
this.maxWait = maxWait;
} publicbyte getWhenExhaustedAction() {
return whenExhaustedAction;
} publicvoid setWhenExhaustedAction(byte whenExhaustedAction) {
this.whenExhaustedAction = whenExhaustedAction;
} publicboolean isTestOnBorrow() {
return testOnBorrow;
} publicvoid setTestOnBorrow(boolean testOnBorrow) {
this.testOnBorrow = testOnBorrow;
} publicboolean isTestOnReturn() {
return testOnReturn;
} publicvoid setTestOnReturn(boolean testOnReturn) {
this.testOnReturn = testOnReturn;
} publicboolean isTestWhileIdle() {
return testWhileIdle;
} publicvoid setTestWhileIdle(boolean testWhileIdle) {
this.testWhileIdle = testWhileIdle;
} publiclong getTimeBetweenEvictionRunsMillis() {
return timeBetweenEvictionRunsMillis;
} publicvoid setTimeBetweenEvictionRunsMillis(
long timeBetweenEvictionRunsMillis) {
this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
} publicint getNumTestsPerEvictionRun() {
return numTestsPerEvictionRun;
} publicvoid setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
this.numTestsPerEvictionRun = numTestsPerEvictionRun;
} publiclong getMinEvictableIdleTimeMillis() {
return minEvictableIdleTimeMillis;
} publicvoid setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
} publiclong getSoftMinEvictableIdleTimeMillis() {
return softMinEvictableIdleTimeMillis;
} publicvoid setSoftMinEvictableIdleTimeMillis(
long softMinEvictableIdleTimeMillis) {
this.softMinEvictableIdleTimeMillis = softMinEvictableIdleTimeMillis;
} }

 

JedisPool使用原理和源代码的更多相关文章

  1. Udp打洞原理和源代码。

    所谓udp打洞就是指客户端A通过udp协议向服务器发送数据包,服务器收到后,获取数据包,并且 可获取客户端A地址和端口号.同样在客户端B发送给服务器udp数据包后,服务器同样在收到B发送过来 的数据包 ...

  2. [Spark内核] 第32课:Spark Worker原理和源码剖析解密:Worker工作流程图、Worker启动Driver源码解密、Worker启动Executor源码解密等

    本課主題 Spark Worker 原理 Worker 启动 Driver 源码鉴赏 Worker 启动 Executor 源码鉴赏 Worker 与 Master 的交互关系 [引言部份:你希望读者 ...

  3. Dubbo原理和源码解析之服务引用

    一.框架设计 在官方<Dubbo 开发指南>框架设计部分,给出了引用服务时序图: 另外,在官方<Dubbo 用户指南>集群容错部分,给出了服务引用的各功能组件关系图: 本文将根 ...

  4. Dubbo原理和源码解析之标签解析

    一.Dubbo 配置方式 Dubbo 支持多种配置方式: XML 配置:基于 Spring 的 Schema 和 XML 扩展机制实现 属性配置:加载 classpath 根目录下的 dubbo.pr ...

  5. Dubbo原理和源码解析之“微内核+插件”机制

    github新增仓库 "dubbo-read"(点此查看),集合所有<Dubbo原理和源码解析>系列文章,后续将继续补充该系列,同时将针对Dubbo所做的功能扩展也进行 ...

  6. Dubbo原理和源码解析之服务暴露

    github新增仓库 "dubbo-read"(点此查看),集合所有<Dubbo原理和源码解析>系列文章,后续将继续补充该系列,同时将针对Dubbo所做的功能扩展也进行 ...

  7. OpenStack 虚拟机冷/热迁移的实现原理与代码分析

    目录 文章目录 目录 前文列表 冷迁移代码分析(基于 Newton) Nova 冷迁移实现原理 热迁移代码分析 Nova 热迁移实现原理 向 libvirtd 发出 Live Migration 指令 ...

  8. 我是如何在短期内快速掌握Dubbo的原理和源码的(纯干货)?

    写在前面 上周,在[Dubbo系列专题]中更新了两篇文章<冰河开始对Dubbo下手了!>和<俯瞰Dubbo全局,阅读源码前必须掌握这些!!>,收到了很多小伙伴的微信私聊消息,大 ...

  9. Kubernetes Job Controller 原理和源码分析(一)

    概述什么是 JobJob 入门示例Job 的 specPod Template并发问题其他属性 概述 Job 是主要的 Kubernetes 原生 Workload 资源之一,是在 Kubernete ...

随机推荐

  1. 递归神经网络(Recurrent Neural Networks,RNN)

    在深度学习领域,传统的多层感知机(MLP)具有出色的表现,取得了许多成功,它曾在许多不同的任务上——包括手写数字识别和目标分类上创造了记录.甚至到了今天,MLP在解决分类任务上始终都比其他方法要略胜一 ...

  2. (六)6.18 cnn 的反向传导算法

    本文主要内容是 CNN 的 BP 算法,看此文章前请保证对CNN有初步认识,可参考Neurons Networks convolutional neural network(cnn). 网络表示 CN ...

  3. 【英语】Bingo口语笔记(40) - [aʊ]的发音规则

    [aʊ]的发音规则 先发音标的音再去拼出单词的读音down

  4. [转载] FFmpeg 错误 C4996: ‘avcodec_alloc_frame’: 被声明为已否决 解决方法

    在 Visual Studio 2013 下编写 FFmpeg 程序时出错,错误如下: 出错代码如下: 解决方法为:将 avcodec_alloc_frame() 替换为 av_frame_alloc ...

  5. 【转】Eclipse和PyDev搭建完美Python开发环境(Ubuntu篇)

    原文网址:http://www.cnblogs.com/Realh/archive/2010/10/10/1847251.html 前两天在Windows下成功地搭好了一个Python开发环境,这次转 ...

  6. MySQL与Oracle 差异比较之七用户权限

    用户权限 编号 类别 ORACLE MYSQL 注释 1 创建用户 Create user user_name identified by user_password default tablespa ...

  7. 支持多种浏览器的纯css下拉菜单

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. python定义影像投影

    import os import arcgisscripting gp=arcgisscripting.create() coordsys=r"C:\Winx86\ArcGIS\Coordi ...

  9. 使用服务器端控制AJAX页面缓存

    你知道 response.setHeader("Cache-Control","no-cache"); 这条语句是干什么的吗? 这是用来防止浏览器缓存动态内容生 ...

  10. <测试用例设计>用户及权限管理功能常规测试方法

    1)  赋予一个人员相应的权限后,在界面上看此人员是否具有此权限,并以此人员身份登陆,验证权限设置是否正确(能否超出所给予的权限): 2)  删除或修改已经登陆系统并正在进行操作的人员的权限,程序能否 ...