Service
Services hold the upstream and plugins that several routes share.
serviceWhat a service is
A service holds what several routes have in common: the instances their requests go to, as nodes of its own or a shared upstream, and the plugins every one of them runs. A route that chooses Service under Target sends its requests to the service's instances and runs the service's plugins beside its own.
Where a route carries the same plugin as its service, the route's own copy is used on that route. How G8 handles a request shows where the service sits between the route and your backend.
When to use it
- Several routes reach the same backend instances, for example
orders-apiandorders-v1for the orders backend, and you want to list the instances once. - Every route of one backend needs the same plugins, for example one request limit, and you want to add them in one place.
- A client's requests should be counted over several routes together, not on each route apart.
- Every route of one backend should answer only the host names the backend serves.
Not for plugins that run on every request of the environment, whatever the route — see Global rule (Global rules run their plugins on every request the engine handles) or plugins that routes share while each keeps instances of its own — see Plugin config (Plugin configs hold a set of plugins that several routes reference).
Guides
Pages that walk through a job with a service, step by step.
- Share plugins between routesPut the routes of one backend on a service so they share its backend nodes and its plugins.
Set it up
Give the routes of the orders backend its two instances and one request limit
orders-api and orders-v1 choose Service under Target and pick orders: their requests go to its two nodes, and its request limit counts each client address once over both routes.
Under General set Name to orders and set Description to The orders backend, for every route that reaches it. Under Target choose Nodes on this service and fill Upstream as in the JSON below. Once it is created, open its Plugins tab and add limit-count with its settings from the JSON below.
{
"name": "orders",
"desc": "The orders backend, for every route that reaches it",
"upstream": {
"type": "roundrobin",
"nodes": {
"10.0.1.10:8080": 1,
"10.0.1.11:8080": 1
}
},
"plugins": {
"limit-count": {
"count": 100,
"time_window": 60,
"key": "remote_addr",
"rejected_code": 429
}
}
}
What you will see
- Repeated requests to orders-api are all answered
200, and the two backend nodes share them, as each node's own log shows, and each answer carriesX-RateLimit-Limit: 100from the service's limit-count, though the route carries no limit of its own. - The same client on orders-v1 is counted in the same 100: after four requests to orders-api, its first request to orders-v1 is answered with
X-RateLimit-Remaining: 95. - Where orders-v1 carries a limit-count of its own, with a Count of 20, its answers carry
X-RateLimit-Limit: 20: the route's copy is used instead of the service's. - Its requests are then counted apart from the service's: requests to orders-v1 do not lower the
X-RateLimit-Remainingthat orders-api answers with.
More scenarios
Group the routes of a service whose instances DNS answers
DNS discovery must be enabled in the gateway's static configuration first; without it every request is refused with 503.
Under General set Name to orders-discovered. Under Target choose Nodes on this service and fill Upstream as in the JSON below.
{
"name": "orders-discovered",
"upstream": {
"type": "roundrobin",
"discovery_type": "dns",
"service_name": "orders.internal.example.com:8080"
}
}
Group routes on a backend that expects its own host name
With verification on, the certificate of the node must be valid for orders.example.com, the name the request now carries.
Under General set Name to orders-public. Under Target choose Nodes on this service and fill Upstream as in the JSON below.
{
"name": "orders-public",
"upstream": {
"type": "roundrobin",
"scheme": "https",
"nodes": {
"10.0.1.20:443": 1
},
"pass_host": "rewrite",
"upstream_host": "orders.example.com",
"tls": {
"verify": true
}
}
}
Group the checkout routes with session affinity
Requests that carry the same session_id cookie reach the same instance; one without the cookie is placed by its client address instead, so that client, and every client behind the same address, always reaches the same instance.
Under General set Name to checkout. Under Target choose Nodes on this service and fill Upstream as in the JSON below.
{
"name": "checkout",
"upstream": {
"type": "chash",
"hash_on": "cookie",
"key": "session_id",
"nodes": {
"10.0.1.10:8080": 1,
"10.0.1.11:8080": 1
}
}
}
Group routes on an upstream that ramps added instances up
An instance added to the list later starts at 10 percent of its weight of 100 and reaches the whole of it over 60 seconds; the instances present when the upstream is created take their full share from the start.
Under General set Name to orders-warmed. Under Target choose Nodes on this service and fill Upstream as in the JSON below.
{
"name": "orders-warmed",
"upstream": {
"type": "roundrobin",
"nodes": {
"10.0.1.10:8080": 100,
"10.0.1.11:8080": 100
},
"warm_up_conf": {
"slow_start_time_seconds": 60,
"min_weight_percent": 10,
"interval": 5
}
}
}
Serve only api.example.com on every route of the orders service
A route on the service that lists no Hosts of its own takes the service's.
Under General set Name to orders. Under Matching fill Hosts as in the JSON below. Under Target choose Nodes on this service and fill Upstream as in the JSON below.
{
"name": "orders",
"hosts": [
"api.example.com"
],
"upstream": {
"type": "roundrobin",
"nodes": {
"10.0.1.10:8080": 1,
"10.0.1.11:8080": 1
}
}
}
What you will see
- Requests for api.example.com are all answered
200, some by the first instance and some by the second. - A route on the service that lists no Hosts of its own answers no other host: a request for shop.example.com is answered
404 Route Not Found.
Things to know
- The engine assigns the
idwhen the object is created; it is not the name, and it is what other objects refer to. - Plugins — A limit-count on the service keeps one count for each client address over every route on it: requests to
orders-apiand toorders-v1draw on the same 100. - Plugins — Where a route carries the same plugin as its service, the route's copy is used on that route, with its own settings and its own count. A route with a limit of 20 of its own is counted by it, and its requests are not counted in the service's 100.
- Plugins — The service's other plugins still run on such a route: a route with cors settings of its own also carries the limit the service adds.
- Hosts — A route on the service that lists no Hosts of its own takes the service's: a request for any other host is then answered
404 Route Not Found. - Each gateway node keeps the count of a limit-count on its own unless its Policy points at Redis, so with two nodes a client can get up to 100 on each.
- A service that routes still use cannot be deleted: g8 refuses the delete while they still use it. Move each route to another target first.
- AdvicePut every route of one backend on its service rather than leaving some with nodes of their own, so that the instances and the shared plugins are changed in one place.
Settings
The fields as the console shows them, section by section. A field under “When … is …” is there only while that value is set. A field that holds the settings of another kind links to that kind’s page.
General
namestringRequireddescstringlabelsobjectKey and value pairs of your own, for grouping and filtering. They change nothing about traffic. An object whose keys are any name, each with a string as its value.
Matching
Routes that use this service inherit these rules.
hostsarray of stringsLeave empty to match any host. A leading * matches subdomains, for example *.example.com.
Target
Where requests to routes of this service are sent.
Choose one:
Upstream
upstream_idstring or integerpattern
^[a-zA-Z0-9-_.]+$Nodes on this service
upstreamobjectHas the settings of an upstream, kept here and shared with nothing; each field is described on that page.
enable_websocketbooleanLets a matching request upgrade the connection to WebSocket.
Plugins
Plugins on this service are managed in the Plugins tab once the service exists.
pluginsobjectThe plugins of this service, keyed by plugin name. The engine runs them by their priority, not by the order they are written in.