客户端负责应用与 KeeWiDB 之间的通信。连接池配置不当可能导致连接耗尽或资源浪费,缺少熔断保护会使单节点故障扩散为服务整体不可用,弱密码则增加被暴力破解的风险。本文档从连接池配置、熔断机制和密码安全三个方面定义设计准则,用于构建可用性和安全性符合生产要求的客户端程序。
一、连接池配置
建议使用带有连接池的客户端访问 KeeWiDB。
1. 连接池的作用
每次建立 TCP 连接都需要经历三次握手和身份认证,在高并发场景下频繁创建和销毁连接会增加延迟开销和系统资源消耗。连接池通过预先创建并复用一组持久连接,将"每次请求建连"变为"从池中借用连接",从而降低连接延迟、控制并发连接总数,并避免连接数超出数据库承载上限。
2. 核心参数
连接池通过以下三个参数控制连接的创建、保持与回收:
参数 | 说明 |
最大连接数 | 连接池中允许同时存在的连接上限。达到上限后,新请求将排队等待空闲连接释放,防止突发流量下连接数暴涨、耗尽服务端连接配额 |
最大空闲连接数 | 允许保持空闲状态的连接上限。超出部分将被主动关闭,避免低峰期占用不必要的系统资源(如文件描述符和内存) |
最小空闲连接数 | 必须始终保持的空闲连接数。低于此阈值时,连接池在后台预创建新连接进行补充,确保流量突增时有可用连接,减少排队等待 |
3. 配置建议
将上述三项参数设为相同数值,可使连接池维持恒定规模。保持固定连接数旨在确保行为可预测性:既能消除频繁建立与销毁连接的性能损耗,又能规避空闲回收后因突发流量触发的连接延迟。具体数值应结合业务并发量与 KeeWiDB 实例的最大连接数限制综合评估。
正确示例(Go 语言 Redigo):
pool := &redis.Pool{MaxIdle: 50, // 最大空闲连接数MaxActive: 50, // 最大连接数,与 MaxIdle 一致IdleTimeout: 240 * time.Second,Dial: func() (redis.Conn, error) {return redis.Dial("tcp", "keewidb-instance:6379",redis.DialPassword("your_password"))},}
正确示例(Java Jedis):
JedisPoolConfig config = new JedisPoolConfig();config.setMaxTotal(50); // 最大连接数config.setMaxIdle(50); // 最大空闲连接数,与 MaxTotal 一致config.setMinIdle(50); // 最小空闲连接数,与 MaxTotal 一致config.setTestOnBorrow(true);JedisPool pool = new JedisPool(config, "keewidb-instance", 6379, 2000, "your_password");
反面示例: 三个参数差异过大,低峰期连接被大量回收,高峰期需重新建连,造成延迟毛刺。
config.setMaxTotal(200);config.setMaxIdle(100);config.setMinIdle(10);
更多参数详情请参见:
Go 语言 Redigo:Redigo 官方文档。
Java Jedis:Jedis 官方文档。
二、熔断机制
在高并发场景下,建议客户端集成熔断保护机制(如 Netflix Hystrix、Sentinel 等)。
1. 熔断的作用
在分布式架构中,当 KeeWiDB 集群的某个节点因磁盘 IO 异常、网络抖动或负载过高而响应变慢时,如果客户端持续向该节点发送请求,大量请求将因超时而堆积在线程池中,最终耗尽客户端的线程和连接资源,导致故障从单节点扩散至整个服务链路。熔断机制通过自动隔离故障节点,将影响限制在单点范围内,维持服务整体可用性。
2. 工作流程
熔断器在以下三个状态之间自动切换:
状态 | 触发条件 | 行为 |
关闭(正常) | 错误率低于阈值 | 所有请求正常放行,持续统计错误率和超时率 |
打开(熔断) | 错误率或超时率超过预设阈值 | 自动停止向故障节点发送请求,直接返回失败或将流量转向健康节点 |
半开(探测) | 熔断持续时间超过冷却期 | 放行少量探测请求。若探测成功,切回关闭状态恢复正常流量;若仍失败,重新进入打开状态 |
3. 核心参数
参数 | 说明 | 参考值 |
错误率阈值 | 在统计窗口内,请求失败比例达到此值时触发熔断 | 50% |
统计窗口 | 计算错误率的时间窗口大小 | 10s |
最小请求数 | 统计窗口内请求数低于此值时不触发熔断,避免少量请求偶发失败导致误熔断 | 20 次 |
冷却期 | 熔断打开后等待多久进入半开状态 | 5s ~ 10s |
半开探测数 | 半开状态下放行的探测请求数量 | 5 ~ 10次 |
说明:
以上参考值适用于一般业务场景。对延迟敏感的业务可缩短冷却期以加快恢复;对稳定性要求高的业务可降低错误率阈值以更早触发熔断。
4. 配置示例
Java Spring Cloud CircuitBreaker(Resilience4j):
CircuitBreakerConfig config = CircuitBreakerConfig.custom().failureRateThreshold(50) // 错误率阈值 50%.slidingWindowSize(10) // 统计窗口:最近 10 次请求.minimumNumberOfCalls(20) // 最小请求数 20 次.waitDurationInOpenState(Duration.ofSeconds(5)) // 冷却期 5 秒.permittedNumberOfCallsInHalfOpenState(5) // 半开探测数 5 次.build();CircuitBreaker breaker = CircuitBreaker.of("keewidb", config);
Go 语言 gobreaker:
cb := gobreaker.NewCircuitBreaker(gobreaker.Settings{Name: "keewidb",MaxRequests: 5, // 半开探测数 5 次Interval: 10 * time.Second, // 统计窗口 10 秒Timeout: 5 * time.Second, // 冷却期 5 秒ReadyToTrip: func(counts gobreaker.Counts) bool {failureRatio := float64(counts.TotalFailures) / float64(counts.Requests)return counts.Requests >= 20 && failureRatio >= 0.5 // 最小 20 次请求,错误率 50%},})
三、密码安全
数据库访问密码用于控制数据库的访问权限。弱密码(如纯数字、常见单词)容易被暴力破解工具在短时间内攻破。密码泄露后,攻击者可访问或清空数据库中的数据。因此,密码必须满足以下复杂度要求:
要求 | 说明 |
长度 | 8 ~ 30个字符 |
复杂度 | 至少包含小写字母、大写字母、数字和特殊字符(` ()~!@#$%^&*-+=_ |
格式限制 | 不能以 / 开头 |
反面示例: 以下密码过于简单,容易被暴力破解。
12345678 # 纯数字,暴力破解工具可在数秒内攻破password # 常见英文单词,在字典攻击列表中排名前列keewidb # 与产品名相关,极易被猜测/Admin@2024 # 以 "/" 开头,不符合格式要求
正确示例: 包含多种字符类型,长度充足,无规律可循。
Cx_order#2024Db # 大小写字母 + 数字 + 特殊字符,16 位长度Kw!9mP$3xR7n # 随机组合,12 位长度,包含 4 种字符类型