在 maven 項目中,redis 服務器的通信協議 resp 已經被公開,任何第三方庫都可以通過此協議實現與 redis 服務器的客戶端通信。幸運的是,Java 生態系統中已經有許多優秀的庫封裝了 resp 協議,提供了與 redis 服務器通信的客戶端。我們這里選擇使用 jedis 庫,因為它的 api 與 redis 命令高度一致。
jedis 可以通過 maven 進行依賴管理,下面的代碼展示了如何在 pom.xml 文件中添加 jedis 依賴:
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>5.1.5</version> </dependency>
在 Windows 環境下,如果需要通過云服務器的外網 IP 訪問 Linux 服務器上的 redis,僅僅修改外網 IP 是遠遠不夠的。因為 Redis 的默認端口 6379 通常會被云服務器的防火墻保護起來,無法從外部直接訪問。防火墻的保護類似于小區內的住宅樓被 NAT 保護,增加了外部訪問的難度。
直接在云服務器后臺開放防火墻是不安全的做法。一旦 Redis 端口暴露在公網上,極易被入侵。即使更換 Redis 端口,也只是掩耳盜鈴,并不能真正提高安全性。
解決方案是,不直接開放 Redis 端口,而是通過 ssh 端口轉發,將云服務器上的 Redis 端口映射到本地主機。這樣,我們就可以通過本地主機訪問云服務器上的 Redis 服務。
ssh 支持端口轉發,通過 ssh 的 22 端口傳遞其他端口的數據。我們可以構造一個特殊的 ssh 數據報,將訪問 Redis 的請求包裝在 ssh 數據報中,通過 22 端口發送給服務器。服務器上的 ssh 程序會解析數據報,并將數據轉發給 6379 端口的 Redis 服務。
在 Linux 主機上,可能會有多個服務器需要通過 ssh 進行端口轉發。為了區分不同的端口,通常會在本地使用不同的端口來表示服務器上的端口。
這樣,客戶端程序訪問 127.0.0.1:8888 就相當于訪問了 Linux 服務器上的 6379 端口。通過簡單的配置,我們就可以將云服務器的端口視為本地端口使用。
在 mac 環境下,客戶端可以通過 127.0.0.1 這樣的 IP 來連接 Redis 服務器。
以下是一個使用 jedis 連接 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("localhost", 6379); // 從 Redis 連接池中取一個連接出來 // 連接用完之后要釋放,此處的釋放不一定是真的關閉 TCP 連接,而是將連接放回到池子里 // 因為是在 try 后面的()里面進行取連接的,執行結束后會自動關閉 try (Jedis jedis = jedisPool.getResource()) { // Redis 的各種命令,就對應到 Jedis 對象的各種方法 String pong = jedis.ping(); System.out.println(pong); } } }
需要注意的是,這里使用的 URL 僅適用于開發階段。如果程序需要部署到云服務器上,則需要根據云服務器的實際情況來設置 IP 和端口。