监听元数据事件
NamingMetadataManager
@Override
public void onEvent(Event event) {
//实例元数据
if (event instanceof MetadataEvent.InstanceMetadataEvent) {
handleInstanceMetadataEvent((MetadataEvent.InstanceMetadataEvent) event);
//服务元数据
} else if (event instanceof MetadataEvent.ServiceMetadataEvent) {
handleServiceMetadataEvent((MetadataEvent.ServiceMetadataEvent) event);
} else {
//服务端断开事件
handleClientDisconnectEvent((ClientEvent.ClientDisconnectEvent) event);
}
}
实例元数据事件处理
private void handleInstanceMetadataEvent(MetadataEvent.InstanceMetadataEvent event) {
//获取服务信息
Service service = event.getService();
//获取metadataId
String metadataId = event.getMetadataId();
if (containInstanceMetadata(service, metadataId)) {
//过期元数据处理
updateExpiredInfo(event.isExpired(),
ExpiredMetadataInfo.newExpiredInstanceMetadata(event.getService(), event.getMetadataId()));
}
}
判断是否包含元数据
public boolean containInstanceMetadata(Service service, String metadataId) {
return instanceMetadataMap.containsKey(service) && instanceMetadataMap.get(service).containsKey(metadataId);
}
操作元数据信息
private final Set<ExpiredMetadataInfo> expiredMetadataInfos;
private void updateExpiredInfo(boolean expired, ExpiredMetadataInfo expiredMetadataInfo) {
// 添加或移除过期的实例元数据
if (expired) {
expiredMetadataInfos.add(expiredMetadataInfo);
} else {
expiredMetadataInfos.remove(expiredMetadataInfo);
}
}
元数据处理操作
@Component
public class NamingMetadataManager extends SmartSubscriber {
//维护过期的元数据信息 包括服务和实例的
private final Set<ExpiredMetadataInfo> expiredMetadataInfos;
//维护服务的元数据
private ConcurrentMap<Service, ServiceMetadata> serviceMetadataMap;
//维护实例的元数据
private ConcurrentMap<Service, ConcurrentMap<String, InstanceMetadata>>
instanceMetadataMap;
private static final int INITIAL_CAPACITY = 1;
public NamingMetadataManager() {
//1<<10 = 1024
serviceMetadataMap = new ConcurrentHashMap<>(1 << 10);
instanceMetadataMap = new ConcurrentHashMap<>(1 << 10);
expiredMetadataInfos = new ConcurrentHashSet<>();
//向NotifyCenter注册自己 这块等后面讲到统一事件中心再详细讲解
//此处略过
NotifyCenter.registerSubscriber(this,
NamingEventPublisherFactory.getInstance());
}
//是否包括给服务的元数据
public boolean containServiceMetadata(Service service) {
return serviceMetadataMap.containsKey(service);
}
//是否包含实例的运输局
public boolean containInstanceMetadata(Service service, String metadataId) {
return instanceMetadataMap.containsKey(service) &&
instanceMetadataMap.get(service).containsKey(metadataId);
}
//查询服务的元数据
public Optional<ServiceMetadata> getServiceMetadata(Service service) {
return Optional.ofNullable(serviceMetadataMap.get(service));
}
//查询实例的元数据
public Optional<InstanceMetadata> getInstanceMetadata(Service service, String
metadataId) {
ConcurrentMap<String, InstanceMetadata> instanceMetadataMapForService =
instanceMetadataMap.get(service);
if (null == instanceMetadataMapForService) {
return Optional.empty();
}
return Optional.ofNullable(instanceMetadataMapForService.get(metadataId));
}
//更新服务的元数据 看到这里应该明白为什么update 和 add 都是调用这个方法了
//新增server的版本号
public void updateServiceMetadata(Service service, ServiceMetadata serviceMetadata)
{
service.incrementRevision();
serviceMetadataMap.put(service, serviceMetadata);
}
//更新实例元数据
//实例元数据是再server为key的子map中 如果子map不存在就new一个
public void updateInstanceMetadata(Service service, String metadataId,
InstanceMetadata instanceMetadata) {
if (!instanceMetadataMap.containsKey(service)) {
instanceMetadataMap.putIfAbsent(service, new ConcurrentHashMap<>
(INITIAL_CAPACITY));
}
instanceMetadataMap.get(service).put(metadataId, instanceMetadata);
}
/**
* Remove service metadata.
*
* @param service service
*/
public void removeServiceMetadata(Service service) {
serviceMetadataMap.remove(service);
expiredMetadataInfos.remove(ExpiredMetadataInfo.newExpiredServiceMetadata(service));
}
//移除服务下的某个实例元数据
//如果给服务下么有么有任务实例就删除服务的元数据
public void removeInstanceMetadata(Service service, String metadataId) {
ConcurrentMap<String, InstanceMetadata> instanceMetadataMapForService = instanceMetadataMap.get(service);
instanceMetadataMapForService.remove(metadataId);
if (instanceMetadataMapForService.isEmpty()) {
serviceMetadataMap.remove(service);
}
expiredMetadataInfos.remove(ExpiredMetadataInfo.newExpiredInstanceMetadata(service, metadataId));
}
//从当前的serviceMetadataMap创建快照
//在导出快照的时候crud是不允许操作的 这个通过前面讲的读写锁来控制
public Map<Service, ServiceMetadata> getServiceMetadataSnapshot() {
ConcurrentMap<Service, ServiceMetadata> result = new ConcurrentHashMap<>
(serviceMetadataMap.size());
result.putAll(serviceMetadataMap);
return result;
}
//从当前的instanceMetadataMap创建快照
//在导出快照的时候cud是不允许操作的 这个通过前面讲的读写锁来控制
//导出时完毕不影响查询操作
public Map<Service, ConcurrentMap<String, InstanceMetadata>>
getInstanceMetadataSnapshot() {
ConcurrentMap<Service, ConcurrentMap<String, InstanceMetadata>> result = new
ConcurrentHashMap<>(
instanceMetadataMap.size());
result.putAll(instanceMetadataMap);
return result;
}
//加载服务的元数据快照
//加载时不可以做cud操作同导出快照一样都是由读写锁控制
//加载时完毕不影响查询操作
//最后清空老的数据
public void loadServiceMetadataSnapshot(ConcurrentMap<Service, ServiceMetadata>
snapshot) {
for (Service each : snapshot.keySet()) {
ServiceManager.getInstance().getSingleton(each);
}
ConcurrentMap<Service, ServiceMetadata> oldSnapshot = serviceMetadataMap;
serviceMetadataMap = snapshot;
oldSnapshot.clear();
}
//加载实例数据 同上
public void loadInstanceMetadataSnapshot(ConcurrentMap<Service,
ConcurrentMap<String, InstanceMetadata>> snapshot) {
ConcurrentMap<Service, ConcurrentMap<String, InstanceMetadata>> oldSnapshot =
instanceMetadataMap;
instanceMetadataMap = snapshot;
oldSnapshot.clear();
}
public Set<ExpiredMetadataInfo> getExpiredMetadataInfos() {
return expiredMetadataInfos;
}
//监听元数据变更事件及客户端断开事件
@Override
public List<Class<? extends Event>> subscribeTypes() {
List<Class<? extends Event>> result = new LinkedList<>();
result.add(MetadataEvent.InstanceMetadataEvent.class);
result.add(MetadataEvent.ServiceMetadataEvent.class);
result.add(ClientEvent.ClientDisconnectEvent.class);
return result;
}
//处理事件
@Override
public void onEvent(Event event) {
if (event instanceof MetadataEvent.InstanceMetadataEvent) {
handleInstanceMetadataEvent((MetadataEvent.InstanceMetadataEvent) event);
} else if (event instanceof MetadataEvent.ServiceMetadataEvent) {
handleServiceMetadataEvent((MetadataEvent.ServiceMetadataEvent) event);
} else {
handleClientDisconnectEvent((ClientEvent.ClientDisconnectEvent) event);
}
}
//客户端delete后 找到它所有发布的服务实例
//从InstancePublishInfo中metadataId, 此处回想下之前讲的的Client对象时管理什么的
//如果元数据管理器中有metadataId的数据就移除掉
private void handleClientDisconnectEvent(ClientEvent.ClientDisconnectEvent event) {
for (Service each : event.getClient().getAllPublishedService()) {
String metadataId =
event.getClient().getInstancePublishInfo(each).getMetadataId();
if (containInstanceMetadata(each, metadataId)) {
updateExpiredInfo(true,
ExpiredMetadataInfo.newExpiredInstanceMetadata(each, metadataId));
}
}
}
//只有包含才更新
//注意不包含的情况不能本地添加 因为要保证集群的数据一致性
//这里更新并不是更新元数据内容 而是根据服务的上下线 判断要不要加上元数据的过期信息
private void handleServiceMetadataEvent(MetadataEvent.ServiceMetadataEvent event) {
Service service = event.getService();
if (containServiceMetadata(service)) {
updateExpiredInfo(event.isExpired(),
ExpiredMetadataInfo.newExpiredServiceMetadata(service));
}
}
//只有包含才更新
//注意不包含的情况不能本地添加 因为要保证集群的数据一致性
//这里更新并不是更新元数据内容 而是根据服务的上下线 判断要不要加上元数据的过期信息
private void handleInstanceMetadataEvent(MetadataEvent.InstanceMetadataEvent event)
{
Service service = event.getService();
String metadataId = event.getMetadataId();
if (containInstanceMetadata(service, metadataId)) {
updateExpiredInfo(event.isExpired(),
ExpiredMetadataInfo.newExpiredInstanceMetadata(event.getService(),
event.getMetadataId()));
}
}
//服务下线或者客户端delete掉后expired 值为true
//服务上线后expired为false
private void updateExpiredInfo(boolean expired, ExpiredMetadataInfo
expiredMetadataInfo) {
if (expired) {
expiredMetadataInfos.add(expiredMetadataInfo);
} else {
expiredMetadataInfos.remove(expiredMetadataInfo);
}
}
}