Java tutorial
/* * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package redis.client.jedis; import static org.testng.Assert.assertEquals; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import redis.client.jedis.spring.CustomShardedJedisPoolFactoryBean.PoolBehaviour; import redis.client.util.RedisConfigUtils; import redis.client.util.TestConfigUtils; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPoolConfig; import redis.clients.jedis.JedisShardInfo; import redis.clients.jedis.Response; import redis.clients.jedis.ShardedJedis; import redis.clients.jedis.ShardedJedisPipeline; import redis.clients.jedis.exceptions.JedisException; /** * Tests for {@link CustomShardedJedisPool}. * * @author huagang.li 2014129 ?9:33:00 */ public class CustomShardedJedisPoolTest { private static final Logger logger = LoggerFactory.getLogger(CustomShardedJedisPoolTest.class); private CustomShardedJedisPool shardedJedisPool; @BeforeClass public void init() throws InterruptedException { List<JedisShardInfo> shards = RedisConfigUtils.parseRedisServerList(TestConfigUtils.getRedisServers(), TestConfigUtils.getTimeoutMillis()); GenericObjectPoolConfig poolConfig = new JedisPoolConfig(); // ? poolConfig.setMaxTotal(TestConfigUtils.getMaxTotalNum()); poolConfig.setMaxIdle(TestConfigUtils.getMaxIdleNum()); // poolConfig.setMinIdle(TestConfigUtils.getMinIdleNum()); poolConfig.setMinIdle(3); // local test // ?"" boolean lifo = TestConfigUtils.getPoolBehaviour() == PoolBehaviour.LIFO ? true : false; poolConfig.setLifo(lifo); // ? poolConfig.setBlockWhenExhausted(false); // // poolConfig.setBlockWhenExhausted(true); // poolConfig.setMaxWaitMillis(TimeUnit.MILLISECONDS.toMillis(10L)); // ""? poolConfig.setTestOnBorrow(false); poolConfig.setTestOnReturn(false); /* * "Evictor?"??"" */ poolConfig.setTestWhileIdle(true); // ?5????? // poolConfig.setTimeBetweenEvictionRunsMillis(TimeUnit.SECONDS.toMillis(TestConfigUtils.getTimeBetweenEvictionRunsSeconds())); poolConfig.setTimeBetweenEvictionRunsMillis(TimeUnit.SECONDS.toMillis(2L)); // local test // ??Evictor // poolConfig.setTimeBetweenEvictionRunsMillis(-1L); // local test // ? // poolConfig.setNumTestsPerEvictionRun(TestConfigUtils.getNumTestsPerEvictionRun()); poolConfig.setNumTestsPerEvictionRun(3); // local test // ? poolConfig.setSoftMinEvictableIdleTimeMillis( TimeUnit.MINUTES.toMillis(TestConfigUtils.getMinEvictableIdleTimeMinutes())); // ??(?) // ? poolConfig.setMinEvictableIdleTimeMillis( TimeUnit.MINUTES.toMillis(TestConfigUtils.getMaxEvictableIdleTimeMinutes())); this.shardedJedisPool = new CustomShardedJedisPool(poolConfig, shards, (int) TimeUnit.SECONDS.toMillis(1), 2); } private static final String DEFAUL_VALUE = "1"; private static final String RET_OK = "OK"; /** * ??? * <p> * ????<font color="red">???????</font> * <p> * "?"?????<br> * ??????? */ @Test(description = "?'????(Pipeline)?'") public void pipeline() { String key = "pipeline"; try { ShardedJedis jedis = shardedJedisPool.getResource(); // ? jedis.del(key); ShardedJedisPipeline pipeline = jedis.pipelined(); Response<Long> newElementNum = pipeline.zadd(key, System.currentTimeMillis(), "23"); Map<String, Double> scoreMembers = new HashMap<>(4); scoreMembers.put("10", new Double(System.currentTimeMillis() + 1)); scoreMembers.put("7", new Double(System.currentTimeMillis() + 2)); pipeline.zadd(key, scoreMembers); Response<Long> elementNum = pipeline.zcard(key); pipeline.sync(); jedis.close(); assertEquals(newElementNum.get().intValue(), 1); assertEquals(elementNum.get().intValue(), 3); } catch (JedisException e) { logger.error(e.getMessage(), e); } } @Test(description = "?\"()Redis???Redis?\"") public void autoDetectBrokenRedisServer() throws InterruptedException { ShardedJedis jedis = null; JedisShardInfo shardInfo = null; String key = null; int size = 4; for (int i = 1; i <= size; i++) { key = "auto_detect_broken_redis_server_" + i; try { // ??Redis jedis = shardedJedisPool.getResource(); // log Shard info shardInfo = jedis.getShardInfo(key); logger.info("Shard Info: " + shardInfo); String statusCode = jedis.set(key, DEFAUL_VALUE); assertEquals(statusCode, RET_OK); // jedis.close(); // ??Redis?()?()Redis? // ????Redis??????Redis? if (1 == i) { clientKill(jedis.getShard(key)); } } catch (JedisException je) { String errorMsg = String.format("Failed to operate on '%s' Jedis Client", shardInfo); logger.warn(errorMsg, je); } logger.info("Complete time: {}", Integer.valueOf(i)); if (i < size) { TimeUnit.SECONDS.sleep(2L); } } } private static final String DEAD_SERVER_CLIENT_NAME = "DEAD"; /** * * * @param jedis */ public static void clientKill(Jedis jedis) { jedis.clientSetname(DEAD_SERVER_CLIENT_NAME); // CLIENT LIST (????) - http://redis.io/commands/client-list // CLIENT LIST (name): // "id=4 addr=127.0.0.1:50946 fd=6 name=DEAD age=0 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=client" for (String clientInfo : jedis.clientList().split("\n")) { if (clientInfo.contains(DEAD_SERVER_CLIENT_NAME)) { for (String field : clientInfo.split(" ")) { if (field.contains("addr")) { String hostAndPort = field.split("=")[1]; // It would be better if we kill the client by Id (CLIENT KILL ID client-id) as it's safer but // Jedis doesn't implement the command yet. // CLIENT KILL () - http://redis.io/commands/client-kill jedis.clientKill(hostAndPort); } } } } } /** * <font color="red">?</font>{@link GenericObjectPoolConfig#setTimeBetweenEvictionRunsMillis(long)}500L<br> * 13?6381?2?45?6380? * * @throws InterruptedException */ @Test(enabled = false, description = "?\"?()???\"") public void accessOtherShardsNormally() throws InterruptedException { ShardedJedis jedis = null; JedisShardInfo shardInfo = null; String key = null; int size = 5; for (int i = 1; i <= size; i++) { key = "st_" + i; try { // ??Redis jedis = shardedJedisPool.getResource(); // log Shard info shardInfo = jedis.getShardInfo(key); logger.info("Shard Info: " + shardInfo); String statusCode = jedis.set(key, DEFAUL_VALUE); assertEquals(statusCode, RET_OK); // jedis.close(); // Redis?Redis? if (1 == i) { Jedis client = jedis.getShard(key); statusCode = client.shutdown(); assertEquals(statusCode, null); // ??? } } catch (JedisException je) { String errorMsg = String.format("Failed to operate on '%s' Jedis Client", shardInfo); logger.warn(errorMsg, je); } logger.info("Complete time: {}", Integer.valueOf(i)); if (i < size) { TimeUnit.SECONDS.sleep(3L); } } } /** * <pre> * ???? * ??????? * </pre> */ @Test(enabled = false, description = "(kill Redis?)??\"()Redis???Redis?\"") public void manualDetectBrokenRedisServer() throws InterruptedException { ShardedJedis jedis = null; JedisShardInfo shardInfo = null; String key = null; int size = 7; for (int i = 1; i <= size; i++) { key = "st_" + i; // ??Redis jedis = shardedJedisPool.getResource(); // log Shard info shardInfo = jedis.getShardInfo(key); logger.info("Shard Info: " + shardInfo); try { String ret = jedis.set(key, "1"); assertEquals(ret, RET_OK); } catch (JedisException e) { logger.error(e.getMessage(), e); } logger.info("Complete time: {}", Integer.valueOf(i)); if (i < size) { TimeUnit.SECONDS.sleep(5L); } } } @AfterClass public void destroy() { if (shardedJedisPool != null) { shardedJedisPool.close(); } } }