生产环境使用

准备好你的 Jedis 应用用于生产环境

本指南提供建议,以在你的生产环境中获得最佳可靠性和性能。

核对清单

以下核对清单中的每个项目都链接到相应建议的部分。使用核对清单图标来记录你在实施建议方面的进度。

0/, 0/, 0/
( 0/)

建议

以下部分提供针对你的生产环境的建议。其中一些可能不适用于你的特定用例。

连接池

示例代码通常在开头打开一个连接,演示一个功能,然后在结尾关闭连接。然而,生产代码通常会间歇性地多次使用连接。重复打开和关闭连接会带来性能开销。

使用连接池来避免打开和关闭连接的开销,而无需编写自己的代码来缓存和重用打开的连接。参见使用连接池连接了解如何在 Jedis 中使用此技术。

客户端缓存

客户端缓存涉及将只读命令的结果存储在本地缓存中。如果稍后再次执行相同的命令,可以直接从缓存获取结果,而无需联系服务器。这提高了客户端的命令执行时间,同时减少了网络流量和服务器负载。参见使用客户端缓存连接获取更多信息和示例代码。

超时

如果在你的代码打开连接或发出命令时发生网络或服务器错误,它可能会无限期挂起。你可以通过设置套接字读写和连接超时的时长来防止这种情况发生。

要为连接设置超时,请使用带有 timeout 参数的 JedisPooledJedisPool 构造函数,或使用带有 socketTimeoutconnectionTimeout 参数的 JedisClientConfig。(套接字超时是执行命令时允许读写数据的最长时间。连接超时是建立新连接允许的最长时间。)

HostAndPort hostAndPort = new HostAndPort("localhost", 6379);

JedisPooled jedisWithTimeout = new JedisPooled(hostAndPort,
    DefaultJedisClientConfig.builder()
        .socketTimeoutMillis(5000)  // set timeout to 5 seconds
        .connectionTimeoutMillis(5000) // set connection timeout to 5 seconds
        .build(),
    poolConfig
);

健康检查

如果你的代码不持续访问 Redis 服务器,那么定期(例如每隔几秒)进行“健康检查”可能很有用。你可以使用简单的 PING 命令来实现。

try (Jedis jedis = jedisPool.getResource()) {
  if (! "PONG".equals(jedis.ping())) {
    // Report problem.
  }
}

健康检查有助于尽快检测到问题,而无需等待用户报告。

异常处理

Redis 使用命令的返回值处理许多错误,但也存在可能抛出异常的情况。在生产代码中,你应该在异常发生时进行处理。

Jedis 异常层次结构的根是 JedisException,它实现了 RuntimeException。因此,层次结构中的所有异常都是非检查异常。

JedisException
├── JedisDataException
│   ├── JedisRedirectionException
│   │   ├── JedisMovedDataException
│   │   └── JedisAskDataException
│   ├── AbortedTransactionException
│   ├── JedisAccessControlException
│   └── JedisNoScriptException
├── JedisClusterException
│   ├── JedisClusterOperationException
│   ├── JedisConnectionException
│   └── JedisValidationException
└── InvalidURIException

一般异常

通常,Jedis 在执行命令时可能会抛出以下异常

  • JedisConnectionException - 当与 Redis 的连接丢失或意外关闭时。配置故障转移,使用 Resilience4J 和内置的 Jedis 故障转移机制自动处理此异常。
  • JedisAccessControlException - 当用户没有执行命令的权限或用户 ID 和/或密码不正确时。
  • JedisDataException - 当发送或接收到 Redis 服务器的数据出现问题时。通常,错误消息会包含有关失败命令的更多信息。
  • JedisException - 此异常是一个包罗万象的异常,可以针对任何其他意外错误抛出。

可能抛出 JedisException 的情况

  • 使用 PING 命令进行健康检查的返回结果异常
  • SHUTDOWN 期间失败
  • Pub/Sub 发布命令时失败(断开连接)
  • 任何未知服务器消息
  • Sentinel:可以连接到 Sentinel,但主节点未被监控或所有 Sentinel 都已宕机。
  • MULTI 或 DISCARD 命令失败
  • Shard 命令键哈希检查失败或没有可到达的分片
  • 重试期限超出/尝试次数过多(重试命令执行器)
  • 连接池 - 连接池耗尽,添加空闲对象出错,将损坏的资源返回到连接池

所有 Jedis 异常都是运行时异常,并且在大多数情况下不可恢复,因此通常会向上抛出到 API 层,并捕获错误消息。

DNS 缓存和 Redis

当你连接到具有多个端点的 Redis 服务器时,例如 Redis Enterprise Active-Active,你必须禁用 JVM 的 DNS 缓存。如果服务器节点或代理失败,受影响的数据库的 IP 地址将会更改。如果启用了 DNS 缓存,你的应用程序会继续尝试使用过时的 IP 地址。

使用以下代码禁用 DNS 缓存

java.security.Security.setProperty("networkaddress.cache.ttl","0");
java.security.Security.setProperty("networkaddress.cache.negative.ttl", "0");
评价此页面
回到顶部 ↑