服务网格:限流保护 (上)

背景

限流是服务治理中保护服务的重要手段之一,也是最直接有效的手段,它可以保护服务不被瞬间的大流量冲垮,类似电路中的“保险丝”。在服务上线前,我们都会对服务进行基准测试,来了解可通过的最大“电流”。

上面所说的这类限流通常放置的入站一侧,对服务起到保护的作用。同样,出站一侧也有限流,这种限流防止程序错误导致瞬间发送大量请求导致其他服务故障,避免了错误的“蔓延”。

这篇文章中“入站限流”是主角,来为大家介绍服务网格如何在 4 层和 7 层网络提供限流保护的功能。

实现

在 osm-edge 中提供了 CRD UpstreamTrafficSetting[1],提供到上游流量的设置,限流就是其中之一。服务网格可以作用在 4 层和 7 层网络上,限流在 4 层和 7 层网络上的体现有所不同。

4 层网络上的限流是限制连接创建的速度,也就是单位时间窗口内创建连接的数量;而 7 层网络上则是消息的发送速度,即单位时间窗口内发送消息的数量。

在下面的例子中,分别定义了 4 层和 7 层网络上的限流,前者 **限制每分钟创建的连接数为 1**,后者 **限制每分钟发送的消息数为 3**。

apiVersion: policy.openservicemesh.io/v1alpha1
kind: UpstreamTrafficSetting
metadata:name: tcp-rate-limit
spec:host: foorateLimit:local:tcp:connections: 1unit: minute
---
apiVersion: policy.openservicemesh.io/v1alpha1
kind: UpstreamTrafficSetting
metadata:name: http-rate-limit
spec:host: barrateLimit:local:http:requests: 3unit: minute
---

细心的读者可能发现了配置中的 local 字眼。是的,这里的实现都是本地限速。与本地限速相对的是全局限速,前者的统计维度是当前的服务实例,后者则可以有更大的维度,比如集群中的所有实例,甚至跨多个集群的所有实例。全局限速需要一个中心化的计数组件,而在实现上需要在性能和准确性上做取舍:每个请求都检查中心化的组件,还是定期从中心化组件申请“配额”,每个请求只进行本地统计(可以理解为本地限速的变种)。在即将发布的版本中,osm-edge 将提供全局限速的支持。

接下来就为大家演示限流功能的使用。

演示

环境准备

export INSTALL_K3S_VERSION=v1.23.8+k3s2
curl -sfL https://get.k3s.io | sh -s - --disable traefik --write-kubeconfig-mode 644 --write-kubeconfig ~/.kube/config

下载 osm-edge CLI

system=$(uname -s | tr [:upper:] [:lower:])
arch=$(dpkg --print-architecture)
release=v1.2.0
curl -L https://github.com/flomesh-io/osm-edge/releases/download/${release}/osm-edge-${release}-${system}-${arch}.tar.gz | tar -vxzf -
./${system}-${arch}/osm version
cp ./${system}-${arch}/osm /usr/local/bin/

安装 osm-edge

export osm_namespace=osm-system 
export osm_mesh_name=osm osm install \--mesh-name "$osm_mesh_name" \--osm-namespace "$osm_namespace" \--set=osm.image.pullPolicy=Always

创建命名空间并加入服务网格

kubectl create namespace samples
osm namespace add samples

部署示例应用

kubectl apply -n samples -f https://raw.githubusercontent.com/flomesh-io/osm-edge-docs/main/manifests/samples/fortio/fortio.yaml
kubectl apply -n samples -f https://raw.githubusercontent.com/flomesh-io/osm-edge-docs/main/manifests/samples/fortio/fortio-client.yaml

确保 pod 启动并正常运行

kubectl wait --for=condition=ready pod --all -n samples
pod/fortio-client-b9b7bbfb8-2hmj2 condition met
pod/fortio-c4bd7857f-zww46 condition met

fortio 启动后会监听几个端口,后面我们会用到 TCP 端口 8078 和 HTTP 端口 8080

TCP 限流

在开启限流之前,我们先验证下访问。执行下面的命令,fortio-client 会通过 3 个并发(-c 3)向 fort 服务发送 10 个 TCP 请求(-n 10)。

fortio_client="$(kubectl get pod -n samples -l app=fortio-client -o jsonpath='{.items[0].metadata.name}')"kubectl exec "$fortio_client" -n samples -c fortio-client -- fortio load -qps -1 -c 3 -n 10 tcp://fortio.samples.svc.cluster.local:8078

从结果 tcp OK : 10 (100.0 %) 可以看出所有的请求发送成功。

Fortio 1.38.4 running at 1 queries per second, 2->2 procs, for 10 calls: tcp://fortio.samples.svc.cluster.local:8078
08:16:50 I tcprunner.go:239> Starting tcp test for tcp://fortio.samples.svc.cluster.local:8078 with 3 threads at 1.0 qps
Starting at 1 qps with 3 thread(s) [gomax 2] : exactly 10, 3 calls each (total 9 + 1)
08:16:59 I periodic.go:809> T002 ended after 9.000531122s : 3 calls. qps=0.3333136633089462408:16:59 I periodic.go:809> T001 ended after 9.000573284s : 3 calls. qps=0.3333121019449943
08:17:02 I periodic.go:809> T000 ended after 12.001176928s : 4 calls. qps=0.33330064409496224
Ended after 12.001215699s : 10 calls. qps=0.83325
Sleep times : count 7 avg 4.2815741 +/- 0.2468 min 3.991364314 max 4.499322287 sum 29.9710185
Aggregated Function Time : count 10 avg 0.0029061275 +/- 0.003739 min 0.000404332 max 0.008700971 sum 0.029061275
# range, mid point, percentile, count
>= 0.000404332 <= 0.001 , 0.000702166 , 70.00, 7
> 0.008 <= 0.00870097 , 0.00835049 , 100.00, 3
# target 50% 0.000801444
# target 75% 0.00811683
# target 90% 0.00846731
# target 99% 0.00867761
# target 99.9% 0.00869863
Error cases : no data
Sockets used: 3 (for perfect no error run, would be 3)
Total Bytes sent: 240, received: 240
tcp OK : 10 (100.0 %)
All done 10 calls (plus 0 warmup) 2.906 ms avg, 0.8 qps

现在我们试着添加策略,将连接限流到 1/min ,意味着每分钟只能创建一个连接。

kubectl apply -n samples -f - <<EOF
apiVersion: policy.openservicemesh.io/v1alpha1
kind: UpstreamTrafficSetting
metadata:name: tcp-rate-limit
spec:host: fortio.samples.svc.cluster.localrateLimit:local:tcp:connections: 1unit: minute
EOF

再次使用前面的命令发送请求。从结果来看,只有 3 次请求成功,因为客户端设置了并发数为 3

kubectl exec "$fortio_client" -n samples -c fortio-client -- fortio load -qps -1 -c 3 -n 10 tcp://fortio.samples.svc.cluster.local:8078...
tcp OK : 3 (30.0 %)
tcp short read : 7 (70.0 %)
...

接下来修改策略,加上一个波动 burst: 10 允许短时间的波动峰值 10

kubectl apply -n samples -f - <<EOF
apiVersion: policy.openservicemesh.io/v1alpha1
kind: UpstreamTrafficSetting
metadata:name: tcp-rate-limit
spec:host: fortio.samples.svc.cluster.localrateLimit:local:tcp:connections: 1unit: minuteburst: 10
EOF

应用新的策略之后,再次发送请求可以发现所有请求发送成功。

kubectl exec "$fortio_client" -n samples -c fortio-client -- fortio load -qps -1 -c 3 -n 10 tcp://fortio.samples.svc.cluster.local:8078...
tcp OK : 10 (100.0 %)
...

测试完成后,记得删除已经应用的限流策略。

kubectl delete upstreamtrafficsettings -n samples tcp-rate-limit

HTTP 限流

在开始之前,我们先验证不限流的情况。这次改为 3 个并发(-c 3)发送 10 个 HTTP 请求(-n 10)到 fortio 的 8080 端口。可以看到在不限流的情况下,所有请求发送成功。

kubectl exec "$fortio_client" -n samples -c fortio-client -- fortio load -c 3 -n 10 http://fortio.samples.svc.cluster.local:8080...
IP addresses distribution:
10.43.52.220:8080: 3
Code 200 : 10 (100.0 %)
...

应用下面的限流策略,将流量限制到 3/min,及每分钟 3 次。

kubectl apply -n samples -f - <<EOF
apiVersion: policy.openservicemesh.io/v1alpha1
kind: UpstreamTrafficSetting
metadata:name: http-rate-limit
spec:host: fortio.samples.svc.cluster.localrateLimit:local:http:requests: 3unit: minute
EOF

还是同样的方式发送 10 个请求,从结果来看 3 个请求发送成功(Code 200),7 个请求被限流(Code 429),符合预期。

kubectl exec "$fortio_client" -n samples -c fortio-client -- fortio load -c 3 -n 10 http://fortio.samples.svc.cluster.local:8080...
IP addresses distribution:
10.43.52.220:8080: 7
Code 200 : 3 (30.0 %)
Code 429 : 7 (70.0 %)
...

响应状态码 429 说明请求被限流,该状态码支持定制,比如我们在当前策略的基础上将状态码修改为 529,并在响应头部添加 hello: flomesh

kubectl apply -f - <<EOF
apiVersion: policy.openservicemesh.io/v1alpha1
kind: UpstreamTrafficSetting
metadata:name: http-rate-limit
spec:host: fortio.samples.svc.cluster.localrateLimit:local:http:requests: 3unit: minuteresponseStatusCode: 509responseHeadersToAdd:- name: hellovalue: flomesh
EOF

假如再发送请求会发现被限流的请求收到 509 状态码。

IP addresses distribution:
10.43.52.220:8080: 7
Code 200 : 3 (30.0 %)
Code 509 : 7 (70.0 %)

与 TCP 限流一样,HTTP 的限流也支持波动峰值的设置,同样将波动峰值设置为 10

kubectl apply -n samples -f - <<EOF
apiVersion: policy.openservicemesh.io/v1alpha1
kind: UpstreamTrafficSetting
metadata:name: http-rate-limit
spec:host: fortio.samples.svc.cluster.localrateLimit:local:http:requests: 3unit: minuteburst: 10
EOF

再次请求,会发现所有的 10 个请求都发送成功。

kubectl exec "$fortio_client" -n samples -c fortio-client -- fortio load -c 3 -n 10 http://fortio.samples.svc.cluster.local:8080...
IP addresses distribution:
10.43.52.220:8080: 3
Code 200 : 10 (100.0 %)
...

总结

本篇介绍了服务网格中限流功能的使用,并通过实际的演示来测试限流的效果。由于篇幅的原因,在上面的例子中不管是 4 层还是 7 层的,限流的作用都是在主机(host)的粒度,即以 host: fortio.samples.svc.cluster.local 为统计的粒度。这种粒度在 4 层网络上能够满足需求,但是在 7 层网络实际环境中会有更多的需求。比如有些 path 只会读写缓存,而有些会读写数据库或者调用其他的服务(RPC),不同的 path 的性能会存在差异。因此,需要在更细的粒度上进行限流控制,这将在下一篇中为大家介绍。

引用链接

[1] UpstreamTrafficSettinghttps://github.com/flomesh-io/osm-edge/blob/release-v1.2/pkg/apis/policy/v1alpha1/upstreamtrafficsetting.go#L11

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/281181.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

博弈论进阶之Anti-SG游戏与SJ定理

前言 在上一节中&#xff0c;我们初步了解了一下SG函数与SG定理。 今天我们来分析一下SG游戏的变式——Anti-SG游戏以及它所对应的SG定理 首先从最基本的Anti-Nim游戏开始 Anti-Nim游戏是这样的 有两个顶尖聪明的人在玩游戏&#xff0c;游戏规则是这样的&#xff1a; 有\(n\)堆…

怎样取消outlook约会_快速提示:在Outlook 2010中设置和取消约会

怎样取消outlook约会Getting everyone in one place at the same time for appointments can be daunting at times. Outlook makes it easy to setup appointments and invite attendees as well, and here we look at doing it in Outlook 2010. 同时让每个人都集中在一个地方…

重视和解决 ABP 分布式事件乱序问题

ABP Framework 5.0 实现了单体应用场景下&#xff0c;收件箱和发件箱的事件严格顺序性。但在微服务或多数据库场景下&#xff0c;由于网络时延和设施效率的限制&#xff0c; 分布式事件将不再是 Linearizability [1] 的&#xff0c;因此必然会存在物理时间上的收件乱序。借用 D…

个人博客建站方案推荐

1.服务器选择 正值双十一来临之际各大服务器提供商又大量的优惠活动&#xff0c;各位要步入个人站长行列的小哥们时机要把握好了&#xff0c;我个人使用过阿里云的服务器&#xff0c;腾讯云的服务器&#xff0c;华为云的服务器。其实&#xff0c;个人感觉就放个博客&#xff0c…

linux系统下nginx安装目录和nginx.conf配置文件目录

linux系统下nginx安装目录和nginx.conf配置文件目录 1、查看nginx安装目录 输入命令 # ps -ef | grep nginx 返回结果包含安装目录 root 2662 1 0 07:12 ? 00:00:00 nginx: master process /usr/sbin/nginx 2、查看nginx.conf配置文件目录 输入命令 # nginx…

android启用hdcp_如何在Android上启用优先收件箱(和设置仅重要通知)

android启用hdcpYesterday Google released an updated Gmail application for Android 2.2 phones that supports the Priority Inbox feature—and more importantly, allows you to change your notifications to only alert you for important email. Let’s take a look. …

.Net CLR GC plan_phase二叉树和Brick_table

楔子Plan_Phase(GC的计划阶段)很早就接触了&#xff0c;但是后面一直没用到&#xff0c;忘记了&#xff0c;此次又用到了&#xff0c;几乎忘光了&#xff0c;费了很大力气理解它&#xff0c;记录下&#xff0c;以免又忘记了。主题计划阶段(plan_phase)主要就两个部分&#xff0…

Vijos p1484 ISBN号码

描述每一本正式出版的图书都有一个ISBN号码与之对应&#xff0c;ISBN码包括9位数字、1位识别码和3位分隔符&#xff0c;其规定格式如“x-xxx-xxxxx-x”&#xff0c;其中符号“-”就是分隔符&#xff08;键盘上的减号&#xff09;&#xff0c;最后一位是识别码&#xff0c;例如0…

scrapy爬虫启示录-小伙子老夫看你血气方刚这本《爬虫秘录》就传给你了

文章来源&#xff1a; IT源点 第一章 误入歧途 每个学习爬虫的人都有一颗爱美的心&#xff0c;俺也是一样的。那么多的美眉图片&#xff0c;不薅下来&#xff0c;没了谁负责。于是夜里孤枕难眠的老男孩开始了他的撸码之旅。从此在学习爬虫&#xff0c;学习Python的道路上越走…

自己设置假期的日历控件_在假期旅行时使用PC娱乐自己

自己设置假期的日历控件Staying connected may be hard no matter what network you are on, and in flight Wi-Fi isn’t pervasive enough to count on. Here are tips and tricks to keep yourself entertained when unplugged and traveling. 无论您使用什么网络&#xff0…

.Net CLR异常和windows C++ 异常调用栈简析

楔子前面一篇研究了下C异常的&#xff0c;这篇来看下&#xff0c;CLR的异常内存模型&#xff0c;实际上都是一个模型&#xff0c;承继自windows异常处理机制。不同的是&#xff0c;有VC编译器(vcruntime.dll&#xff09;接管的部分&#xff0c;被CLR里面的函数ProcessCLRExcept…

Codeforces936C. Lock Puzzle

给个串&#xff0c;只能用操作shift x表示把后面x个字符翻转后放到串的前面。问s串怎么操作能变t串。n<2000&#xff0c;操作次数<6100。 打VP时这转来转去的有点晕。。。 可以想一种逐步构造的方法&#xff0c;即从一个小的完成构造的部分通过一顿操作&#xff0c;在不影…

公共服务领域英文译写规范_公共领域日:对版权和公共领域重要性的思考

公共服务领域英文译写规范The first of the year is Public Domain Day, a day intended to call attention to copyright issues and the public domain. At the Center for the Study of the Public Domain they have an interesting (and sobering) review of works that wo…

Elasticsearch 实战经验总结

Centos7下es 7.7.0安装配置 怎么安装使用elasticsearch-head插件 用logstash同步Mysql数据到ES Springboot使用ES官方推荐方式REST Client整合ES实现关键词高亮 ELK-Elasticsearch&#xff0c;Logstash&#xff0c;kibana搭建基于日志文件的日志分析系统 设置elasticsearc…

.Net 7 的 AOT 和 CLR有什么区别?

楔子&#xff1a;AOT和 CLR的区别是什么呢&#xff1f;大部分人肯定会说&#xff0c;一个编译成本地机器码&#xff08;Native Code&#xff09;&#xff0c;一个是JIT即时编译的结果。这么说&#xff0c;其实也对&#xff0c;但是不具体。具体应该怎么看呢&#xff1f;AOTAOT实…

接入amazon avs_每日新闻综述:亚马逊将互联网接入推向全球的宏伟计划

接入amazon avsPlus Snap’s big push to stay relevant, Amazon’s Alexa-powered AirPods alternatives, more Android Q news, and a lot more. It’s time to talk about the biggest, coolest, or generally most interesting stories from the last 24 hours. 加上Snap保…

计算的未来

我自己倒是后来也是觉得我自己可以想象一个未来的技术&#xff0c;就是以后的编程的语言和库可以抽象现在的一些高级语言的关键字。比如要写一个编辑器的时候&#xff0c;只要给点这些东西的数据结构和数据流向&#xff0c;而一些什么很繁琐的一些底层编码都是可以用高级语言来…

nginx 实用配置问题总结

配置 tomcat&#xff0c;nginx&#xff0c;解决 post 请求超时问题nginx 跨域问题 CORS policy: No Access-Control-Allow-Originnginx 配置静态验证文件&#xff0c;报 404&#xff0c;解决方案nginx 获取用户真实 IPcentos 部署 php 网站方法-使用 nginx ssl https

零部件分类属性

离散制造业的研发、生产跟产品零部件紧密联系在一起&#xff0c;从企业业务流程来说零部件涉及研发、采购、仓储、生产、质量、售后和配件等多个部门&#xff0c;为了更好地管理零部件&#xff0c;下面我们一起来看看零部件概念及分类。1、按行业属性分类&#xff08;1&#xf…

键盘忍者:使用单个热键弹出Vista日历

We’ve covered how to access the Windows Vista Calendar using the keyboard, but what if you wanted to assign a single keystroke to pop up the calendar? Yeah, sure, you can just click it with the mouse, but where’s the geek fun in that? 我们已经介绍了如何…