背景
工作长达10多年来,也许是Redis命令敲多了,突然有一个不想敲redis命令的冲动,于是就开始设计这款Redis图形化客户端。那么这次有人肯定会问我,Redis客户端有那么多,为什么不直接用,而要浪费时间去开发一个呢?关于此问题我的答案是:我有那个实力!
哈哈哈,当然不是这个原因,真实原因是市面上的Redis客户端大多很丑陋,只提供了图形来展示信息功能弱,而实现一个Redis客户端也用不了多少代码,于是才做的此决定。
下载地址
-
软件支持Windwos 版本、Mac版本
-
下载地址:bg-boom-ui
软件特点
-
纯Java开发
-
免费使用
-
支持Redis 图形化操作String、Hash、Set、ZSet、List的操作
-
支持Redis客户端命令行操作,并带有输入提示
-
支持Redis的慢指令监控
-
支持Redis执行的指令,逆监控
-
支持自动识别单机或集群操作,简化了集群客户端的使用方式
-
当然还有很重要的是支持美轮美奂的皮肤功能
软件截图
实现原理
软件是用纯Java实现的,底层并没有使用Netty去与redis通信,而是使用Jedis直接实现,其核心的实现代码不足两百行:
package com.madou.dbtool.redis.manager;
import com.madou.common.annotation.HideClass;
import com.madou.dbtool.language.redis.parser.RedisContentTypeParser;
import com.madou.inters.util.TipUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisMonitor;
import redis.clients.jedis.Protocol;
import redis.clients.jedis.params.ScanParams;
import redis.clients.jedis.resps.ScanResult;
import java.io.UnsupportedEncodingException;
import java.util.*;
/**
* @author miukoo
* Redis 直连客户端
*/
@HideClass("directRedisSourceManager")
public class DirectRedisSourceManager implements RedisSourceManager {
String host;
int port;
Jedis jedis;
String password;
// 标记是否为集群
boolean cluster=false;
// 集群连接器
ClusterRedisSourceManager clusterRedisSourceManager;
public DirectRedisSourceManager(String host,int port,String password){
this.host = host;
this.port = port;
this.password = password;
}
private synchronized Jedis connection(){
if(jedis==null||!jedis.isConnected()) {
try {
jedis = new Jedis(host, port);
if (password != null && password != "") {
jedis.auth(password);
}
jedis.info();
}catch (Exception e){
TipUtils.showErrorDialog("连接失败:"+e.getMessage(),"Tips");
}
}
return jedis;
}
@Override
public int getDBCount() {
connection();
return Integer.parseInt(jedis.configGet("databases").get(1));
}
@Override
public boolean isCluster() {
return cluster;
}
@Override
public List<RedisNodeInfo> getNodes() {
connection();
String info = jedis.info();
List<RedisNodeInfo> list = new ArrayList<>();
if(info.contains("cluster_enabled:1")){
cluster=true;
ClusterRedisSourceManager clusterRedisSourceManager = new ClusterRedisSourceManager(host,port,password);
String[] nodes = jedis.clusterNodes().split("\n");
for (String node : nodes) {
String tmp[] = node.split(" ");
String addr[] = tmp[1].split("@");
RedisNodeInfo redisNodeInfo = new RedisNodeInfo();
redisNodeInfo.setIp(addr[0].split(":")[0]);
redisNodeInfo.setPort(Integer.valueOf(addr[0].split(":")[1]));
redisNodeInfo.setRole(tmp[2]);
if(redisNodeInfo.getIp().equals(host)&&redisNodeInfo.getPort()==port){
redisNodeInfo.setRedisSourceManager(new ClusterRedisSourceManager(host,port,password,this));
}else {
redisNodeInfo.setRedisSourceManager(new ClusterRedisSourceManager(redisNodeInfo.getIp(),redisNodeInfo.getPort(),password));
}
list.add(redisNodeInfo);
}
}else {
RedisNodeInfo redisNodeInfo = new RedisNodeInfo();
redisNodeInfo.setIp(host);
redisNodeInfo.setPort(port);
redisNodeInfo.setRedisSourceManager(this);
list.add(redisNodeInfo);
}
return list;
}
@Override
public Long getDBSize(int index) {
connection();
jedis.select(index);
return jedis.dbSize();
}
/**
* 获取第一页的数据
* @return
*/
@Override
public List<String> getFirst(int index) {
connection();
jedis.select(index);
return jedis.scan("").getResult();
}
/**
* 执行命令
* @param commandText
* @return
*/
@Override
public Object execute(int index,String commandText){
connection();
if(index>=0) {
jedis.select(index);
}
String[] temp = commandText.trim().split(" ");
Protocol.Command command = Protocol.Command.valueOf(temp[0].toUpperCase(Locale.ROOT));
List<String> args = new ArrayList<>();
for (int i = 1; i < temp.length; i++) {
if(temp[i]!=""&&temp[i]!=" "){
args.add(temp[i]);
if(i==1) {
RedisContentTypeParser.redisKeywordTrieLoader.addWord(temp[i]);
}
}
}
String[] commandArgs = new String[args.size()];
args.toArray(commandArgs);
if(commandText.length()<20){
RedisContentTypeParser.redisKeywordTrieLoader.addWord(commandText);
}
return jedis.sendCommand(command, commandArgs);
}
/**
* 开启监控
* @param jedisMonitor
* @return
*/
@Override
public void monitor(JedisMonitor jedisMonitor){
connection();
jedis.monitor(jedisMonitor);
}
@Override
public RedisSourceManager cloneDirect() {
return new DirectRedisSourceManager(host,port,password);
}
@Override
public RedisSourceManager cloneCluster() {
return cloneDirect();
}
@Override
public void close() {
if(jedis!=null){
jedis.disconnect();
jedis.close();
jedis = null;
}
}
}