使用Envoy 作Sidecar Proxy的微服务模式-2.超时和重试

news/2024/11/9 9:20:31 标签: java, json, 运维

本博客是深入研究Envoy Proxy和Istio.io 以及它如何实现更优雅的方式来连接和管理微服务系列文章的一部分。

这是接下来几个部分的想法(将在发布时更新链接):

  • 断路器(第一部分)
  • 重试/超时(第二部分)
  • 分布式跟踪(第三部分)
  • Prometheus的指标收集(第四部分)
  • rate limiter(第五部分)

第一部分 - 使用envoy proxy 实现超时和重试

第一篇博文向您介绍了Envoy Proxy的断路功能实现。在第二部分中,我们将详细介绍如何启用其他弹性功能,如超时和重试。有意进行一些简单的演示,因此我可以单独说明模式和用法。请下载此演示的源代码并按照说明进行操作!

该演示由一个客户端和一个服务组成。客户端是一个Java http应用程序,模拟对“上游”服务进行http调用(注意,我们在这里使用Envoys术语,并贯穿整个repo)。客户端打包在docker.io/ceposta/http-envoy-client:latest的Docker镜像中。除了http-client Java应用程序之外,还有Envoy Proxy的一个实例。在此部署模型中,Envoy被部署为服务的sidercar(在本例中为http客户端)。当http-client进行出站调用(到“上游”服务)时,所有调用都通过Envoy Proxy sidercar。

这些示例的“上游”服务是httpbin.org。 httpbin.org允许我们轻松模拟HTTP服务行为。它很棒,所以如果你没有看到它,请查看它。

图片描述

重试和超时演示有自己的envoy.json配置文件。我绝对建议您查看配置文件每个部分的参考文档,以帮助理解完整配置。 datawire.io的优秀人员也为Envoy及其配置提供了一个很好的介绍,你也应该检查一下。

运行 重试 demo

对于重试演示,我们将在Envoy中配置我们的路由,如下所示:

json">  "routes": [
    {
      "timeout_ms": 0,
      "prefix": "/",
      "auto_host_rewrite": true,
      "cluster": "httpbin_service",
      "retry_policy": {
        "retry_on": "5xx",
        "num_retries": 3
      }

    }

这里我们在HTTP状态为5xx时重试最多3次。

如果您已经运行过以前的演示,请确保为此(或任何)演示开始一个新的初始化状态。我们为每个演示提供不同的Envoy配置,并希望确保每次都从一个新的初始化状态开始。

首先停止已经存在的demo:

./docker-stop.sh

现在开始运行重试demo:

./docker-run.sh -d retries

现在让我们通过一次调用来运行客户端,该调用将触发应该返回HTTP 500错误的HTTP端点。我们将使用curl.sh脚本,该脚本设置为在我们的演示容器中调用curl。

./curl.sh -vvvv localhost:15001/status/500

我们将会看到类似的输出:

* Hostname was NOT found in DNS cache
*   Trying ::1...
* connect to ::1 port 15001 failed: Connection refused
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 15001 (#0)
> GET /status/500 HTTP/1.1
> User-Agent: curl/7.35.0
> Host: localhost:15001
> Accept: */*
> 
< HTTP/1.1 500 Internal Server Error
* Server envoy is not blacklisted
< server: envoy
< date: Thu, 25 May 2017 05:55:37 GMT
< content-type: text/html; charset=utf-8
< access-control-allow-origin: *
< access-control-allow-credentials: true
< x-powered-by: Flask
< x-processed-time: 0.000718116760254
< content-length: 0
< via: 1.1 vegur
< x-envoy-upstream-service-time: 684
< 
* Connection #0 to host localhost left intact

现在我们检查一下,envoy为我们做了哪些工作:

./get-envoy-stats.sh | grep retry
cluster.httpbin_service.retry.upstream_rq_500: 3
cluster.httpbin_service.retry.upstream_rq_5xx: 3
cluster.httpbin_service.upstream_rq_retry: 3
cluster.httpbin_service.upstream_rq_retry_overflow: 0
cluster.httpbin_service.upstream_rq_retry_success: 0

我们在这里看到由于HTTP 500错误,envoy重试了3次。

如果从另外一个角度看待,重试可能会对您的服务架构产生有害影响。它们可以帮助传播故障或对可能正在挣扎的内部服务造成DDoS类型攻击。

图片描述

对于重试,需要注意以下几点:

  • envoy将通过抖动进行自动指数重试。有关更多信息,请参阅文档

您可以设置重试超时(每次重试超时),但总路由超时(为路由表配置;请参阅超时演示以获取确切配置)仍将保留/应用;这是为了使任何失控的重试/指数退避短路
您应始终设置断路器重试配置,以便在可能具有大量连接时限制重试的配额。请参阅Envoy文档中断路器部分的有效重试

运行超时 demo

对于超时演示,我们将在Envoy中配置我们的路由,如下所示:

json">   "routes": [
    {
      "timeout_ms": 0,
      "prefix": "/",
      "auto_host_rewrite": true,
      "cluster": "httpbin_service",
      "timeout_ms": 3000
    }

此配置为通过此路由到httpbin_service群集的任何调用设置全局(即,包括所有重试)3s超时。

每当处理超时时,我们必须知道源自边缘的请求的整体全局超时。当我们深入到网络调用图中时,我们发现自己很难调试超时不会逐渐减少的情况。换句话说,当您浏览调用图时,调用图中更深层次的服务调用的服务超时应该小于先前服务的调用:

图片描述

envoy可以帮助传播超时信息,像gRPC这样的协议可以传播截止时间信息。随着我们继续本系列,我们将看到如何使用Istio Mesh控制Envoy代理,并且控制平面可以帮助我们进行故障注入以发现超时异常。

如果您已经运行过以前的演示,请确保为此(或任何)演示开始一个新的初始化状态。我们为每个演示提供不同的Envoy配置,并希望确保每次都从一个新的初始化状态开始。

首先停止已经存在的demo:

./docker-stop.sh

现在开始运超时demo:

./docker-run.sh -d timeouts

现在让我们用一个调用来运行客户端,该调用将触发HTTP端点,该端点应该将响应延迟大约5秒。此延迟应足以触发envoy超时。我们将使用curl.sh脚本,该脚本设置为在我们的演示容器中调用curl。

./curl.sh -vvvv localhost:15001/delay/5

我们将看到类似的输出:

* Hostname was NOT found in DNS cache
*   Trying ::1...
* connect to ::1 port 15001 failed: Connection refused
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 15001 (#0)
> GET /delay/5 HTTP/1.1
> User-Agent: curl/7.35.0
> Host: localhost:15001
> Accept: */*
> 
< HTTP/1.1 504 Gateway Timeout
< content-length: 24
< content-type: text/plain
< date: Thu, 25 May 2017 06:13:53 GMT
* Server envoy is not blacklisted
< server: envoy
< 
* Connection #0 to host localhost left intact
upstream request timeout

我们看到我们的请求是超时的。

下面我们检查以下envoy的状态:

./get-envoy-stats.sh | grep timeout

在这里,我们看到1个请求(我们发送的请求!)由Envoy超时。

cluster.httpbin_service.upstream_cx_connect_timeout: 0
cluster.httpbin_service.upstream_rq_per_try_timeout: 0
cluster.httpbin_service.upstream_rq_timeout: 1
http.admin.downstream_cx_idle_timeout: 0
http.egress_http.downstream_cx_idle_timeout: 0

如果我们发送请求,这次延迟较小,我们应该看到调用:

./curl.sh -vvvv localhost:15001/delay/2
* Hostname was NOT found in DNS cache
*   Trying ::1...
* connect to ::1 port 15001 failed: Connection refused
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 15001 (#0)
> GET /delay/2 HTTP/1.1
> User-Agent: curl/7.35.0
> Host: localhost:15001
> Accept: */*
> 
< HTTP/1.1 200 OK
* Server envoy is not blacklisted
< server: envoy
< date: Thu, 25 May 2017 06:15:41 GMT
< content-type: application/json
< access-control-allow-origin: *
< access-control-allow-credentials: true
< x-powered-by: Flask
< x-processed-time: 2.00246119499
< content-length: 309
< via: 1.1 vegur
< x-envoy-upstream-service-time: 2145
< 
{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Accept": "*/*", 
    "Connection": "close", 
    "Host": "httpbin.org", 
    "User-Agent": "curl/7.35.0", 
    "X-Envoy-Expected-Rq-Timeout-Ms": "3000"
  }, 
  "origin": "68.3.84.124", 
  "url": "http://httpbin.org/delay/2"
}
* Connection #0 to host localhost left intact

另请注意,Envoy会传播超时 headers,以便上游服务可以了解所期望的内容。


http://www.niftyadmin.cn/n/1147688.html

相关文章

【微信小程序】3 - 数据绑定 、 模板引用 、 事件

文章目录1、数据绑定2、 模板的操作 和 引用3、微信小程序事件调用 和原理操作事件分类布局&#xff1a;主要是弹性布局 rpx1、数据绑定 数据绑定&#xff1a;WXML中的一种 数据呈现方式&#xff1b; 运用JS的data对象完成的WXML数据的动态显示 微信里没有window对象&#x…

海尔海外冰箱首次返销中国 规避汇率风险

不过人民币升值也会降低进口家电在中国市场上的价格&#xff0c;所以&#xff0c;在这种情况下&#xff0c;海尔集团通过全球化生产资源配置来“以全球资源应对全球市场”&#xff0c;将海外工厂冰箱返销至中国市场&#xff0c;能够有效地规避汇率风险。 对于去年全球营业额达…

【H5】1 - 新增属性:placeholder、input 的 新type、contenteditable - 是否可编辑、draggable - 是否可拖拽

文章目录1、placeholder - 用作提示信息2、input 的 新type3、contenteditable - 是否可编辑4、draggable - 是否可拖拽总结&#xff1a; 只有placeholder \ contenteditable 没有兼容问题 1、placeholder - 用作提示信息 placeholder&#xff1a;用作提示信息 &#xff0c;没…

Laravel核心解读--完结篇

过去一年时间写了20多篇文章来探讨了我认为的Larave框架最核心部分的设计思路、代码实现。通过更新文章自己在软件设计、文字表达方面都有所提高&#xff0c;在刚开始决定写Laravel源码分析地文章的时候我地期望是自己和读者通过学习Laravel核心的代码能在软件设计上带来提高&a…

大连马拉松比赛期间多条公交临时改线移站

为了保证第22届大连国际马拉松赛顺利进行&#xff0c;根据大连市公安局交通警察支队《关于第22届大连国际马拉松赛期间部分道路采取临时交通管制措施的通告》&#xff0c;下列公交车线路将临时改线、移站&#xff0c;具体事宜通告如下&#xff1a; 16、29、405、801路汽车及旅…

南方都市报:红心照耀MSN

16日&#xff0c;许多网友在打开MSN的时候都有点惊讶&#xff0c;发现MSN界面一片飘红&#xff0c;一众好友签名前都多了一颗红心和“CHINA”字样。有网友以“那场面是相当的壮观”来形容。 在国际上一些组织和个体对北京奥运提出抵制的大背景下&#xff0c;中国网友以自己的…

好用工具推荐

文章目录1、LICEcap - Github/CSDN 添加gif动图2、 XSwitch - 跨域3、pdf 文件 转 word4、最新Axure谷歌浏览器Chrome扩展程序安装方法1、LICEcap - Github/CSDN 添加gif动图 写博客的时候&#xff0c;遇到复杂的过程&#xff0c;用动图表述&#xff0c;直观有效又显得逼格很高…

webpackPlugin插件总结

功能类 html-webpack-plugin 自动生成html&#xff0c;基本用法&#xff1a; new HtmlWebpackPlugin({filename: index.html, // 生成文件名template: path.join(process.cwd(), ./index.html) // 模班文件 }) copy-webpack-plugin 拷贝资源插件 基本用法&#xff1a; new Copy…