Dubbo 服务注册机制
Dubbo所支持的注册中心
-
Multicast
组网广播,只可以在局域网内使用,一般只是作为测试
-
Zookeeper (常用)
是Apache Hadoop 的子项目,是一个树形的目录服务
-
Redis
-
Simple
-
基于Dubbo 的服务实现(SimpleRegistryService),不支持集群
Redis注册中心
- 数据结构:如何存储服务的注册与订阅关系
- 状态更新:当服务状态改变,如何及时更新
数据结构:
redis 注册中心使用Map
存储服务发布,订阅等信息:
key:map
key:value
key:value
...
发布订阅:
/dubbo/{serviceName}/providers
{providerUrl1}:{periodTimestamp}
{providerUrl2}:{periodTimestamp}
...
订阅服务:
/dubbo/{serviceName}/consumers
{consumerUrl1}:{periodTimestamp}
{consumerUrl2}:{periodTimestamp}
...
有效期:
这个value值(periodTimestamp)是一种有效期:
provider和consumer发给redis的数据会有一个当前时间+30秒的时间戳作为有效期。要是provider活consumer还“活着”,就会不断“续命”,每次都是+3# Dubbo 服务注册机制
Dubbo所支持的注册中心
-
Multicast
组网广播,只可以在局域网内使用,一般只是作为测试
-
Zookeeper (常用)
是Apache Hadoop 的子项目,是一个树形的目录服务
-
Redis
-
Simple
-
基于Dubbo 的服务实现(SimpleRegistryService),不支持集群
Redis注册中心
- 数据结构:如何存储服务的注册与订阅关系
- 状态更新:当服务状态改变,如何及时更新
数据结构:
redis 注册中心使用Map
存储服务发布,订阅等信息:
key:map
key:value
key:value
...
发布订阅:
/dubbo/{serviceName}/providers
{providerUrl1}:{periodTimestamp}
{providerUrl2}:{periodTimestamp}
...
订阅服务:
/dubbo/{serviceName}/consumers
{consumerUrl1}:{periodTimestamp}
{consumerUrl2}:{periodTimestamp}
...
有效期:
这个value值(periodTimestamp)是一种有效期:
provider和consumer发给redis的数据会有一个当前时间+30秒的时间戳作为有效期。要是provider活consumer还“活着”,就会不断“续命”,每次都是+30秒。
相关源码:
在RedisRegistry
这个类中的有个线程专门来干这个活expireExecutor
ScheduledExecutorService expireExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("DubboRegistryExpireTimer", true));
this.expirePeriod = url.getParameter(SESSION_TIMEOUT_KEY, DEFAULT_SESSION_TIMEOUT); //默认是60s
this.expireFuture = expireExecutor.scheduleWithFixedDelay(() -> {
try {
deferExpired(); // Extend the expiration time
} catch (Throwable t) {
// Defensive fault tolerance
logger.error("Unexpected exception occur at defer expire time, cause: " + t.getMessage(), t);
}
}, expirePeriod / 2, expirePeriod / 2, TimeUnit.MILLISECONDS); //定时每30执行一次
DEFAULT_SESSION_TIMEOUT = 60 * 1000;
可以看到有效周期默认是60s, 但是dubbo会给自动在有效期的二分之一的时间就发送一次“续命”
if (jedis.hset(key, url.toFullString(), String.valueOf(System.currentTimeMillis() + expirePeriod)) == 1) {
jedis.publish(key, REGISTER);
}
奇怪?不应该是value不应该是+30s吗?
是的,没错。但是你想想每次都是30s执行一次,每次加60s,是不是距离上次的推送的value差值就是30s呢。确实优点绕,但是还是给聪明的我发现了。
发布订阅的流程
Consumer
事件:类似topic
相关代码:
-
RedisRegistry