盘点一下Redis中常用的Java客户端,或者咱们手写一个?
mhr18 2024-10-27 10:51 35 浏览 0 评论
Java中那些Redis的客户端
前面我们的所有操作都是基于redis-cli来完成的,那么我们要在Java中操作Redis,怎么做呢?首先我们先来了解一下Redis Serialization Protocol(Redis序列化协议),这个是Redis提供的一种,客户端和Redis服务端通信传输的编码协议,服务端收到罅隙ihou,会基于这个约定编码进行解码。
打开Wireshark工具,对VMnet8这个网络进行抓包
增加过滤条件
ip.dst_host==192.168.221.128 and tcp.port in {6379}
使用RDM工具连接到Redis Server进行key-value操作,比如执行 set name mic
通过Wireshark工具监控数据包内容,如图3-3所示,可以看到实际发出的数据包是:
*3\r\n$3\r\nSET\r\n$4\r\nname\r\n$3\r\nmic
其中
*3*
代表参数个数,set name mic, 表示三个参数。$3
表示属性长度,$
表示包含3个字符。
客户端和服务器发送的命令或数据一律以 \r\n (CRLF回车+换行)结尾。
图3-3
基于这样一个特性,我们可以自己实现一个Java客户端。
自定义Redis客户端
下面我们通过抓包相关的命令,了解Redis客户端的工作机制。
定义常量池。
public class CommandConstant {
/**
* 开始符
*/
public static final String START = "*";
/**
* 指令长度符
*/
public static final String LENGTH = "#34;;
/**
* 换行符
*/
public static final String LINE = "\r\n";
public enum CommandEnum {
SET,
GET,
INCR
}
}
CustomClientSocket
CustomClientSocket用来建立网络通信连接,并且发送数据指定到RedisServer。
public class CustomClientSocket {
private Socket socket;
private InputStream inputStream;
private OutputStream outputStream;
public CustomClientSocket(String ip,int port) {
try {
socket=new Socket(ip,port);
inputStream=socket.getInputStream();
outputStream=socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
public void send(String cmd){
try {
outputStream.write(cmd.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
public String read(){
byte[] bytes = new byte[1024];
int count = 0;
try {
count = inputStream.read(bytes);
} catch (IOException e) {
e.printStackTrace();
}
return new String(bytes, 0, count);
}
}
封装客户端
public class CustomRedisClient {
private CustomClientSocket customClientSocket;
public CustomRedisClient(String host,int port) {
customClientSocket=new CustomClientSocket(host,port);
}
public String set(String key, String value) {
customClientSocket.send(convertToCommand(CommandConstant.CommandEnum.SET, key.getBytes(), value.getBytes()));
return customClientSocket.read();
}
public String get(String key) {
customClientSocket.send(convertToCommand(CommandConstant.CommandEnum.GET, key.getBytes()));
return customClientSocket.read();
}
public static String convertToCommand(CommandConstant.CommandEnum command, byte[]... bytes) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(CommandConstant.START).append(bytes.length + 1).append(CommandConstant.LINE);
stringBuilder.append(CommandConstant.LENGTH).append(command.toString().length()).append(CommandConstant.LINE);
stringBuilder.append(command.toString()).append(CommandConstant.LINE);
for (byte[] aByte : bytes) {
stringBuilder.append(CommandConstant.LENGTH).append(aByte.length).append(CommandConstant.LINE);
stringBuilder.append(new String(aByte)).append(CommandConstant.LINE);
}
return stringBuilder.toString();
}
}
测试方法
public static void main(String[] args) {
CustomRedisClient redisClient=new CustomRedisClient("192.168.221.128",6379);
System.out.println(redisClient.set("name","mic"));
System.out.println(redisClient.get("name"));
}
总结
你看,理解了原理之后,自己去实现起来发现并不难。
但是实际开发过程中,我们难倒也需要开发自己开发客户端吗?当然不用,官方推荐了以下三种客户端
配置 | 作用 |
---|---|
Jedis | A blazingly small and sane redis java client |
lettuce | Advanced Redis client for thread-safe sync, async, and reactive usage. Supports Cluster, Sentinel, Pipelining, and codecs. |
Redisson | distributed and scalable Java data structures on top of Redis server |
Jedis
Jedis是我们最熟悉和最常用的客户端。轻量,简洁,便于集成和改造。
简单使用方法
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.6.1</version>
</dependency>
public static void main(String[] args) {
Jedis jedis = new Jedis("127.0.0.1", 6379);
jedis.set("qingshan", "2673");
System.out.println(jedis.get("qingshan"));
jedis.close();
}
一般来说,我们不会使用单个Jedis连接,而是会使用连接池,Jedis提供了连接池的功能。
public static void main(String[] args) {
JedisPool pool = new JedisPool(ip, port);
Jedis jedis = jedisPool.getResource();
}
Luttece
Lettuce
是一个Redis
的Java
驱动包,大家常用的spring-boot-starter-data-redis中默认就采用的Lettuce。Lettuce
是一个高性能基于Java
编写的Redis
驱动框架,底层集成了Project Reactor
提供天然的反应式编程,通信框架集成了Netty
使用了非阻塞IO
,5.x
版本之后融合了JDK1.8
的异步编程特性,在保证高性能的同时提供了十分丰富易用的API
。
简单使用方法
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>
Lettuce
使用的时候依赖于四个主要组件:
RedisURI
:连接信息。RedisClient
:Redis
客户端,特殊地,集群连接有一个定制的RedisClusterClient
。Connection
:Redis
连接,主要是StatefulConnection
或者StatefulRedisConnection
的子类,连接的类型主要由连接的具体方式(单机、哨兵、集群、订阅发布等等)选定,比较重要。RedisCommands
:Redis
命令API
接口,基本上覆盖了Redis
发行版本的所有命令,提供了同步(sync
)、异步(async
)、反应式(reative
)的调用方式,对于使用者而言,会经常跟RedisCommands
系列接口打交道。
public static void main(String[] args) {
RedisURI redisUri = RedisURI.builder() // <1> 创建单机连接的连接信息
.withHost("192.168.221.128")
.withPort(6379)
.withTimeout(Duration.of(10, ChronoUnit.SECONDS))
.build();
RedisClient redisClient = RedisClient.create(redisUri); // <2> 创建客户端
StatefulRedisConnection<String, String> connection = redisClient.connect(); // <3> 创建线程安全的连接
RedisCommands<String, String> redisCommands = connection.sync(); // <4> 创建同步命令
SetArgs setArgs = SetArgs.Builder.nx().ex(5);
String result = redisCommands.set("name", "throwable", setArgs);
System.out.println(result);
result = redisCommands.get("name");
System.out.println(result);
// ... 其他操作
connection.close(); // <5> 关闭连接
redisClient.shutdown(); // <6> 关闭客户端
}
和Spring Boot集成使用
Lettuce是Spring Boot 2.x 默认的客户端,替换了Jedis。集成之后我们不需要单独使用它,直接调用Spring的RedisTemplate操作,连接和创建和关闭也不需要我们操心。
引入依赖jar包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
application.yml配置文件如下
redis:
port: 6379
host: 192.168.221.128
lettuce:
pool:
max-active: -1
max-idle: 2000
max-wait: -1
min-idle: 1
time-between-eviction-runs: 5000
使用方法
@RestController
@RequestMapping("/")
public class LutteceController {
@Autowired
RedisTemplate redisTemplate;
@GetMapping
public ResponseEntity get(){
String name=(String)redisTemplate.opsForValue().get("name");
return ResponseEntity.ok(name);
}
}
Redisson
Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid)。它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务。其中包括(BitSet
, Set
, Multimap
, SortedSet
, Map
, List
, Queue
, BlockingQueue
, Deque
, BlockingDeque
, Semaphore
, Lock
, AtomicLong
, CountDownLatch
, Publish / Subscribe
, Bloom filter
, Remote service
, Spring cache
, Executor service
, Live Object service
, Scheduler service
) Redisson提供了使用Redis的最简单和最便捷的方法。Redisson的宗旨是促进使用者对Redis的关注分离(Separation of Concern),从而让使用者能够将精力更集中地放在处理业务逻辑上。
简单使用方法
引入依赖Jar包
<dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>3.16.0</version> </dependency>
时间单节点连接和操作
public static void main(String[] args) { Config config=new Config(); config.useSingleServer().setAddress("redis://192.168.221.128:6379"); RedissonClient redissonClient= Redisson.create(config); redissonClient.getBucket("test").set("mic"); System.out.println(redissonClient.getBucket("test").get()); }
和Spring Boot集成
Spring Boot的集成方式。
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.16.0</version>
</dependency>
application.yml中的配置。
spring:
redis:
timeout: 2000
host: 192.168.221.128
port: 6379
使用方法。
@RestController
public class RedissonController {
@Autowired
RedissonClient redissonClient;
@GetMapping("/")
public String get(){
return redissonClient.getBucket("test").get().toString();
}
}
另外一种配置方式如下
修改application.yml
spring: redis: redisson: file: classpath:redisson.yml
创建一个redisson.yml文件,内容如下
singleServerConfig: address: redis://192.168.221.128:6379 #--------------------------------------------- # 连接空闲超时,单位:毫秒 idleConnectionTimeout: 10000 # 连接超时,单位:毫秒 connectTimeout: 10000 # 命令等待超时,单位:毫秒 timeout: 3000 # 命令失败重试次数,如果尝试达到 retryAttempts(命令失败重试次数) 仍然不能将命令发送至某个指定的节点时,将抛出错误。 # 如果尝试在此限制之内发送成功,则开始启用 timeout(命令等待超时) 计时。 retryAttempts: 3 # 命令重试发送时间间隔,单位:毫秒 retryInterval: 1500
相关推荐
- Dubai's AI Boom Lures Global Tech as Emirate Reinvents Itself as Middle East's Silicon Gateway
-
AI-generatedimageAsianFin--Dubaiisrapidlytransformingitselffromadesertoilhubintoaglob...
- OpenAI Releases o3-pro, Cuts o3 Prices by 80% as Deal with Google Cloud Reported to Make for Compute Needs
-
TMTPOST--OpenAIisescalatingthepricewarinlargelanguagemodel(LLM)whileseekingpartnershi...
- 黄仁勋说AI Agent才是未来!但究竟有些啥影响?
-
,抓住风口(iOS用户请用电脑端打开小程序)本期要点:详解2025年大热点你好,我是王煜全,这里是王煜全要闻评论。最近,有个词被各个科技大佬反复提及——AIAgent,智能体。黄仁勋在CES展的发布...
- 商城微服务项目组件搭建(五)——Kafka、Tomcat等安装部署
-
1、本文属于mini商城系列文档的第0章,由于篇幅原因,这篇文章拆成了6部分,本文属于第5部分2、mini商城项目详细文档及代码见CSDN:https://blog.csdn.net/Eclipse_...
- Python+Appium环境搭建与自动化教程
-
以下是保姆级教程,手把手教你搭建Python+Appium环境并实现简单的APP自动化测试:一、环境搭建(Windows系统)1.安装Python访问Python官网下载最新版(建议...
- 零配置入门:用VSCode写Java代码的正确姿
-
一、环境准备:安装JDK,让电脑“听懂”Java目标:安装Java开发工具包(JDK),配置环境变量下载JDKJava程序需要JDK(JavaDevelopmentKit)才能运行和编译。以下是两...
- Mycat的搭建以及配置与启动(mycat2)
-
1、首先开启服务器相关端口firewall-cmd--permanent--add-port=9066/tcpfirewall-cmd--permanent--add-port=80...
- kubernetes 部署mysql应用(k8s mysql部署)
-
这边仅用于测试环境,一般生产环境mysql不建议使用容器部署。这里假设安装mysql版本为mysql8.0.33一、创建MySQL配置(ConfigMap)#mysql-config.yaml...
- Spring Data Jpa 介绍和详细入门案例搭建
-
1.SpringDataJPA的概念在介绍SpringDataJPA的时候,我们首先认识下Hibernate。Hibernate是数据访问解决技术的绝对霸主,使用O/R映射(Object-Re...
- 量子点格棋上线!“天衍”邀您执子入局
-
你是否能在策略上战胜量子智能?这不仅是一场博弈更是一次量子智力的较量——量子点格棋正式上线!试试你能否赢下这场量子智局!游戏玩法详解一笔一画间的策略博弈游戏目标:封闭格子、争夺领地点格棋的基本目标是利...
- 美国将与阿联酋合作建立海外最大的人工智能数据中心
-
当地时间5月15日,美国白宫宣布与阿联酋合作建立人工智能数据中心园区,据称这是美国以外最大的人工智能园区。阿布扎比政府支持的阿联酋公司G42及多家美国公司将在阿布扎比合作建造容量为5GW的数据中心,占...
- 盘后股价大涨近8%!甲骨文的业绩及指引超预期?
-
近期,美股的AI概念股迎来了一波上升行情,微软(MSFT.US)频创新高,英伟达(NVDA.US)、台积电(TSM.US)、博通(AVGO.US)、甲骨文(ORCL.US)等多股亦出现显著上涨。而从基...
- 甲骨文预计新财年云基础设施营收将涨超70%,盘后一度涨8% | 财报见闻
-
甲骨文(Oracle)周三盘后公布财报显示,该公司第四财季业绩超预期,虽然云基建略微逊于预期,但管理层预计2026财年云基础设施营收预计将增长超过70%,同时资本支出继上年猛增三倍后,新财年将继续增至...
- Springboot数据访问(整合MongoDB)
-
SpringBoot整合MongoDB基本概念MongoDB与我们之前熟知的关系型数据库(MySQL、Oracle)不同,MongoDB是一个文档数据库,它具有所需的可伸缩性和灵活性,以及所需的查询和...
- Linux环境下,Jmeter压力测试的搭建及报错解决方法
-
概述 Jmeter最早是为了测试Tomcat的前身JServ的执行效率而诞生的。到目前为止,它的最新版本是5.3,其测试能力也不再仅仅只局限于对于Web服务器的测试,而是涵盖了数据库、JM...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- Dubai's AI Boom Lures Global Tech as Emirate Reinvents Itself as Middle East's Silicon Gateway
- OpenAI Releases o3-pro, Cuts o3 Prices by 80% as Deal with Google Cloud Reported to Make for Compute Needs
- 黄仁勋说AI Agent才是未来!但究竟有些啥影响?
- 商城微服务项目组件搭建(五)——Kafka、Tomcat等安装部署
- Python+Appium环境搭建与自动化教程
- 零配置入门:用VSCode写Java代码的正确姿
- Mycat的搭建以及配置与启动(mycat2)
- kubernetes 部署mysql应用(k8s mysql部署)
- Spring Data Jpa 介绍和详细入门案例搭建
- 量子点格棋上线!“天衍”邀您执子入局
- 标签列表
-
- oracle位图索引 (74)
- oracle批量插入数据 (65)
- oracle事务隔离级别 (59)
- oracle 空为0 (51)
- oracle主从同步 (56)
- oracle 乐观锁 (53)
- redis 命令 (78)
- php redis (88)
- redis 存储 (66)
- redis 锁 (69)
- 启动 redis (66)
- redis 时间 (56)
- redis 删除 (67)
- redis内存 (57)
- redis并发 (52)
- redis 主从 (69)
- redis 订阅 (51)
- redis 登录 (54)
- redis 面试 (58)
- 阿里 redis (59)
- redis 搭建 (53)
- redis的缓存 (55)
- lua redis (58)
- redis 连接池 (61)
- redis 限流 (51)