[Netty ]自己实现一个redis客户端难吗?

用Netty实现Redis 这是一个用Netty实现的Redis(服务器版本) github地址:https://github.com/pyb1993/JavaRedis 目的有三: 深入理解redis,将redis上的各种功能慢慢迁移到java上来 用C语言来实现太麻烦了,而且一般工作中用不到C,加上我前两个项目(编译器和http服务器)都是用c写的,正好练习一下Java 降低开发难度,对于一些功能可以更轻松的... 阅读详情

📣 📣 📣 📢📢📢
☀️☀️你好啊!小伙伴,我是小冷。是一个兴趣驱动自学练习两年半的的Java工程师。
📒 一位十分喜欢将知识分享出来的Java博主⭐️⭐️⭐️,擅长使用Java技术开发web项目和工具
📒 文章内容丰富:覆盖大部分java必学技术栈,前端,计算机基础,容器等方面的文章
📒 如果你也对Java感兴趣,关注小冷吧,一起探索Java技术的生态与进步,一起讨论Java技术的使用与学习
✏️高质量技术专栏专栏链接: 微服务,数据结构,netty,单点登录,SSM ,SpringCloudAlibaba等
😝公众号😝 : 想全栈的小冷,分享一些技术上的文章,以及解决问题的经验
⏩当前专栏:Netty 实战系列
⏩专栏代码地址: Netty练手项目仓库地址

Netty:模拟Redis的客户端

因为redis是部署在服务器上的 我们只需要模拟客户端发送请求即可所以只需要编写客户端的代码就可以了

前置知识

编写前我们需要知道 redis的请求规范

Redis 的通信 是需要遵循 RESP 协议的

例子:

set hello 123
*3\r\n $3 \r\n set \r\n hello \r\n 123

建立 channel 通道后 发送命令给服务端 此时是写数据【输出】 在出战handler里增加逻辑 当接受响应后 此时数据需要【输入】 存入栈 handler 中 在入栈handler 里增加逻辑

Netty中 Redis 命令对应的类型

  • 单行
  • 错误
  • 整形数字
  • 批量回复
  • 多个批量回复

客户端

我们只需要编写客户端。请求搭建redis的服务器接受和传输数据即可就可以了

客户端还是常见的写法

public class RedisClient {
    private static final String HOST = "xxxxxxxxx";
    private static final int PORT = 6379;

    public static void main(String[] args) {
        NioEventLoopGroup bossGroup = new NioEventLoopGroup();
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(bossGroup)
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        //  调用netty 提供的支持netty 协议的编解码器
                        //    RedisBulkStringAggregator 和 RedisarrayAggregator 是协议中两种特殊格式的聚合器
                        ChannelPipeline pipeline = socketChannel.pipeline();
                        pipeline.addLast(new RedisDecoder());
                        pipeline.addLast(new RedisBulkStringAggregator());
                        pipeline.addLast(new RedisArrayAggregator());
                        pipeline.addLast(new RedisEncoder());
                        // 我们自己的处理器
                        pipeline.addLast(new RedisClientHandler());
                    }
                });
        try {
            ChannelFuture syncFuture = bootstrap.connect(HOST, PORT).sync();
            System.out.println("enter redis commands");
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
            for (; ; ) {
                String input = bufferedReader.readLine();
                //退出任务
                if ("quit".equals(input)) {
                    syncFuture.channel().close().sync();
                    break;
                }
                syncFuture.channel().writeAndFlush(input).sync();
            }
            syncFuture.channel().closeFuture().sync();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            bossGroup.shutdownGracefully();
        }
    }
}

处理器

因为要读取和写入 所以我们需要集成混合处理器类 : ChannelDuplexHandler

我们需要判断五种请求类型 所以先封装一个类别输出的方法

RedisMessage Netty提供的redis的信息对象,以下五种类型都来自于它

    private void printRedisResponse(RedisMessage msg) {
        if (msg instanceof SimpleStringRedisMessage) {
            SimpleStringRedisMessage tmpMsg = (SimpleStringRedisMessage) msg;
            System.out.println(tmpMsg.content());
        } else if (msg instanceof ErrorRedisMessage) {
            ErrorRedisMessage tmpMsg = (ErrorRedisMessage) msg;
            System.out.println(tmpMsg.content());
        } else if (msg instanceof IntegerRedisMessage) {
            IntegerRedisMessage tmpMsg = (IntegerRedisMessage) msg;
            System.out.println(tmpMsg.value());
        } else if (msg instanceof FullBulkStringRedisMessage) {
            FullBulkStringRedisMessage tmpMsg = (FullBulkStringRedisMessage) msg;
            if (tmpMsg.isNull()) {
                return;
            }
            System.out.println(tmpMsg.content().toString(CharsetUtil.UTF_8));
        } else if (msg instanceof ArrayRedisMessage) {
            ArrayRedisMessage tmpMsg = (ArrayRedisMessage) msg;
            for (RedisMessage child : tmpMsg.children()) {
                printRedisResponse(child);
            }
        }
        // 如果都是不是应该抛出异常
    }

写命令

    // 写
    // 出栈handler 的常用方法
    //需要处理redis 命令
    @Override
    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
        // 键盘传入的字符串 如 : keys *
        String commandStr = (String) msg;
        // 通过空格来分离出命令
        String[] commandArr = commandStr.split("\\s+");
        // 接受redis 命令的列表  RedisMessag保存命令的内容
        List<RedisMessage> redisMessageList = new ArrayList<>(commandArr.length);
        for (String cmdStr : commandArr) {
            FullBulkStringRedisMessage message = new FullBulkStringRedisMessage(
                    ByteBufUtil.writeUtf8(ctx.alloc(), cmdStr));
            redisMessageList.add(message);
        }
        //将分离的命令 合并成一个完整的命令
        RedisMessage request = new ArrayRedisMessage(redisMessageList);
        //写入通道
        ctx.write(request, promise);
    }

读取命令

// 读取
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    // 此时接受的时候这个值 就是我们存储redismessage 的对象
    RedisMessage redisMessage = (RedisMessage) msg;
    // 返回的结果是不同类型 分开进行处理
    printRedisResponse(redisMessage);
    //    内存管理使用了 引用计数的方式 所以我们需要释放资源
    ReferenceCountUtil.release(redisMessage);
}

演示效果

image-20220416181606909

用Java手写Redis服务端,从设计者的角度聊一聊Redis本身 零,起因我为什么要造redis这个轮子?1,破除对redis神秘感。2,“基础服务中台”的同事们在开会讨论redis云,以及redis代理。3,开一个redis资源并不是容易事,为什么不可以不可以写成java直接推送到未来云上,简单方便。以这个思路我开始使用业余时间研究了redis的tcp通讯原理与redis命令,出发点是写一个redis云代理之类的云管理软件,但是还是忍不住写成了java版的re... 阅读详情

相关推荐

基于Netty手写一个远程连接Redis的IDEA插件

我想问下大家当初选择做程序员的初衷是什么?有思考过这个问题吗?高薪?热爱?既然入了这行就应该知道,这个行业是靠本事吃饭的,你想要拿高薪没有问题,请好好磨练自己的技术,不要抱怨。有的人通过培训可以让自己成长,有些人可以通过自律强大的自学能力成长,如果你两者都不占,还怎么拿高薪?架构师是很多程序员的职业目标,一个好的架构师是不愁所谓的35岁高龄门槛的,到了那个时候,照样大把的企业挖他。为什么很多人想进阿里巴巴,无非不是福利待遇好以及优质的人脉资源,这对个人职业发展是有非常大帮助的。

m0_58269070的博客 980

Netty、Redis、Zookeeper高并发实战

Netty、Redis、 ZooKeeper,作为高性能、高并发、高可用的实力代表,在争取一个有吸引力、薪酬竞争力的offer时,都是必须掌握的Java中间件。

公众号:该用户快成仙了 366

用Netty解析Redis网络协议

用Netty解析Redis网络协议根据Redis官方文档的介绍,学习了一下Redis网络通信协议。然后偶然在GitHub上发现了个用Netty实现的Redis服务器,很有趣,于是就动手实现了一下!1.RESP协议Redis的客户端与服务端采用一种叫做 RESP(REdis Serialization Protocol)的网络通信协议交换数据。RESP的设计权衡了实现简单、解析快速、人类可读这三个因素

西代零零发 1万+

Java NIO(Netty,Redis,Zookeeper高并发实战整理)

Java NIO NIO与OIO的对比 1.OIO事面向流的,NIO是面向缓冲区的。OIO是面向字节流或字符流的,在一般的OIO操作中,一流式的方法顺序地从一个流中读取一个或多个字节,因此,不能随意地改变读取指针的位置。NIO中引入了Channel(通道)和Buffer(缓冲区)的概念。读取和写入,只需要从通道中读取数据到缓冲区中,或将数据从缓冲区中写入到Channel中。可以随意地读取Buffer中任意位置的数据。 2.OIO的操作是阻塞的,而NIO的操作是非阻塞的。 3.OIO没有选择器的概念,而NIO

朱夏彤的博客 6155

分布式IM及Netty服务集群解决方案

一、概述 使用netty开发分布式Im,提供分布netty集群解决方案。服务端通过负载均衡策略与服务集群建立连接,消息发送通过服务间集群的通信进行消息转发。 二、集群架构 三、项目地址 https://github.com/beardlessCat/im,烦请star 1.客户端 用户聊天客户端,客户端连接IM服务需要进行用户认证。用户认证成功之后,开始连接上线。 2.服务路由 服务路由负责将客户端的连接请求按照不同的负载均衡策略路由到不同的IM服务,建立长链接。负载均衡策略分为以下四种: 一致性HAS

绿眼加菲的博客 1万+

netty+redis

实现了服务器和客户端的连接 加入redis配置,客户端可以发消息给服务器,服务器能接受消息,可以发消息给客户端,采用JFRAM页面。 但是有个问题:没有实现服务器向多个客户端发消息的机制,客户端接收不到, 原因:我用第三方缓存保存客户端注册过来的连接对象ChannelHandlerContext,保存不了 因为这个对应没有被序列化。致使服务器缓存没有办法保存客户端的消息对象。 大家有什么办法可以交流交流。

基于netty实现redis服务(解析redis协议密码验证)

最近使用redis缓存,但是不允许客户端直接连接redis服务器,需要模拟redis的服务器,实现redis的get\set\del\auth基础功能。 网上该场景的解决方案不多,文章如有问题,请指正以备完善。 使用netty来实现,Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序,Netty 是一个基于NIO的客户、服务器端的编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议(redis协议)的客户、服务端应用

weixin_43241706的博客 3039

Qt 5.12.8在Linux下编译qtvirtualkeyboard模块,我踩过的那些坑(附完整解决方案)

本文详细介绍了在Linux系统下为Qt 5.12.8单独编译qtvirtualkeyboard模块的完整解决方案。通过分析模块缺失原因、提供精准的编译步骤和常见问题处理,帮助开发者高效解决虚拟键盘模块缺失问题,避免重新编译整个Qt源码的繁琐过程。

weixin_29248611的博客 457

netty之实现一个redis的客户端

本文看下如何使用redis来实现一个类似于redis官方提供的redis-cli.exe的客户端工具。

wang0907的博客 925

从实验室到生活:构建一份全面的手机相机主观画质评测指南

本文详细介绍了如何从实验室数据转向实际体验,构建全面的手机相机主观画质评测指南。通过基础装备清单、室内外场景实战评测及数据之外的感知艺术,帮助用户发现手机相机在色彩还原、动态范围和夜景模式等方面的真实表现。特别关注主观体验与客观参数的差异,提供实用的评测技巧和报告撰写心法。

weixin_30940783的博客 307

使用Docker搭建SearXNG搜索引擎

【代码】使用Docker搭建SearXNG搜索引擎。

janthinasnail的博客 1153

netty+springBoot+webSocket+redis实现各个客户端之间通信、及时聊天等功能

本项目用到的技术 1、netty框架,为什么要使用netty框架呢?netty框架是基于Nio的,那和传统的Bio有什么区别呢? Bio BIO 有的称之为 basic(基本) IO,有的称之为 block(阻塞) IO,主要应用于文件 IO 和网络 IO, 这里不再说文件 IO, 在 JDK1.4 之前,我们建立网络连接的时候只能采用 BIO,需要先在服务端启动一个 ServerSocket,然...

qq_30765051的博客 6326

尝试使用CubeMX做stm32开发之九:SYS配置

参考《STM32中文参考手册_V10》,研究CubeMX中有关SYS的配置

Forster-C的博客 9419

Netty在Redis客户端中的应用

在我们日常使用Redis实现分布式锁中,依赖如下 <dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>3.10.1</version> </dependency> 在使用Redisson作为客户端,它需要与服务端进行通信,那么它的底层通信使用的是Netty. 在启动

书唐瑞的博客 1170

道闸不自动落杆故障排查:从传感器原理到控制器调试全解析

在工业自动化和物联网系统中,传感器与控制器构成的闭环控制是保障设备可靠运行的核心。其基本原理是通过传感器采集环境状态,控制器依据预设逻辑做出决策并驱动执行器动作。这一技术价值在于实现了无人值守下的安全、高效自动化,广泛应用于智能交通、安防和智能楼宇等领域。以停车场道闸系统为例,其自动落杆功能高度依赖地感线圈与防砸雷达的协同。地感线圈作为触发单元,负责感知车辆接近;而防砸雷达则作为持续监测的安全单元,通过微波探测防砸区域内是否有障碍物,其信号是控制器执行落杆决策的关键依据。当系统出现车辆通过后闸杆不落的典型故

weixin_29190651的博客 307

QT上位机开发(掌握一点c++基础)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 c++是c语言的补充和扩展,本身的语法构成也是在一直迭代中。相信很多同学上大学读书的时候,或多或少对c语言有所了解,对它的变量、指针、函数也应该不陌生。既然大家都有c语言基础的话,那么在这方面稍微拓展一下的话,就可以学会c++了。当然c++本身的内容很多,很多方面还很琐碎,但我们学习的时候还是应该把精力放在那些经常使用到的语法上面。

嵌入式-老费,一个分享专业嵌入式知识的blog 1130

Netty 入门应用:结合 Redis 实现服务器通信

通过这个简单的结合 Redis 的服务端示例,我们展示了如何使用 Netty 接收客户端的请求,并结合 Redis 进行数据存取操作。在实际的应用场景中,Netty 可以用于处理高并发的客户端请求,而 Redis 作为内存存储,可以存储临时数据或常用的数据以提高响应速度。我们可以用 Netty 作为服务端,接受客户端的数据请求,并将数据存储或读取到 Redis 中。在这个示例中,我们将构建一个 Netty 服务端来接收客户端的存取请求,将数据存储到 Redis 中,或者从 Redis 获取并返回给客户端。

秋元的博客 1716

YOLO26改进策略【卷积层】| SPD-Conv 针对小目标和低分辨率图像的检测任务

SPD-Conv是一种新的 CNN 构建模块,用于替代传统 CNN 架构中使用的步长卷积(strided convolution)和池化(pooling)层,它由空间到深度(Space-to-depth,SPD)层和非步长卷积(non - strided convolution)层组成。

Limiiiing的博客 356

redis 客户端_Netty在Redis客户端中的应用

在我们日常使用Redis实现分布式锁中,依赖如下<dependency> <groupId>org.redissongroupId> <artifactId>redissonartifactId> <version>3.10.1version>dependency>在使用Redisson作为客户端,它需要...

weixin_39878247的博客 726

【异常】Milvus 向量数据库字段缺失错误分析与解决 MilvusVectorStoreServiceV2 - Failed to insert batch [0-1]: The field:

本文分析了Milvus向量数据库插入操作中出现的字段缺失错误。错误显示age_mode字段未提供,导致批量插入失败。根本原因是Milvus Schema要求所有定义字段必须存在,但代码中对部分字段采用条件添加方式。解决方案是将条件添加改为始终添加,为可能为null的字段提供空字符串默认值。文章总结了Schema约束、防御性编程等经验,并建议通过Schema变更检查、单元测试覆盖和数据校验层等预防措施避免类似问题。该问题影响product、mac、source等多个字段,修改后确保了数据插入的可靠性。

奶爸的编程之路,也就一周冷个三天 403

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

基于Netty的Redis客户端-Nedis

最近温习了一遍Redis命令,忧伤的是很多东西已交还给老师,正好赶上antirez大神在愚人节发布了Redis 3.0,Redis终于有了支持集群的正式版本,于是心血来潮决定自己实现一个Redis客户端来抚慰我这颗忧伤的心灵。 Jedis已经足够强大,它的网络连接是基于阻塞式IO,实现非常简单易懂,但是OIO和NIO相比性能上有劣势,于是决定通过NIO来实现和Redis服务器的网络连接,现在

pentiumchen的专栏 5642

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

了解 Redisson:一个强大的 Redis 客户端

Redisson是一个基于 Redis 的 Java 客户端,它提供了对 Redis 数据类型的封装,并扩展了 Redis 的功能,使得 Java 应用程序可以方便地与 Redis 进行交互。Redisson 基于Netty实现,支持高效的非阻塞 I/O 操作,且提供了多种高级功能,适合于分布式系统和高并发场景。与传统的 Redis 客户端(如 Jedis 和 Lettuce)不同,Redisson 提供了更加丰富的 API,支持 Redis 的各种数据结构,如字符串、哈希、列表、集合、排序集合等。

m0_69178550的博客 1415

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Netty框架之协议应用一(redis客户端简单实现以及使用websocket实现弹幕功能)

前言 今天小编带大家继续学习netty框架的应用,接下来的几篇文章都是讲解其应用,帮助大家理解一些高级框架底层的一些网络传输。话不多说进入正题。 redis客户端实现 redis网络传输采用的是文本协议,同时兼顾了二进制协议的优点,体积小,既保证了传输的效率又保证了可读性。可谓一箭双雕。相信大家在开发过程中使用过redis的客户端jedis,jedis也是非常好的客户端但是他使用的是BIO模式。目前可能采用Lettuce比较多,当然Redisson有更加强大的功能。小编推荐使用Lettuce,大家可以自行搜

a1032722788的博客 942

使用netty实现redis客户端连接

1、pom文件 <dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.1.75.Final</version> </dependency> 2、客户端处理实现 RedisClientHand.

zsj777的专栏 1071

Netty + Redis + Websocket IM 分布式集群实现

常量表 Constants.java /** * 项目中的全局常量定义 */ public interface Constants { String WEBSOCKET_STR = "websocket"; String UPGRADE_STR = "Upgrade"; int OK_CODE = 200; String HTTP_CODEC...

轰轰烈烈的生活 8067
上一篇: Netty网络框架 :HTTP模拟文件列表服务器
下一篇: 【Netty】Netty+springboot实现IM即时通讯服务端
冷环渊
博客等级 码龄7年 1130粉丝 176原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冷环渊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值