Skip to content

Commit

Permalink
Update README on how to enable check cache. (#204)
Browse files Browse the repository at this point in the history
* Update README on how to enable check cache.

* Update the comment.
  • Loading branch information
qiwzhang authored Mar 26, 2017
1 parent 3bcb6c4 commit c93dcc5
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 24 deletions.
38 changes: 34 additions & 4 deletions src/envoy/mixer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ This filter will intercept all HTTP requests and call Mixer. Here is its config:
},
"quota_name": "RequestCount",
"quota_amount": "1",
"check_cache_expiration_in_seconds": "600",
"check_cache_keys": [
"request.host",
"request.path",
Expand All @@ -85,16 +86,23 @@ Notes:
* mixer_server is required
* mixer_attributes: these attributes will be sent to the mixer in both Check and Report calls.
* forward_attributes: these attributes will be forwarded to the upstream istio/proxy. It will send them to mixer in Check and Report calls.
* quota_name, quota_amount are used for making quota call. quota_amount is default to 1 if missing.
* quota_name, quota_amount are used for making quota call. quota_amount defaults to 1.
* check_cache_keys is to cache check calls. If missing or empty, check calls are not cached.

By default, mixer filter forwards attributes and does not invoke mixer server. You can customize this behavior per HTTP route by supplying an opaque config in the route config:
## HTTP Route opaque config
By default, the mixer filter only forwards attributes and does not call mixer server. This behavior can be changed per HTTP route by supplying an opaque config:

```
"opaque_config": {
"routes": [
{
"timeout_ms": 0,
"prefix": "/",
"cluster": "service1",
"opaque_config": {
"mixer_control": "on",
"mixer_forward": "off"
}
}
}
```

This route opaque config reverts the behavior by sending requests to mixer server but not forwarding any attributes.
Expand All @@ -111,3 +119,25 @@ Mixer client can be configured to make Quota call for all requests. If "quota_n
## How to pass some attributes from client proxy to mixer.

Usually client proxy is not configured to call mixer (it can be enabled in the route opaque_config). Client proxy can pass some attributes to mixer by using "forward_attributes" field. Its attributes will be sent to the upstream proxy (the server proxy). If the server proxy is calling mixer, these attributes will be sent to the mixer.


## How to enable cache for Check calls

Check calls can be cached. By default, it is not enabled. It can be enabled by supplying non-empty "check_cache_keys" string list in the mixer filter config. Only these attributes in the Check request, their keys and values, are used to calculate the key for the cache lookup. If it is a cache hit, the cached response will be used.
The cached response will be expired in 5 minutes by default. It can be overrided by supplying "check_cache_expiration_in_seconds" in the mixer filter config. The Check response from the mixer has an expiration field. If it is filled, it will be used. By design, the mixer will control the cache expiration time.

Following is a sample mixer filter config to enable the Check call cache:
```
"check_cache_expiration_in_seconds": "600",
"check_cache_keys": [
"request.host",
"request.path",
"source.labels",
"request.headers/:method",
"origin.user"
]
```

For the string map attributes in the above example:
1) "request.headers" attribute is a string map, "request.headers/:method" cache key means only its ":method" key and value are used for cache key.
2) "source.labels" attribute is a string map, "source.labels" cache key means all key value pairs for the string map will be used.
31 changes: 16 additions & 15 deletions src/envoy/mixer/config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,22 @@ namespace Mixer {
namespace {

// The Json object name for mixer-server.
const std::string kJsonNameMixerServer("mixer_server");
const std::string kMixerServer("mixer_server");

// The Json object name for static attributes.
const std::string kJsonNameMixerAttributes("mixer_attributes");
const std::string kMixerAttributes("mixer_attributes");

// The Json object name to specify attributes which will be forwarded
// to the upstream istio proxy.
const std::string kJsonNameForwardAttributes("forward_attributes");
const std::string kForwardAttributes("forward_attributes");

// The Json object name for quota name and amount.
const std::string kJsonNameQuotaName("quota_name");
const std::string kJsonNameQuotaAmount("quota_amount");
const std::string kQuotaName("quota_name");
const std::string kQuotaAmount("quota_amount");

// The Json object name for check cache keys.
const std::string kJsonNameCheckCacheKeys("check_cache_keys");
const std::string kCheckCacheKeys("check_cache_keys");
const std::string kCheckCacheExpiration("check_cache_expiration_in_seconds");

void ReadString(const Json::Object& json, const std::string& name,
std::string* value) {
Expand Down Expand Up @@ -67,28 +68,28 @@ void ReadStringVector(const Json::Object& json, const std::string& name,
} // namespace

void MixerConfig::Load(const Json::Object& json) {
ReadString(json, kJsonNameMixerServer, &mixer_server);
ReadString(json, kMixerServer, &mixer_server);

ReadStringMap(json, kJsonNameMixerAttributes, &mixer_attributes);
ReadStringMap(json, kJsonNameForwardAttributes, &forward_attributes);
ReadStringMap(json, kMixerAttributes, &mixer_attributes);
ReadStringMap(json, kForwardAttributes, &forward_attributes);

ReadString(json, kJsonNameQuotaName, &quota_name);
ReadString(json, kJsonNameQuotaAmount, &quota_amount);
ReadString(json, kQuotaName, &quota_name);
ReadString(json, kQuotaAmount, &quota_amount);

ReadStringVector(json, kJsonNameCheckCacheKeys, &check_cache_keys);
ReadStringVector(json, kCheckCacheKeys, &check_cache_keys);
ReadString(json, kCheckCacheExpiration, &check_cache_expiration);
}

void MixerConfig::ExtractQuotaAttributes(Attributes* attr) const {
if (!quota_name.empty()) {
attr->attributes[ ::istio::mixer_client::kQuotaName] =
attr->attributes[Attributes::kQuotaName] =
Attributes::StringValue(quota_name);

int64_t amount = 1; // default amount to 1.
if (!quota_amount.empty()) {
amount = std::stoi(quota_amount);
}
attr->attributes[ ::istio::mixer_client::kQuotaAmount] =
Attributes::Int64Value(amount);
attr->attributes[Attributes::kQuotaAmount] = Attributes::Int64Value(amount);
}
}

Expand Down
1 change: 1 addition & 0 deletions src/envoy/mixer/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ struct MixerConfig {

// The attribute names for check cache.
std::vector<std::string> check_cache_keys;
std::string check_cache_expiration;

// Load the config from envoy config.
void Load(const Json::Object& json);
Expand Down
30 changes: 26 additions & 4 deletions src/envoy/mixer/http_control.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,12 @@
#include "src/envoy/mixer/utils.h"

using ::google::protobuf::util::Status;
using ::istio::mixer_client::CheckOptions;
using ::istio::mixer_client::Attributes;
using ::istio::mixer_client::DoneFunc;
using ::istio::mixer_client::MixerClientOptions;
using ::istio::mixer_client::ReportOptions;
using ::istio::mixer_client::QuotaOptions;

namespace Http {
namespace Mixer {
Expand All @@ -45,6 +49,26 @@ const std::string kResponseLatency = "response.latency";
const std::string kResponseSize = "response.size";
const std::string kResponseTime = "response.time";

// Check cache size: 10000 cache entries.
const int kCheckCacheEntries = 10000;
// Default check cache expired in 5 minutes.
const int kCheckCacheExpirationInSeconds = 300;

CheckOptions GetCheckOptions(const MixerConfig& config) {
int expiration = kCheckCacheExpirationInSeconds;
if (!config.check_cache_expiration.empty()) {
expiration = std::stoi(config.check_cache_expiration);
}

// Remove expired items from cache 1 second later.
CheckOptions options(kCheckCacheEntries, expiration * 1000,
(expiration + 1) * 1000);

options.cache_keys = config.check_cache_keys;

return options;
}

void SetStringAttribute(const std::string& name, const std::string& value,
Attributes* attr) {
if (!value.empty()) {
Expand Down Expand Up @@ -110,11 +134,9 @@ void FillRequestInfoAttributes(const AccessLog::RequestInfo& info,

HttpControl::HttpControl(const MixerConfig& mixer_config)
: mixer_config_(mixer_config) {
::istio::mixer_client::MixerClientOptions options;
MixerClientOptions options(GetCheckOptions(mixer_config), ReportOptions(),
QuotaOptions());
options.mixer_server = mixer_config_.mixer_server;
options.check_options.cache_keys.insert(
mixer_config_.check_cache_keys.begin(),
mixer_config_.check_cache_keys.end());
mixer_client_ = ::istio::mixer_client::CreateMixerClient(options);

mixer_config_.ExtractQuotaAttributes(&quota_attributes_);
Expand Down
2 changes: 1 addition & 1 deletion src/envoy/mixer/repositories.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
################################################################################
#

MIXER_CLIENT = "0e6f858bc7b52dc8f143f46ac32afc79d504e8a4"
MIXER_CLIENT = "c5d857e28bfcc53f20f59466b464f99526737545"

def mixer_client_repositories(bind=True):
native.git_repository(
Expand Down

0 comments on commit c93dcc5

Please sign in to comment.