上周有同事过来求助,他申请了pika集群,进行接入结果监控发现只有一个集群上连接数很大,其他集群上连接数没几个,连接偏移了。他写的代码我这边就不贴了,1.安全问题,2.知识产权问题,3.防止对大家产生误导。这里只写接入的正确姿势。
先说说pika是啥,是奇虎公司(即大家熟悉的360公司)开源的基于Redis通讯协议的基于硬盘存储高速缓存。github地址:https://github.com/OpenAtomFoundation/pika 。所以大家接入的时候,使用spring boot 集成的 redis jar包即可。pika是单节点的,没有集群,所以分片的路由规则需要自己写。
前面是铺垫,下面进入正题,首先这位同事申请的是5个节点。
1、添加的maven 引用
org.springframework.boot spring-boot-starter-data-redis redis.clients jedis 4.2.3 2、在 application.properties 添加配置
pika.database=0pika.pool.maxActive=8pika.pool.maxIdle=8pika.pool.minIdle=1pika.pool.maxWait=5000pika.pool.testOnBorrow=falsepika.pool.blockWhenExhausted=truepika.timeout=60000pika.pika0.host=ip0pika.pika0.password=mima0pika.pika0.port=8096pika.pika1.host=ip1pika.pika1.password=mima1pika.pika1.port=8096pika.pika2.host=ip2pika.pika2.password=mima2pika.pika2.port=8096pika.pika3.host=ip3pika.pika3.password=mima3pika.pika3.port=8096pika.pika4.host=ip4pika.pika4.password=mima4pika.pika4.port=80963.添加 PikaClusterConfig 配置类
@Slf4j@Configurationpublic class PikaClusterConfig { /** * pika连接池最大连接数 */ @Value("${pika.pool.maxActive}") private int pikaPoolMaxActive; /** * pika连接池最大空闲 */ @Value("${pika.pool.maxIdle}") private int pikaPoolMaxIdle; /** * pika连接池最小空闲 */ @Value("${pika.pool.minIdle}") private int pikaPoolMinIdle; /** * pika获取连接时的最大等待时间 */ @Value("${pika.pool.maxWait}") private long pikaPoolMaxWait; /** * pika拿取链接时测试是否成功 */ @Value("${pika.pool.testOnBorrow}") private boolean pikaPoolTestOnBorrow; /** * 用尽报错 */ @Value("${pika.pool.blockWhenExhausted}") private boolean pikaPoolBlockWhenExhausted; /** * pika连接超时时间,单位毫秒.60×1000 */ @Value("${pika.timeout}") private long pikaTimeout; @Bean(name = "redisTemplate0") public RedisTemplate redisTemplate0(@Value("${pika.pika0.host}") String hostName, @Value("${pika.pika0.port}") int port, @Value("${pika.pika0.password}") String password) { StringRedisTemplate template = new StringRedisTemplate(jedisConnectionFactory(hostName, port, password)); return initSerializer(template); } @Bean(name = "redisTemplate1") public RedisTemplate redisTemplate1(@Value("${pika.pika1.host}") String hostName, @Value("${pika.pika1.port}") int port, @Value("${pika.pika1.password}") String password) { StringRedisTemplate template = new StringRedisTemplate(jedisConnectionFactory(hostName, port, password)); return initSerializer(template); } @Bean(name = "redisTemplate2") public RedisTemplate redisTemplate2(@Value("${pika.pika2.host}") String hostName, @Value("${pika.pika2.port}") int port, @Value("${pika.pika2.password}") String password) { StringRedisTemplate template = new StringRedisTemplate(jedisConnectionFactory(hostName, port, password)); return initSerializer(template); } @Bean(name = "redisTemplate3") public RedisTemplate redisTemplate3(@Value("${pika.pika3.host}") String hostName, @Value("${pika.pika3.port}") int port, @Value("${pika.pika3.password}") String password) { StringRedisTemplate template = new StringRedisTemplate(jedisConnectionFactory(hostName, port, password)); return initSerializer(template); } @Bean(name = "redisTemplate4") public RedisTemplate redisTemplate4(@Value("${pika.pika4.host}") String hostName, @Value("${pika.pika4.port}") int port, @Value("${pika.pika4.password}") String password) { StringRedisTemplate template = new StringRedisTemplate(jedisConnectionFactory(hostName, port, password)); return initSerializer(template); } private RedisTemplate initSerializer(StringRedisTemplate template) { StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); template.setKeySerializer(stringRedisSerializer); template.setValueSerializer(stringRedisSerializer); GenericJackson2JsonRedisSerializer jackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer(); template.setHashKeySerializer(jackson2JsonRedisSerializer); template.setHashValueSerializer(jackson2JsonRedisSerializer); return template; } /** * 获取redis连接池 * * @param hostName * @param port * @param password * @return */ private JedisConnectionFactory jedisConnectionFactory(String hostName, int port, String password) { RedisStandaloneConfiguration standaloneConfig = new RedisStandaloneConfiguration(); standaloneConfig.setHostName(hostName); standaloneConfig.setPort(port); if (!StringUtils.isEmpty(password)) { standaloneConfig.setPassword(password); } //standaloneConfig.setDatabase(pikaDatabase); //连接池配置 GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig(); genericObjectPoolConfig.setMaxIdle(pikaPoolMaxIdle); genericObjectPoolConfig.setMinIdle(pikaPoolMinIdle); genericObjectPoolConfig.setMaxTotal(pikaPoolMaxActive); genericObjectPoolConfig.setMaxWaitMillis(pikaPoolMaxWait); genericObjectPoolConfig.setBlockWhenExhausted(pikaPoolBlockWhenExhausted); genericObjectPoolConfig.setTestOnBorrow(pikaPoolTestOnBorrow); //client配置 JedisClientConfiguration clientConfig = JedisClientConfiguration.builder() .connectTimeout(Duration.ofMillis(pikaTimeout)) .readTimeout(Duration.ofMillis(pikaTimeout)) .usePooling().poolConfig(genericObjectPoolConfig) .build(); //返回连接池 JedisConnectionFactory factory = new JedisConnectionFactory(standaloneConfig, clientConfig); factory.afterPropertiesSet(); return factory; }}4.添加 PikaService 根据主键获取RedisTemplate
@Servicepublic class PikaService { @Qualifier("redisTemplate0") @Autowired private RedisTemplate redisTemplate0; @Qualifier("redisTemplate1") @Autowired private RedisTemplate redisTemplate1; @Qualifier("redisTemplate2") @Autowired private RedisTemplate redisTemplate2; @Qualifier("redisTemplate3") @Autowired private RedisTemplate redisTemplate3; @Qualifier("redisTemplate4") @Autowired private RedisTemplate redisTemplate4; public RedisTemplate shardRedisTemplate(String key) { int index = Math.abs(key.hashCode() % 5); // replace Math.abs(key.hashCode()) % REDIS_TEMPLATES.size() 因存在问题:hashCode=Integer.MIN_VALUE时仍为负数 switch (index) { case 0: return redisTemplate0; case 1: return redisTemplate1; case 2: return redisTemplate2; case 3: return redisTemplate3; case 4: return redisTemplate4; default: return null; } }}好了,核心的代码添加完毕了。
| 留言与评论(共有 0 条评论) “” |