上篇讲到请求通过遍历每个shard发送请求,执行executePhaseOnShard方法,转发请求的同时定义了一个Listener,用于监听处理结果。
private void performPhaseOnShard(final int shardIndex, final SearchShardIterator shardIt, final ShardRouting shard) {
final Thread thread = Thread.currentThread();
if (shard == null) {
.....
} else {
try {
executePhaseOnShard(shardIt, shard, new SearchActionListener<FirstResult>(
shardIt.newSearchShardTarget(shard.currentNodeId()), shardIndex) {
@Override
public void innerOnResponse(FirstResult result) {
// 执行收到成功的回复
maybeFork(thread, () -> onShardResult(result, shardIt));
}
@Override
public void onFailure(Exception t) {
// // 执行收到失败的回复
maybeFork(thread, () -> onShardFailure(shardIndex, shard, shard.currentNodeId(), shardIt, t));
}
});
} catch (final Exception e) {
.....
}
}
}
然后进入SearchQueryThenFetchAsyncAction#executePhaseOnShard,通过SearchTransportService的sendChildRequest方法向具体的分片发送Query阶段的子任务进行异步处理。
transportService.sendChildRequest(connection, QUERY_ACTION_NAME, request, task,
new ConnectionCountingHandler<>(handler, reader, clientConnections, connection.getNode().getId()));
3.2 收集查询结果
每个分片在执行完毕Query子任务后,通过节点间通信,回调祖父类InitialSearchPhase的onShardSuccess方法,把查询结果记录在协调节点保存的数组结构results中,并增加计数:
private void onShardResult(FirstResult result, SearchShardIterator shardIt) {
// 对收集到的结果进行合并
onShardSuccess(result);
// 检查是否所有请求都已经收到回复了
succ