generateResponse((HttpServletResponse) asyncContext.getResponse(), changedGroups);
//同步完成结束阻塞
asyncContext.complete();
}
Http请求到达sou-admin之后,并非立马响应数据,而是利用Servlet3.0的异步机制,异步响应数据。首先,将长轮询请求任务LongPollingClient
扔到BlockingQueue
中,并且开启调度任务,60s后执行,这样做的目的是60s后将该长轮询请求移除队列,即便是这段时间内没有发生配置数据变更。因为即便是没有配置变更,也得让网关知道,总不能让其干等吧,而且网关请求配置服务时,也有90s的超时时间
长轮询时配置数据变更立即响应数据
讲完了Http请求到达sou-admin这段时间没有变更配置数据60s后返回响应,如果这段时间内,存在配置数据变更呢?
首先Http请求到达sou-admin时最终拿到的配置信息数据都是从AbstractDataChangedListener
的Cache
中获取的
public abstract class AbstractDataChangedListener implements DataChangedListener, InitializingBean {
protected static final ConcurrentMap<String, ConfigDataCache> CACHE = new ConcurrentHashMap<>();
那AbstractDataChangedListener
中本地缓存数据是何时更新的,只有本地缓存更新了才会立即响应数据
AbstractDataChangedListener中本地缓存数据更新时机:
-
触发DataChangedEvent事件,DataChangedEventDispatcher监听到来处理数据同步的事件分类及分发
-
定时任务同步
1)触发Spring事件,DataChangedEventDispatcher监听到来处理数据同步的事件分类及分发
就是DataChangedListener
体系中讲解的内容,下面以创建和修改Plugin为例:
@Service(“pluginService”)
public class PluginServiceImpl implements PluginService {
@Override
@Transactional(rollbackFor = Exception.class)
public String createOrUpdate(final PluginDTO pluginDTO) {
final String msg = checkData(pluginDTO);
if (StringUtils.isNoneBlank(msg)) {
return msg;
}
PluginDO pluginDO = PluginDO.buildPluginDO(pluginDTO);
DataEventTypeEnum eventType = DataEventTypeEnum.CREATE;
if (StringUtils.isBlank(pluginDTO.getId())) {
insertPluginDataToResource(pluginDTO);
pluginMapper.insertSelective(pluginDO);
} else {
eventType = DataEventTypeEnum.UPDATE;
pluginMapper.updateSelective(pluginDO);
}
//触发事件
eventPublisher.publishEvent(new DataChangedEvent(ConfigGroupEnum.PLUGIN, eventType,
Collections.singletonList(PluginTransfer.INSTANCE.mapToData(pluginDO))));
return StringUtils.EMPTY;
}
创建和修改Plugin之后,触发了DataChangedEvent
,DataChangedEventDispatcher
根据groupKey进行分发,调用了AbstractDataChangedListener中
实现的onXxxChanged()
方法:
@Component
pub