• Jedis 源代码阅读一 —— Jedis


    这是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对象,对下面代码肯定不会陌生:

    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去运行命令。都是这个持有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.
         * <p>
         * 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

  • 相关阅读:
    设计模式之结构型(6)-享元模式(Flyweight)
    设计模式之结构型(7)-代理模式(Proxy)
    设计模式之行为型(1)-职责链模式(Chain)
    设计模式之行为型(2)-命令模式(Command)
    设计模式之行为型(3)-解释器模式(Interpreter)
    设计模式之行为型(4)-迭代器模式(Iterator)
    设计模式之行为型(5)-中介者模式(Mediator)
    设计模式之行为型(6)-备忘录模式(Memento)
    设计模式之行为型(7)-观察者模式(Observer)
    设计模式之行为型(8)-状态模式(State)
  • 原文地址:https://www.cnblogs.com/llguanli/p/7403505.html
Copyright © 2020-2023  润新知