istio.io/archive/v1.6/zh/blog/2019/appswitch/index.html

28 lines
43 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html><html lang=zh itemscope itemtype=https://schema.org/WebPage><head><meta charset=utf-8><meta http-equiv=x-ua-compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name=theme-color content="#466BB0"><meta name=title content="使用 AppSwitch 进行 Sidestepping 依赖性排序"><meta name=description content="使用 AppSwitch 解决应用程序启动顺序和启动延迟。"><meta name=author content="Dinesh Subhraveti (AppOrbit and Columbia University)"><meta name=keywords content="microservices,services,mesh,appswitch,performance"><meta property="og:title" content="使用 AppSwitch 进行 Sidestepping 依赖性排序"><meta property="og:type" content="website"><meta property="og:description" content="使用 AppSwitch 解决应用程序启动顺序和启动延迟。"><meta property="og:url" content="/v1.6/zh/blog/2019/appswitch/"><meta property="og:image" content="/v1.6/img/istio-whitelogo-bluebackground-framed.svg"><meta property="og:image:alt" content="Istio Logo"><meta property="og:image:width" content="112"><meta property="og:image:height" content="150"><meta property="og:site_name" content="Istio"><meta name=twitter:card content="summary"><meta name=twitter:site content="@IstioMesh"><title>Istioldie 1.6 / 使用 AppSwitch 进行 Sidestepping 依赖性排序</title><script async src="https://www.googletagmanager.com/gtag/js?id=UA-98480406-2"></script><script>window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments);}
gtag('js',new Date());gtag('config','UA-98480406-2');</script><link rel=alternate type=application/rss+xml title="Istio Blog" href=/v1.6/blog/feed.xml><link rel=alternate type=application/rss+xml title="Istio News" href=/v1.6/news/feed.xml><link rel=alternate type=application/rss+xml title="Istio Blog and News" href=/v1.6/feed.xml><link rel="shortcut icon" href=/v1.6/favicons/favicon.ico><link rel=apple-touch-icon href=/v1.6/favicons/apple-touch-icon-180x180.png sizes=180x180><link rel=icon type=image/png href=/v1.6/favicons/favicon-16x16.png sizes=16x16><link rel=icon type=image/png href=/v1.6/favicons/favicon-32x32.png sizes=32x32><link rel=icon type=image/png href=/v1.6/favicons/android-36x36.png sizes=36x36><link rel=icon type=image/png href=/v1.6/favicons/android-48x48.png sizes=48x48><link rel=icon type=image/png href=/v1.6/favicons/android-72x72.png sizes=72x72><link rel=icon type=image/png href=/v1.6/favicons/android-96x96.png sizes=96xW96><link rel=icon type=image/png href=/v1.6/favicons/android-144x144.png sizes=144x144><link rel=icon type=image/png href=/v1.6/favicons/android-192x192.png sizes=192x192><link rel=manifest href=/v1.6/manifest.json><meta name=apple-mobile-web-app-title content="Istio"><meta name=application-name content="Istio"><link rel=stylesheet href="https://fonts.googleapis.com/css?family=Work+Sans:400|Chivo:400|Work+Sans:500,300,600,300italic,400italic,500italic,600italic|Chivo:500,300,600,300italic,400italic,500italic,600italic"><link rel=stylesheet href=/v1.6/css/all.css><script src=/v1.6/js/themes_init.min.js></script></head><body class="language-unknown archive-site"><script>const branchName="release-1.6";const docTitle="使用 AppSwitch 进行 Sidestepping 依赖性排序";const iconFile="\/v1.6/img/icons.svg";const buttonCopy='复制到剪切板';const buttonPrint='打印';const buttonDownload='下载';</script><script src="https://www.google.com/cse/brand?form=search-form" defer></script><script src=/v1.6/js/all.min.js data-manual defer></script><header><nav><a id=brand href=/v1.6/zh/><span class=logo><svg viewBox="0 0 300 300"><circle cx="150" cy="150" r="146" stroke-width="2"/><polygon points="65 240 225 240 125 270"/><polygon points="65 230 125 220 125 110"/><polygon points="135 220 225 230 135 30"/></svg></span><span class=name>Istioldie 1.6</span></a><div id=hamburger><svg class="icon"><use xlink:href="/v1.6/img/icons.svg#hamburger"/></svg></div><div id=header-links><a title="了解如何部署、使用和运维 Istio。" href=/v1.6/zh/docs/>文档</a>
<a class=current title="关于使用 Istio 的博客文章。" href=/v1.6/zh/blog/2020/>博客<i class=dot data-prefix=/blog></i></a>
<a title="关于 Istio 项目的最新报道。" href=/v1.6/zh/news/>新闻<i class=dot data-prefix=/news></i></a>
<a title="关于 Istio 的常见问题。" href=/v1.6/zh/faq/>FAQ</a>
<a title="关于 Istio 项目的说明。" href=/v1.6/zh/about/>关于</a><div class=menu><button id=gearDropdownButton class=menu-trigger title=选项和设置 aria-label="Options and Settings" aria-controls=gearDropdownContent><svg class="icon"><use xlink:href="/v1.6/img/icons.svg#gear"/></svg></button><div id=gearDropdownContent class=menu-content aria-labelledby=gearDropdownButton role=menu><a tabindex=-1 role=menuitem lang=en id=switch-lang-en>English</a>
<a tabindex=-1 role=menuitem lang=zh id=switch-lang-zh class=active>中文</a><div role=separator></div><a tabindex=-1 role=menuitem class=active id=light-theme-item>亮主题</a>
<a tabindex=-1 role=menuitem id=dark-theme-item>暗主题</a><div role=separator></div><a tabindex=-1 role=menuitem id=syntax-coloring-item>代码高亮</a><div role=separator></div><h6>本站的其它版本</h6><a tabindex=-1 role=menuitem onclick="navigateToUrlOrRoot('https://istio.io/blog\/2019\/appswitch\/');return false;">当前版本</a>
<a tabindex=-1 role=menuitem onclick="navigateToUrlOrRoot('https://preliminary.istio.io/blog\/2019\/appswitch\/');return false;">下个版本</a>
<a tabindex=-1 role=menuitem href=https://istio.io/archive>旧版本</a></div></div><button id=search-show title="搜索 istio.io" aria-label=搜索><svg class="icon"><use xlink:href="/v1.6/img/icons.svg#magnifier"/></svg></button></div><form id=search-form name=cse role=search><input type=hidden name=cx value=002184991200833970123:iwwf17ikgf4>
<input type=hidden name=ie value=utf-8>
<input type=hidden name=hl value=en>
<input type=hidden id=search-page-url value=/v1.6/search>
<input id=search-textbox class=form-control name=q type=search aria-label="搜索 istio.io">
<button id=search-close title=取消搜索 type=reset aria-label=取消搜索><svg class="icon"><use xlink:href="/v1.6/img/icons.svg#cancel-x"/></svg></button></form></nav></header><div class=banner-container></div><main class=primary><div id=sidebar-container class="sidebar-container sidebar-offcanvas"><nav id=sidebar aria-label="Section Navigation"><div class=directory><div class=card><button class="header dynamic" id=card0 title="2020 年的博客文章。" aria-controls=card0-body><svg class="icon"><use xlink:href="/v1.6/img/icons.svg#blog"/></svg>2020 年的博客文章</button><div class=body aria-labelledby=card0 role=region id=card0-body><ul role=tree aria-expanded=true class=leaf-section aria-labelledby=card0><li role=none><a role=treeitem title="Istiod 将 Istio 控制平面组件合并为一个二进制文件。 (2020年3月19日)" href=/v1.6/zh/blog/2020/istiod/>介绍 istiod简化控制平面</a></li><li role=none><a role=treeitem title="以声明方式为 Envoy 和 Istio 配置 Wasm 扩展。 (2020年3月16日)" href=/v1.6/zh/blog/2020/deploy-wasm-declarative/>在 Istio 中进行 WebAssembly 声明式部署</a></li><li role=none><a role=treeitem title="Istio 的扩展中使用 WASM 的前景。 (2020年3月5日)" href=/v1.6/zh/blog/2020/wasm-announce/>重新定义代理的扩展性Envoy 和 Istio 引入 WebAssembly</a></li><li role=none><a role=treeitem title="Istio 在 2020 年的愿景声明及路线图。 (2020年3月3日)" href=/v1.6/zh/blog/2020/tradewinds-2020/>Istio 2020——为了商用</a></li><li role=none><a role=treeitem title="一种更安全的秘密管理方式。 (2020年2月20日)" href=/v1.6/zh/blog/2020/istio-agent/>移除跨 pod Unix domain socket</a></li><li role=none><a role=treeitem title="为 Istio deploymentcluster提供自动化 Istio 配置,并让其像单个网格一样工作。 (2020年1月5日)" href=/v1.6/zh/blog/2020/multi-cluster-mesh-automation/>使用 Admiral 管理 Istio 多集群的配置和服务发现</a></li></ul></div></div><div class=card><button class="header dynamic" id=card1 title="2019 年的博客文章。" aria-controls=card1-body><svg class="icon"><use xlink:href="/v1.6/img/icons.svg#blog"/></svg>2019 年的博客文章</button><div class="body default" aria-labelledby=card1 role=region id=card1-body><ul role=tree aria-expanded=true class=leaf-section aria-labelledby=card1><li role=none><a role=treeitem title="一种更安全管理 Istio webhook 的方法。 (2019年11月14日)" href=/v1.6/zh/blog/2019/webhook/>安全管理 Webhook</a></li><li role=none><a role=treeitem title="正式启用访问 Istio 资源。 (2019年11月14日)" href=/v1.6/zh/blog/2019/announcing-istio-client-go/>Istio client-go 发布公告</a></li><li role=none><a role=treeitem title="关于 Istio 基于 operator 的安装和控制平面管理特性的介绍。 (2019年11月14日)" href=/v1.6/zh/blog/2019/introducing-istio-operator/>Istio Operator 简介</a></li><li role=none><a role=treeitem title="通过分析 Istio 配置来发现潜在问题和一般问题。 (2019年11月14日)" href=/v1.6/zh/blog/2019/introducing-istioctl-analyze/>istioctl analyze 介绍</a></li><li role=none><a role=treeitem title="在 Istio 中配置和管理 DNS 证书。 (2019年11月14日)" href=/v1.6/zh/blog/2019/dns-cert/>DNS 证书管理</a></li><li role=none><a role=treeitem title="Istio v1beta1 授权策略的设计原则、基本概述及迁移操作。 (2019年11月14日)" href=/v1.6/zh/blog/2019/v1beta1-authorization-policy/>Istio v1beta1 授权策略概述</a></li><li role=none><a role=treeitem title="把 Istio 入口网关配置为外部服务的代理。 (2019年10月15日)" href=/v1.6/zh/blog/2019/proxy/>把 Istio 作为外部服务的代理</a></li><li role=none><a role=treeitem title="将需要隔离的环境部署到单独的网格中,并通过网格联邦启用网格间通信。 (2019年10月2日)" href=/v1.6/zh/blog/2019/isolated-clusters/>用于隔离和边界保护的多网格部署</a></li><li role=none><a role=treeitem title="如何使用 Istio 去监控被阻止的和透传的外部服务流量。 (2019年9月28日)" href=/v1.6/zh/blog/2019/monitoring-external-service-traffic/>监控被阻止的和透传的外部服务流量</a></li><li role=none><a role=treeitem title="本文演示 Mixer 进程外适配器实现 Knative scale-from-zero 逻辑的具体过程。 (2019年9月18日)" href=/v1.6/zh/blog/2019/knative-activator-adapter/>适用于 Knative 的 Mixer 适配器</a></li><li role=none><a role=treeitem title="使用 Istio 实现零代码改动保护多云 Kubernetes 应用。 (2019年9月18日)" href=/v1.6/zh/blog/2019/app-identity-and-access-adapter/>APP 身份和访问适配器</a></li><li role=none><a role=treeitem title="利用 Kubernetes 可信任的 JWT 来更安全地为工作负载实例颁发证书。 (2019年9月10日)" href=/v1.6/zh/blog/2019/trustworthy-jwt-sds/>Istio 1.3 Secret 服务发现的更改</a></li><li role=none><a role=treeitem title="Istio API 的设计原则和这些 API 是如何演变的。 (2019年8月5日)" href=/v1.6/zh/blog/2019/evolving-istios-apis/>Istio API 的演变</a></li><li role=none><a role=treeitem title="管控出口流量的备选方案比较,包括性能因素。 (2019年7月22日)" href=/v1.6/zh/blog/2019/egress-traffic-control-in-istio-part-3/>Istio 中安全管控出口流量,第三部分</a></li><li role=none><a role=treeitem title="使用 Istio 的出口流量管控来阻止相关出口流量攻击。 (2019年7月10日)" href=/v1.6/zh/blog/2019/egress-traffic-control-in-istio-part-2/>Istio 中的安全管控出口流量,第二部分</a></li><li role=none><a role=treeitem title="评估 Istio 数据平面性能的工具和指南。 (2019年7月9日)" href=/v1.6/zh/blog/2019/performance-best-practices/>最佳实践Service Mesh 基准性能测试</a></li><li role=none><a role=treeitem title="了解如何延长 Istio 自签名根证书的有效期。 (2019年6月7日)" href=/v1.6/zh/blog/2019/root-transition/>延长 Istio 自签名根证书的有效期</a></li><li role=none><a role=treeitem title="涉及出口流量攻击和出口流量管控要求。 (2019年5月22日)" href=/v1.6/zh/blog/2019/egress-traffic-control-in-istio-part-1/>Istio 中的安全管控出口流量,第一部分</a></li><li role=none><a role=treeitem title="Istio 1.1 性能概览。 (2019年3月19日)" href=/v1.6/zh/blog/2019/istio1.1_perf/>为性能而设计的 Istio 1.1</a></li><li role=none><a role=treeitem title="在多集群服务网格环境中配置 Istio 的路由规则。 (2019年2月7日)" href=/v1.6/zh/blog/2019/multicluster-version-routing/>多集群服务网格中的分版本路由</a></li><li role=none><a role=treeitem title="宣布新的博客策略。 (2019年2月5日)" href=/v1.6/zh/blog/2019/sail-the-blog/>博客策略更新!</a></li><li role=none><a role=treeitem title="评估加入 Egress gateway 对性能造成的影响。 (2019年1月31日)" href=/v1.6/zh/blog/2019/egress-performance/>Egress gateway 性能测试</a></li><li role=none><a role=treeitem title="揭秘 Istio 是如何将其数据平面组件添加到现有 deployment。 (2019年1月31日)" href=/v1.6/zh/blog/2019/data-plane-setup/>揭开 Istio Sidecar 注入模型的神秘面纱</a></li><li role=none><span role=treeitem class=current title="使用 AppSwitch 解决应用程序启动顺序和启动延迟。 (2019年1月14日)">使用 AppSwitch 进行 Sidestepping 依赖性排序</span></li><li role=none><a role=treeitem title="如何使用 cert-manager 手工部署一个自定义 Ingress 网关。 (2019年1月10日)" href=/v1.6/zh/blog/2019/custom-ingress-gateway/>使用 Cert-Manager 部署一个自定义 Ingress 网关</a></li><li role=none><a role=treeitem title="Istio 有了一个新的论坛。 (2019年1月10日)" href=/v1.6/zh/blog/2019/announcing-discuss.istio.io/>Istio 论坛成立</a></li></ul></div></div><div class=card><button class="header dynamic" id=card2 title="2018 年的博客文章。" aria-controls=card2-body><svg class="icon"><use xlink:href="/v1.6/img/icons.svg#blog"/></svg>2018 年的博客文章</button><div class=body aria-labelledby=card2 role=region id=card2-body><ul role=tree aria-expanded=true class=leaf-section aria-labelledby=card2><li role=none><a role=treeitem title="如何在不部署 Sidecar 代理的情况下使用 Istio 进行流量管理。 (2018年11月21日)" href=/v1.6/zh/blog/2018/incremental-traffic-management/>增量式应用 Istio 第一部分,流量管理</a></li><li role=none><a role=treeitem title="描述了一个基于 Istio 的 Bookinfo 示例的简单场景。 (2018年11月16日)" href=/v1.6/zh/blog/2018/egress-mongo/>使用外部 MongoDB 服务</a></li><li role=none><a role=treeitem title="Istio 在 Twitch 举办了为期一天的直播庆祝 1.0 的发布。 (2018年8月3日)" href=/v1.6/zh/blog/2018/istio-twitch-stream/>Istio 在 Twitch 上全天直播</a></li><li role=none><a role=treeitem title="惠普如何在 Istio 上构建其下一代鞋类个性化平台。 (2018年7月31日)" href=/v1.6/zh/blog/2018/hp/>Istio 是惠普 FitStation 平台的改变者</a></li><li role=none><a role=treeitem title="使用 AppSwitch 自动接入应用并降低延迟。 (2018年7月30日)" href=/v1.6/zh/blog/2018/delayering-istio/>使用 AppSwitch 精简 Istio 层次</a></li><li role=none><a role=treeitem title="描述 Istio 的授权功能以及如何在各种用例中使用它。 (2018年7月20日)" href=/v1.6/zh/blog/2018/istio-authorization/>基于 Istio 授权的 Micro-Segmentation</a></li><li role=none><a role=treeitem title="如何通过 Stackdriver 将 Istio 访问日志导出到 BigQuery、GCS、Pub/Sub 等不同的接收器。 (2018年7月9日)" href=/v1.6/zh/blog/2018/export-logs-through-stackdriver/>通过 Stackdriver 将日志导出到 BigQuery、GCS、Pub/Sub</a></li><li role=none><a role=treeitem title="描述如何配置 Istio 进行 HTTP Egress 流量监控和访问策略。 (2018年6月22日)" href=/v1.6/zh/blog/2018/egress-monitoring-access-control/>HTTP Egress 流量监控和访问策略</a></li><li role=none><a role=treeitem title="Istio v1alpha3 路由 API 介绍, 动机及其设计原则。 (2018年4月25日)" href=/v1.6/zh/blog/2018/v1alpha3-routing/>Istio v1aplha3 路由 API 介绍</a></li><li role=none><a role=treeitem title="描述如何在 AWS 上使用网络负载均衡器配置 Istio Ingress。 (2018年4月20日)" href=/v1.6/zh/blog/2018/aws-nlb/>使用 AWS NLB 配置 Istio Ingress</a></li><li role=none><a role=treeitem title="使用 Kubernetes 命名空间和 RBAC 为 Istio 构建软性多租户环境。 (2018年4月19日)" href=/v1.6/zh/blog/2018/soft-multitenancy/>Istio 的软性多租户支持</a></li><li role=none><a role=treeitem title="介绍更安全,低风险的部署和发布到生产。 (2018年2月8日)" href=/v1.6/zh/blog/2018/traffic-mirroring/>用于在生产环境进行测试的 Istio 流量镜像功能</a></li><li role=none><a role=treeitem title="描述基于 Istio 的 Bookinfo 示例的简单场景。 (2018年2月6日)" href=/v1.6/zh/blog/2018/egress-tcp/>使用外部 TCP 服务</a></li><li role=none><a role=treeitem title="描述基于 Istio Bookinfo 示例的简单场景。 (2018年1月31日)" href=/v1.6/zh/blog/2018/egress-https/>使用外部 Web 服务</a></li></ul></div></div><div class=card><button class="header dynamic" id=card3 title="2017 年的博客文章。" aria-controls=card3-body><svg class="icon"><use xlink:href="/v1.6/img/icons.svg#blog"/></svg>2017 年的博客文章</button><div class=body aria-labelledby=card3 role=region id=card3-body><ul role=tree aria-expanded=true class=leaf-section aria-labelledby=card3><li role=none><a role=treeitem title="提高可用,降低延迟。 (2017年12月7日)" href=/v1.6/zh/blog/2017/mixer-spof-myth/>Mixer 和 SPOF 神话</a></li><li role=none><a role=treeitem title="概要说明 Mixer 的插件架构。 (2017年11月3日)" href=/v1.6/zh/blog/2017/adapter-model/>Mixer 适配器模型</a></li><li role=none><a role=treeitem title="Istio 的策略如何关联 Kubernetes 的网络策略 。 (2017年8月10日)" href=/v1.6/zh/blog/2017/0.1-using-network-policy/>Istio 使用网络策略</a></li><li role=none><a role=treeitem title="使用 Istio 创建自动缩放的金丝雀部署。 (2017年6月14日)" href=/v1.6/zh/blog/2017/0.1-canary/>使用 Istio 进行金丝雀部署</a></li><li role=none><a role=treeitem title="Istio Auth 0.1 公告。 (2017年5月25日)" href=/v1.6/zh/blog/2017/0.1-auth/>使用 Istio 增强端到端安全</a></li></ul></div></div></div></nav></div><div class=article-container><button tabindex=-1 id=sidebar-toggler title=折叠导航栏><svg class="icon"><use xlink:href="/v1.6/img/icons.svg#pull"/></svg></button><nav aria-label=Breadcrumb><ol><li><a href=/v1.6/zh/ title=用于连接、保护、控制和观测服务。>Istio</a></li><li><a href=/v1.6/zh/blog/ title="关于使用 Istio 的博客文章。">博客</a></li><li><a href=/v1.6/zh/blog/2019/ title="2019 年的博客文章。">2019 年的博客文章</a></li><li>使用 AppSwitch 进行 Sidestepping 依赖性排序</li></ol></nav><article aria-labelledby=title><div class=title-area><div style=width:100%><h1 id=title>使用 AppSwitch 进行 Sidestepping 依赖性排序</h1><p class=byline><span>作者</span>
<span class=attribution>Dinesh Subhraveti (AppOrbit and Columbia University)</span><span> | </span><span><svg class="icon"><use xlink:href="/v1.6/img/icons.svg#calendar"/></svg><span>&nbsp;</span>2019年1月14日</span><span> | </span><span title="297 字"><svg class="icon"><use xlink:href="/v1.6/img/icons.svg#clock"/></svg><span>&nbsp;</span>阅读大约需要 2 分钟</span></p></div></div><nav class=toc-inlined aria-label="Table of Contents"><div><hr><ol><li role=none aria-label=依赖性排序问题><a href=#dependency-ordering-problem>依赖性排序问题</a><ol><li role=none aria-label="示例场景IBM WebSphere ND"><a href=#example-scenario-IBM-WebSphere>示例场景IBM WebSphere ND</a><li role=none aria-label="Istio 中的 Sidecar 依赖"><a href=#sidecar-dependency-in-Istio>Istio 中的 Sidecar 依赖</a></ol></li><li role=none aria-label="使用 AppSwitch 进行依赖性排序"><a href=#dependency-ordering-with-AppSwitch>使用 AppSwitch 进行依赖性排序</a><ol><li role=none aria-label="AppSwitch 模型和构造"><a href=#AppSwitch-model-and-constructs>AppSwitch 模型和构造</a><li role=none aria-label=将服务与其引用分离><a href=#decoupling-services-from-their-references>将服务与其引用分离</a><li role=none aria-label=非阻塞请求><a href=#non-blocking-requests>非阻塞请求</a><li role=none aria-label=应用程序超时><a href=#application-timeouts>应用程序超时</a><li role=none aria-label="为 Sidecar 提供服务引用的通配符支持"><a href=#wildcard-service-references-for-sidecar-dependency>为 Sidecar 提供服务引用的通配符支持</a></ol></li><li role=none aria-label=总结><a href=#summary>总结</a><li role=none aria-label=致谢><a href=#acknowledgements>致谢</a><li role=none aria-label=相关内容><a href=#see-also>相关内容</a></li></ol><hr></div></nav><div><aside class="callout warning"><div class=type><svg class="large-icon"><use xlink:href="/v1.6/img/icons.svg#callout-warning"/></svg></div><div class=content>该博客文章是在 Istio 1 的版本下编写的,因此其中某些内容现在可能已过时。</div></aside></div><p>我们正在经历一个有趣事情,对应用程序进行拆分和重组。虽然微服务需要把单体应用分解为多个微型服务,但服务网格会把这些服务连结为一个应用程序。因此,微服务是逻辑上分离而又不是相互独立的。它们通常是紧密相互依赖的,而拆分单体应用的同时会引入了许多新的问题,例如服务之间需要双向认证等。而 Istio 恰巧能解决大多数问题。</p><h2 id=dependency-ordering-problem>依赖性排序问题</h2><p>依赖性排序的问题是由于应用程序拆分而导致的问题且 Istio 也尚未解决 - 确保应用程序整体快速正确地的顺序启动应用程序的各个服务。在单体应用程序中,内置所有组件,组件之间的依赖顺序由内部锁机制强制执行。但是,如果单个服务分散在服务网格的集群中,则启动服务需要首先检查它所依赖的服务是否已启动且可用。</p><p>依赖性排序由于存在许多相互关联的问题而具有欺骗性。对单个服务进行排序需要具有服务的依赖关系图,以便它们可以从叶节点开始返回到根节点。由于相互依赖性随着应用程序的行为而发展,因此构建这样的图并随时保持更新并不容易。即使以某种方式提供依赖图,强制执行排序本身并不容易。简单地按指定的顺序启动服务显然是行不通的。服务可能已启动但尚未准备好提供服务。例如 docker-compose 中的 depends-on 标签就存在这样的问题。</p><p>除了在服务启动之间引入足够长的睡眠之外,还有一个常见的模式是,在启动服务之前检查被依赖的服务是否已经准备就绪。在 Kubernetes 中,可以用在 Pod 的 Init 容器中加入等待脚本的方式来完成。但是,这意味着整个应用程序将被暂停,直到所有的依赖服务都准备就绪。有时,应用程序会在启动第一次出站连接之前花几分钟时间初始化自己。不允许服务启动会增加应用程序整体启动时间的大量开销。此外,等待 init 容器的策略不适用于同一 pod 中的多个服务相互依赖的情况。</p><h3 id=example-scenario-IBM-WebSphere>示例场景IBM WebSphere ND</h3><p>IBM WebSphere ND 是一个常见的应用程序中间件,通过对它的观察,能够更好地理解这种问题。它本身就是一个相当复杂的框架,由一个名为 Deployment manager<code>dmgr</code>)的中央组件组成,它管理一组节点实例。它使用 UDP 协商节点之间的集群成员资格,并要求部署管理器在任何节点实例出现并加入集群之前已启动并可运行。</p><p>为什么我们在现代云原生环境中讨论传统应用程序?事实证明,通过使它们能够在 Kubernetes 和 Istio 平台上运行可以获得显著的收益。从本质上讲它是现代化之旅的一部分它允许在同一现代平台上运行传统应用程序和全新的现代应用程序以促进两者之间的互操作。实际上WebSphere ND 是一个要求很高的应用程序。它期望具有特定网络接口属性的一致网络环境等。AppSwitch 可以满足这些要求。本博客的将重点关注依赖顺序需求以及 AppSwitch 在这方面的解决方法。</p><p>在 Kubernetes 集群上简单地部署 <code>dmgr</code> 和节点实例作为 pod 是行不通的。<code>dmgr</code> 和节点实例碰巧有一个很长的初始化过程,可能需要几分钟。如果他们被同时部署,那么应用程序通常会处于一个有趣的状态。当一个节点实例出现并发现缺少 <code>dmgr</code>它将需要一个备用启动路径。相反如果它立即退出Kubernetes 崩溃循环将接管,也许应用程序会出现。但即使在这种情况下,事实证明及时启动并不能得到保证。</p><p>一个 <code>dmgr</code> 及其节点实例是 WebSphere ND 的基本部署配置。构建在生产环境中运行的 WebSphere ND 之上的 IBM Business Process Manager 等应用程序包括其他一些服务。在这些配置中,可能存在一系列相互依赖关系。根据节点实例托管的应用程序,它们之间也可能存在排序要求。使用较长的服务初始化时间和崩溃循环重启,应用程序几乎没有机会在任何合理的时间内启动。</p><h3 id=sidecar-dependency-in-Istio>Istio 中的 Sidecar 依赖</h3><p>Istio 本身受依赖性排序问题版本的影响。由于在 Istio 下运行的服务的连接通过其 sidecar 代理重定向,因此在应用程序服务及其 sidecar 之间创建了隐式依赖关系。除非 sidecar 完全正常运行,否则所有来自服务的请求都将被丢弃。</p><h2 id=dependency-ordering-with-AppSwitch>使用 AppSwitch 进行依赖性排序</h2><p>那么我们如何解决这些问题呢?一种方法是将其推迟到应用程序并说它们应该“表现良好”并实施适当的逻辑以使自己免受启动顺序问题的影响。但是,许多应用程序(尤其是传统应用程序)如果错误则会超时或死锁。即使对于新的应用程序,为每个服务实现一个关闭逻辑也是最大的额外负担,最好避免。服务网格需要围绕这些问题提供足够的支持。毕竟,将常见模式分解为底层框架实际上是服务网格的重点。</p><p><a href=http://appswitch.io>AppSwitch</a> 明确地解决了依赖性排序。它位于应用程序在集群中的客户端和服务之间的网络交互的控制路径上,并且通过进行 <code>connect</code> 调用以及当特定服务通过使 <code>listen</code> 准备好接受连接时,准确地知道服务何时成为客户端。调用它的 <em>service router</em> 组件在集群中传播有关这些事件的信息并仲裁客户端和服务器之间的交互。AppSwitch 就是以这种简单有效的方式实现负载均衡和隔离等功能的。利用应用程序的网络控制路径的相同战略位置,可以想象这些服务所做的“连接”和“监听”调用可以以更精细的粒度排列,而不是按照依赖关系图对整个服务进行粗略排序。这将有效地解决多级依赖问题和加速应用程序启动。</p><p>但这仍然需要一个依赖图。存在许多产品和工具来帮助发现服务依赖性。但它们通常基于对网络流量的被动监控,并且无法预先为任意应用程序提供信息。由于加密和隧道导致的网络级混淆也使它们不可靠。发现和指定依赖项的负担最终落在应用程序的开发人员或操作员身上。实际上,甚至一致性检查依赖性规范本身也非常复杂,相对来说,能够避免使用依赖图的任何方法都会更加理想。</p><p>依赖图的要点是知道哪些客户端依赖于特定服务以便让客户端能够等待被依赖服务准备就绪。但具体客户真的重要吗归根结底一个服务的所有客户端都是依赖这个服务的。AppSwitch 正是利用这一点来解决依赖问题。事实上,这完全避免了依赖性排序。可以同时调度应用程序中的所有服务,而无需考虑启动顺序。它们之间的相互依赖性会根据各个请求和响应的粒度自动完成,从而实现快速,正确的应用程序启动。</p><h3 id=AppSwitch-model-and-constructs>AppSwitch 模型和构造</h3><p>既然我们对 AppSwitch 的高级方法有了概念性的理解,那么让我们来看看所涉及的结构。但首先要对使用模型进行快速总结。尽管它是针对不同的上下文编写的,但在此主题上查看我之前的 <a href=/v1.6/zh/blog/2018/delayering-istio/>blog</a> 也很有用。为了完整起见,我还要注意 AppSwitch 不会打扰非网络依赖。例如,两个服务可能使用 IPC 机制或通过共享文件系统进行交互。像这样的深层联系的流程通常是同一服务的一部分,并且不需要主动地对应用程序的正常执行进行干预。</p><p>AppSwitch 的核心能够使用 BSD Socket API 及其相关的其它调用(例如 <code>fcntl</code> 和 ioctl来完成对 Socket 的处理。它的实现细节很有意思,但是为了防止偏离本文的主题,这里仅对其独特的关键属性进行一个总结。
1速度很快。它使用 <code>seccomp</code> 过滤和二进制检测的组合来积极地限制应用程序正常执行的干预。AppSwitch 特别适用于服务网格和应用程序网络用例,因为它实现了这些功能,而无需实际触摸数据。相反,网络级方法会导致每个数据包的成本。看看这个<a href=/v1.6/zh/blog/2018/delayering-istio/>博客</a>进行一些性能测量。
2它不需要任何内核支持内核模块或补丁可以在标准的发行版内核上运行
3它可以作为普通用户运行非 root。事实上该机制甚至可以通过删除对网络容器的根要求来运行<a href=https://linuxpiter.com/en/materials/2478>非 root 的 Docker 守护进程</a>
4它可以不加更改的用于任何类型的应用程序上适用于任何类型的应用程序 - 从 WebSphere ND 和 SAP 到自定义 C 应用程序,再到静态链接的 <code>Golang</code> 应用程序。Linux/x86 是仅有的运行需求。</p><h3 id=decoupling-services-from-their-references>将服务与其引用分离</h3><p>AppSwitch 建立在应用程序应与其引用分离的基本前提之上。传统上,应用程序的标识源自它们运行的​​ 主机的标识。但是,应用程序和主机是需要独立引用的非常不同的对象。本<a href=https://arxiv.org/abs/1711.02294>主题</a>介绍了围绕此主题的详细讨论以及 AppSwitch 的概念基础。</p><p>实现服务对象及其身份之间解耦的中央 AppSwitch 构造是 _service reference_简称 <em>reference</em> 。AppSwitch 基于上面概述的 API 检测机制实现服务引用。服务引用由 IP端口对以及可选的 DNS 名称和标签选择器组成标签选择器选择引用所代表的服务以及此引用所适用的客户端。引用支持一些关键属性。1它的名称可以独立于它所引用的对象的名称。也就是说服务可能正在侦听 IP 和端口,但是引用允许在用户选择的任何其他 IP 和端口上达到该服务。这使 AppSwitch 能够运行从源环境中捕获的传统应用程序,通过静态 IP 配置在 Kubernetes 上运行,为其提供必要的 IP 地址和端口而不管目标网络环境如何。2即使目标服务的位置发生变化它也保持不变。引用自动重定向自身因为其标签选择器现在解析为新的服务实例3对于此讨论最重要的是在目标服务的启动过程中引用就已经生效了。</p><p>为了便于发现可通过服务引用访问的服务AppSwitch 提供了一个 _auto-curated 服务注册表_。根据 AppSwitch 跟踪的网络 API当服务进出群集时注册表会自动保持最新。注册表中的每个条目都包含相应服务绑定的 IP 和端口。除此之外,它还包括一组标签,指示此服务所属的应用程序,应用程序在创建服务时通过 Socket API 传递的 IP 和端口AppSwitch 实际绑定基础主机上的服务的 IP 和端口此外,在 AppSwitch 下创建的应用程序带有一组用户传递的标签用于描述应用程序以及一些默认系统标签指示创建应用程序的用户和运行应用程序的主机等。这些标签都可以在服务引用所携带的标签选择器中表示。通过创建服务引用可以使客户端访问注册表中的服务。然后客户端将能够以引用的名称IP端口访问服务。现在让我们来看看 AppSwitch 如何在目标服务尚在启动的过程中就让服务引用开始生效的。</p><h3 id=non-blocking-requests>非阻塞请求</h3><p>AppSwitch 利用 BSD Socket API 的语义确保服务引用从客户的角度看起来是有效的因为相应的服务出现了。当客户端对一个尚未启动的服务发起阻塞式连接调用时AppSwitch 会阻止该调用一段时间等待目标服务变为活动状态。由于已知目标服务是应用程序的一部分并且预计很快就会出现,因此客户端会被阻塞,而不是收到 ECONNREFUSED 之类的返回信息导致启动失败。如果服务没有及时出现,则会向应用程序返回一个错误,以便像 Kubernetes 崩溃循环这样的框架级机制可以启动。</p><p>如果客户端请求被标记为非阻塞,则 AppSwitch 通过返回 <code>EAGAIN</code> 来处理该请求以通知应用程序重试而不是放弃。再次,这与 Socket API 的语义一致并防止由于启动竞争而导致的失败。AppSwitch 通过对 BSD Socket API 的支持,将重试逻辑内置到应用程序之中,从而透明的为应用提供了依赖排序支持。</p><h3 id=application-timeouts>应用程序超时</h3><p>如果应用程序基于其自己的内部计时器超时怎么办说实话如果需要AppSwitch 还可以伪造应用程序对时间的感知,但这种做法不仅越界,而且并无必要。应用程序决定并知道它应该等待多长时间,这对 AppSwitch 来说是不合适的。应用程序超过保守时长如果目标服务仍未及时出现则不太可能是依赖性排序问题。一定是出现了其它问题AppSwitch 不应掩盖这些问题。</p><h3 id=wildcard-service-references-for-sidecar-dependency>为 Sidecar 提供服务引用的通配符支持</h3><p>服务引用可用于解决前面提到的 Istio sidecar 依赖性问题。AppSwitch 用 IP端口的方式来描述对服务的引用这种描述中是可以使用通配符的。也就是说服务引用描述中可以用 IP 掩码的形式来表达要捕捉的 IP 地址的范围。如果服务引用的标签选择器指向 sidecar 服务,则应用此服务引用的任何应用程序的所有传出连接将被透明地重定向到 sidecar。当然在 Sidecar 启动过程中,服务引用仍然是有效的。</p><p>使用 sidecar 依赖性排序的服务引用也隐式地将应用程序的连接重定向到 sidecar ,而不需要 iptables 和随之而来的权限问题。基本上它就像应用程序直接连接到 sidecar 而不是目标目的地一样工作,让 sidecar 负责做什么。AppSwitch 将使用 sidecar 可以在将连接传递到应用程序之前解码的代理协议将关于原始目的地等的元数据插入到连接的数据流中。其中一些细节已在<a href=/v1.6/zh/blog/2018/delayering-istio/>此处</a>进行了讨论。出站连接是这样处理的,那么入站连接呢?由于所有服务及其 sidecar 都在 AppSwitch 下运行,因此来自远程节点的任何传入连接都将被重定向到各自的远程 sidecar 。所以传入连接没有什么特别处理。</p><h2 id=summary>总结</h2><p>依赖顺序是一个讨厌的问题。这主要是由于无法访问有关服务间交互的细粒度应用程序级事件。解决这个问题通常需要应用程序来实现自己的内部逻辑。但 AppSwitch 使这些内部应用程序事件无需更改应用程序即可进行检测。然后AppSwitch 利用对 BSD Socket API 的普遍支持来回避排序依赖关系的要求。</p><h2 id=acknowledgements>致谢</h2><p>感谢 Eric Herness 和团队对 IBM WebSphere 和 BPM 产品的见解和支持,我们将它们应用到现代化 Kubernetes 平台,还要感谢 Mandar JogMartin Taillefer 和 Shriram Rajagopalan 对于此博客早期草稿的评审。</p><nav id=see-also><h2>相关内容</h2><div class=see-also><div class=entry><p class=link><a data-skipendnotes=true href=/v1.6/zh/blog/2018/delayering-istio/>使用 AppSwitch 精简 Istio 层次</a></p><p class=desc>使用 AppSwitch 自动接入应用并降低延迟。</p></div><div class=entry><p class=link><a data-skipendnotes=true href=/v1.6/zh/blog/2020/wasm-announce/>重新定义代理的扩展性Envoy 和 Istio 引入 WebAssembly</a></p><p class=desc>Istio 的扩展中使用 WASM 的前景。</p></div><div class=entry><p class=link><a data-skipendnotes=true href=/v1.6/zh/blog/2020/tradewinds-2020/>Istio 2020——为了商用</a></p><p class=desc>Istio 在 2020 年的愿景声明及路线图。</p></div><div class=entry><p class=link><a data-skipendnotes=true href=/v1.6/zh/blog/2019/performance-best-practices/>最佳实践Service Mesh 基准性能测试</a></p><p class=desc>评估 Istio 数据平面性能的工具和指南。</p></div><div class=entry><p class=link><a data-skipendnotes=true href=/v1.6/zh/blog/2019/istio1.1_perf/>为性能而设计的 Istio 1.1</a></p><p class=desc>Istio 1.1 性能概览。</p></div><div class=entry><p class=link><a data-skipendnotes=true href=/v1.6/zh/blog/2019/egress-performance/>Egress gateway 性能测试</a></p><p class=desc>评估加入 Egress gateway 对性能造成的影响。</p></div></div></nav></article><nav class=pagenav><div class=left><a title="揭秘 Istio 是如何将其数据平面组件添加到现有 deployment。" href=/v1.6/zh/blog/2019/data-plane-setup/><svg class="icon"><use xlink:href="/v1.6/img/icons.svg#left-arrow"/></svg>揭开 Istio Sidecar 注入模型的神秘面纱</a></div><div class=right><a title="Istio 有了一个新的论坛。" href=/v1.6/zh/blog/2019/announcing-discuss.istio.io/>Istio 论坛成立<svg class="icon"><use xlink:href="/v1.6/img/icons.svg#right-arrow"/></svg></a></div></nav><div id=feedback><div id=feedback-initial>这些信息有用吗?<br><button class="btn feedback" onclick="sendFeedback('zh',1)">是的</button>
<button class="btn feedback" onclick="sendFeedback('zh',0)">没有</button></div><div id=feedback-comment>Do you have any suggestions for improvement?<br><br><input id=feedback-textbox type=text placeholder="Help us improve..." data-lang=zh></div><div id=feedback-thankyou>Thanks for your feedback!</div></div><div id=endnotes-container aria-hidden=true><h2>链接</h2><ol id=endnotes></ol></div></div><div class=toc-container><nav class=toc aria-label="Table of Contents"><div id=toc><ol><li role=none aria-label=依赖性排序问题><a href=#dependency-ordering-problem>依赖性排序问题</a><ol><li role=none aria-label="示例场景IBM WebSphere ND"><a href=#example-scenario-IBM-WebSphere>示例场景IBM WebSphere ND</a><li role=none aria-label="Istio 中的 Sidecar 依赖"><a href=#sidecar-dependency-in-Istio>Istio 中的 Sidecar 依赖</a></ol></li><li role=none aria-label="使用 AppSwitch 进行依赖性排序"><a href=#dependency-ordering-with-AppSwitch>使用 AppSwitch 进行依赖性排序</a><ol><li role=none aria-label="AppSwitch 模型和构造"><a href=#AppSwitch-model-and-constructs>AppSwitch 模型和构造</a><li role=none aria-label=将服务与其引用分离><a href=#decoupling-services-from-their-references>将服务与其引用分离</a><li role=none aria-label=非阻塞请求><a href=#non-blocking-requests>非阻塞请求</a><li role=none aria-label=应用程序超时><a href=#application-timeouts>应用程序超时</a><li role=none aria-label="为 Sidecar 提供服务引用的通配符支持"><a href=#wildcard-service-references-for-sidecar-dependency>为 Sidecar 提供服务引用的通配符支持</a></ol></li><li role=none aria-label=总结><a href=#summary>总结</a><li role=none aria-label=致谢><a href=#acknowledgements>致谢</a><li role=none aria-label=相关内容><a href=#see-also>相关内容</a></li></ol></div></nav></div></main><footer><div class=user-links><a class=channel title="立刻下载 Istio 1.6.8" href=/v1.6/docs/setup/getting-started/#download aria-label="Download Istio"><span>download</span><svg class="icon"><use xlink:href="/v1.6/img/icons.svg#download"/></svg>
</a><a class=channel title="加入 Istio discussion board 参与讨论获取帮助" href=https://discuss.istio.io aria-label="Istio discussion board"><span>discuss</span><svg class="icon"><use xlink:href="/v1.6/img/icons.svg#discourse"/></svg></a>
<a class=channel title="Stack Overflow 中列举了针对实际问题以及部署、配置和使用 Istio 的各项回答" href=https://stackoverflow.com/questions/tagged/istio aria-label="Stack Overflow"><span>stack overflow</span><svg class="icon"><use xlink:href="/v1.6/img/icons.svg#stackoverflow"/></svg></a>
<a class=channel title="在 Slack 上与 Istio 社区交互讨论开发问题(仅限邀请)" href=https://istio.slack.com aria-label=slack><span>slack</span><svg class="icon"><use xlink:href="/v1.6/img/icons.svg#slack"/></svg></a>
<a class=channel title="关注我们的 Twitter 来获取最新信息" href=https://twitter.com/IstioMesh aria-label=Twitter><span>twitter</span><svg class="icon"><use xlink:href="/v1.6/img/icons.svg#twitter"/></svg></a><div class=tag>对于用户</div></div><div class=info><p class=copyright>中文内容由 ServiceMesher 社区维护,部分文档可能稍微滞后于英文版本,同步工作持续进行中<br>Istio 归档
1.6.8<br>&copy; 2020 Istio Authors, <a href=https://policies.google.com/privacy>隐私政策</a><br>归档于 2020年8月21日</p></div><div class=dev-links><a class=channel title="Istio 的代码在 GitHub 上开发" href=https://github.com/istio/community aria-label=GitHub><span>github</span><svg class="icon"><use xlink:href="/v1.6/img/icons.svg#github"/></svg></a>
<a class=channel title="如果您想深入了解 Istio 的技术细节,请查看我们日益完善的设计文档" href=https://groups.google.com/forum/#!forum/istio-team-drive-access aria-label="team drive"><span>drive</span><svg class="icon"><use xlink:href="/v1.6/img/icons.svg#drive"/></svg></a>
<a class=channel title="如果您想为 Istio 项目做出贡献,请考虑加入我们的工作组" href=https://github.com/istio/community/blob/master/WORKING-GROUPS.md aria-label="working groups"><span>working groups</span><svg class="icon"><use xlink:href="/v1.6/img/icons.svg#working-groups"/></svg></a><div class=tag>对于开发者</div></div></footer><div id=scroll-to-top-container aria-hidden=true><button id=scroll-to-top title=回到顶部><svg class="icon"><use xlink:href="/v1.6/img/icons.svg#top"/></svg></button></div></body></html>