如何剖析一个项目之Redis(一)

拆解的项目源码地址:
https://github.com/xk4848123/ef-redis

感谢开源!!!


如何剖析一个项目之Redis(一)
如何剖析一个项目之Redis(二)
如何剖析一个项目之Redis(三)

已知

这是一款阉割的Java版的redis,通信基于Netty编写。

已知的未知(该篇我们能学到什么)

一个命令被该系统接收到后,是如何处理然后又返回的。

解决已知的未知

我们先准备一个redis-client(我这里用的Windows)。

windows版redis下载地址

下载完成后,我们开始调试这个java版的redis。

在这里插入图片描述
用这个main方法来启动该redis服务!


redis已启动!!!

在这里插入图片描述
可以看出启动时候实际上是启动了一个Netty的服务端,redis-cli客户端首先会建立网络连接,然后通过该连接发送命令,这里首先会使用CommandDecoder来解码。

public class CommandDecoder extends LengthFieldBasedFrameDecoder
{
   
    private static final Logger LOGGER = Logger.getLogger(CommandDecoder.class);
    private static final int MAX_FRAME_LENGTH = Integer.MAX_VALUE;
    private  Aof aof=null;
//    static {
   
//        if(PropertiesUtil.getAppendOnly()) {
   
//            aof=new Aof();
//        }
//    }
    public CommandDecoder(Aof aof){
   
        this();
        this.aof=aof;
    }
    public CommandDecoder() {
   
        super(MAX_FRAME_LENGTH, 0, 4);
    }
    @Override
    public Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
   

        TRACEID.newTraceId();
        while (in.readableBytes() != 0)
        {
   
            int mark = in.readerIndex();
            try
            {
   
                Resp resp = Resp.decode(in);
                if (!(resp instanceof RespArray||resp instanceof SimpleString))
                {
   
                    throw new IllegalStateException("客户端发送的命令应该只能是Resp Array 和 单行命令 类型");
                }
                Command command=null;
                if(resp instanceof RespArray) {
   
                    command = CommandFactory.from((RespArray) resp);
                }else if(resp instanceof SimpleString){
   
                    command  = CommandFactory.from((SimpleString) resp);

                }
                if (command == null)
                {
   
                    //取出命令
                    ctx.writeAndFlush(new Errors("unsupport command:" + ((BulkString) ((RespArray) resp).getArray()[0]).getContent().toUtf8String()));
                }
                else
                {
   
                    if (aof!=null&&command instanceof WriteCommand) {
   
                        aof.put(resp);
                    }
                    return command;
                }
            }
            catch (Exception e)
            {
   
                in.readerIndex(mark);
                LOGGER.error("解码命令", e);
                break;
            }
        }
        return null;
    }

LengthFieldBasedFrameDecoder快速了解

使用redis-cli发送命令:set hello world。
在这里插入图片描述
redis通信协议详细指南

这一条命令按照通信协议会呈现出这种样子。

*3
$3
SET
$5
hello
$7
world

redis-cli发出命令后CommandDecoder的decode方法会被调用,该方法中会调用Resp的decode静态方法解析命令。

 static Resp decode(ByteBuf buffer) {
   
        if (buffer.readableBytes() <= 0) {
   
            new IllegalStateException("没有读取到完整的命令");
        }
        char c = (char) buffer.readByte();
        if (c == RespType.STATUS.getCode()) {
   
            return new SimpleString(getString(buffer));
        } else if (c == RespType.ERROR.getCode()) {
   
            return new Errors(getString(buffer));
        } else if (c == RespType.INTEGER.getCode()) {
   
            int value = getNumber(buffer);
            return new RespInt(value);
        } else if (c == RespType.BULK.getCode()) {
   
            int length = getNumber(buffer);
            if (buffer.readableBytes() < length + 2) {
   
                throw new IllegalStateException("没有读取到完整的命令");
            }
            byte[] content;
            if (length == -1) {
   
                content = null;
            } else {
   
                content = new byte[length];
                buffer.readBytes(content);
            }
            if (buffer.readByte(
  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值