深度源码分析 istiod 生成 Gateway/VirtualService 到 Envoy XDS 处理流程
基于 Istio 1.12 源码与 Envoy 1.20 源码
实例配置
全文以此实例贯穿:
apiVersion: networking.istio.io/v1alpha3kind: Gatewaymetadata:name: my-gatewaynamespace: defaultspec:selector:istio: ingressgatewayservers:- port:number: 80name: httpprotocol: HTTPhosts:- "bookinfo.example.com"---apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata:name: bookinfo-vsnamespace: defaultspec:hosts:- "bookinfo.example.com"gateways:- my-gatewayhttp:- match:- uri:prefix: /reviewsrewrite:uri: /timeout: 5sretries:attempts: 3perTryTimeout: 2sretryOn: "5xx,connect-failure"route:- destination:host: reviewsport:number: 9080subset: v2weight: 80- destination:host: reviewsport:number: 9080subset: v3weight: 20
全景数据流

第一部分:istiod 侧 — 配置生成
1. Gateway 索引与合并
1.1 索引 — initGateways()
Istio 源码:pilot/pkg/model/push_context.go:1889-1907
func(ps *PushContext) initGateways(env *Environment) error {gatewayConfigs, err := env.List(gvk.Gateway, NamespaceAll)sortConfigByCreationTime(gatewayConfigs)ps.gatewayIndex.all = gatewayConfigsps.gatewayIndex.namespace = make(map[string][]config.Config)for _, gatewayConfig := range gatewayConfigs {ps.gatewayIndex.namespace[gatewayConfig.Namespace] = append(...)}}
1.2 合并 — mergeGateways() → MergeGateways()
Istio 源码:pilot/pkg/model/push_context.go:1924-1998, pilot/pkg/model/gateway.go:134-336
通过 selector 标签匹配 proxy Pod,将匹配到的所有 Gateway 合并为 MergedGateway:
type MergedGateway struct {ServerPorts []ServerPortMergedServers map[ServerPort]*MergedServersGatewayNameForServer map[*networking.Server]string // Server → "default/my-gateway"ServersByRouteName map[string][]*networking.Server // "http.80" → [Server]TLSServerInfo map[*networking.Server]*TLSServerInfo}
Route Name 生成规则(pilot/pkg/model/gateway.go:460-476):
|
|
|
|
|---|---|---|
|
|
http.<port> |
http.80 |
|
|
https.<port>.<portName>.<gwName>.<ns> |
https.443.https.my-gateway.default |
|
|
|
|
本例:HTTP 协议,port 80 →
"http.80"
2. LDS — Listener 生成
Istio 源码:pilot/pkg/networking/core/v1alpha3/gateway.go:59-243
func(configgen *ConfigGeneratorImpl) buildGatewayListeners(builder *ListenerBuilder) {for _, port := range mergedGateway.ServerPorts {// 协议判断 → 构建 FilterChainif p.IsHTTP() {// 单个 FilterChain,所有同端口 HTTP Server 共享opts.filterChainOpts = []*filterChainOpts{configgen.createGatewayHTTPFilterChainOpts(node, port, nil,serversForPort.RouteName, ...) // RouteName = "http.80"}}}}
createGatewayHTTPFilterChainOpts() 创建 HCM 配置:
rds = "http.80"
:Envoy 用这个名字请求 RDS useRemoteAddress = true
:Gateway 特有,使用真实客户端 IP XffNumTrustedHops
:信任的代理跳数
3. RDS — 路由配置生成
Istio 源码:pilot/pkg/networking/core/v1alpha3/gateway.go:328-480
funcbuildGatewayHTTPRouteConfig(node, push, routeName) *route.RouteConfiguration {servers := merged.ServersByRouteName[routeName] // "http.80" → Serversfor _, server := range servers {gatewayName := merged.GatewayNameForServer[server] // "default/my-gateway"virtualServices := push.VirtualServicesForGateway(node, gatewayName) // 找绑定的 VSfor _, vs := range virtualServices {// 计算 Host 交集intersectingHosts := serverHosts.Intersection(virtualServiceHosts)// 构建 Envoy Routeroutes := istio_route.BuildHTTPRoutesForVirtualService(...)// 创建 VirtualHostnewVHost := &route.VirtualHost{Name: "bookinfo.example.com:80",Domains: ["bookinfo.example.com", "bookinfo.example.com:80"],Routes: routes,}}}}
3.1 路由转换 — translateRoute()
Istio 源码:pilot/pkg/networking/core/v1alpha3/route/route.go:386-620
每条 VirtualService HTTPRoute 逐字段翻译为 Envoy Route:
匹配条件:translateRouteMatch()
// uri.prefix: /reviews → RouteMatch.Prefix = "/reviews"case *networking.StringMatch_Prefix:out.PathSpecifier = &route.RouteMatch_Prefix{Prefix: m.Prefix}
重写:
if in.Rewrite != nil {action.PrefixRewrite = in.Rewrite.GetUri() // "/"
超时:
if in.Timeout != nil {d = gogo.DurationToProtoDuration(in.Timeout) // 5s}action.Timeout = d
重试(pilot/pkg/networking/core/v1alpha3/route/retry/retry.go:65-104):
func ConvertPolicy(in *networking.HTTPRetry) *route.RetryPolicy {out := DefaultPolicy() // 基础:2次, connect-failure,refused-stream,unavailable,cancelledout.NumRetries = uint32(in.Attempts) // 3out.RetryOn = parseRetryOn(in.RetryOn) // "5xx,connect-failure"out.PerTryTimeout = in.PerTryTimeout // 2s// RetryHostPredicate: previous_hosts(避免重试同一台机器)}
加权路由:
for _, dst := range in.Route {n := GetDestinationCluster(dst.Destination, ...)// → "outbound|9080|v2|reviews.default.svc.cluster.local"weighted = append(weighted, &route.WeightedCluster_ClusterWeight{Name: n, Weight: dst.Weight})}action.ClusterSpecifier = &route.RouteAction_WeightedClusters{WeightedClusters: ...}
4. CDS — Cluster 生成
Istio 源码:pilot/pkg/networking/core/v1alpha3/cluster.go:80-294
Gateway proxy 只为 VirtualService 引用的服务生成 Cluster:
```goif features.FilterGatewayClusterConfig && proxy.Type == model.Router {services = req.Push.GatewayServices(proxy) // 只取 VS 引用的}
本例生成:
outbound|9080||reviews.default.svc.cluster.local
(默认) outbound|9080|v2|reviews.default.svc.cluster.local
(subset v2) outbound|9080|v3|reviews.default.svc.cluster.local
(subset v3)
5. xDS 推送
Istio 源码:pilot/pkg/xds/ads.go:715-779
var PushOrder = []string{ClusterType, EndpointType, ListenerType, RouteType, SecretType}funcpushConnection(con, pushEv) error {for _, w := range orderWatchedResources(con.proxy.WatchedResources) {s.pushXds(con, pushRequest.Push, w, pushRequest)}}
严格按 CDS → EDS → LDS → RDS → SDS 顺序推送。
第二部分:Envoy 侧 — 配置接收
6. ADS 订阅机制
Envoy 源码:source/common/config/grpc_mux_impl.cc, source/common/config/grpc_subscription_impl.cc
6.1 ADS 流建立
Envoy 启动时,ClusterManager 创建一个共享的 GrpcMuxImpl(SotW ADS):
var PushOrder = []string{ClusterType, EndpointType, ListenerType, RouteType, SecretType}funcpushConnection(con, pushEv) error {for _, w := range orderWatchedResources(con.proxy.WatchedResources) {s.pushXds(con, pushRequest.Push, w, pushRequest)}}
所有资源类型(CDS/EDS/LDS/RDS)共享这一个 gRPC 双工流。
6.2 订阅注册与请求发送
各子系统(CDS、LDS 等)通过 grpc_mux_->addWatch(type_url, resources, ...) 注册订阅:
// source/common/config/grpc_mux_impl.cc:104-130GrpcMuxWatchPtr GrpcMuxImpl::addWatch(conststd::string& type_url, ...) {if (!apiStateFor(type_url).subscribed_) {apiStateFor(type_url).subscribed_ = true;subscriptions_.emplace_back(type_url); // 按首次订阅顺序入队}queueDiscoveryRequest(type_url);}
流建立时按 subscriptions_ 顺序发送首次 DiscoveryRequest:
// source/common/config/grpc_mux_impl.cc:291-296void GrpcMuxImpl::onStreamEstablished() {for (const auto& type_url : subscriptions_) {queueDiscoveryRequest(type_url); // CDS → EDS → LDS → RDS 顺序}}
6.3 响应处理与 ACK/NACK
// source/common/config/grpc_mux_impl.cc:158-284void GrpcMuxImpl::onDiscoveryResponse(unique_ptr<DiscoveryResponse>&& message, ...) {// 解码资源for(const auto& resource : message->resources()) {decoded_resource = DecodedResourceImpl::fromResource(...);resources.emplace_back(std::move(decoded_resource));}// 分发给订阅回调for(auto watch : api_state.watches_) {watch->callbacks_.onConfigUpdate(found_resources, message->version_info());}// ACK:更新 version_infoapi_state.request_.set_version_info(message->version_info());api_state.request_.set_response_nonce(message->nonce());queueDiscoveryRequest(type_url); // 发送 ACK}// NACK:catch 到异常时不更新 version_info,设置 error_detailcatch(const EnvoyException& e) {error_detail->set_code(Grpc::Status::WellKnownGrpcStatus::Internal);error_detail->set_message(e.what());}
6.4 CDS 暂停机制:保证 Cluster warm 后再发 ACK
// source/common/upstream/cluster_manager_impl.cc:839-863// 有集群在 warming 时,暂停 CDS ACKif(previous_warming == 0 && !warming_clusters_.empty()) {resume_cds_ = ads_mux_->pause(type_url); // 暂停 CDS}// 所有集群 warm 后,恢复 CDS,ACK 发往 ADS// ADS 据此知道集群已就绪,可以推 RDSelse if (previous_warming > 0 && warming_clusters_.empty()) {resume_cds_.reset(); // 恢复}
这就是 istiod 按 CDS→EDS→LDS→RDS 推送 + Envoy CDS 暂停机制 共同保证配置一致性的原因。
7. CDS 接收 — Cluster 创建
Envoy 源码:source/common/upstream/cds_api_impl.cc, source/common/upstream/cluster_manager_impl.cc
// source/common/upstream/cds_api_impl.cc:41-101voidCdsApiImpl::onConfigUpdate(added_resources, removed_resources, version_info){// 更新时暂停 EDS/LEDSmaybe_resume_eds = cm_.adsMux()->pause(eds_type_url);for (const auto& resource : added_resources) {cm_.addOrUpdateCluster(cluster, version); // 添加/更新集群}for (const auto& removed : removed_resources) {cm_.removeCluster(removed);}}
Cluster 创建流程:
ClusterManagerImpl::loadCluster()
→ factory_.clusterFromProto()根据 type 创建具体 Cluster-
新集群进入 warming_clusters_ -
EDS 订阅获取 endpoints、健康检查通过后 → clusterWarmingToActive() -
通过 TLS ( postThreadLocalClusterUpdate()) 向各 worker 线程下发
8. EDS 接收 — Endpoint 更新
Envoy 源码:source/common/upstream/eds.cc
// source/common/upstream/eds.cc:46-127void EdsClusterImpl::BatchUpdateHelper::batchUpdate(host_update_cb) {PriorityStateManager priority_state_manager(...);for (const auto& locality_lb_endpoint : cluster_load_assignment_.endpoints()) {priority_state_manager.initializePriorityFor(locality_lb_endpoint);for (const auto& lb_endpoint : locality_lb_endpoint.lb_endpoints()) {updateLocalityEndpoints(lb_endpoint, locality_lb_endpoint,priority_state_manager, all_new_hosts);}}// 更新 PrioritySet,触发 LB 重建}
Endpoint 按 locality (region/zone/sub_zone) + priority 组织,支持 locality-aware load balancing。
9. LDS 接收 — Listener 管理
Envoy 源码:source/server/lds_api.cc, source/server/listener_manager_impl.cc
// source/server/lds_api.cc:41-101voidLdsApiImpl::onConfigUpdate(added_resources, removed_resources, version_info){// 更新 Listener 时暂停 RDSmaybe_resume_rds = cm_.adsMux()->pause(route_type_url);// 先删除for (const auto& removed : removed_resources) {listener_manager_.removeListener(removed);}// 再添加/更新for (const auto& resource : added_resources) {listener_manager_.addOrUpdateListener(listener, version, true);}}
Listener 状态机:
addOrUpdateListener() │ ┌──────────┴──────────┐ ↓ ↓ warming_listeners_ inPlaceFilterChainUpdate() (等待 RDS 就绪) (仅 FilterChain 变更) │ onListenerWarmed() │ ↓ active_listeners_ ←── 开始接收流量 │ 旧 listener → draining_listeners_ → 关闭
FilterChain 匹配(source/server/filter_chain_manager_impl.cc:465-539):
findFilterChain(socket) → Destination Port → Destination IP → Server Name (SNI) → Transport Protocol → Application Protocols (ALPN) → Direct Source IP → Source Type → Source IP/Port → default_filter_chain_(兜底)
10. RDS 接收 — 路由配置更新
Envoy 源码:source/common/router/rds_impl.cc
// source/common/router/rds_impl.cc:112-162void RdsRouteConfigSubscription::onConfigUpdate(resources, version_info) {config_update_info_->onRdsUpdate(route_config, version_info);route_config_provider_->onConfigUpdate();}// source/common/router/rds_impl.cc:262-294void RdsRouteConfigProviderImpl::onConfigUpdate() {// 通过 ThreadLocal 原子替换路由配置到所有 worker 线程tls_.runOnAllThreads([new_config = config_update_info_->parsedConfiguration()](OptRef<ThreadLocalConfig> tls) {tls->config_ = new_config;});}
无损更新关键:
-
使用 ThreadLocal::TypedSlot在每个 worker 线程存储路由配置 runOnAllThreads
原子替换,新请求用新配置,已有连接不受影响 -
Listener warming 机制保证 RDS 就绪后 Listener 才激活
第三部分:Envoy 侧 — 请求处理
11. 请求到达与连接建立
Envoy 源码:source/server/active_tcp_listener.cc, source/common/http/conn_manager_impl.cc
客户端请求 → Listener (0.0.0.0:8080)→ TcpListenerImpl::onAccept()→ ActiveTcpListener::onAcceptWorker()→ connectionBalancer().pickTargetHandler() // 分配到某个 worker→ ActiveTcpSocket::continueFilterChain()→ 执行 listener filter (如 TLS Inspector)→ newConnection()→ FilterChainManager::findFilterChain(socket) // 匹配 FilterChain→ 创建网络连接,安装 network filter(HCM 等)
12. HCM 处理与路由匹配
Envoy 源码:source/common/http/conn_manager_impl.cc, source/common/router/config_impl.cc
HCM::onData(data)→ codec_->dispatch(data) // HTTP/1.x 或 H2 解码→ newStream() → ActiveStream→ decodeHeaders(headers)→ snapped_route_config_ = routeConfigProvider()->config() // 快照当前路由配置→ refreshCachedRoute()→ snapped_route_config_->route(headers, stream_info)→ RouteMatcher::route()→ findVirtualHost(headers) // Host 头匹配→ VirtualHostImpl::getRouteFromEntries() // 按顺序匹配 Route
VirtualHost 匹配逻辑
Envoy 源码:source/common/router/config_impl.cc:1512-1550
findVirtualHost(headers):1. headers.getHostValue() → "bookinfo.example.com"2. virtual_hosts_.find("bookinfo.example.com") // 精确匹配 ✓3. wildcard_virtual_host_suffixes_ // 后缀通配 (*.example.com)4. wildcard_virtual_host_prefixes_ // 前缀通配5. default_virtual_host_ // 兜底
Route 匹配逻辑
Envoy 源码:source/common/router/config_impl.cc:1457-1509
getRouteFromEntries(headers):遍历 routes_,对每个 route 调用 matches():→ PrefixRouteEntryImpl::matches()→ path.startsWith("/reviews") ✓→ 检查 headers matcher→ 检查 query params→ 返回匹配的 RouteEntry
13. prefix_rewrite 执行
Envoy 源码:source/common/router/config_impl.cc:577-628, 735-759
在 Router filter 转发前执行 finalizeRequestHeaders():
// config_impl.cc:735-746absl::optional<std::string> currentUrlPathAfterRewriteWithMatchedPath(headers, matched_path){const auto& rewrite = getPathRewrite(headers); // "/"std::string path(headers.getPathValue()); // "/reviews/detail?id=1"return path.replace(0, matched_path.size(), rewrite);// matched_path = "/reviews", rewrite = "/"// 结果: "/detail?id=1"}
/reviews/detail?id=1→/detail?id=1(前缀/reviews被替换为/)
14. 加权集群选择
Envoy 源码:source/common/router/config_impl.cc:1019-1048
// pickWeightedCluster():selected_value = random_value % total_cluster_weight_; // total = 100// 遍历 weighted_clusters_:// v2: [0, 80) → 80% 概率// v3: [80, 100) → 20% 概率for (const auto& cluster : weighted_clusters_) {selected_value -= cluster.clusterWeight();if (selected_value <= 0) {return cluster; // 选中}}
15. 负载均衡与 Endpoint 选择
Envoy 源码:source/common/upstream/load_balancer_impl.cc
Router::Filter::decodeHeaders()→ createConnPool()→ cm_.getThreadLocalCluster("outbound|9080|v2|reviews.default.svc.cluster.local")→ lb_->chooseHost(context)→ chooseHostSet() // 按 priority 选 HostSet→ chooseHostOnce() // 在 HostSet 中做 LB(RR/Random/LeastRequest 等)→ 返回 Host: 10.244.1.5:9080
Locality-aware 调度:
tryChooseLocalLocalityHosts()
优先选择本地 locality -
按 locality weight 通过 EDF 调度器选 locality -
在选中的 locality 内按 LB 算法选具体 Host
16. 上游请求转发
Envoy 源码:source/common/router/router.cc, source/common/router/upstream_request.cc
Router::Filter::decodeHeaders()→ 创建 UpstreamRequest→ upstream_request->encodeHeaders(end_stream)→ conn_pool_->newStream(this) // 从连接池获取/创建连接→ onPoolReady(encoder, host) // 连接就绪→ encoder->encodeHeaders(...) // 发送请求头到上游→ encoder->encodeData(...) // 发送请求体
17. 重试机制
Envoy 源码:source/common/router/retry_state_impl.cc, source/common/router/router.cc
重试策略创建
// router.cc:661retry_state_ = createRetryState(route_entry_->retryPolicy(), headers, *cluster_, ...);// RetryPolicy 来自 RDS 配置:// num_retries=3, retry_on="5xx,connect-failure", per_try_timeout=2s
重试触发
上游返回 503:Filter::onUpstreamHeaders()→ retry_state_->shouldRetryHeaders(response_headers, ...)→ wouldRetryFromHeaders() // 检查 5xx → true→ 检查 budget/circuit breaker→ 返回 RetryStatus::Yes连接失败:Filter::onUpstreamReset()→ retry_state_->shouldRetryReset(reset_reason, ...)→ wouldRetryFromReset() // 检查 connect-failure → truePer-try 超时 (2s):UpstreamRequest::onPerTryTimeout()→ parent_.onPerTryTimeout()→ retry_state_->shouldRetryReset(timeout, ...)
重试执行
// router.cc:1666-1730voidFilter::doRetry(bool can_send_early_data, bool can_use_http3, TimeoutRetry is_timeout_retry){// 创建新的 UpstreamRequestauto upstream_request = std::make_unique<UpstreamRequest>(*this, ...);upstream_request->is_retry_ = true;// RetryHostPredicate: previous_hosts → 避免选择已失败的 hostupstream_request->encodeHeaders(end_stream);}
重试时序
请求到达 → 选 host A → 发送 → 503 (耗时 200ms)→ 重试 1: 选 host B (避开 A) → 发送 → connect-failure (耗时 100ms)→ 重试 2: 选 host C (避开 A,B) → 发送 → 200 OK总耗时 < 5s (全局 timeout)每次重试 < 2s (per_try_timeout)
18. 超时机制
Envoy 源码:source/common/router/router.cc:125-230, 871-947
超时配置解析
// FilterUtility::finalTimeout():global_timeout = route.timeout() // 5s (来自 VS 的 timeout)per_try_timeout = route.retryPolicy().perTryTimeout() // 2s
超时执行
全局超时 (5s):Filter::onRequestComplete()→ response_timeout_ = dispatcher.createTimer(onResponseTimeout)→ response_timeout_->enableTimer(5s)超时触发:Filter::onResponseTimeout()→ 重置所有 upstream 请求→ 返回 504 Gateway TimeoutPer-try 超时 (2s):UpstreamRequest::setupPerTryTimeout()→ per_try_timeout_->enableTimer(2s)超时触发:UpstreamRequest::onPerTryTimeout()→ 触发 retry(如果还有重试次数)→ 或返回 504
第四部分:完整时序图
时间轴 →istiod Envoy (ingressgateway) Client │ │ │ │ ── CDS Response ──────────→ │ │ │ (Cluster: outbound|9080|v2|reviews...) │ │ │ (Cluster: outbound|9080|v3|reviews...) │ │ │ │── CDS ACK (暂停直到 warm) ──→ │ │ │ │ │ ── EDS Response ──────────→ │ │ │ (endpoints: 10.244.1.5:9080, ...) │ │ │ │── EDS ACK ──────────────────→ │ │ │ clusters warm 完成 │ │ │── CDS ACK (恢复) ───────────→ │ │ │ │ │ ── LDS Response ──────────→ │ │ │ (Listener 0.0.0.0:8080, HCM rds:"http.80") │ │ │ │── listener warming (等 RDS) │ │ │ │ │ ── RDS Response ──────────→ │ │ │ (RouteConfig "http.80", VHost, Routes) │ │ │ │── RDS ACK ──────────────────→ │ │ │── listener warm 完成 → active │ │ │ │ │ │ ← ── GET /reviews/detail ─────── │ │ │ Listener accept │ │ │ FilterChain match │ │ │ HCM decode headers │ │ │ Route match: prefix=/reviews │ │ │ Rewrite: /reviews/detail → /detail │ │ │ Weighted cluster: v2(80%) ✓ │ │ │ LB: choose 10.244.1.5:9080 │ │ │ ── GET /detail ──→ upstream Pod │ │ │ ← ── 200 OK ──── upstream Pod │ │ │ ── 200 OK ───────────────────→ │ │ │ │
附录:核心源码文件索引
istiod 侧
|
|
|
|
|---|---|---|
|
|
pilot/pkg/model/push_context.go |
initGateways() |
|
|
pilot/pkg/model/gateway.go |
MergeGateways()
gatewayRDSRouteName() |
|
|
pilot/pkg/networking/core/v1alpha3/gateway.go |
buildGatewayListeners() |
|
|
|
createGatewayHTTPFilterChainOpts()
buildGatewayConnectionManager() |
|
|
|
buildGatewayHTTPRouteConfig() |
|
|
pilot/pkg/networking/core/v1alpha3/route/route.go |
BuildHTTPRoutesForVirtualService()
translateRoute() |
|
|
|
translateRouteMatch() |
|
|
pilot/pkg/networking/core/v1alpha3/route/retry/retry.go |
ConvertPolicy()
DefaultPolicy() |
|
|
pilot/pkg/networking/core/v1alpha3/cluster.go |
BuildClusters()
buildOutboundClusters() |
|
|
pilot/pkg/xds/ads.go |
pushConnection()
PushOrder |
Envoy 侧
|
|
|
|
|---|---|---|
|
|
source/common/config/grpc_mux_impl.cc |
GrpcMuxImpl
onDiscoveryResponse() |
|
|
source/common/config/grpc_subscription_impl.cc |
GrpcSubscriptionImpl::start() |
|
|
source/common/upstream/cds_api_impl.cc |
CdsApiImpl::onConfigUpdate() |
|
|
source/common/upstream/cluster_manager_impl.cc |
ClusterManagerImpl::loadCluster()
clusterWarmingToActive() |
|
|
source/common/upstream/eds.cc |
EdsClusterImpl::BatchUpdateHelper::batchUpdate() |
|
|
source/server/lds_api.cc |
LdsApiImpl::onConfigUpdate() |
|
|
source/server/listener_manager_impl.cc |
addOrUpdateListener()
onListenerWarmed() |
|
|
source/server/filter_chain_manager_impl.cc |
findFilterChain() |
|
|
source/common/router/rds_impl.cc |
RdsRouteConfigSubscription::onConfigUpdate() |
|
|
source/common/router/config_impl.cc |
findVirtualHost()
getRouteFromEntries() |
|
|
source/common/http/conn_manager_impl.cc |
onData()
decodeHeaders(), refreshCachedRoute() |
|
|
source/common/router/router.cc |
Filter::decodeHeaders()
doRetry() |
|
|
source/common/router/config_impl.cc |
finalizeRequestHeaders()
currentUrlPathAfterRewriteWithMatchedPath() |
|
|
source/common/router/retry_state_impl.cc |
shouldRetryHeaders()
shouldRetryReset() |
|
|
source/common/router/router.cc |
FilterUtility::finalTimeout()
onResponseTimeout() |
|
|
source/common/upstream/load_balancer_impl.cc |
chooseHostSet()
chooseHostOnce() |
|
|
source/common/router/config_impl.cc |
pickWeightedCluster() |
夜雨聆风
