English version doc for the integration design of APISIX eureka.

# Integration service discovery registry

## Summary

When system traffic changes, the number of servers of the downstream service 
also increases or decreases, or the server needs to be replaced due to its 
hardware failure. If the gateway maintains downstream service information 
through configuration, the maintenance costs in the microservices architecture 
pattern are unpredictable. Furthermore, due to the untimely update of these 
information, will also bring a certain impact for the business, and the impact 
of human error operation can not be ignored. So it is very necessary for the 
gateway to automatically get the latest list of service instances through the 
service registry??As shown in the figure below??


1. When the service starts, it will report some of its information, such as the 
service name, IP, port and other information to the registry. The services 
communicate with the registry using a mechanism such as a heartbeat, and if the 
registry and the service are unable to communicate for a long time, the 
instance will be cancel.When the service goes offline, the registry will delete 
the instance information.
2. The gateway gets service instance information from the registry in near-real 
time.
3. When the user requests the service through the gateway, the gateway selects 
one instance from the registry for proxy.

Common registries: Eureka, Etcd, Consul, Zookeeper, Nacos etc.

## Enabled discovery client

Add the following configuration to `conf/config.yaml` file and select one 
discovery client type which you want:

```yaml
apisix:
  discovery: eureka
```

The supported discovery client: Eureka.

## Configuration for discovery client

Once the registry is selected, it needs to be configured.

### Configuration for Eureka

Add following configuration in `conf/config.yaml` ??

```yaml
eureka:
  host:                            # it's possible to define multiple eureka 
hosts addresses of the same eureka cluster.
    - "http://${usename}:${passowrd}@${eureka_host1}:${eureka_port1}";
    - "http://${usename}:${passowrd}@${eureka_host2}:${eureka_port2}";
  prefix: "/eureka/"
  weight: 100                      # default weight for node
  enable_metadata: false
  timeout:
    connect: 2000
    send: 2000
    read: 5000
```


**Tip**?? It would be even better if these configurations could be moved to the 
configuration center for management.

## Upstream setting

Here is an example of routing a request with a uri of "/user/*" to a service 
which named "user-service"  in the registry :

```shell
$ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: 
edd1c9f034335f136f87ad84b625c8f1' -X PUT -i -d '
{
    "uri": "/user/*",
    "upstream": {
        "service_name": "USER-SERVICE",
        "type": "roundrobin"
    }
}'

HTTP/1.1 201 Created
Date: Sat, 31 Aug 2019 01:17:15 GMT
Content-Type: text/plain
Transfer-Encoding: chunked
Connection: keep-alive
Server: APISIX web server

{"node":{"value":{"uri":"\/user\/*","upstream": {"service_name": 
"USER-SERVICE", "type": 
"roundrobin"}},"createdIndex":61925,"key":"\/apisix\/routes\/1","modifiedIndex":61925},"action":"create"}
```

*Notice**??When configuring `upstream.service_name`,  `upstream.nodes` will no 
longer take effect, but will be replaced by 'nodes' obtained from the registry.

## How do I extend the discovery client?

It is very easy for APISIX to extend the discovery client. Let's take Eureka as 
an example.

### 1. the code structure of discovery client

First, add 'eureka.lua' in the 'lua/apisix/discovery/' directory;

Then implement the 'init_worker' function for initialization and the 'nodes' 
function for obtaining the list of service instance nodes in' eureka.lua':

  ```lua
  local _M = {
      version = 1.0,
  }


  function _M.nodes(service_name)
      ... ...
  end


  function _M.init_worker()
      ... ...
  end


  return _M
  ```

### 2. How convert Eureka's instance data to APISIX's node?

Here's an example of Eureka's data??

```json
{
  "applications": {
      "application": [
          {
              "name": "USER-SERVICE",                 # service name
              "instance": [
                  {
                      "instanceId": "192.168.1.100:8761",
                      "hostName": "192.168.1.100",
                      "app": "USER-SERVICE",          # service name
                      "ipAddr": "192.168.1.100",      # IP address
                      "status": "UP",
                      "overriddenStatus": "UNKNOWN",
                      "port": {
                          "$": 8761,
                          "@enabled": "true"
                      },
                      "securePort": {
                          "$": 443,
                          "@enabled": "false"
                      },
                      "metadata": {
                          "management.port": "8761",
                          "weight": 100               # Setting by 
'eureka.instance.metadata-map.weight' of the spring boot application
                      },
                      "homePageUrl": "http://192.168.1.100:8761/";,
                      "statusPageUrl": 
"http://192.168.1.100:8761/actuator/info";,
                      "healthCheckUrl": 
"http://192.168.1.100:8761/actuator/health";,
                      ... ...
                  }
              ]
          }
      ]
  }
}
```

Deal with the Eureka's instance data need the following steps :

1. select the UP instance. When the value of `overriddenStatus` is "UP" or the 
value of `overriddenStatus` is "UNKNOWN" and the value of `status` is "UP".
2. IP address. The `ipAddr` is the IP address of instance; and must be IPv4 or 
IPv6.
3. Port. If the value of `port["@enabled"]` is equal to "true", using the value 
of `port["\$"]`, If the value of `securePort["@enabled"]` is equal to "true", 
using the value of `securePort["\$"]`.
4. Weight. `local weight =  metadata.weight or local_conf.eureka.weight or 100`

By default, the result of this example is as follows:

```json
{
  "192.168.1.100:8761":100
}
```

The configuration of this format, which is very easy and clear for static 
configuration, has obvious disadvantages, such as poor extendibility for 
complex scenarios, such as when you want to customize the routing rules by the 
metadata (e.g., grouping, etc.) information of the instance. To solve this 
problem, we have reserved a switch for users to use, that is, when 
'eureka-enable_metadata' is set to 'true', the result of this example is as 
follows:

```json
[
  {
    "ip" : "192.168.1.100",
    "port" : 8761,
    "weight" : 100,
    "metadata" : {
      "management.port": "8761",
      "weight": 100
    }
  }
]
```

However, the default balancer of APISIX does not support this format yet. In 
addition, the metadata and processing logic may not be the same for different 
users, so users need to customize balancer.


>
> > Ming Wen <[email protected]> ??2020??3??26?????? ????12:10??????
>
> > that will be great, and you can also post the design here instead of PR
> >
> > ~Jarvis.Qiu <[email protected]>??2020??3??26?? ????????11:57??????
> >
> > > just Chinese version now.
> > >
> > >
> > > I need to spend some time translating it??
> > >
> > > ------------------ ???????? ------------------
> > > ??????: "Ming Wen"<[email protected];
> > > ????????: 2020??3??26??(??????) ????11:54
> > > ??????: "dev"<[email protected];
> > >
> > > ????: Re: [DISCUSS] how about the design of APISIX eureka
> integration?
> > >
> > >
> > >
> > > Do you have the English version?
> > >
> > > Thanks,
> > > Ming Wen, Apache APISIX & Apache SkyWalking
> > > Twitter: _WenMing
> > >
> > >
> > > ~Jarvis.Qiu <[email protected] ??2020??3??26?????? ????11:53??????
> > >
> > >  the doc url is : 

> https://github.com/apache/incubator-apisix/blob/170f4650f1faeb454c1ff69ea97fe1287710ec77/doc/discovery-cn.md
> > > 
> >
> https://github.com/apache/incubator-apisix/blob/170f4650f1faeb454c1ff69ea97fe1287710ec77/doc/discovery-cn.md
> > >
> > >
> > > 
> > > 
> > > 
> > >  ------------------ ???????? ------------------
> > >  ??????: "Ming Wen"<[email protected];
> > >  ????????: 2020??3??26??(??????) ????11:49
> > >  ??????: "dev"<[email protected];
> > > 
> > >  ????: Re: [DISCUSS] how about the design of APISIX eureka
> > > integration?
> > > 
> > > 
> > > 
> > >  bad link, return 404.
> > > 
> > >  Thanks,
> > >  Ming Wen, Apache APISIX &amp; Apache SkyWalking
> > >  Twitter: _WenMing
> > > 
> > > 
> > >  ~Jarvis.Qiu <[email protected] ??2020??3??26?????? ????11:48??????
> > > 
> > >   Hi:

> > > here is a doc 
> > > :https://github.com/apache/incubator-apisix/blob/170f4650f1faeb454c1ff69ea97fe1287710ec77/doc/discovery-cn.mdfor
> > >  the design of APISIX eureka integration.

> > > I hope you can give me some advice.

> > > the PR: https://github.com/apache/incubator-apisix/pull/1281

Reply via email to