What does Dubbo want to do with a gateway? Try to integrate Spring Cloud Gateway

1, Background

In the microservice architecture, API gateway is very important. As a global traffic portal, the gateway is not only a reverse route, but also a public "service" (Gateway) to extract the common needs of various edge services (Web layer), such as security authentication, authority control, current limiting and fusing, monitoring, cross domain processing, aggregation of API documents and other public functions.

 

In the microservice architecture built by dubbo framework system, you want to add API gateway. If you don't want to develop by yourself, there are few mainstream gateways supporting dubbo protocol in the current open source community, but there are two very popular open source API gateways to choose under Spring Cloud system. This paper mainly introduces how to integrate Spring Cloud Gateway with Nacos dubbo service.

 

2, Traditional dubbo architecture

dubbo belongs to rpc call, so it must provide a web layer service as an http entry to the client to call, and provide basic functions such as security authentication on it, while the web layer is faced with Nginx and other reverse agents for unified entry and load balancing.

The web layer is generally segmented according to the business module, which is used to aggregate the service services that a business module depends on

PS: can we integrate all the web layers in the figure above into an API gateway? (not recommended)

Because this kind of web layer does not implement the generalized call, it must introduce the api dependency of all dubbo services, which will make the gateway very unstable. Any change of service interface needs to modify the api dependency in the gateway!

 

3, Integrating Srping Cloud Gateway

Now let's talk about whether it is feasible to use the popular Srping Cloud Gateway as the gateway of dubbo architecture. First, the API gateway is one of the components of Spring Cloud architecture. To integrate dubbo, we need to solve the following problems:

  1. Get through the registration center: spring cloud gateway needs to discover downstream services through the registration center, and dubbo also needs to register and discover services through the registration center. If the two registration centers can't get through, it will become a dual registration center architecture, which is very complex!
  2. Protocol conversion: gateway uses http transport protocol to call downstream services, while dubbo service uses tcp transport protocol by default

The first problem mentioned above is "getting through the registration center". At present, dubbo supports Zookeeper and Nacos, while Spring Cloud has basically supported all mainstream registration centers since @ EnableEurekaClient was changed to @ EnableDiscoveryClient. In this paper, Nacos will be used as the registration center to get through the two

 

3.1. Mode 1

Replace the Nginx in the traditional dubbo architecture with the Spring Cloud Gateway, and move the common functions such as security authentication to the gateway for implementation

Because the web layer service itself provides the http interface, the gateway layer does not need to make protocol conversion, but because the security authentication moves forward to the gateway, it needs to be isolated by the network to prevent being bypassed by the web layer behind the direct request of the gateway

 

3.2. Mode 2

dubbo service itself modifies or adds the support of rest transport protocol, so that the gateway can communicate with dubbo service through http transport protocol

Rest transport protocol: Based on standard Java REST API -- rest call support implemented by JAX-RS 2.0

The current version of dubbo supports 10 transport protocols, such as dubbo, rest, rmi, hessian, http, webservice, thrift, redis, etc., and also supports the definition of multiple protocols for the same service at the same time. For example, if you configure protocol = {"dubbo", "rest"}, the service supports both dubbo and rest transport protocols

 

3.3. Summary

Mode 1 has one more layer of Web services, so there is one more network call overhead, but the advantage is that their respective responsibilities are clear and single. The web layer can be used as the aggregation layer to aggregate multiple service services, and the results are returned to the front end through fusion processing, so this architecture can greatly reduce the cyclic dependence of services

 

4, Code practice

Dependent environment

  • lombok
  • jdk 1.8
  • Nacos 1.3
  • Spring Boot 2.2.8.RELEASE
  • Spring Cloud Hoxton.SR5
  • Spring Cloud Alibaba 2.2.1.RELEASE

 

At the root pom.xml Global dependent version defined in

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>8</java.version>

        <spring-boot-dependencies.version>2.2.8.RELEASE</spring-boot-dependencies.version>
        <spring-cloud-dependencies.version>Hoxton.SR5</spring-cloud-dependencies.version>
        <spring-cloud-alibaba-dependencies.version>2.2.1.RELEASE</spring-cloud-alibaba-dependencies.version>
        <jaxrs.version>3.12.1.Final</jaxrs.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot-dependencies.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud-dependencies.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba-dependencies.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

 

4.1. Create Dubbo API project

Define two api interfaces respectively

DubboService services using the dubbo protocol

public interface DubboService {
    String test(String param);
}

RestService service using rest protocol

public interface RestService {
    String test(String param);
}

 

4.2. Create web Dubbo project

Use mode 1 to integrate the docking gateway. In order to simplify the definition of controller layer and service layer under the same service, only the logical layer is used. There is no service splitting

4.2.1. Create configuration

Define spring boot configuration

server:
  port: 8081

spring:
  application:
    name: zlt-web-dubbo
  main:
    allow-bean-definition-overriding: true
  cloud:
    nacos:
      server-addr: 192.168.28.130:8848
      username: nacos
      password: nacos

server.port : configure the port exposed by the application server

spring.cloud.nacos : configure the parameters related to the registration center of spring cloud. The configuration of Nacos needs to be changed to the one corresponding to its own environment

Define dubbo configuration

dubbo:
  scan:
    base-packages: org.zlt.service
  protocols:
    dubbo:
      name: dubbo
      port: -1
  registry:
    address: spring-cloud://localhost
  consumer:
    timeout: 5000
    check: false
    retries: 0
  cloud:
    subscribed-services:

dubbo.scan.base-packages: Specifies the scanning benchmark package of Dubbo service implementation class

dubbo.protocols : the protocol configuration exposed by the service, in which the sub attribute name is the protocol name and the port is the protocol port (- 1 refers to the self increasing port, starting from 20880)

dubbo.registry.address : Dubbo service registry configuration, where the value of the sub property address“ spring-cloud://localhost ", note mount to Spring Cloud registry

 

4.2.2. Create the implementation class of DubboService

Specify using dubbo protocol to define service through protocol = "dubbo"

@Service(protocol = "dubbo")
public class DubboServiceImpl implements DubboService {
    @Override
    public String test(String param) {
        return "dubbo service: " + param;
    }
}

 

4.2.3. Create Controller class

Using Spring Boot's @ RestController annotation to define web Services

@RestController
public class WebController {
    @Autowired
    private DubboService dubboService;

    @GetMapping("/test/{p}")
    public String test(@PathVariable("p") String param) {
        return dubboService.test(param);
    }
}

 

4.3. Create rest Dubbo project

Use mode 2 to integrate the docking gateway. Because the service creates rest service through dubbo, you do not need to use the Spring Boot built-in application service

4.3.1. Create configuration

Define spring boot configuration

spring:
  application:
    name: zlt-rest-dubbo
  main:
    allow-bean-definition-overriding: true
  cloud:
    nacos:
      server-addr: 192.168.28.130:8848
      username: nacos
      password: nacos

Because you do not use the built-in application service of Spring Boot, you do not need to specify server.port

Define dubbo configuration

dubbo:
  scan:
    base-packages: org.zlt.service
  protocols:
    dubbo:
      name: dubbo
      port: -1
    rest:
      name: rest
      port: 8080
      server: netty
  registry:
    address: spring-cloud://localhost
  consumer:
    timeout: 5000
    check: false
    retries: 0
  cloud:
    subscribed-services:

dubbo.protocols : configure two protocols, in which rest protocol defines port 8080 and uses netty as application server

 

4.3.2. Create the implementation class of RestService

Specify to use rest protocol to define service through protocol = "rest"

@Service(protocol = "rest")
@Path("/")
public class RestServiceImpl implements RestService {
    @Override
    @Path("test/{p}")
    @GET
    public String test(@PathParam("p") String param) {
        return "rest service: " + param;
    }
}

 

4.4. Create the Spring Cloud Gateway project

Define spring boot configuration

server:
  port: 9900

spring:
  application:
    name: sc-gateway
  main:
    allow-bean-definition-overriding: true
  cloud:
    nacos:
      server-addr: 192.168.28.130:8848
      username: nacos
      password: nacos

server.port : define gateway port as 9090

Define gateway configuration

spring:
  cloud:
    gateway:
      discovery:
        locator:
          lowerCaseServiceId: true
          enabled: true
      routes:
        - id: web
          uri: lb://zlt-web-dubbo
          predicates:
            - Path=/api-web/**
          filters:
            - StripPrefix=1
        - id: rest
          uri: lb://zlt-rest-dubbo
          predicates:
            - Path=/api-rest/**
          filters:
            - StripPrefix=1

Two routing policies are defined:

  • Path / API Web / request web Dubbo project
  • Path / API rest / is the request rest Dubbo project

 

4.5. Testing

Start the Nacos, SC gateway, web Dubbo and rest Dubbo projects respectively, and test the two integration methods through the following two interfaces of the gateway

  1. http://127.0.0.1:9900/api-web/test/abc : request web Dubbo engineering test integration mode 1
  2. http://127.0.0.1:9900/api-rest/test/abc : request rest Dubbo engineering test integration mode II

 

5, demo download

ide needs to install lombok plug-in

https://github.com/zlt2000/dubboSpringCloud

 

Scan the code and pay attention to the surprise!

Tags: Dubbo Spring REST Maven

Posted on Sat, 27 Jun 2020 22:21:41 -0400 by erikjan