Demonstration of Spring Cloud Alibaba integrated architecture

Posted by tapdancingtenor on Thu, 27 Jan 2022 14:29:27 +0100


Spring Cloud is a comprehensive microservice framework set, which integrates the implementation of functions such as service registration and discovery, configuration center, message bus, load balancing, circuit breaker, API gateway and so on. On the Internet, it is often found that Spring Cloud and Alibaba's Dubbo make a choice and comparison. In fact, this is not very appropriate. The former is a relatively complete architecture scheme, while Dubbo is only a service governance and RPC implementation scheme.
Dubbo has a very large user group in China, but its surrounding facilities and components are not so perfect. Many developers and users hope to enjoy the ecology of Spring Cloud, so there will be some cases and methods of using Spring Cloud with Dubbo, but most of the use schemes of integrating Spring Cloud with Dubbo have not been perfect all the time. This problem was not solved until the emergence of Spring Cloud Alibaba.
Before that, we have learned how to use Spring Cloud Alibaba to integrate Nacos and Spring Cloud applications, and under this, we can use Ribbon or Feign to collaborate between microservices like traditional Spring Cloud applications. Since Feign is a call based on Http Restful, the performance under high concurrency is not ideal. Can the RPC scheme be switched to Dubbo? Can some components of Spring Cloud and Ali system be perfectly integrated?

1. Overall structure

The system architecture is as follows:

1. Component description:

  • API gateway: unified system entrance, shielding architecture, internal structure, unified security interception, implemented by Zuul.
  • application-1: application 1, simulates an application and provides http interface services.
  • service-1: microservice 1, which simulates microservices and provides dubbo interface services.
  • service-2: microservice 2, which simulates microservices and provides dubbo interface services.

2. Call process:
All requests to access the system must pass through the gateway. The gateway forwards the Http request to application-1. Application-1 uses dubbo to call service1 to complete its own business, and then sevice1 calls service2 to complete its own business. So far, all component penetrations have been completed.
3. What is the difference between application and sevice in the architecture?

  • Service provides basic service functions; application assembles basic service functions and provides services directly available to users.
  • service has small granularity and basic functions, and is not easy to change; application provides upstream business functions, adheres to business requirements and is prone to change.
  • Form the overall architecture of service supporting application, and add changeable applications without even changing the service.

2. Description of engineering structure

Description of engineering structure

3. Create parent project Nacos micro service

The pom file of Nacos micro service is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.demo.nacos</groupId>
    <artifactId>nacos‐micro‐service</artifactId>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>api‐gateway</module>
        <module>application‐1</module>
        <module>service‐1</module>
        <module>service‐2</module>
    </modules>
    <packaging>pom</packaging>

    <properties>
        <project.build.sourceEncoding>UTF‐8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF‐8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.1.2.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-dependencies -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-dependencies -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.1.3.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-commons-dependencies</artifactId>
                <version>2.1.3.RELEASE</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

4. Implement application1

application1 belongs to the application layer and provides http interface services.
(1) Initialize Maven project of application-1

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>nacos‐micro‐service</artifactId>
        <groupId>com.demo.nacos</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>application‐1</artifactId>

    <dependencies>
        <dependency>
            <groupId>com.demo.nacos</groupId>
            <artifactId>service‐1‐api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-dubbo</artifactId>
        </dependency>
    </dependencies>

</project>

(2) Implementation of application-1 function

package com.demo.microservice.application1;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

package com.demo.microservice.application1.controller;

import com.demo.microservice.service1.api.ConsumerService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Description:
 * DATE: 2022/1/27 10:47
 */
@RestController
public class Application1Controller {

    private static final Logger log = LoggerFactory.getLogger(Application1Controller.class);

    @org.apache.dubbo.config.annotation.Reference
    private ConsumerService consumerService;

    @GetMapping("/service")
    public String service(){
        log.info("get into servcie method...");
        String service = consumerService.service();
        return "test|"+service ;
    }
}

(3) application1 configuration
Pure dubbo service consumers, the configuration looks simpler.
Define bootstrap yml

server:
  port: 56020 #Start port command line injection
  servlet:
    context‐path: /application1 #Configure the context of the access path url
spring:
  application:
    name: application1
  main:
    allow‐bean‐definition‐overriding: true # Spring Boot 2.1 needs to be set
  cloud:
    nacos:
      discovery:
        server‐addr: 127.0.0.1:8848
        namespace: 20dd9cd5-8ce6-4f73-8380-dfa3074ce5a8
        cluster‐name: DEFAULT
      config:
        server‐addr: 127.0.0.1:8848 # Configuration center address
        file‐extension: yaml
        namespace: 20dd9cd5-8ce6-4f73-8380-dfa3074ce5a8 # development environment 
        group: NACOS_MICROSERVICE_GROUP # xx business group

(4) application1 startup

package com.demo.microservice.application1;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

/**
 * Description:
 * DATE: 2022/1/27 10:49
 */
@SpringBootApplication
@EnableDiscoveryClient
public class Application1Bootstrap {
    public static void main(String[] args) {
        SpringApplication.run(Application1Bootstrap.class,args);
    }
}

When Service1Bootstrap is started, application 1 will appear in the Nacos console interface.

5. Implement Service1

5.1. Define parent project

Define service1 parent project, POM The XML is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>nacos‐micro‐service</artifactId>
        <groupId>com.demo.nacos</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>service‐1</artifactId>
    <packaging>pom</packaging>
    <modules>
        <module>service‐1‐api</module>
        <module>service‐1‐server</module>
    </modules>
</project>

5.2 define service-1-api

In order to facilitate other services to call dubbo services, api projects are specially defined, which will be relied on by other projects as jar s.
Define the service-1-api project, POM The XML is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>service‐1</artifactId>
        <groupId>com.demo.nacos</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>service‐1‐api</artifactId>

</project>

Define service interface:

package com.demo.microservice.service1.api;

/**
 * Description:
 * DATE: 2022/1/27 11:09
 */
public interface ConsumerService {
    public String service();
}

5.3. Implement service-1-server

(1) Initialize the service-1-server Maven project
Similar to the Maven project of the service provider, relevant Maven dependencies need to be added:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>service‐1</artifactId>
        <groupId>com.demo.nacos</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>service‐1‐server</artifactId>

    <dependencies>
        <dependency>
            <groupId>com.demo.nacos</groupId>
            <artifactId>service‐1‐api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>com.demo.nacos</groupId>
            <artifactId>service‐2‐api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-dubbo</artifactId>
        </dependency>
    </dependencies>

</project>

(2) Implement Dubbo service

package com.demo.microservice.service1.service;

import com.demo.microservice.service1.api.ConsumerService;
import com.demo.microservice.service2.api.ProviderService;

/**
 * Description:
 * DATE: 2022/1/27 11:13
 */
@org.apache.dubbo.config.annotation.Service
public class ConsumerServiceImpl implements ConsumerService {

    @org.apache.dubbo.config.annotation.Reference
    ProviderService providerService;

    @Override
    public String service() {
        String service = providerService.service();
        return "Consumer invoke |"+service;
    }
}

Note: use @ org apache. dubbo. config. annotation. Service tag Dubbo service
(3) Configure Dubbo service
As a consumer of Dubbo service, Service2 is configured similarly to the service provider. Note that service1 is not only a consumer, but also a service provider:

server:
  port: ${port:56030} #Start port command line injection

spring:
  application:
    name: service1
  main:
    allow‐bean‐definition‐overriding: true # Spring Boot 2.1 needs to be set
  cloud:
    nacos:
      discovery:
        server‐addr: 127.0.0.1:8848
        namespace: 20dd9cd5-8ce6-4f73-8380-dfa3074ce5a8
        cluster‐name: DEFAULT
      config:
        server‐addr: 127.0.0.1:8848 # Configuration center address
        file‐extension: yaml
        namespace: 20dd9cd5-8ce6-4f73-8380-dfa3074ce5a8 # development environment 
        group: NACOS_MICROSERVICE_GROUP # xx business
dubbo:
  scan:
    # dubbo service scanning benchmark package
    base‐packages: com.demo.microservice
  protocol:
    # dubbo agreement
    name: dubbo
    # dubbo protocol port
    port: ${dubbo_port:20881}
  registry:
    address: nacos://127.0.0.1:8848
    application:
      qos‐enable: false #Whether dubbo operation and maintenance service is enabled
    consumer:
      check: false #Whether to check the dependent services at startup

In the above YAML content, the beginning of dubbo is the configuration of dubbo service:

  • dubbo. scan. Base packages: specify the scanning benchmark package of Dubbo service implementation class, which will be sent to @ org. Org apache. dubbo. config. annotation. The service marked by the service annotation is exposed as a Dubbo service.
  • dubbo. Protocol: the protocol configuration exposed by Dubbo service, where the sub attribute name is the protocol name and port is the Dubbo protocol port. Multiple protocols can be specified, such as Dubbo protocol. rmi. port=1099
  • dubbo. Registry: Dubbo service registry configuration, where the value of the sub attribute address“ nacos://127.0.0.1:8848 ”, indicating that Dubbo service is registered with Nacos
  • It is equivalent to < dubbo: Registry address = "10.20.153.10:9090" / > in the xml configuration of the native dubbo

The upper part is the related configuration of spring cloud:

  • spring. application. Name: spring application name, which is used for Spring Cloud service registration and discovery. This value is regarded as Dubbo under the blessing of Dubbo Spring Cloud application. Name, so there is no need to configure Dubbo application. name
  • spring. cloud. nacos. Discovery: Nacos service discovery and registration configuration, where the sub attribute server addr specifies the Nacos server host and port
  • spring. cloud. nacos. Config: the configuration of the Nacos configuration center, where the sub attribute server addr specifies the host and port of the Nacos server.

(4) Start the service consumer application

package com.demo.microservice.service1;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

/**
 * Description:
 * DATE: 2022/1/27 11:19
 */
@SpringBootApplication
@EnableDiscoveryClient
public class Service1Bootstrap {
    public static void main(String[] args) {
        SpringApplication.run(Service1Bootstrap.class, args);
    }
}

When Service1Bootstrap is started, application service1 will appear in the Nacos console interface.
Start successfully. Observe the list of nacos services

6. Implement application1 to call Service

Now service1 has exposed the dubbo service and registered it in nacos. Next, implement application1 and call service1

6.1. Reference service1

service1 is referenced in application1 below
In POM Introducing service-1-api dependency into XML

<dependency>
    <groupId>com.demo.nacos</groupId>
    <artifactId>service‐1‐api</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

Spring cloud starter Dubbo dependency is introduced, which will generate proxy objects according to the interface

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>

6.2. Realize remote call

package com.demo.microservice.application1.controller;

import com.demo.microservice.service1.api.ConsumerService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Description:
 * DATE: 2022/1/27 10:47
 */
@RestController
public class Application1Controller {

    private static final Logger log = LoggerFactory.getLogger(Application1Controller.class);

    @org.apache.dubbo.config.annotation.Reference
    private ConsumerService consumerService;

    @GetMapping("/service")
    public String service(){
        log.info("get into servcie method...");
        String service = consumerService.service();
        return "test|"+service ;
    }
}

Note: Note: the @ reference annotation here is org apache. dubbo. config. annotation. Reference
Test:
Request: http://localhost:56020/application1/service
consumerService normally generates proxy objects, and service1 is called.

7. Implement Service2

As shown in the above design, Service2 needs to expose the dubbo interface for service1 consumption. If you want to integrate and use it in Spring cloud Alibaba
dubbo.

7.1. Define parent project

Define service2 parent project, POM The XML is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>nacos‐micro‐service</artifactId>
        <groupId>com.demo.nacos</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>service‐2</artifactId>
    <packaging>pom</packaging>
    <modules>
        <module>service‐2‐api</module>
        <module>service‐2‐server</module>
    </modules>
</project>

7.2. Define service-2-api

Define the service-2-api project, POM The XML is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>service‐2</artifactId>
        <groupId>com.demo.nacos</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>service‐2‐api</artifactId>

</project>

And define the service interface. The Dubbo service interface is the remote communication contract between the service provider and the consumer, which is usually declared by the ordinary Java interface, such as the ProviderService interface:

package com.demo.microservice.service2.api;

/**
 * Description:
 * DATE: 2022/1/27 11:40
 */
public interface ProviderService {
    String service();
}

7.3. Implement service-2-server

(1) Initialize the service-2-server Maven project
First, create a Maven project with artifactId named service-2-server and add it in its POM Add the necessary dependencies of Dubbo Spring Cloud to the XML file:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>service‐2</artifactId>
        <groupId>com.demo.nacos</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>service‐2‐server</artifactId>

    <dependencies>
        <dependency>
            <groupId>com.demo.nacos</groupId>
            <artifactId>service‐2‐api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-dubbo</artifactId>
        </dependency>
    </dependencies>

</project>

The above dependent artifact s are described as follows:

  • service-2-api: the artifact that provides the ProviderService interface
  • Spring boot starter Web: spring boot starter artifact, which indirectly introduces spring boot artifact
  • Spring cloud starter Dubbo: Dubbo spring cloud starter artifact, which indirectly introduces Dubbo spring bootstarter and other artifacts
  • Spring cloud starter Alibaba Nacos discovery: Nacos spring cloud service registration and discovery artifact

(2) Implement Dubbo service

ProviderService is an exposed Dubbo service interface, and the service provider service-2-server needs to implement it:

package com.demo.microservice.service2.service;

import com.demo.microservice.service2.api.ProviderService;

/**
 * Description:
 * DATE: 2022/1/27 11:47
 */
@org.apache.dubbo.config.annotation.Service
public class ProviderServiceImpl implements ProviderService {
    @Override
    public String service() {
        return "Provider invoke";
    }
}

Where, @ org apache. dubbo. config. annotation. Service is a Dubbo service annotation, which only declares that the Java service (local) is implemented as a Dubbo service. Therefore, the next step is to configure it to Dubbo service (remote).

(3) Configure Dubbo service
In terms of exposing Dubbo services, it is recommended that developers externalize the configuration, that is, specify the scanning benchmark package of Java service implementation classes.

Meanwhile, Dubbo remote service needs to expose the network port and set the communication protocol. The complete YAML configuration is as follows:

server:
  port: ${port:56040} #Start port command line injection

spring:
  application:
    name: service2
  main:
    allow‐bean‐definition‐overriding: true # Spring Boot 2.1 needs to be set
  cloud:
    nacos:
      discovery:
        server‐addr: 127.0.0.1:8848
        namespace: 20dd9cd5-8ce6-4f73-8380-dfa3074ce5a8
        cluster‐name: DEFAULT
      config:
        server‐addr: 127.0.0.1:8848 # Configuration center address
        file‐extension: yaml
        namespace: 20dd9cd5-8ce6-4f73-8380-dfa3074ce5a8 # development environment 
        group: NACOS_MICROSERVICE_GROUP # xx business
dubbo:
  scan:
    # dubbo service scanning benchmark package
    base‐packages: com.demo.microservice
  protocol:
    # dubbo agreement
    name: dubbo
    # dubbo protocol port
    port: ${dubbo_port:20891}
  registry:
    address: nacos://127.0.0.1:8848
    application:
      qos‐enable: false #Whether dubbo operation and maintenance service is enabled
    consumer:
      check: false #Whether to check the dependent services at startup

(4) Start service provider app
Dubbo Spring Cloud boot class is no different from ordinary Spring Cloud applications, as shown below:

package com.demo.microservice.service2;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

/**
 * Description:
 * DATE: 2022/1/27 11:49
 */
@SpringBootApplication
@EnableDiscoveryClient
public class Service2Bootstrap {
    public static void main(String[] args) {
        SpringApplication.run(Service2Bootstrap.class, args);
    }
}

Before booting Service2Bootstrap, please start the Nacos server in advance. When Service2Bootstrap is started, application service2 will appear in the Nacos console interface.

8. Implement service1 and call service2

8.1 reference service2

Add the dependency of service-2-api in pom file of service-1-server:

<dependency>
     <groupId>com.demo.nacos</groupId>
     <artifactId>service‐2‐api</artifactId>
     <version>1.0-SNAPSHOT</version>
 </dependency>

8.2. Realize remote call

package com.demo.microservice.service1.service;

import com.demo.microservice.service1.api.ConsumerService;
import com.demo.microservice.service2.api.ProviderService;

/**
 * Description:
 * DATE: 2022/1/27 11:13
 */
@org.apache.dubbo.config.annotation.Service
public class ConsumerServiceImpl implements ConsumerService {

    @org.apache.dubbo.config.annotation.Reference
    ProviderService providerService;

    @Override
    public String service() {
        String service = providerService.service();
        return "Consumer invoke |"+service;
    }
}

Test:
Request: http://localhost:56020/application1/service
application1 calls service1, and service1 calls service2

9. Implement API gateway

9.1 introduction to Zuul

What is a gateway?
In the original single architecture, all services are local, and the UI can be called directly. Now it is divided into independent services according to functions, running in independent Java processes that are generally on independent virtual machines. How is the client UI accessed? His background has N services. The front desk needs to remember to manage N services. When a service goes offline / updated / upgraded, the front desk needs to be redeployed, which obviously does not serve our concept of splitting. Especially when the current station is a mobile application, the pace of business change is usually faster. In addition, the call of N small services is also a large network overhead.

With the gateway as the unified service entrance, the above problems can be avoided. Moreover, the service gateway sets a barrier in front of the micro service. The request comes to the service gateway first, and the gateway will process the request such as filtering, verification and routing. With the service gateway, the security of the micro service can be improved. The gateway verifies the legitimacy of the request. If the request is illegal, it will be intercepted and access will be denied.

  • Provide a unified service entrance to make the micro service transparent to the front desk
  • Aggregate background services to save traffic and improve performance
  • Provide API management functions such as security, filtering and flow control
    1. What is Zuul?
    Spring Cloud Zuul is a microservice gateway integrated with the Zuul open source project of Netflix company. It realizes the functions of request routing, load balancing, verification filtering and so on.
    official: https://github.com/Netflix/zuul
    2. How do Zuul and Nginx work together?
    Zuul and Nginx need to be used together in actual projects. As shown in the figure below, Nginx is used for reverse proxy and load balancing, and zuul is used to ensure micro services
    Secure access to services, intercept microservice requests, verify legitimacy and load balancing.

9.2. Gateway construction

Initialize API gateway Maven project

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>nacos‐micro‐service</artifactId>
        <groupId>com.demo.nacos</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>api‐gateway</artifactId>

    <dependencies>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
    </dependencies>

</project>

9.3 API gateway configuration

server:
  port: 56010 #Start port command line injection
spring:
  application:
    name: api-gateway
  main:
    allow‐bean‐definition‐overriding: true # Spring Boot 2.1 needs to be set
  cloud:
    nacos:
      discovery:
        server‐addr: 127.0.0.1:8848
        namespace: 20dd9cd5-8ce6-4f73-8380-dfa3074ce5a8
        cluster‐name: DEFAULT
      config:
        server‐addr: 127.0.0.1:8848 # Configuration center address
        file‐extension: yaml
        namespace: 20dd9cd5-8ce6-4f73-8380-dfa3074ce5a8 # development environment 
        group: NACOS_MICROSERVICE_GROUP # xx business group

The routing configuration of gateway adopts the remote configuration of nacos, and API gateway is added in the development environment of nacos console Yaml configuration set, configuration group is
TEST_GROUP, the configuration contents are as follows:

zuul:
  routes:
    application1:
      stripPrefix: false
      path: /application1/**

Route the request starting with / application1 / to the application1 service and keep / application1 / in the request url.

9.4. API gateway startup

Note: use the @ EnableZuulProxy annotation on the startup class to identify this project as a Zuul gateway. The startup class code is as follows:

package com.demo.nacos;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

/**
 * Description:
 * DATE: 2022/1/27 14:34
 */
@SpringBootApplication
@EnableDiscoveryClient
@EnableZuulProxy
public class ApiGatewayBootstrap {
    public static void main(String[] args) {
        SpringApplication.run(ApiGatewayBootstrap.class, args);
    }
}

When Service1Bootstrap is started, the application API gateway will appear in the list of Nacos services.

Test:
The application 1 application is requested through the API gateway, and the service implementation of application 1 runs through service1 and service2 http://127.0.0.1:56010/application1/service , the following results will be obtained:

Attachment: Spring Cloud Nacos discovery Starter configuration item information description

Topics: Spring Cloud architecture Nacos