使用了不到200行的核心代码就实现了一个美轮美奂的Redis客户端
2023-06-13 09:15:53 时间
背景
工作长达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;
}
}
}
相关文章
- Redis(六):java里常用的redis客户端(Jedis和Redisson)详解大数据
- 操纵Redis客户端操控:从入门到精通(redis客户端)
- 探讨Redis与数据库之间的差异(redis与数据库的区别)
- 构建利用Redis客户端构建简易数据库(redis客户端方式)
- Redis代码分析:探索高性能数据存储魅力(redis代码分析)
- Redis代码编写指南简单易行(怎么写redis代码)
- 如何在苹果电脑上安装Redis客户端(苹果安装redis客户端)
- 探究Redis客户端的秘密(查看redis的客服端)
- 部署Redis,架构稳定性大幅提升(服务器上部署redis)
- 从0开始学习克隆Redis代码(克隆redis代码)
- 利用Redis管道实现多客户端协作(多客户端redis 管道)
- 快速启用支持异步功能的Redis客户端(启用异步redis客户端)
- Redis有必要么(redis 需要吗)
- 客户端Java客户端快速关闭Redis连接(关闭redis的java)
- 基于Redis实现代码块级别的锁定(redis锁实现锁代码块)
- Redis简单实现非密码访问(redis设置非密码)
- 利用Redis分分钟设置数据存储时限(redis 设置存储时间)
- Redis最大订阅数上限探究(redis 订阅上限)
- 使用Redis自带客户端快速访问(redis自带客户端访问)
- 查看Redis缓存的简单命令指南(redis查看缓存的命令)