Jedis 源码阅读一 —— Jedis

文章目录

  • Jedis.java
  • 关于soTimeout 与 connectionTimeOut

这是jedis 源码目录,我们接下来选择性阅读重要的接口以及实现。

└─redis
    └─clients
        ├─jedis
        │  │  BinaryClient.java
        │  │  BinaryJedis.java
        │  │  BinaryJedisCluster.java
        │  │  BinaryJedisPubSub.java
        │  │  BinaryShardedJedis.java
        │  │  BitOP.java
        │  │  BitPosParams.java
        │  │  Builder.java
        │  │  BuilderFactory.java
        │  │  Client.java
        │  │  Connection.java
        │  │  DebugParams.java
        │  │  GeoCoordinate.java
        │  │  GeoRadiusResponse.java
        │  │  GeoUnit.java
        │  │  HostAndPort.java
        │  │  Jedis.java
        │  │  JedisCluster.java
        │  │  JedisClusterCommand.java
        │  │  JedisClusterConnectionHandler.java
        │  │  JedisClusterInfoCache.java
        │  │  JedisFactory.java
        │  │  JedisMonitor.java
        │  │  JedisPool.java
        │  │  JedisPoolAbstract.java
        │  │  JedisPoolConfig.java
        │  │  JedisPubSub.java
        │  │  JedisSentinelPool.java
        │  │  JedisShardInfo.java
        │  │  JedisSlotBasedConnectionHandler.java
        │  │  MultiKeyPipelineBase.java
        │  │  Pipeline.java
        │  │  PipelineBase.java
        │  │  Protocol.java
        │  │  Queable.java
        │  │  Response.java
        │  │  ScanParams.java
        │  │  ScanResult.java
        │  │  ShardedJedis.java
        │  │  ShardedJedisPipeline.java
        │  │  ShardedJedisPool.java
        │  │  SortingParams.java
        │  │  Transaction.java
        │  │  Tuple.java
        │  │  ZParams.java
        │  │  
        │  ├─commands
        │  │      AdvancedBinaryJedisCommands.java
        │  │      AdvancedJedisCommands.java
        │  │      BasicCommands.java
        │  │      BasicRedisPipeline.java
        │  │      BinaryJedisClusterCommands.java
        │  │      BinaryJedisCommands.java
        │  │      BinaryRedisPipeline.java
        │  │      BinaryScriptingCommands.java
        │  │      BinaryScriptingCommandsPipeline.java
        │  │      ClusterCommands.java
        │  │      ClusterPipeline.java
        │  │      Commands.java
        │  │      JedisClusterBinaryScriptingCommands.java
        │  │      JedisClusterCommands.java
        │  │      JedisClusterScriptingCommands.java
        │  │      JedisCommands.java
        │  │      MultiKeyBinaryCommands.java
        │  │      MultiKeyBinaryJedisClusterCommands.java
        │  │      MultiKeyBinaryRedisPipeline.java
        │  │      MultiKeyCommands.java
        │  │      MultiKeyCommandsPipeline.java
        │  │      MultiKeyJedisClusterCommands.java
        │  │      ProtocolCommand.java
        │  │      RedisPipeline.java
        │  │      ScriptingCommands.java
        │  │      ScriptingCommandsPipeline.java
        │  │      SentinelCommands.java
        │  │      
        │  ├─exceptions
        │  │      InvalidURIException.java
        │  │      JedisAskDataException.java
        │  │      JedisClusterCrossSlotException.java
        │  │      JedisClusterException.java
        │  │      JedisClusterMaxRedirectionsException.java
        │  │      JedisConnectionException.java
        │  │      JedisDataException.java
        │  │      JedisException.java
        │  │      JedisMovedDataException.java
        │  │      JedisRedirectionException.java
        │  │      
        │  └─params
        │      │  Params.java
        │      │  
        │      ├─geo
        │      │      GeoRadiusParam.java
        │      │      
        │      ├─set
        │      │      SetParams.java
        │      │      
        │      └─sortedset
        │              ZAddParams.java
        │              ZIncrByParams.java
        │              
        └─util
                ClusterNodeInformation.java
                ClusterNodeInformationParser.java
                Hashing.java
                IOUtils.java
                JedisByteHashMap.java
                JedisClusterCRC16.java
                JedisURIHelper.java
                KeyMergeUtil.java
                MurmurHash.java
                Pool.java
                RedisInputStream.java
                RedisOutputStream.java
                SafeEncoder.java
                Sharded.java
                ShardInfo.java
                Slowlog.java

Jedis.java

Jedis 源码阅读一 —— Jedis_第1张图片
我们每次使用jedis都会初始化一个jedis对象,对以下代码肯定不会陌生:

public class Jedis extends BinaryJedis implements JedisCommands, MultiKeyCommands,
    AdvancedJedisCommands, ScriptingCommands, BasicCommands, ClusterCommands, SentinelCommands {

  protected JedisPoolAbstract dataSource = null;

  public Jedis() {
    super();
  }

  public Jedis(final String host) {
    super(host);
  }

  public Jedis(final String host, final int port) {
    super(host, port);
  }
............

Jedis对象调用父类BinaryJedis构造器:

public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKeyBinaryCommands,
		AdvancedBinaryJedisCommands, BinaryScriptingCommands, Closeable {
	protected Client client = null;
	protected Transaction transaction = null;
	protected Pipeline pipeline = null;

	public BinaryJedis() {
		client = new Client();
	}

	public BinaryJedis(final String host) {
		URI uri = URI.create(host);
		if (uri.getScheme() != null && uri.getScheme().equals("redis")) {
			initializeClientFromURI(uri);
		} else {
			client = new Client(host);
		}
	}

	public BinaryJedis(final String host, final int port) {
		client = new Client(host, port);
	}

	public BinaryJedis(final String host, final int port, final int timeout) {
		client = new Client(host, port);
		client.setConnectionTimeout(timeout);
		client.setSoTimeout(timeout);
	}

实际上,new Jedis()的初始化中,最重要的是new Client()这句代码。
Client 继承自 BinaryClient

public class Client extends BinaryClient implements Commands {

  public Client() {
    super();
  }

而BinaryClient又继承自Collection


public class BinaryClient extends Connection {
 ............
  private String password;

  private int db;

  private boolean isInWatch;

............
  public BinaryClient() {
    super();
  }
............

接着我们来看Collection代码:

	public class Connection implements Closeable {
	.....
	protected Connection sendCommand(final ProtocolCommand cmd, final String... args) {
		final byte[][] bargs = new byte[args.length][];
		for (int i = 0; i < args.length; i++) {
			// 对cmd判空并返回bytes
			bargs[i] = SafeEncoder.encode(args[i]);
		}
		return sendCommand(cmd, bargs);
	}

	protected Connection sendCommand(final ProtocolCommand cmd) {
		return sendCommand(cmd, EMPTY_ARGS);
	}

	protected Connection sendCommand(final ProtocolCommand cmd, final byte[]... args) {
		try {
			// 1.建立Socket连接
			connect();
			// 2.按照协议完成IO操作,也就是命令的执行
			Protocol.sendCommand(outputStream, cmd, args);
			return this;
		} catch (JedisConnectionException ex) {
			/*
			 * When client send request which formed by invalid protocol, Redis
			 * send back error message before close connection. We try to read
			 * it to provide reason of failure.
			 */
			try {
				String errorMessage = Protocol.readErrorLineIfPossible(inputStream);
				if (errorMessage != null && errorMessage.length() > 0) {
					ex = new JedisConnectionException(errorMessage, ex.getCause());
				}
			} catch (Exception e) {
				/*
				 * Catch any IOException or JedisConnectionException occurred
				 * from InputStream#read and just ignore. This approach is safe
				 * because reading error message is optional and connection will
				 * eventually be closed.
				 */
			}
			// Any other exceptions related to connection?
			broken = true;
			throw ex;
		}
	}
	...
	// 建立Sock连接
	public void connect() {
		if (!isConnected()) {
			try {

				socket = new Socket();
				// ->@wjw_add
				socket.setReuseAddress(true);
				socket.setKeepAlive(true); // Will monitor the TCP connection is
				// valid
				socket.setTcpNoDelay(true); // Socket buffer Whetherclosed, to
				// ensure timely delivery of data
				socket.setSoLinger(true, 0); // Control calls close () method,
				// the underlying socket is closed
				// immediately
				// <-@wjw_add

				socket.connect(new InetSocketAddress(host, port), connectionTimeout);
				socket.setSoTimeout(soTimeout);
				outputStream = new RedisOutputStream(socket.getOutputStream());
				inputStream = new RedisInputStream(socket.getInputStream());
			} catch (IOException ex) {
				broken = true;
				throw new JedisConnectionException(ex);
			}
		}
	}
	...

在这里完成了Socket连接,并返回这个Socket.
Jedis 源码阅读一 —— Jedis_第2张图片
每次我们使用Jedis去执行命令,都是这个持有Soket的client去执行的。
比如:

	/**
	 * Get the value of the specified key. If the key does not exist null is
	 * returned. If the value stored at key is not a string an error is returned
	 * because GET can only handle string values.
	 * 

* Time complexity: O(1) * * @param key * @return Bulk reply */ @Override public String get(final String key) { checkIsInMultiOrPipeline();// 检查是否在事物中;检查是否是哟好难过管道技术 client.sendCommand(Protocol.Command.GET, key);// 使用Socket进行IO操作,执行命令 return client.getBulkReply(); }

jedis除了继承的BinaryJedis完成基本的IO操作,还实现了 JedisCommands, MultiKeyCommands, AdvancedJedisCommands,ScriptingCommands, BasicCommands, ClusterCommands, SentinelCommands
这几个可使用的命令的接口。

你可以参考redis自带的 unitTest,更深入的理解。
http://download.csdn.net/detail/lemon89/9407039

关于soTimeout 与 connectionTimeOut

我不多说了,这个链接解释很清楚。

http://stackoverflow.com/questions/7360520/connectiontimeout-versus-sockettimeout

你可能感兴趣的:(redis相关)