目录
引言
RESP 协议
Redis 通信过程
实现步骤
步骤一
步骤二
步骤三
步骤四
引言
- 在 Redis 命令行客户端中手敲命令并不是我们日常开发中的主要形式
- 而更多的时候是使用 Redis 的 API 来实现定制化的 Redis 客户端程序,进而操作 Redis 服务器
- 即使用程序来操作 Redis,使用代码来执行 Redis 命令
注意:
- Redis 所提供的命令行客户端 抑或是 第三方的图形化客户端
- 这二者本质上均属于 通用的客户端程序
- 相比之下,我们在工作中更希望使用到的是 专用的、定制化 的客户端程序
RESP 协议
- RESP(Redis Serialization Protocol) 协议,用于在 Redis 客户端和服务器之间进行通信
注意:
- 正因为 Redis 官方开放了 RESP 协议,所以我们才能够基于该协议,来编写出一个自定义的 Redis 客户端
RESP 协议优点:
- 简单且容易实现
- 可快速解析
- 肉眼可读
RESP 协议特点:
- RESP 协议的实现通常基于 TCP,但并不意味着RESP 协议与 TCP 强耦合在一起,即也可选择其他传输层协议
- 请求和响应之间的通信模型是一问一答的形式,即客户端给服务器发送一个请求,服务器返回一个响应
Redis 通信过程
- 客户端向服务器发送 Redis 命令(Bulk String 数组形式发送)
- 不同的命令,服务器返回不同的结果
- 有的命令,可能返回个 OK
- 有的命令,可能返回个 整数
- 有的命令,可能返回个 数组
数据类型 首比特位 实例理解 Simple String + "+OK\r\n" Errors - "-Error message\r\n" Integers : ":1000\r\n" Bulk Strings $ "$5\r\nhello\r\n" Arrays * "*2\r\n$5\r\nhello\r\n$5\r\nworld\r\n"
- 即服务器在返回时,会将上述 实例字符串,写入到 tcp socket 中
注意:
- Simple Sting 只能用来传输文本
- Bulk Stirng 可以传输二进制数据
总结:
- 因此 redis 服务器要做的工作就是
- 按照上述格式,构造出字符串,往 socket 中写入
- 从 socekt 中读取字符串,按照上述格式解析
- 当然我们无需自己写代码,即按照按照上述的协议来 解析 和 构造字符串
- 因为我们可以使用现成的库,这些库已经帮我们实现了这套协议的解析 和 构造
- 因此我们便可以比较简单方便的来完成和 Redis 服务器通信的操作了!
实现步骤
- 此处我们使用 jedis 库,因为 jedis 库所提供的 api 和 Redis 命令高度一致
步骤一
- 在 maven 项目的 pom.xml 文件中添加依赖
<!-- https://mvnrepository.com/artifact/redis.clients/jedis --><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>4.4.2</version></dependency>
步骤二
- 配置 ssh 端口转发,把云服务器的 Redis 端口,映射到本地主机
此处我们解释并理解步骤二,着急配置的可直接省略
- 使用 Java 开发进行的代码,通常高度依赖 windows(IDEA)
- 所以当我们想直接在自己主机上 操作 Redis 时,便需要通过 外网ip
- 但是直接使用 外网ip 也无法访问到云服务器中的 Redis 服务器
- 因为 Redis 服务器所占用的 6379 端口,默认被云服务器的防火墙给保护起来了
- 而防火墙一旦将 6379 端口保护起来,不仅黑客访问不了,就连自己也无法访问 Redis 服务器
问题:
- 直接在云服务器后台,把 6379 端口防火墙放开不就行了?
回答:
- 千万不要这么做!
- Redis 服务器的端口一旦放开到公网上,就特别容易被入侵!
两难境地:
- 不能开放 Redis 服务器的端口
- 我们自己又想能够通过外网对 Redis 服务器进行访问
解决方案一:
- 直接让 java 程序在 linux 上运行
- 这就需要我们将代码打成可执行的 jar 包,然后再将 jar 包拷贝到 linux 服务器上,最后再执行 jar 包
- 如果按照上述操作一步一步完成,还是十分繁琐的
- 虽然也可以通过一些第三方插件来简化上述步骤,但总体来说还是比较繁琐的!
解决方案二:
- 配置 ssh 端口转发,把云服务器的 Redis 端口,映射到本地主机
- ssh 的功能十分强大,其中很重要的特性就是能够支持端口转发
- 相当于通过 22 端口,来传递其他端口的数据
- 本身我们需要通过 windwos 主机来访问云服务器 6379 端口
- 但是我们可以直接构造一个特殊的 ssh 数据报将要访问的 redis 请求放到 ssh 数据报中
步骤三
- 当 ssh 连接上了之后,端口转发才会生效,即如歌将 ssh 连接断开,端口转发自然失效
- 所以我们完成上述步骤后,便可以使用 netstat 命令观察本地 8888 端口是否被监听成功
- 打开 cmd ,输入下方命令
netstat -ano | findstr 8888
- 出现红框所示,表示配置成功!
注意:
- 当配置了 端口转发之后,一定要断开之前的连接,重新连接才能生效!
步骤四
- 此处将创建一个 RedisDemo 类,来测试操作云服务器的 Redis
import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool;public class RedisDemo {public static void main(String[] args) { // 连接到 redis 服务器上JedisPool jedisPool = new JedisPool("tcp://127.0.0.1:8888");// 从 redis 连接池中取一个出来 // 连接使用完之后要记得释放(close) // 此处的释放不一定是真的关闭 tcp 连接,而是放回到池子里try (Jedis jedis = jedisPool.getResource()){ // redis 的各种命令,就都对应到 jedis 对象的各种方法String pong = jedis.ping();System.out.println(pong);}} }
运行结果:
注意点一:
- 当前咱们的这个程序能跑通,除了配置 ssh 端口映射之外,还有一个要点
- 即最开始安装 Redis 服务器时,配置好绑定的 ip ,以及关闭保护模式
想具体在 Centos7 上安装 Redis 5 可点击下方链接
关于云服务器 CentOS7 安装 Redis5
注意点二:
- 上述 url 的写法仅局限于开发阶段,后续如果我们的程序需要部署到云服务器
- 此时便需按照云服务的实际情况来更换此处的 ip 和 端口了