java ssdb简单的连接池

一个高性能的支持丰富数据结构的 NoSQL 数据库, 用于替代 Redis.,目前有一些互联网公司都在使用ssdb,比如360,百度等。官方提供了多种语言的client实现,但是没有给出一个高效的连接池方案,因此本文结合项目的使用,给出一个java版本的ssdb连接池方案。
(注意:SSDB,Link,Response,MemoryStream,4个类的实现,请参考官方代码,这里不提供)

public class SSDBPool  {
    private static final Logger logger = LogManager.getLogger(SSDBPool.class);

    private String host;			 //连接ip
    private int port;                 //连接端口
    private int timeoutMs;      //连接超时
    private int count;          //连接数大小
    private final Map connMap;

    public SSDBPool(String host, int port) {
        this(host, port, 5,0);
    }

    public SSDBPool(String host, int port, int count) {
        this(host, port, count, 0);
    }

    public SSDBPool(String host, int port, int count, int timeoutMs)  {
        if (count <= 0) {
            throw new IllegalArgumentException("Illegal connect count: " + count);
        }
        this.host = host;
        this.port = port;
        this.timeoutMs = timeoutMs;
        this.count = count;
        this.connMap = new HashMap<>(this.count);
        try {
            for (int i = 0; i < this.count; i++) {
                connMap.put(new SSDB(host,port,timeoutMs),0);
            }
        } catch (Exception e) {
            throw new ExceptionInInitializerError(e);
        }
    }

    private SSDB getSSDB() throws Exception {
        while(true) {
        	// 线程同步处理,没有可以用的连接,则线程阻塞
            synchronized (connMap) {
                for (Map.Entry entry : connMap.entrySet()) {
                    if (entry.getValue() == 0) {
                        entry.setValue(1);
                        return entry.getKey();
                    }
                }
                if (connMap.size() < count) {
                    SSDB ssdb = new SSDB(host, port, timeoutMs);
                    connMap.put(ssdb, 1);
                    return ssdb;
                } else {
                    connMap.wait();
                }
            }
        }
    }

    private void releaseSSDB(SSDB ssdb, boolean remove) {
        // 线程同步处理,释放连接,唤醒阻塞线程
        synchronized (connMap) {
            try {
                if (remove) {
                    connMap.remove(ssdb);
                } else if (ssdb != null){
                    connMap.put(ssdb, 0);
                }
            } catch (Exception e) {
                logger.warn("releaseSSDB fail, mgs={}", e.getMessage());
            }
            connMap.notifyAll();
        }
    }

    public String getValue(String key) {
        //针对异常连接进行重试,重试次数为连接数,防止连接自动断开
        return getValue(key, count);
    }

    private String getValue(String key, int tryTimes) {
        SSDB ssdb = null;
        try {
            ssdb = this.getSSDB();
            byte[] content = ssdb.get(key);
            if (null != content) {
                this.releaseSSDB(ssdb, false);
                return new String(content,"UTF-8");
            }
            this.releaseSSDB(ssdb, false);
            return null;
        } catch (Exception e) {
            logger.warn("key={},msg={}", key, e.getMessage());
            this.releaseSSDB(ssdb, true);
            //针对异常连接进行重试
            if (tryTimes > 0) {
                return getValue(key, tryTimes -1);
            } else {
                return null;
            }
        }
    }

    public int getTtl(String key) {
        return getTtl(key, count);
    }

    private int getTtl(String key, int tryTime) {
        SSDB ssdb = null;
        try {
            ssdb = this.getSSDB();
            byte[] content = ssdb.ttl(key);
            if (null != content) {
                this.releaseSSDB(ssdb, false);
                String ttlStr = new String(content,"UTF-8");
                return Integer.parseInt(ttlStr);
            }
            this.releaseSSDB(ssdb, false);
            return -1;
        } catch (Exception e) {
            logger.warn(e.getMessage());
            this.releaseSSDB(ssdb, true);
            if (tryTime > 0) {
                return getTtl(key, tryTime -1);
            } else {
                return -1;
            }
        }
    }

    public void save(String key, String value) {
        save(key, value, count);
    }

    private void save(String key, String value, int tryTimes) {
        SSDB ssdb = null;
        try {
            ssdb = this.getSSDB();
            ssdb.set(key, value.getBytes("UTF-8"));
            this.releaseSSDB(ssdb, false);
        } catch (Exception e) {
            logger.warn("key={},value={},msg={}", key, value, e.getMessage());
            this.releaseSSDB(ssdb, true);
            if (tryTimes > 0) {
                save(key, value, tryTimes -1);
            }
        }
    }

    public void save(String key, String value, Integer ttl) {
        save(key, value, ttl, count);
    }

    private void save(String key, String value, Integer ttl, int tryTimes) {
        SSDB ssdb = null;
        try {
            ssdb = this.getSSDB();
            ssdb.setx(key, value.getBytes("UTF-8"), ttl);
            this.releaseSSDB(ssdb, false);
        } catch (Exception e) {
            logger.warn("key={},value={},msg={}", key, value, e.getMessage());
            this.releaseSSDB(ssdb, true);
            if (tryTimes > 0) {
                save(key, value, ttl,tryTimes -1);
            }
        }
    }

    public void del(String key) {
        this.del(key, count);
    }

    private void del(String key, int tryTimes) {
        SSDB ssdb = null;
        try {
            ssdb = this.getSSDB();
            ssdb.del(key);
            this.releaseSSDB(ssdb, false);
        } catch (Exception e) {
            logger.warn("key={},msg={}", key, e.getMessage());
            this.releaseSSDB(ssdb, true);
            if (tryTimes > 0) {
                del(key,tryTimes -1);
            }
        }
    }

    public String monitor() {
        return "connect state:" + this.connMap.values();
    }

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public int getTimeoutMs() {
        return timeoutMs;
    }

    public void setTimeoutMs(int timeoutMs) {
        this.timeoutMs = timeoutMs;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

你可能感兴趣的:(Java,架构&设计模式)