1、首先写个测试类,方便进入查看源码
package com.redisson;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
/**
* @Description TODO
* @Date 2020/6/30 10:29
* @Author zsj
*/
public class RedissonTest {
public static void main(String[] args) {
Config config = new Config();
config.useSingleServer().setAddress("redis://192.168.2.41:6379")
.setPassword("rabbit123@");
RedissonClient redisson = Redisson.create(config);
redisson.shutdown();
}
}
2、进入到Redisson这个类,查看其构造函数
protected Redisson(Config config) {
this.config = config;
Config configCopy = new Config(config);
// 继续查看源码
this.connectionManager = ConfigSupport.createConnectionManager(configCopy);
this.evictionScheduler = new EvictionScheduler(this.connectionManager.getCommandExecutor());
this.writeBehindService = new WriteBehindService(this.connectionManager.getCommandExecutor());
}
3、进入到 MasterSlaveConnectionManager类
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package org.redisson.connection;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.epoll.EpollDatagramChannel;
import io.netty.channel.epoll.EpollEventLoopGroup;
import io.netty.channel.epoll.EpollSocketChannel;
import io.netty.channel.kqueue.KQueueDatagramChannel;
import io.netty.channel.kqueue.KQueueEventLoopGroup;
import io.netty.channel.kqueue.KQueueSocketChannel;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.resolver.AddressResolverGroup;
import io.netty.resolver.DefaultAddressResolverGroup;
import io.netty.resolver.dns.DnsServerAddressStreamProviders;
import io.netty.util.HashedWheelTimer;
import io.netty.util.Timeout;
import io.netty.util.Timer;
import io.netty.util.TimerTask;
import io.netty.util.concurrent.DefaultThreadFactory;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.ImmediateEventExecutor;
import io.netty.util.concurrent.Promise;
import io.netty.util.internal.PlatformDependent;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReferenceArray;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import org.redisson.ElementsSubscribeService;
import org.redisson.Version;
import org.redisson.api.NodeType;
import org.redisson.api.RFuture;
import org.redisson.client.RedisClient;
import org.redisson.client.RedisClientConfig;
import org.redisson.client.RedisConnection;
import org.redisson.client.RedisException;
import org.redisson.client.RedisNodeNotFoundException;
import org.redisson.client.codec.Codec;
import org.redisson.client.protocol.RedisCommand;
import org.redisson.cluster.ClusterSlotRange;
import org.redisson.command.CommandSyncService;
import org.redisson.config.BaseMasterSlaveServersConfig;
import org.redisson.config.Config;
import org.redisson.config.MasterSlaveServersConfig;
import org.redisson.config.TransportMode;
import org.redisson.misc.CountableListener;
import org.redisson.misc.InfinitySemaphoreLatch;
import org.redisson.misc.RPromise;
import org.redisson.misc.RedisURI;
import org.redisson.misc.RedissonPromise;
import org.redisson.pubsub.PublishSubscribeService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MasterSlaveConnectionManager implements ConnectionManager {
public static final Timeout DUMMY_TIMEOUT = new Timeout() {
public Timer timer() {
return null;
}
public TimerTask task() {
return null;
}
public boolean isExpired() {
return false;
}
public boolean isCancelled() {
return false;
}
public boolean cancel() {
return true;
}
};
protected final String id;
public static final int MAX_SLOT = 16384;
protected final ClusterSlotRange singleSlotRange;
private final Logger log;
private HashedWheelTimer timer;
//redisson序列化协议
protected Codec codec;
// netty客户端连接服务端的EventLoopGroup
protected final EventLoopGroup group;
//netty客户端连接服务端的channelClass 根据传输方式而定
protected final Class socketChannelClass;
protected DNSMonitor dnsMonitor;
protected MasterSlaveServersConfig config;
private final AtomicReferenceArray slot2entry;
private final Map client2entry;
private final Promise shutdownPromise;
private final InfinitySemaphoreLatch shutdownLatch;
private IdleConnectionWatcher connectionWatcher;
private final ConnectionEventsHub connectionEventsHub;
private final ExecutorService executor;
private final CommandSyncService commandExecutor;
private final Config cfg;
protected final AddressResolverGroup resolverGroup;
private final ElementsSubscribeService elementsSubscribeService;
private PublishSubscribeService subscribeService;
private final Map nodeConnections;
public MasterSlaveConnectionManager(MasterSlaveServersConfig cfg, Config config, UUID id) {
this(config, id);
this.config = cfg;
this.initTimer(cfg);
this.initSingleEntry();
}
protected MasterSlaveConnectionManager(Config cfg, UUID id) {
this.singleSlotRange = new ClusterSlotRange(0, 16383);
this.log = LoggerFactory.getLogger(this.getClass());
this.slot2entry = new AtomicReferenceArray(16384);
this.client2entry = new ConcurrentHashMap();
this.shutdownPromise = ImmediateEventExecutor.INSTANCE.newPromise();
this.shutdownLatch = new InfinitySemaphoreLatch();
this.connectionEventsHub = new ConnectionEventsHub();
this.elementsSubscribeService = new ElementsSubscribeService(this);
this.nodeConnections = new ConcurrentHashMap();
this.id = id.toString();
Version.logVersion();
if (cfg.getTransportMode() == TransportMode.EPOLL) {
//传输方式 epoll
if (cfg.getEventLoopGroup() == null) {
this.group = new EpollEventLoopGroup(cfg.getNettyThreads(), new DefaultThreadFactory("redisson-netty"));
} else {
this.group = cfg.getEventLoopGroup();
}
// 对应传输方式epoll的SocketChannel
this.socketChannelClass = EpollSocketChannel.class;
if (PlatformDependent.isAndroid()) {
this.resolverGroup = DefaultAddressResolverGroup.INSTANCE;
} else {
this.resolverGroup = cfg.getAddressResolverGroupFactory().create(EpollDatagramChannel.class, DnsServerAddressStreamProviders.platformDefault());
}
} else if (cfg.getTransportMode() == TransportMode.KQUEUE) {
//传输方式 kqueue
if (cfg.getEventLoopGroup() == null) {
this.group = new KQueueEventLoopGroup(cfg.getNettyThreads(), new DefaultThreadFactory("redisson-netty"));
} else {
this.group = cfg.getEventLoopGroup();
}
// 对应传输方式kqueue的SocketChannel
this.socketChannelClass = KQueueSocketChannel.class;
if (PlatformDependent.isAndroid()) {
this.resolverGroup = DefaultAddressResolverGroup.INSTANCE;
} else {
this.resolverGroup = cfg.getAddressResolverGroupFactory().create(KQueueDatagramChannel.class, DnsServerAddressStreamProviders.platformDefault());
}
} else {
//默认 nio传输方式
if (cfg.getEventLoopGroup() == null) {
this.group = new NioEventLoopGroup(cfg.getNettyThreads(), new DefaultThreadFactory("redisson-netty"));
} else {
this.group = cfg.getEventLoopGroup();
}
// 对应传输方式nio的SocketChannel
this.socketChannelClass = NioSocketChannel.class;
if (PlatformDependent.isAndroid()) {
this.resolverGroup = DefaultAddressResolverGroup.INSTANCE;
} else {
this.resolverGroup = cfg.getAddressResolverGroupFactory().create(NioDatagramChannel.class, DnsServerAddressStreamProviders.platformDefault());
}
}
if (cfg.getExecutor() == null) {
int threads = Runtime.getRuntime().availableProcessors() * 2;
if (cfg.getThreads() != 0) {
threads = cfg.getThreads();
}
this.executor = Executors.newFixedThreadPool(threads, new DefaultThreadFactory("redisson"));
} else {
this.executor = cfg.getExecutor();
}
this.cfg = cfg;
this.codec = cfg.getCodec();
this.commandExecutor = new CommandSyncService(this);
}
protected void closeNodeConnections() {
List> futures = new ArrayList();
Iterator var2 = this.nodeConnections.values().iterator();
while(var2.hasNext()) {
RedisConnection connection = (RedisConnection)var2.next();
RFuture future = connection.getRedisClient().shutdownAsync();
futures.add(future);
}
var2 = futures.iterator();
while(var2.hasNext()) {
RFuture future = (RFuture)var2.next();
future.syncUninterruptibly();
}
}
protected void closeNodeConnection(RedisConnection conn) {
if (this.nodeConnections.values().remove(conn)) {
conn.closeAsync();
}
}
protected final void disconnectNode(RedisURI addr) {
RedisConnection conn = (RedisConnection)this.nodeConnections.remove(addr);
if (conn != null) {
conn.closeAsync();
}
}
protected final void disconnectNode(RedisClient client) {
RedisConnection conn = (RedisConnection)this.nodeConnections.remove(client);
if (conn != null) {
conn.closeAsync();
}
}
protected final RFuture connectToNode(BaseMasterSlaveServersConfig cfg, RedisURI addr, RedisClient client, String sslHostname) {
Object key;
if (client != null) {
key = client;
} else {
key = addr;
}
RedisConnection conn = (RedisConnection)this.nodeConnections.get(key);
if (conn != null) {
if (conn.isActive()) {
return RedissonPromise.newSucceededFuture(conn);
}
this.nodeConnections.remove(key);
conn.closeAsync();
}
if (addr != null) {
client = this.createClient(NodeType.MASTER, addr, cfg.getConnectTimeout(), cfg.getTimeout(), sslHostname);
}
RPromise result = new RedissonPromise();
RFuture future = client.connectAsync();
future.onComplete((connection, e) -> {
if (e != null) {
result.tryFailure(e);
} else {
if (connection.isActive()) {
this.nodeConnections.put(key, connection);
result.trySuccess(connection);
} else {
connection.closeAsync();
result.tryFailure(new RedisException("Connection to " + connection.getRedisClient().getAddr() + " is not active!"));
}
}
});
return result;
}
public String getId() {
return this.id;
}
public boolean isClusterMode() {
return false;
}
public CommandSyncService getCommandExecutor() {
return this.commandExecutor;
}
public IdleConnectionWatcher getConnectionWatcher() {
return this.connectionWatcher;
}
public Config getCfg() {
return this.cfg;
}
public MasterSlaveServersConfig getConfig() {
return this.config;
}
public Codec getCodec() {
return this.codec;
}
public Collection getEntrySet() {
return this.client2entry.values();
}
protected void initTimer(MasterSlaveServersConfig config) {
int[] timeouts = new int[]{config.getRetryInterval(), config.getTimeout()};
Arrays.sort(timeouts);
int minTimeout = timeouts[0];
if (minTimeout % 100 != 0) {
minTimeout = minTimeout % 100 / 2;
} else if (minTimeout == 100) {
minTimeout = 50;
} else {
minTimeout = 100;
}
this.timer = new HashedWheelTimer(new DefaultThreadFactory("redisson-timer"), (long)minTimeout, TimeUnit.MILLISECONDS, 1024, false);
this.connectionWatcher = new IdleConnectionWatcher(this, config);
this.subscribeService = new PublishSubscribeService(this, config);
}
protected void initSingleEntry() {
try {
Object entry;
if (this.config.checkSkipSlavesInit()) {
entry = new SingleEntry(this, this.config);
} else {
entry = this.createMasterSlaveEntry(this.config);
}
RFuture f = ((MasterSlaveEntry)entry).setupMasterEntry(new RedisURI(this.config.getMasterAddress()));
//客户端异步连接
f.syncUninterruptibly();
for(int slot = this.singleSlotRange.getStartSlot(); slot < this.singleSlotRange.getEndSlot() + 1; ++slot) {
this.addEntry(slot, (MasterSlaveEntry)entry);
}
this.startDNSMonitoring((RedisClient)f.getNow());
} catch (Exception var4) {
this.stopThreads();
throw var4;
}
}
protected void startDNSMonitoring(RedisClient masterHost) {
if (this.config.getDnsMonitoringInterval() != -1L) {
Set slaveAddresses = (Set)this.config.getSlaveAddresses().stream().map((r) -> {
return new RedisURI(r);
}).collect(Collectors.toSet());
this.dnsMonitor = new DNSMonitor(this, masterHost, slaveAddresses, this.config.getDnsMonitoringInterval(), this.resolverGroup);
this.dnsMonitor.start();
}
}
protected MasterSlaveEntry createMasterSlaveEntry(MasterSlaveServersConfig config) {
MasterSlaveEntry entry = new MasterSlaveEntry(this, config);
List> fs = entry.initSlaveBalancer(Collections.emptySet());
Iterator var4 = fs.iterator();
while(var4.hasNext()) {
RFuture future = (RFuture)var4.next();
future.syncUninterruptibly();
}
return entry;
}
protected MasterSlaveServersConfig create(BaseMasterSlaveServersConfig cfg) {
MasterSlaveServersConfig c = new MasterSlaveServersConfig();
c.setPingConnectionInterval(cfg.getPingConnectionInterval());
c.setSslEnableEndpointIdentification(cfg.isSslEnableEndpointIdentification());
c.setSslProvider(cfg.getSslProvider());
c.setSslTruststore(cfg.getSslTruststore());
c.setSslTruststorePassword(cfg.getSslTruststorePassword());
c.setSslKeystore(cfg.getSslKeystore());
c.setSslKeystorePassword(cfg.getSslKeystorePassword());
c.setRetryInterval(cfg.getRetryInterval());
c.setRetryAttempts(cfg.getRetryAttempts());
c.setTimeout(cfg.getTimeout());
c.setLoadBalancer(cfg.getLoadBalancer());
c.setPassword(cfg.getPassword());
c.setUsername(cfg.getUsername());
c.setClientName(cfg.getClientName());
c.setMasterConnectionPoolSize(cfg.getMasterConnectionPoolSize());
c.setSlaveConnectionPoolSize(cfg.getSlaveConnectionPoolSize());
c.setSubscriptionConnectionPoolSize(cfg.getSubscriptionConnectionPoolSize());
c.setSubscriptionsPerConnection(cfg.getSubscriptionsPerConnection());
c.setConnectTimeout(cfg.getConnectTimeout());
c.setIdleConnectionTimeout(cfg.getIdleConnectionTimeout());
c.setFailedSlaveCheckInterval(cfg.getFailedSlaveCheckInterval());
c.setFailedSlaveReconnectionInterval(cfg.getFailedSlaveReconnectionInterval());
c.setMasterConnectionMinimumIdleSize(cfg.getMasterConnectionMinimumIdleSize());
c.setSlaveConnectionMinimumIdleSize(cfg.getSlaveConnectionMinimumIdleSize());
c.setSubscriptionConnectionMinimumIdleSize(cfg.getSubscriptionConnectionMinimumIdleSize());
c.setReadMode(cfg.getReadMode());
c.setSubscriptionMode(cfg.getSubscriptionMode());
c.setDnsMonitoringInterval(cfg.getDnsMonitoringInterval());
c.setKeepAlive(cfg.isKeepAlive());
return c;
}
public RedisClient createClient(NodeType type, RedisURI address, String sslHostname) {
RedisClient client = this.createClient(type, address, this.config.getConnectTimeout(), this.config.getTimeout(), sslHostname);
return client;
}
public RedisClient createClient(NodeType type, InetSocketAddress address, RedisURI uri, String sslHostname) {
RedisClient client = this.createClient(type, address, uri, this.config.getConnectTimeout(), this.config.getTimeout(), sslHostname);
return client;
}
public RedisClient createClient(NodeType type, RedisURI address, int timeout, int commandTimeout, String sslHostname) {
RedisClientConfig redisConfig = this.createRedisConfig(type, address, timeout, commandTimeout, sslHostname);
return RedisClient.create(redisConfig);
}
private RedisClient createClient(NodeType type, InetSocketAddress address, RedisURI uri, int timeout, int commandTimeout, String sslHostname) {
RedisClientConfig redisConfig = this.createRedisConfig(type, (RedisURI)null, timeout, commandTimeout, sslHostname);
redisConfig.setAddress(address, uri);
return RedisClient.create(redisConfig);
}
protected RedisClientConfig createRedisConfig(NodeType type, RedisURI address, int timeout, int commandTimeout, String sslHostname) {
RedisClientConfig redisConfig = new RedisClientConfig();
redisConfig.setAddress(address).setTimer(this.timer).setExecutor(this.executor).setResolverGroup(this.resolverGroup).setGroup(this.group).setSocketChannelClass(this.socketChannelClass).setConnectTimeout(timeout).setCommandTimeout(commandTimeout).setSslHostname(sslHostname).setSslEnableEndpointIdentification(this.config.isSslEnableEndpointIdentification()).setSslProvider(this.config.getSslProvider()).setSslTruststore(this.config.getSslTruststore()).setSslTruststorePassword(this.config.getSslTruststorePassword()).setSslKeystore(this.config.getSslKeystore()).setSslKeystorePassword(this.config.getSslKeystorePassword()).setClientName(this.config.getClientName()).setDecodeInExecutor(this.cfg.isDecodeInExecutor()).setKeepPubSubOrder(this.cfg.isKeepPubSubOrder()).setPingConnectionInterval(this.config.getPingConnectionInterval()).setKeepAlive(this.config.isKeepAlive()).setTcpNoDelay(this.config.isTcpNoDelay()).setUsername(this.config.getUsername()).setPassword(this.config.getPassword()).setNettyHook(this.cfg.getNettyHook());
if (type != NodeType.SENTINEL) {
redisConfig.setDatabase(this.config.getDatabase());
}
return redisConfig;
}
public int calcSlot(String key) {
return this.singleSlotRange.getStartSlot();
}
public int calcSlot(byte[] key) {
return this.singleSlotRange.getStartSlot();
}
public MasterSlaveEntry getEntry(InetSocketAddress address) {
Iterator var2 = this.client2entry.values().iterator();
MasterSlaveEntry entry;
InetSocketAddress addr;
do {
if (!var2.hasNext()) {
return null;
}
entry = (MasterSlaveEntry)var2.next();
addr = entry.getClient().getAddr();
} while(!addr.getAddress().equals(address.getAddress()) || addr.getPort() != address.getPort());
return entry;
}
protected MasterSlaveEntry getEntry(RedisURI addr) {
Iterator var2 = this.client2entry.values().iterator();
MasterSlaveEntry entry;
do {
if (!var2.hasNext()) {
return null;
}
entry = (MasterSlaveEntry)var2.next();
if (RedisURI.compare(entry.getClient().getAddr(), addr)) {
return entry;
}
} while(!entry.hasSlave(addr));
return entry;
}
public MasterSlaveEntry getEntry(RedisClient redisClient) {
MasterSlaveEntry entry = (MasterSlaveEntry)this.client2entry.get(redisClient);
if (entry != null) {
return entry;
} else {
Iterator var3 = this.client2entry.values().iterator();
MasterSlaveEntry mentry;
do {
if (!var3.hasNext()) {
return null;
}
mentry = (MasterSlaveEntry)var3.next();
} while(!mentry.hasSlave(redisClient));
return mentry;
}
}
public MasterSlaveEntry getEntry(String name) {
int slot = this.calcSlot(name);
return this.getEntry(slot);
}
public MasterSlaveEntry getEntry(int slot) {
return (MasterSlaveEntry)this.slot2entry.get(slot);
}
protected final RFuture changeMaster(int slot, RedisURI address) {
MasterSlaveEntry entry = this.getEntry(slot);
RedisClient oldClient = entry.getClient();
RFuture future = entry.changeMaster(address);
future.onComplete((res, e) -> {
if (e == null) {
this.client2entry.remove(oldClient);
this.client2entry.put(entry.getClient(), entry);
}
});
return future;
}
protected final void addEntry(Integer slot, MasterSlaveEntry entry) {
MasterSlaveEntry oldEntry = (MasterSlaveEntry)this.slot2entry.getAndSet(slot, entry);
if (oldEntry != entry) {
entry.incReference();
this.shutdownEntry(oldEntry);
}
this.client2entry.put(entry.getClient(), entry);
}
protected final void removeEntry(Integer slot) {
MasterSlaveEntry entry = (MasterSlaveEntry)this.slot2entry.getAndSet(slot, (Object)null);
this.shutdownEntry(entry);
}
private void shutdownEntry(MasterSlaveEntry entry) {
if (entry != null && entry.decReference() == 0) {
this.client2entry.remove(entry.getClient());
entry.getAllEntries().forEach((e) -> {
entry.nodeDown(e);
});
entry.masterDown();
entry.shutdownAsync();
String slaves = (String)entry.getAllEntries().stream().filter((e) -> {
return !e.getClient().getAddr().equals(entry.getClient().getAddr());
}).map((e) -> {
return e.getClient().toString();
}).collect(Collectors.joining(","));
this.log.info("{} master and related slaves: {} removed", entry.getClient().getAddr(), slaves);
}
}
public RFuture connectionWriteOp(NodeSource source, RedisCommand command) {
MasterSlaveEntry entry = this.getEntry(source);
if (entry == null) {
return this.createNodeNotFoundFuture(source);
} else {
return source.getRedirect() != null && !RedisURI.compare(entry.getClient().getAddr(), source.getAddr()) && entry.hasSlave(source.getAddr()) ? entry.redirectedConnectionWriteOp(command, source.getAddr()) : entry.connectionWriteOp(command);
}
}
private MasterSlaveEntry getEntry(NodeSource source) {
if (source.getRedirect() != null) {
return this.getEntry(source.getAddr());
} else {
MasterSlaveEntry entry = source.getEntry();
if (source.getRedisClient() != null) {
entry = this.getEntry(source.getRedisClient());
}
if (entry == null && source.getSlot() != null) {
entry = this.getEntry(source.getSlot());
}
return entry;
}
}
public RFuture connectionReadOp(NodeSource source, RedisCommand command) {
MasterSlaveEntry entry = this.getEntry(source);
if (entry == null) {
return this.createNodeNotFoundFuture(source);
} else if (source.getRedirect() != null) {
return entry.connectionReadOp(command, source.getAddr());
} else {
return source.getRedisClient() != null ? entry.connectionReadOp(command, source.getRedisClient()) : entry.connectionReadOp(command);
}
}
protected RFuture createNodeNotFoundFuture(NodeSource source) {
RedisNodeNotFoundException ex;
if (source.getSlot() != null && source.getAddr() == null && source.getRedisClient() == null) {
ex = new RedisNodeNotFoundException("Node for slot: " + source.getSlot() + " hasn't been discovered yet. Check cluster slots coverage using CLUSTER NODES command. Increase value of retryAttempts and/or retryInterval settings.");
} else {
ex = new RedisNodeNotFoundException("Node: " + source + " hasn't been discovered yet. Increase value of retryAttempts and/or retryInterval settings.");
}
return RedissonPromise.newFailedFuture(ex);
}
public void releaseWrite(NodeSource source, RedisConnection connection) {
MasterSlaveEntry entry = this.getEntry(source);
if (entry == null) {
this.log.error("Node: " + source + " can't be found");
} else {
entry.releaseWrite(connection);
}
}
public void releaseRead(NodeSource source, RedisConnection connection) {
MasterSlaveEntry entry = this.getEntry(source);
if (entry == null) {
this.log.error("Node: " + source + " can't be found");
} else {
entry.releaseRead(connection);
}
}
public void shutdown() {
this.shutdown(0L, 2L, TimeUnit.SECONDS);
}
public void shutdown(long quietPeriod, long timeout, TimeUnit unit) {
if (this.dnsMonitor != null) {
this.dnsMonitor.stop();
}
this.connectionWatcher.stop();
RPromise result = new RedissonPromise();
CountableListener listener = new CountableListener(result, (Object)null, this.getEntrySet().size());
Iterator var8 = this.getEntrySet().iterator();
while(var8.hasNext()) {
MasterSlaveEntry entry = (MasterSlaveEntry)var8.next();
entry.shutdownAsync().onComplete(listener);
}
result.awaitUninterruptibly(timeout, unit);
this.resolverGroup.close();
this.shutdownLatch.close();
if (this.cfg.getExecutor() == null) {
this.executor.shutdown();
try {
this.executor.awaitTermination(timeout, unit);
} catch (InterruptedException var10) {
Thread.currentThread().interrupt();
}
}
this.shutdownPromise.trySuccess((Object)null);
this.shutdownLatch.awaitUninterruptibly();
if (this.cfg.getEventLoopGroup() == null) {
this.group.shutdownGracefully(quietPeriod, timeout, unit).syncUninterruptibly();
}
this.timer.stop();
}
public boolean isShuttingDown() {
return this.shutdownLatch.isClosed();
}
public boolean isShutdown() {
return this.group.isTerminated();
}
public EventLoopGroup getGroup() {
return this.group;
}
public Timeout newTimeout(TimerTask task, long delay, TimeUnit unit) {
try {
return this.timer.newTimeout(task, delay, unit);
} catch (IllegalStateException var6) {
if (this.isShuttingDown()) {
return DUMMY_TIMEOUT;
} else {
throw var6;
}
}
}
public InfinitySemaphoreLatch getShutdownLatch() {
return this.shutdownLatch;
}
public Future getShutdownPromise() {
return this.shutdownPromise;
}
public ConnectionEventsHub getConnectionEventsHub() {
return this.connectionEventsHub;
}
protected void stopThreads() {
this.shutdown();
}
public PublishSubscribeService getSubscribeService() {
return this.subscribeService;
}
public ElementsSubscribeService getElementsSubscribeService() {
return this.elementsSubscribeService;
}
public ExecutorService getExecutor() {
return this.executor;
}
public RedisURI getLastClusterNode() {
return null;
}
public RedisURI applyNatMap(RedisURI address) {
return address;
}
}
3、RedisClient类,创建客户端连接服务端所需的Bootstrap
private Bootstrap createBootstrap(RedisClientConfig config, Type type) {
Bootstrap bootstrap = (Bootstrap)((Bootstrap)(new Bootstrap()).resolver(config.getResolverGroup()).channel(config.getSocketChannelClass())).group(config.getGroup());
bootstrap.handler(new RedisChannelInitializer(bootstrap, config, this, this.channels, type));
bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, config.getConnectTimeout());
bootstrap.option(ChannelOption.SO_KEEPALIVE, config.isKeepAlive());
bootstrap.option(ChannelOption.TCP_NODELAY, config.isTcpNoDelay());
config.getNettyHook().afterBoostrapInitialization(bootstrap);
return bootstrap;
}
4、创建连接 RedisClient类
public RFuture connectAsync() {
RPromise f = new RedissonPromise();
RFuture addrFuture = this.resolveAddr();
addrFuture.onComplete((res, e) -> {
if (e != null) {
f.tryFailure(e);
} else {
//netty 异步连接
ChannelFuture channelFuture = this.bootstrap.connect(res);
channelFuture.addListener(new ChannelFutureListener() {
public void operationComplete(final ChannelFuture future) throws Exception {
if (RedisClient.this.bootstrap.config().group().isShuttingDown()) {
IllegalStateException cause = new IllegalStateException("RedisClient is shutdown");
f.tryFailure(cause);
} else {
if (future.isSuccess()) {
RedisConnection c = RedisConnection.getFrom(future.channel());
c.getConnectionPromise().onComplete((res, e) -> {
RedisClient.this.bootstrap.config().group().execute(new Runnable() {
public void run() {
if (e == null) {
if (!fx.trySuccess(c)) {
c.closeAsync();
}
} else {
fx.tryFailure(e);
c.closeAsync();
}
}
});
});
} else {
RedisClient.this.bootstrap.config().group().execute(new Runnable() {
public void run() {
f.tryFailure(future.cause());
}
});
}
}
}
});
}
});
return f;
}