We define a configuration group in the plugin configuration that includes each data center and the services within it. It allows to configure a separate upstream for each service, while using the datacenter-level upstream as a fallback.
When the request arrives, we parse the content of the source Host and extract the target data center and services from it.
Then it will read that desired upstream from our predefined list of upstreams and set it as the upstream for this request. In this process, the request header and request body will be sent directly to the target service without being modified.
-
Install the plugin to APISIX and add it to the plugin list.
-
Create some upstreams for testing
## data center level
curl -XPUT 'http://127.0.0.1:9080/apisix/admin/upstreams/test_dc1' \
--header 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \
--header 'Content-Type: application/json' \
--data-raw '{
"nodes": {
"httpbin.org:80": 1
},
"type": "roundrobin"
}'## service level #1
curl -XPUT 'http://127.0.0.1:9080/apisix/admin/upstreams/test_dc1_service1' \
--header 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \
--header 'Content-Type: application/json' \
--data-raw '{
"nodes": {
"httpbin.org:80": 1
},
"type": "roundrobin"
}'## service level #2
curl -XPUT 'http://127.0.0.1:9080/apisix/admin/upstreams/test_dc1_service2' \
--header 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \
--header 'Content-Type: application/json' \
--data-raw '{
"nodes": {
"httpbin.org:80": 1
},
"type": "roundrobin"
}'All the upstream nodes above are configured as httpbin.org, for your testing you can replace them with other services.
- Create route for testing
You can see that we configured a data center with one services, and data center and service is configured with upstream. One of the upstream test_dc1_service2 is not configured as a service object, so it will fallback to the data center level.
Tip: In order to avoid nested upstreams that lead to overly complex configuration structures, this plugin only allows the use of upstream_id.
curl -XPUT 'http://127.0.0.1:9080/apisix/admin/routes/1' \
--header 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \
--header 'Content-Type: application/json' \
--data-raw '{
"uri": "/*",
"plugins": {
"multi-dc": {
"data_centers": {
"destination-datacenter1": {
"services": {
"example-application1": {
"upstream_id": "test_dc1_service1"
}
},
"upstream_id": "test_dc1"
}
}
}
}
}'- let's try it
curl -XGET 'http://127.0.0.1:9080/get' \
--header 'Host: example-application.destination-datacenter1-dci.source-datacenter.example.com'Note that host, the host above was originally example-application-destination-datacenter1-dci, but we didn't actually have the ability to perform a regular expression on this to extract the service name and data center name, so I modified it to the above format with the service name and data center name using . split.
{
"args": {},
"headers": {
"Accept": "*/*",
"Host": "example-application.destination-datacenter1-dci.source-datacenter.example.com",
"User-Agent": "curl/7.81.0",
"X-Amzn-Trace-Id": "Root=1-6332c583-70c3c9c0446464c00a25c91c",
"X-Forwarded-Host": "example-application.destination-datacenter1-dci.source-datacenter.example.com"
},
"origin": "127.0.0.1",
"url": "http://example-application.destination-datacenter1-dci.source-datacenter.example.com/get"
}