In the microservice architecture, a large and complex system is vertically divided into smaller subsystems according to functional or business requirements. These subsystems exist as independently deployed sub-processes and communicate with each other through network calls. How these independently deployed services discover each other has become the first problem to be solved, so there is often a centralized registry in the microservice architecture.

As the core development framework in the Java ecosystem, Spring continues to liberate the productivity of Java developers from Spring MVC to Spring Boot, and Spring Cloud is Spring's answer to the cloud-native era microservice architecture.

In Spring Cloud, Eureka plays the role of the registry. Eureka is a registry service open sourced by Netflix and written in the Java language, which plays an important role in Netflix's infrastructure.

APISIX, as a cloud native microservice API gateway, has already supported etcd as a service discovery at the beginning of its design, and also supports consul, nacos, eureka

As an industry-leading microservice gateway, Apache APISIX provides native support for Eureka. This article will use the Spring Cloud demo project as an example to show you the main functions and features of Apache APISIX docking Eureka service discovery.

Preparation Phase

This demonstration uses the spring-cloud-netflix tutorial officially provided by Spring as an example, which provides the Eureka Server started with SpringBoot as the registration center of Spring Cloud, and we also use the same method to start the Eureka for demonstration. Server. Please visit spring-cloud-samples/eureka for the project address.

The following will introduce you to the relevant code and startup method.

Eureka Server

Spring Cloud provides an annotation of EnableEurekaServer for Eureka, which can directly start an Eureka Server in the way of Spring Boot.

The code example is as follows:

@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {
        public static void main(String[] args) {
                SpringApplication.run(EurekaApplication.class,args);
        }
}

The startup method can directly refer to the following code:

git clone git@github.com:spring-cloud-samples/eureka.git
# 在项目根目录执行
./gradlew bootRun

The resources file in the application.yml directory defines the Eureka Server listening on port 8761 .

server:
  port: 8761

Access the HTTP service of Eureka Client

The client annotation corresponding to EnableEurekaServer is EnableEurekaClient . Using EnableEurekaClient , it is very simple to register an HTTP application started with Spring Boot to Eureka.

Here is the sample code:

@SpringBootApplication
@EnableEurekaClient
@RestController
public class Application {

        @Value("${server.port}")
        int serverPort;

        @RequestMapping("/")
        public String home() {
                return String.format("server-%s",serverPort);
        }

        public static void main(String[] args) {
                new SpringApplicationBuilder(Application.class).web(WebApplicationType.SERVLET).run(args);
        }
        
}

Here we expose an HTTP service on the / path and return the port currently used by Spring Boot, so that we can use different configuration files to start multiple instances to demonstrate the effect of APISIX on load balancing the list of server instances registered with Eureka .

The configuration file is as follows:

spring.application.name=a-bootiful-client #将会作为注册到 Eureka 中的 application name
server.port=8080 # 修改监听端口以启动多个实例

Set the listening ports to 8080 , 8081 , 8082 , and start three Spring Boot instances. After completion, use a browser to access the 8761 port of Eureka Server to view the result of service registration.

img

You can see that three instances are registered under the application A-BOOTIFUL-CLIENT (note: spring.application.name has been converted to uppercase characters), respectively exposing ports 8080 , 8081 , and 8082 , and they are all in the state of UP .

Proxying SpringCloud applications using APISIX

Next, we will implement the request chain as shown in the following figure:

img

Start Apache APISIX

First, you need to find 062300138a2f99 in the configuration file config.yaml of Apache apisix.discovery , modify the relevant configuration of Eureka Server connection information, and finally start APISIX.

    discovery:                       # service discovery center                                                                                                                                                                                                                                                                                                                                                                         
      eureka:                                                                                                                                                                                                                                                                                                                                                                                                                           
        host:                        # it's possible to define multiple eureka hosts addresses of the same eureka cluster.                                                                                                                                                                                                                                                                                                              
          - "http://172.23.79.129:8761" # 通过 Spring Boot 方式启动的 Eureka Server 的访问地址                                                                                                                                                                                                                                                                                                                                                                                             
        prefix: /eureka/                                                                                                                                                                                                                                                                                                                                                                                                                
        fetch_interval: 30           # default 30s                                                                                                                                                                                                                                                                                                                                                                                      
        weight: 100                  # default weight for node                                                                                                                                                                                                                                                                                                                                                                          
        timeout:                                                                                                                                                                                                                                                                                                                                                                                                                        
          connect: 2000              # default 2000ms                                                                                                                                                                                                                                                                                                                                                                                   
          send: 2000                 # default 2000ms                                                                                                                                                                                                                                                                                                                                                                                   
          read: 5000                 # default 5000ms 

Create route

Create a Route and enable the Eureka Service Discovery plugin in Upstream.

curl http://172.30.45.72:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -i -d '
    "uri": "/*",
    "host": "eureka-demo",
    "upstream": {
        "service_name": "A-BOOTIFUL-CLIENT",
        "type": "roundrobin",
        "discovery_type": "eureka"
    }
}'

in:

  • upstream.discovery_type is eureka .
  • upstream.service_name is the application name A-BOOTIFUL-CLIENT registered in Eureka.

request routing

Use the curl command to make multiple requests to verify the load balancing effect.

$ curl http://172.30.45.72:9080/ -H "Host: eureka-demo"
server-8081%
$ curl http://172.30.45.72:9080/ -H "Host: eureka-demo"
server-8080%
$ curl http://172.30.45.72:9080/ -H "Host: eureka-demo"
server-8082%
$ curl http://172.30.45.72:9080/ -H "Host: eureka-demo"
server-8081%
$ curl http://172.30.45.72:9080/ -H "Host: eureka-demo"
server-8080%
$ curl http://172.30.45.72:9080/ -H "Host: eureka-demo"
server-8082%

As can be seen from the above returned results, the requests are allocated to the three instances registered in Eureka in turn. This is because the load balancing algorithm we use is roundrobin , and all backend instances will be allocated requests in turn.

Simulate instance downtime

Close the 8081 instance, simulate the downtime of the instance, and observe the effect of the request.

while true; do curl http://172.30.45.72:9080/ -H "Host: eureka-demo"; echo; sleep 1; done
server-8080
server-8082
server-8081
server-8080
server-8082
server-8081
server-8080
server-8082
server-8080
server-8082
server-8080

It can be seen from the above results that after closing 8081 instance, Apache APISIX will synchronize to the latest instance list of Eureka in time, and then forward the request to the correct backend.

Diagnostic tools

In microservice systems, unexpected forwarding problems are often encountered. The reasons for these problems may come from various links in service discovery, such as: client registration exception, registration center data exception, gateway reading registration data exception, etc. etc., diagnostic tools that can be used in the link when an anomaly occurs will be particularly important.

Therefore, APISIX provides a diagnostic interface in the Service Discovery plug-in, which can easily query the list of services currently being used by the gateway. Combined with the console of the registry, we can quickly diagnose the link from the gateway to the registry.

The diagnostic interface is exposed on port 9090 of the loopback interface by default, and the access mode is GET /v1/discovery/{discovery_type}/dump , for example:

curl http://localhost:9090/v1/discovery/eureka/dump

{
  "services": {
    "A-BOOTIFUL-CLIENT": [
      {
        "weight": 100,
        "metadata": {
          "management.port": "8081"
        },
        "host": "192.168.50.164",
        "port": 8081
      },
      {
        "weight": 100,
        "metadata": {
          "management.port": "8080"
        },
        "host": "192.168.50.164",
        "port": 8080
      },
      {
        "weight": 100,
        "metadata": {
          "management.port": "8082"
        },
        "host": "192.168.50.164",
        "port": 8082
      }
    ]
  },
  "config": {
    "prefix": "\/eureka\/",
    "timeout": {
      "connect": 2000,
      "send": 2000,
      "read": 5000
    },
    "fetch_interval": 30,
    "host": [
      "http:\/\/172.23.79.129:8761"
    ],
    "weight": 100
  }
}

In this way, the Eureka data that APISIX is using is queried.

Summarize

Spring Cloud is a widely popular microservice framework, and Apache APISIX provides the ability to handle Spring Cloud application traffic by supporting Eureka Service Discovery. We can see that the close integration of these two ecosystems makes the implementation of the microservice architecture change. It is simpler and more efficient, so that business development can focus more on business value.

For more instructions and complete configuration information about the eureka plugin, please refer to the Eureka official website documentation: eureka .

The Apache APISIX project is currently developing additional plugins to support integrating more services, if you are interested, you can start a discussion on GitHub Discussions , or communicate on the mailing list .


API7_技术团队
99 声望47 粉丝

API7.ai 是一家提供 API 处理和分析的开源基础软件公司,于 2019 年开源了新一代云原生 API 网关 -- APISIX 并捐赠给 Apache 软件基金会。此后,API7.ai 一直积极投入支持 Apache APISIX 的开发、维护和社区运营...