istio.io/archive/v0.1/docs/tasks/rate-limiting.html

44 lines
19 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="en" itemscope itemtype="https://schema.org/WebPage" style="overflow-y: scroll;"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><meta name="title" content="Enabling Rate Limits"><meta name="og:title" content="Enabling Rate Limits"><meta name="og:image" content="/v0.1/img/logo.png"/><meta name="description" content="This task shows you how to use Istio to dynamically limit the traffic to a service."><meta name="og:description" content="This task shows you how to use Istio to dynamically limit the traffic to a service."><title>Istioldie 0.1 / Enabling Rate Limits</title><script> window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date; ga('create', 'UA-98480406-2', 'auto'); ga('send', 'pageview'); </script> <script async src='https://www.google-analytics.com/analytics.js'></script><link href='https://fonts.googleapis.com/css?family=Roboto:400,100,100italic,300,300italic,400italic,500,500italic,700,700italic,900,900italic' rel='stylesheet' type='text/css'><link rel="alternate" type="application/rss+xml" title="Istio Blog RSS" href="/v0.1/feed.xml"><link rel="apple-touch-icon" href="/v0.1/favicons/apple-touch-icon.png" sizes="180x180"><link rel="icon" type="image/png" href="/v0.1/favicons/android-chrome-96x96.png" sizes="96x96" ><link rel="icon" type="image/png" href="/v0.1/favicons/favicon-32x32.png" sizes="32x32"><link rel="icon" type="image/png" href="/v0.1/favicons/favicon-16x16.png" sizes="16x16"><link rel="manifest" href="/v0.1/favicons/manifest.json"><link rel="mask-icon" href="/v0.1/favicons/safari-pinned-tab.svg" color="#2DA6B0"><meta name="msapplication-TileColor" content="#ffffff"><meta name="msapplication-TileImage" content="/v0.1/favicons/mstile-150x150.png"><link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet"><link rel="stylesheet" href="/v0.1/css/all.css"><link rel="stylesheet" href="/v0.1/css/prism.css"><link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script></head><body class="language-unknown"><div class="nav-hero-container" style="z-index: 200000;"><nav id="header-nav" class="navbar navbar-inverse" role="navigation"><div class="container"><div class="row"><div class="col-md-11 nofloat center-block "><div class="navbar-header"> <button type="button" class="hamburger navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse-1" aria-expanded="false"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="/v0.1/"><div> <img src="/v0.1/img/logo.png" alt="Istio" width="36px" height="54px"/> <span class="brand-name">Istioldie 0.1</span></div></a></div><div class="collapse navbar-collapse" id="navbar-collapse-1"><ul class="nav navbar-nav navbar-right"><li><a href="/v0.1/about/" >About</a></li><li><a href="/v0.1/docs/" class='current'>Docs</a></li><li><a href="/v0.1/blog/" >Blog</a></li><li><a href="/v0.1/community/" >Community</a></li><li><a href="/v0.1/faq/" >FAQ</a></li><li class="dropdown"> <a class="dropdown-toggle" data-toggle="dropdown" href=""> <i class='fa fa-lg fa-cog'></i> <span class="caret"></span> </a><ul class="dropdown-menu"><h6 class="dropdown-header">Other versions of this site</h6><li> <a href="https://istio.io">Current Release</a></li><li> <a href="https://preliminary.istio.io">Next Release</a></li><li> <a href="https://archive.istio.io">Older Releases</a></li></ul></li><li><form name="cse" id="searchbox_demo" class="navbar-form navbar-right" role="search"> <input type="hidden" name="cx" value="013699703217164175118:iwwf17ikgf4" /> <input type="hidden" name="ie" value="utf-8" /> <input type="hidden" name="hl" value="en" /><div class="form-group"><div class="input-group"> <input name="q" class="form-control" type="text" size="30" /><div class="input-group-addon"> <span class="btn-search glyphicon glyphicon-search"></span></div></div></div></form> <script type="text/javascript" src="https://www.google.com/cse/brand?form=searchbox_demo"></script></li></ul></div></div></div></div></nav></div><div class="container"><div class="row"><div class="col-md-11 nofloat center-block" style="margin-top: 3px;"><ul class="col-sm-10 nav nav-tabs"><li role="presentation" ><a href="/v0.1/docs/index.html">Welcome</a></li><li role="presentation" ><a href="/v0.1/docs/concepts/index.html">Concepts</a></li><li role="presentation" class='active'><a href="/v0.1/docs/tasks/index.html">Tasks</a></li><li role="presentation" ><a href="/v0.1/docs/samples/index.html">Samples</a></li><li role="presentation" ><a href="/v0.1/docs/reference/index.html">Reference</a></li></ul></div></div></div><script src="/v0.1/js/navtree.js"></script><div class="container docs"><div class="row"><div class="col-md-11 nofloat center-block"><div class="row"><div id="sidebar-container" class="col-sm-3"><ul class="doc-side-nav"><li><h5 class='doc-side-nav-title'>Tasks</h5></li><script type="text/javascript"> var docs = []; docs.push({path: [ "basic-access-control.md", ], url: "/docs/tasks/basic-access-control.html", title: "Enabling Simple Access Control", order: 90, overview: "This task shows how to use Istio to control access to a service."}); docs.push({path: [ "egress.md", ], url: "/docs/tasks/egress.html", title: "Enabling Egress Traffic", order: 40, overview: "Describes how to configure Istio to route traffic from services in the mesh to external services."}); docs.push({path: [ "fault-injection.md", ], url: "/docs/tasks/fault-injection.html", title: "Fault Injection", order: 60, overview: "This task shows how to inject delays and test the resiliency of your application."}); docs.push({path: [ "index.md", ], url: "/docs/tasks/index.html", title: "Tasks", order: 20, overview: "Tasks show you how to do a single specific targeted activity with the Istio system."}); docs.push({path: [ "ingress.md", ], url: "/docs/tasks/ingress.html", title: "Enabling Ingress Traffic", order: 30, overview: "Describes how to configure Istio to expose a service outside of the service mesh."}); docs.push({path: [ "installing-istio.md", ], url: "/docs/tasks/installing-istio.html", title: "Installing Istio", order: 10, overview: "This task shows you how to setup the Istio service mesh."}); docs.push({path: [ "integrating-services-into-istio.md", ], url: "/docs/tasks/integrating-services-into-istio.html", title: "Integrating Services into the Mesh", order: 20, overview: "This task shows you how to integrate your applications with the Istio service mesh."}); docs.push({path: [ "istio-auth.md", ], url: "/docs/tasks/istio-auth.html", title: "Testing Istio Auth", order: 100, overview: "This task shows you how to verify and test Istio-Auth."}); docs.push({path: [ "metrics-logs.md", ], url: "/docs/tasks/metrics-logs.html", title: "Collecting Metrics and Logs", order: 110, overview: "This task shows you how to configure Mixer to collect metrics and logs from Envoy instances."}); docs.push({path: [ "rate-limiting.md", ], url: "/docs/tasks/rate-limiting.html", title: "Enabling Rate Limits", order: 80, overview: "This task shows you how to use Istio to dynamically limit the traffic to a service."}); docs.push({path: [ "request-routing.md", ], url: "/docs/tasks/request-routing.html", title: "Configuring Request Routing", order: 50, overview: "This task shows you how to configure dynamic request routing based on weights and HTTP headers."}); docs.push({path: [ "request-timeouts.md", ], url: "/docs/tasks/request-timeouts.html", title: "Setting Request Timeouts", order: 70, overview: "This task shows you how to setup request timeouts in Envoy using Istio."}); docs.push({path: [ "zipkin-tracing.md", ], url: "/docs/tasks/zipkin-tracing.html", title: "Distributed Request Tracing", order: 120, overview: "How to configure the proxies to send tracing requests to Zipkin"}); genNavBarTree(docs) </script></ul></div><div id="tab-container" class="col-xs-1 tab-neg-margin pull-left"> <a id="sidebar-tab" class="glyphicon glyphicon-chevron-left" href="javascript:void 0;"></a></div><div id="content-container" class="thin-left-border col-sm-9 markdown"><div id="toc" class="toc"></div><div id="doc-content"><h1>Enabling Rate Limits</h1><p>This task shows you how to use Istio to dynamically limit the traffic to a service.</p><h2 id="before-you-begin">Before you begin</h2><ul><li><p>Setup Istio by following the instructions in the <a href="./installing-istio.html">Installation guide</a>.</p></li><li><p>Deploy the <a href="/v0.1/docs/samples/bookinfo.html">BookInfo</a> sample application.</p></li><li><p>Initialize the application version routing to direct <code>reviews</code> service requests from test user “jason” to version v2 and requests from any other user to v3.</p><pre><code class="language-bash">istioctl create -f samples/apps/bookinfo/route-rule-reviews-test-v2.yaml
istioctl create -f samples/apps/bookinfo/route-rule-reviews-v3.yaml
</code></pre><blockquote><p>Note: if you have conflicting rule that you set in previous tasks, use <code>istioctl replace</code> instead of <code>istioctl create</code>.</p></blockquote></li></ul><h2 id="rate-limits">Rate limits</h2><p>Istio enables users to rate limit traffic to a service.</p><p>Consider <code>ratings</code> as an external paid service like Rotten Tomatoes® with <code>1qps</code> free quota. Using Istio we can ensure that <code>1qps</code> is not breached.</p><ol><li><p>Point your browser at the BookInfo <code>productpage</code> (http://$GATEWAY_URL/productpage).</p><p>If you log in as user “jason”, you should see black ratings stars with each review, indicating that the <code>ratings</code> service is being called by the “v2” version of the <code>reviews</code> service.</p><p>If you log in as any other user (or logout) you should see red ratings stars with each review, indicating that the <code>ratings</code> service is being called by the “v3” version of the <code>reviews</code> service.</p></li><li><p>Configure mixer with the rate limit.</p><p>Save this as ratelimit.yaml:</p><pre><code class="language-yaml">rules:
- aspects:
- kind: quotas
params:
quotas:
- descriptorName: RequestCount
maxAmount: 1
expiration: 1s
</code></pre><p>and then run the following command:</p><pre><code class="language-bash">istioctl mixer rule create global ratings.default.svc.cluster.local -f ratelimit.yaml
</code></pre><p><code>istioctl</code> sets configuration for <code>subject=ratings.default.svc.cluster.local</code></p></li><li><p>Generate load on the <code>productpage</code> with the following command:</p><pre><code class="language-bash">while true; do curl -s -o /dev/null http://$GATEWAY_URL/productpage; done
</code></pre></li><li><p>Refresh the <code>productpage</code> in your browser.</p><p>While the load generator is running (i.e., generating more than 1 req/s), the traffic generated by your browser will be rate limited. Notice that if you log in as user “jason” or any other user, the <code>reviews</code> service is unable to access the <code>ratings</code> service, so you stop seeing stars, red or black.</p></li></ol><h2 id="conditional-rate-limits">Conditional rate limits</h2><p>In the previous example we applied a rate limit to the <code>ratings</code> service without regard to any other attributes. It is possible to conditionally apply rate limits based on attributes like the source of the traffic.</p><p>The following configuration applies a <code>1qps</code> rate limit only to version <code>v3</code> of <code>reviews</code>.</p><ol><li><p>Configure mixer with the conditional rate limit.</p><p>Save this as ratelimit-conditional.yaml:</p><pre><code class="language-yaml">rules:
- selector: source.labels["app"]=="reviews" &amp;&amp; source.labels["version"] == "v3"
aspects:
- kind: quotas
params:
quotas:
- descriptorName: RequestCount
maxAmount: 1
expiration: 1s
</code></pre><p>and then run the following command:</p><pre><code class="language-bash">istioctl mixer rule create global ratings.default.svc.cluster.local -f ratelimit-conditional.yaml
</code></pre><p>Notice the rule is the same as the previous example, only this one uses a <code>selector</code> to apply the ratelimit only for requests from <code>reviews:v3</code>.</p></li><li><p>Generate load on the <code>productpage</code> with the following command:</p><pre><code class="language-bash">while true; do curl -s -o /dev/null http://$GATEWAY_URL/productpage; done
</code></pre></li><li><p>Refresh the <code>productpage</code> in your browser.</p><p>As in the previous example, while the load generator is running (i.e., generating more than 1 req/s), the traffic generated by your browser will be rate limited, but this time only if the request is from <code>reviews:v3</code>. Notice that this time if you log in as user “jason” (the <code>reviews:v2</code> user) you will continue to see the black ratings stars. Only the other users will stop seeing the red ratings stars while the load generator is running.</p></li></ol><h2 id="understanding-rate-limits">Understanding rate limits</h2><p>In the preceding examples we saw how Mixer applies rate limits to requests that match certain conditions.</p><p>Every distinct rate limit configuration represents a counter. If the number of requests in the last <code>expiration</code> duration exceed <code>maxAmount</code>, Mixer returns a <code>RESOURCE_EXHAUSTED</code> message to the proxy. The proxy in turn returns status <code>HTTP 429</code> to the caller.</p><p>Multiple rate limits may apply to the same request.</p><p>Mixer <code>MemQuota</code> adapter uses a sliding window of sub second resolution to enforce rate limits.</p><p>Consider the following example</p><pre><code class="language-yaml">descriptorName: RequestCount
maxAmount: 5000
expiration: 5s
labels:
label1: target.service
</code></pre><p>This defines a set of counters with a limit of <code>5000</code> per every <code>5 seconds</code>. Individual counters within the set are identified by unique keys. A key is formed on the request path by using all parameters of the configuration. Here we introduce the notion of labels that enable creation of more granular counter keys. When a request arrives at Mixer with <code>target.service=ratings</code> it forms the following counter key.</p><p><code>$aspect_id;RequestCount;maxAmount=5000;expiration=5s;label1=ratings</code></p><p>Using <code>target.service</code> in the counter key enables independent rate limits for every service. In absence of <code>target.service</code> as part of the key, the same counter location is used by all services resulting in combined rate limit of <code>5000</code> requests per <code>5 seconds</code></p><p>Mixer supports an arbitrary number of labels by defining <code>QuotaDescriptors</code>.</p><pre><code class="language-yaml">name: RequestCount
rate_limit: true
labels:
label1: 1 # STRING
</code></pre><p>Here we define <code>RequestCount</code> quota descriptor that takes 1 string label. We recommend using meaningful label names even though label names are arbitrary.</p><pre><code class="language-yaml">name: RequestCount_byService_byUser
rate_limit: true
labels:
service: 1 # STRING
user: 1 # STRING
</code></pre><p>Mixer expects <code>user,service</code> labels when the <code>RequestCount_byService_byUser</code> descriptor is used and produces the following config validation error if any labels are missing.</p><pre><code class="language-bash">* quotas: aspect validation failed: 1 error occurred:
* quotas[RequestCount_byService_byUser].labels: wrong dimensions: descriptor expects 2 labels, found 0 labels
</code></pre><h2 id="cleanup">Cleanup</h2><ul><li><p>Remove the mixer configuration rule:</p><pre><code class="language-bash">istioctl mixer rule create global ratings.default.svc.cluster.local -f samples/apps/bookinfo/mixer-rule-empty-rule.yaml
</code></pre><blockquote><p>Note: removing a rule by setting an empty rule list is a temporary workaround because <code>istioctl delete</code> does not yet support mixer rules.</p></blockquote></li><li><p>Remove the application routing rules:</p><pre><code>istioctl delete -f samples/apps/bookinfo/route-rule-reviews-test-v2.yaml
istioctl delete -f samples/apps/bookinfo/route-rule-reviews-v3.yaml
</code></pre></li></ul><h2 id="whats-next">Whats next</h2><ul><li><p>Learn more about <a href="/v0.1/docs/concepts/policy-and-control/mixer.html">Mixer</a> and <a href="/v0.1/docs/concepts/policy-and-control/mixer-config.html">Mixer Config</a>.</p></li><li><p>Discover the full <a href="/v0.1/docs/reference/config/mixer/attribute-vocabulary.html">Attribute Vocabulary</a>.</p></li><li><p>Read the reference guide to <a href="/v0.1/docs/reference/writing-config.html">Writing Config</a>.</p></li><li><p>If you are not planning to explore any follow-on tasks, refer to the <a href="/v0.1/docs/samples/bookinfo.html#cleanup">BookInfo cleanup</a> instructions to shutdown the application and cleanup the associated rules.</p></li></ul></div></div></div></div></div></div><script src="/v0.1/js/sidemenu.js"></script><footer><div class="container"><div class="row"><div class="col-md-2"></div><div class="col-md-3 col-sm-4 col-xs-12 center-block"><ul class="toggle"><p class="header">Docs</p><li><a href="/v0.1/docs/">Welcome</a></li><li><a href="/v0.1/docs/concepts">Concepts</a></li><li><a href="/v0.1/docs/tasks">Tasks</a></li><li><a href="/v0.1/docs/samples">Samples</a></li><li><a href="/v0.1/docs/reference">Reference</a></li></ul></div><hr class="footer-sections" /><div class="col-md-3 col-sm-4 col-xs-12 center-block"><ul class="toggle"><p class="header">Resources</p><li><a href="/v0.1/faq">Frequently Asked Questions</a></li><li><a href="/v0.1/troubleshooting">Troubleshooting Guide</a></li><li><a href="/v0.1/bugs">Report a Bug</a></li><li><a href="https://github.com/istio/istio.github.io/issues/new?title=Issue with _docs/tasks/rate-limiting.md">Report a Doc Issue</a></li><li><a href="https://github.com/istio/istio.github.io/edit/master/_docs/tasks/rate-limiting.md">Edit This Page on GitHub</a></li></ul></div><hr class="footer-sections" /><div class="col-md-3 col-sm-4 col-xs-12 center-block"><ul class="toggle"><p class="header">Community</p><li><a href="https://groups.google.com/forum/#!forum/istio-users" target="_blank"><span class="group">User</span></a> | <a href="https://groups.google.com/forum/#!forum/istio-dev" target="_blank">Dev Mailing Lists</a></li><li><a href="https://twitter.com/IstioMesh" target="_blank"><span class="twitter">Twitter</span></a></li><li><a href="https://github.com/istio/istio" target="_blank"><span class="github">GitHub</span></a></li></ul></div><div class="col-md-1"></div></div><div class="row"><p class="description small text-center"> Copyright &copy; 2017 Istio Authors<br> Istio 0.1<br> Archived on 20-Jul-2017</p></div></div></footer><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.15.0/jquery.validate.min.js"></script> <script src="/v0.1/js/jquery.form.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script> <script src="/v0.1/js/slick.min.js"></script> <script src="/v0.1/js/jquery.visible.min.js"></script> <script src="/v0.1/js/common.js" type="text/javascript" charset="utf-8"></script> <script src="/v0.1/js/buttons.js"></script> <script src="/v0.1/js/search.js"></script> <script src="/v0.1/js/prism.js"></script></body></html>