博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Lettuce快速入门
阅读量:2438 次
发布时间:2019-05-10

本文共 3698 字,大约阅读时间需要 12 分钟。

最近在开发一个使用Redis协议包装HBase的Proxy服务器,一路写的很顺,客户端使用redis-py提供的execute_command方法也轻松搞定。但是在编写Java客户端的时候却遇到了难题,我们常用的Jedis不提供自定义指令,连反射这条路子都给堵死了,感觉陷入了僵局。难道需要自己改造Jedis的源代码么,代价有点大。

转念一想,Redis4.0插件化都出来了,有那么多的自定义指令,官方肯定有客户端的解决方案,果然,Lettuce【莴笋】冒出来了,945个Star,看来很受欢迎。

0?wx_fmt=jpeg

看Lettuce项目介绍,它是基于Netty开发的,提供了同步异步两种调用方法,支持Pipeline,也支持Redis Sentinel和Cluster,最重要的是它支持自定义指令。还在使用Java7以下的小伙伴们就要叹息了,Lettuce只支持Java8+,赶快升级吧。

好,我们来试试Lettuce,看看它好不好用,首先引入依赖

   
io.lettuce
   
lettuce-core
   
5.0.0.RELEASE

再看看它的基本用法

public class LettuceTest {	public static void main(String[] args) {		RedisClient client = RedisClient.create("redis://localhost:6379/0");		StatefulRedisConnection
connection = client.connect(); // 获取一个连接 RedisCommands
commands = connection.sync(); // 获取同步指令集 commands.set("dream-codehole", "Yui Aragaki"); System.out.println(commands.get("dream-codehole")); commands.zadd("dreams-codehole", 10, "Yui Aragaki"); commands.zadd("dreams-codehole", 8, "Elane Zhong"); System.out.println(commands.zcard("dreams-codehole")); connection.close(); // 关闭连接 client.shutdown(); // 关闭所有连接 }}

好像和Jedis用法一样简单。Lettuce还支持异步用法,我们来看看异步怎么用。

public class LettuceTest {	public static void main(String[] args) {		RedisClient client = RedisClient.create("redis://localhost:6379/0");		StatefulRedisConnection
connection = client.connect(); // 获取一个连接 RedisAsyncCommands
commands = connection.async(); // 获取异步指令集 RedisFuture
future1 = commands.get("dream-codehole"); future1.whenComplete((value, e) -> { System.out.println(value); }); RedisFuture
future2 = commands.zcard("dreams-codehole"); future2.whenComplete((value, e) -> { System.out.println(value); }); try { Thread.sleep(1000); // 等一会,保证结果在连接关闭之前都拿到了 } catch (InterruptedException e1) { }                connection.close(); client.shutdown(); }}

使用也很简单,异步的结果都使用RedisFuture对象进行包装。RedisFuture对象提供了大量的回调方法,任君选择。注意关闭连接之前一定要等待一段时间,确保所有的指令都异步执行完了,否则你的回调方法会统一收到NULL。

在使用Redis一般不会只使用一个连接的,我们一般会使用连接池。Jedis提供了内置的JedisPool封装,拿来即用,内部使用的是Apache Commons提供的对象池来实现。Lettuce的连接池用起来也差不多。

public class LettuceTest {	public static void main(String[] args) throws Exception {		RedisClient client = RedisClient.create("redis://localhost:6379/0");		GenericObjectPool
> pool = ConnectionPoolSupport .createGenericObjectPool(() -> client.connect(), new GenericObjectPoolConfig()); try (StatefulRedisConnection
connection = pool.borrowObject()) { RedisCommands
commands = connection.sync(); commands.set("dream-codehole", "Yui Aragaki"); System.out.println(commands.get("dream-codehole")); commands.zadd("dreams-codehole", 10, "Yui Aragaki"); commands.zadd("dreams-codehole", 8, "Elane Zhong"); System.out.println(commands.zcard("dreams-codehole")); } pool.close(); client.shutdown(); }}

接下来我们进入最精彩的部分,也是Lettuce区别于Jedis最大的部分,Lettuce提供了自定义指令接口。实现自定义指令需要提供3个东西。

  1. 指令名称

  2. 参数

  3. 结果解码器

public class HBaseClient {	private RedisCommands
commands; private StringCodec codec = new StringCodec(); public boolean create(String table, List
families) { CommandArgs
args = new CommandArgs<>(codec); args.add(table); args.addKeys(families); return commands.dispatch(HBaseCommand.CREATE, new BooleanOutput
(codec), args); }}

create指令的的参数是一个字符串列表,表名和列簇的字符串定义,返回结果就是一个bool值。在redis协议中,客户端指令参数就是一个字符串列表,没有复杂的结构,但是返回结果却是可以任意嵌套的,可以具有无限的深度。对于大部分指令,Lettuce内置提供的很多Output解码器足以应付,不能应付的部分,Lettuce提供了扩展的接口可以自定义。

0?wx_fmt=jpeg
内置丰富的解码器

我们看到所有的解码器都是继承了CommandOutput接口,当我们想要自定义指令时,继承这个接口就可以了,然后在子类里实现你想要的任意复杂的解码逻辑。

0?wx_fmt=jpeg

转载地址:http://qtbqb.baihongyu.com/

你可能感兴趣的文章
实验-闪回数据库
查看>>
实验-闪回表
查看>>
oracle审计
查看>>
日期格式的转换
查看>>
JavaScript:charCodeAt()和codePointAt()的区别
查看>>
JavaScript:Array数组
查看>>
JavaScript:toString()和toLocaleString()的区别
查看>>
jquery 中remove()与detach()的区别
查看>>
Markdown入门1-概述、定义、优点、缺点、应用场景、在线编辑器
查看>>
Markdown入门2-标题、引用、列表、代码、分隔线
查看>>
本站地图--程序员
查看>>
Markdown技巧
查看>>
Markdown入门3-链接、强调、代码、图片
查看>>
Markdown入门6-序列图
查看>>
SQLite的性能优化
查看>>
SQLite的并发处理
查看>>
cocos2d-x on wp8架构简介
查看>>
cocos2d-x中对象的位置,旋转,缩放
查看>>
cocos2d-x 的动画
查看>>
Camera相关技术
查看>>