队列目的就是存放3分钟内有变化的服务实例,为什么呢,3分钟无变化那就大可不必被拉取一下。如果有注册或者移除实例的操作时,才应该被客户端去拉取。同时,还要清除掉3分钟无变化的服务实例。
- 首先,要有一个队列
队列记录服务实例变更动作
/*** 最近变更的服务实例的队列*/private LinkedList<RecentlyChangedServiceInstance> recentlyChangedQueue =new LinkedList<>();
- 其次,建立一个表示“最近变化的服务实例”对象
这个对象,包含了服务的实例,还有时间戳以及表示实例变更的操作
class RecentlyChangedServiceInstance {/*** 服务实例*/ServiceInstance serviceInstance;/*** 服务实例发生变更的时间戳*/Long changedTimeStamp;/*** 变更操作*/String changedOperation;public RecentlyChangedServiceInstance(ServiceInstance serviceInstance,Long changedTimeStamp,String changedOperation) {this.serviceInstance = serviceInstance;this.changedTimeStamp = changedTimeStamp;this.changedOperation = changedOperation;}}
还需要建立一个表示操作状态的类
/*** 服务实例操作*/class ServiceInstanceOperation {/*** 注册*/public static final String REGISTER = "register";/*** 删除*/public static final String REMOVE = "remove";}
为了定时剔除不需要被拉取的实例数据,还应该需要一个监控线程类
/*** 最近变更队列的监控线程*/class RecentlyChangedQueueMonitor extends Thread {@Overridepublic void run() {while (true) {try {synchronized (instance) {//遍历queueRecentlyChangedServiceInstance recentlyChangedServiceInstance = null;long currentTimeStamp = System.currentTimeMillis();while ((recentlyChangedServiceInstance = recentlyChangedQueue.peek()) != null) {//判断如果一个服务实例变更信息已经在队列里存在超过3分钟就从队列中移除if (currentTimeStamp - recentlyChangedServiceInstance.changedTimeStamp> RECENTLY_CHANGED_ITEM_EXPIRED_INTERVAL) {recentlyChangedQueue.pop();}}}Thread.sleep(RECENTLY_CHANGED_ITEM_CHECK_INTERVAL);} catch (InterruptedException e) {e.printStackTrace();}}}}
在注册和移除方法中,加上对服务实例变更操作的记录 ```java /**
- 服务注册
@param serviceInstance */ public synchronized void registry(ServiceInstance serviceInstance) { //将服务实例放入最近变更的队列中 RecentlyChangedServiceInstance recentlyServiceInstance =
new RecentlyChangedServiceInstance(serviceInstance, System.currentTimeMillis(), ServiceInstanceOperation.REGISTER);//加入队尾 recentlyChangedQueue.offer(recentlyServiceInstance);
//将服务实例放入注册表中 Map
serviceInstanceMap = registry.get(serviceInstance.getServiceName());//如果获取不到map证明实例一个都没有注册过,就要创建一个实例集合map存放集群实例信息 if (serviceInstanceMap == null) {
serviceInstanceMap = new HashMap<String, ServiceInstance>(); registry.put(serviceInstance.getServiceName(),serviceInstanceMap);} //如果存在对应的实例集合就把新的实例加入该集合中 serviceInstanceMap.put(serviceInstance.getServiceInstanceId(),
serviceInstance);System.out.println(“服务实例【”+serviceInstance+”】完成注册”); System.out.println(“注册表”+registry); }
/**
- 移除服务实例
- @param serviceName
@param serviceInstanceId */ public synchronized void remove(String serviceName, String serviceInstanceId) { //获取服务实例 Map
serviceInstanceMap = registry.get(serviceName);ServiceInstance serviceInstance = serviceInstanceMap.get(serviceInstanceId); //将服务实例变更信息放入队列中 RecentlyChangedServiceInstance recentlyServiceInstance =
new RecentlyChangedServiceInstance(serviceInstance, System.currentTimeMillis(), ServiceInstanceOperation.REMOVE);//加入队尾 recentlyChangedQueue.offer(recentlyServiceInstance);
//从服务注册表中删除实例 System.out.println(“服务实例从注册表中摘除【”+ serviceName + serviceInstanceId + “】”); serviceInstanceMap.remove(serviceInstanceId); }
6. 提供获取增量注册表方法接口
```java
/**
* 拉取增量注册表
* @return
*/
public LinkedList<ServiceRegistry.RecentlyChangedServiceInstance> fetchDeltaServiceRegistry() {
return registry.getRecntlyChangedQueue();
}
