Spring Cloud Alibaba is compatible with both dubbo and openfeign

I. Introduction

Both dubbo and springcloud can be used alone as a microservice governance framework in production, but students who have used springcloud probably know that the relevant components of the springcloud ecosystem have been gradually stopped over the years, which leads to iterations in the evolution of the service architecture Faults, so that the introduction of some new technical components is difficult, so there is an upgraded version of springcloud-alibaba in the domestic market.

2. Comparison between springcloud-alibba and dubbo

2.1 Brief introduction of springcloud-alibaba

Spring Cloud Alibaba is committed to providing a one-stop solution for microservice development. This project contains the necessary components to develop distributed application microservices, so that developers can easily use these components to develop distributed application services through the Spring Cloud programming model.

2.1.1 Introduction of Main Technical Components

springcloud-alibaba provides a wealth of service governance technology components, listed as follows:

  • Sentinel: flow control governance component, which takes traffic as the entry point, and protects the stability of services from multiple dimensions such as flow control, fuse downgrade, and system load protection;
  • Nacos: a dynamic service discovery, distributed configuration management and service management platform that is easier to build cloud-native applications;
  • RocketMQ: An open source distributed messaging system, based on highly available distributed cluster technology, provides low-latency, highly reliable message publishing and subscription services;
  • Dubbo: Apache Dubbo™ is a high-performance Java RPC framework that can be used as a service governance framework alone;
  • Seata: Alibaba's open source product, an easy-to-use high-performance microservice distributed transaction solution;
  • Alibaba Cloud ACM (the fee is equivalent to Nacos): an application configuration center product that centrally manages and pushes application configurations in a distributed architecture environment;
  • Alibaba Cloud OSS: Alibaba Cloud Object Storage Service (OSS for short) is a massive, secure, low-cost, and highly reliable cloud storage service provided by Alibaba Cloud. You can store and access any type of data in any application, anytime, anywhere;
  • Alibaba Cloud SchedulerX: (charged) A distributed task scheduling product developed by the Alibaba middleware team, which provides second-level, accurate, highly reliable, and highly available scheduled (based on Cron expression) task scheduling services;
  • Alibaba Cloud SMS: short message service covering the world, friendly, efficient, and intelligent interconnected communication capabilities, helping enterprises quickly build customer access channels;

Using the combination of the above-mentioned components can better complete the microservice transformation of production-level projects. From the perspective of technological evolution, this set of technical components is also gradually adapting to the pace of cloud-native, so you don’t have to worry about the process of integrating cloud-native in the future. Having trouble getting a problem that doesn't get resolved.

2.1.2 springcloud-alibaba usage scenarios

Springcloud architecture upgrade and transformation

Since some components in the springcloud ecosystem have not been updated for a long time, it is aimed at those scenarios that used native springcloud before but needed deeper optimization, adjustment, and expansion of the architecture.

More complete flow control management

Sentinel in springcloud-alibaba is even better in terms of flow control management. Although springcloud also has hystrix for service degradation, flow control and other functions, the function is still relatively simple.

Centralized management of services and configuration

In springcloud-alibaba, nacos integrates service and configuration management, and provides a more friendly and convenient visual interface for development and operation, which can reduce deployment and operation and maintenance costs, while native springcloud needs to use eureka at the same time and introduce other configurations Common use of management components.

Containerized deployment and cloud native support

Backed by a strong technical team and Alibaba Cloud's support and integration of cloud-native technologies, Spring Cloud Alibaba supports Kubernetes, Docker and other container technologies, which can be easily deployed.

Cross application interface call

Springcloud implements mutual calls between microservices mainly through the http interface, which can be considered for scenarios where different applications are deployed across machines or even across networks.

2.2 Brief introduction of dubbo

Dubbo is Ali's open source distributed service governance framework. Its simple, efficient and convenient use method has won the favor of many architects. The bottom layer uses RPC to call remote services.

dubbo provides three core capabilities:

  • Interface-oriented remote method invocation;
  • Intelligent fault tolerance and load balancing;
  • and service auto-registration and discovery;

2.2.1 dubbo business model

The following picture is the model architecture diagram of dubbo. It is not difficult to see that the architecture mainly includes 4 parts:

  • Registry, service registration center;
  • Provider, service provider, provides service interface for external or other applications;
  • Consumer, the service consumer, calls the service provided by the Provider, calling it like a local;
  • Monitor, service monitoring, generally rarely used;

2.2.2 dubbo usage scenarios

Although dubbo can also be used alone as a framework for microservice governance, and it is widely used in many companies. Compared with springcloud-alibaba, it can be replaced in most scenarios. Regarding the usage scenarios of dubbo, here is a summary of the following A few points for reference;

Microservice architecture transformation

The splitting of services under the microservice architecture is very fine, and the services need to call each other. Dubbo can be used to easily realize the communication between microservices. For the service consumer, it only needs to import the SDK of the provider, just like a local call convenient;

Distributed Systems

In a distributed system, each microservice module needs to cooperate with each other to process tasks. At this time, you can consider using Dubbo as a service call middleware

Internal System Architecture

When calling services between applications at the platform level, using dubbo is more efficient than springcloud in terms of transmission efficiency

High concurrency and high traffic scenarios

The bottom layer of dubbo uses netty. Compared with http, the transmission efficiency is better to a certain extent. Under high concurrency, the advantages of dubbo are more obvious.

Pay more attention to interface-level API governance

dubbo provides a complete service governance technology, based on the idea of ​​service governance, it provides a complete set of solutions such as service discovery, load balancing, fault tolerance mechanism, thread tuning, communication protocol, etc., and the governance at the API level is more friendly and refined

3. Difficulties in Service Transformation

3.1 Technology selection problem

For a slightly larger company-level product, the technical architecture is of course not static, but I believe that many partners can still reach a consensus, that is, for the products of most small and medium-sized companies, the technical architecture is quite long. It is difficult to make major adjustments within a period of time, and the technical architecture is basically finalized after the initial selection. Why do you say that?

3.1.1 The technical style of the technical leader

It can be said that the breadth and depth of the technology stack of the technical leaders of many teams largely determines the architectural tone of a product. Some leaders have a deep understanding of dubbo technology and may choose to use dubbo as the service governance framework from the very beginning. And if you are familiar with springcloud, you may be biased towards springcloud;

3.1.2 Rapid business growth is difficult to determine

In recent years, the concept of DDD has been very popular in the market. In fact, there is still a considerable price to promote the implementation of DDD. This requires the company's business model to be relatively stable, clear, and have certain controllability. If a company's business is in In the rapid expansion, it will be full of more uncertainties. The direct problem brought by the uncertainties is that a reasonable trade-off needs to be made in the selection of the technical architecture. It should not be too complicated, but it must also leave a certain Scalability, leaving room for the expansion of subsequent architectures. Due to business uncertainties, it is difficult to say that adopting that microservice framework is the best model for service governance;

3.1.3 Integration problems of microservice framework

Many students must have encountered such a scenario. For example, your springboot version is 1.5.X, and now you need to upgrade to 2.X version. It seems that it is just a jar package version upgrade problem, but for students who have experience in upgrading , This upgrade process is comparable to learning from the Western Paradise, not to mention the hardships, a lot of pits to fill, and finally go deep into the code level to adjust layer by layer...

Adjustments involving the framework level are also commonplace. For example, your microservice governance framework uses springcloud, but you find it inconvenient to use git for the management of the configuration center, and it always feels unreliable to host the configuration on the external network. It needs to be taken back, or you need to implement unified visual flow control management for each microservice of the entire platform. If you think hystrix in springcloud is not easy to use, you may think of introducing other third-party flow control management components...

The situation above is that if you have a headache, you will treat your head, and if your foot hurts, you will treat your foot. In the end, more and more third-party technical components are introduced into the entire product, the cost of maintenance is getting higher and higher, and more and more manpower is required for deployment and operation and maintenance. , the more terrible thing is that once a problem occurs, the efficiency of solving the problem is very low. The reason is that under the micro-service governance system, the original springcloud framework itself is beginning to be unable to cope with today's increasingly complex service governance needs, so many people begin to consider springcloud-alibaba for integration and structural adjustments.

In fact, although springcloud-alibaba also perfectly supports springcloud and has done a lot of upgrades, in terms of structural adjustment, this is also a considerable amount of transformation work. The main problems are concentrated in the following points:

Incompatible top-level pom dependencies

The root pom adaptation versions of springcloud and springcloud-alibaba are different. It is no exaggeration to say that it is almost impossible for springcloud-alibaba to work with springboot 1.5.X series versions;

Internal components need to be adjusted and compatible

The registration center of springcloud is eureka, and the configuration management of springcloud-alibaba mainly promotes nacos. How to adjust eureka to use nacos? Or continue to use nacos directly in springcloud-alibaba?

Adjustments to the deployment model

springcloud-alibaba is endorsed by the Alibaba technical team, and its deployment model has natural advantages in adapting to containerization and cloud native, while springcloud has lost its competitiveness in this regard, but at the same time, it also gives the technical team Operation and maintenance put forward higher requirements;

Learning costs for team members

Relatively speaking, the technology stack involved in springloud-alibaba is more comprehensive, and the learning cost will be even higher if it is considered to integrate with cloud native in the future, which requires developers to master more new skills. This cost cannot be ignored .

3.2 Integration problem of dubbo and springcloud

As the advantages of dubbo in microservice governance become more and more obvious, the governance system of springcloud-alibaba is also taking great pains to be able to eat it all. For a practical scenario, if your current team uses springcloud-alibaba With this set of frameworks, ribbon or openfeign is naturally indispensable for RPC calls between services;

Take openfeign as an example. For service consumers, it is very convenient and smooth to use. When calling remote services, it is as simple as calling local services. However, from the perspective of governance and control of a single API service, regardless of Whether it is openfeign or ribbon, neither is very friendly, and even for governance, you need to rely on external means, such as agents, or coding methods, or other external components for service monitoring. What is more terrible is that if all internal The service is called by openfeign. In high concurrency scenarios, this performance problem will be exposed to some extent;

So the architect or technical director thought that it would be great if dubbo could be used. After all, dubbo is still very good at API-level service governance and provides a complete set of governance solutions. But it is unrealistic to directly kill openfeign and replace dubbo. If there are many microservice modules, it is not just a matter of transforming one or two applications.

Therefore, further thinking, can a compromise solution be adopted to introduce dubbo on the existing basis, that is, to support the calls of openfeign and dubbo at the same time? This consideration seems to be feasible, and it is also a relatively reasonable solution. In fact, many products also follow this idea when making structural adjustments. In order to get rid of the old ones, introduce new technologies, and then let the old and new coexist for a period of time before gradually discarding them. old technology.

With the above scenarios and solutions as the background, the following is a practical case to demonstrate the completion process of using springcloud-alibaba to integrate dubbo and openfeign.

Fourth, springcloud-alibaba integrates openfeign

4.1 Pre-preparation

In order to facilitate the later tests, create a database in advance and create a data table for testing. The name of the database is: dbuser01, and the table sql is as follows:

CREATE TABLE `user` (
  `id` varchar(32) NOT NULL,
  `user_name` varchar(32) NOT NULL,
  `pass_word` varchar(32) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


INSERT INTO `dbuser01`.`user`(`id`, `user_name`, `pass_word`) VALUES ('001', 'jerry', '123456');
INSERT INTO `dbuser01`.`user`(`id`, `user_name`, `pass_word`) VALUES ('002', 'mike', '123456');
INSERT INTO `dbuser01`.`user`(`id`, `user_name`, `pass_word`) VALUES ('003', 'john', '123456');

4.2 Operation steps

4.2.1 Project directory structure

The complete project directory structure is as follows

4.2.2 The parent module imports the following dependencies

The basic global version number dependency is defined in the root pom, which mainly includes: springcloud, springcloud-alibaba and other versions. Others can be incrementally supplemented in specific modules. In addition, it is necessary to pay attention to the version compatibility between springcloud, springcloud-alibaba and springboot For this question, you can refer to relevant information, there are many on the Internet.

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.9.RELEASE</version>
        <relativePath/>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.SR10</spring-cloud.version>
        <mysql.version>5.1.47</mysql.version>
        <mybatis.version>2.1.1</mybatis.version>

        <dubbo.version>2.7.18</dubbo.version>
    </properties>

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

            <!-- mysql驱动 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>

            <!--mybatis-->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis.version}</version>
            </dependency>

            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.2.6.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

        </dependencies>
    </dependencyManagement>

    <dependencies>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

4.2.3 Service provider core dependencies

It mainly includes: mysql connection, mybatis, nacos service registration center, and the dependency of openfeign, and the dependency of dubbo can be added later;

    <dependencies>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>com.congge</groupId>
            <artifactId>biz-common</artifactId>
            <version>1.0</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

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

        <!--nacos配置管理依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

        <!-- Dubbo Spring Cloud Starter -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-dubbo</artifactId>
        </dependency>

    </dependencies>

4.2.3 Public modules define entity classes and service interfaces

Define an entity class in the public module, which is mapped to the database user table. Note that serialization must be implemented here to avoid serialization errors when calling the dubbo interface later;

@Data
public class User implements Serializable {

    private static final long serialVersionUID = -2896873555774275129L;
    private String id;
    private String userName;
    private String passWord;

}

Define the service interface UserDubboApiService

public interface UserDubboApiService {
    User getById(String id);
}

Finally, install the common module to the local warehouse through the mvn install command, and then reference it to the other two modules

4.2.4 Service Provider Core Code

core configuration file


server:
  port: 8081

spring:
  application:
    name: biz-provider-service

  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848

  datasource:
    url: jdbc:mysql://IP:3306/dbuser01?useUnicode=true&characterEncoding=utf-8
    username: 用户名
    password: 密码
    driver-class-name: com.mysql.jdbc.Driver


#mybatis相关配置
mybatis:
  type-aliases-package: com.congge.entity
  configuration:
    map-underscore-to-camel-case: true
  mapper-locations: classpath:mybatis/*.xml

Add a service interface for testing

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    //http://localhost:8081/user/getById?id=001
    @GetMapping("/getById")
    public Object getByUserId(@RequestParam("id") String id){
        /*User user = new User();
        user.setId("001");
        user.setUserName("jerry");
        user.setPassWord("123456");
        return user;*/
        return userService.getById(id);
    }

}

service realization

import com.congge.entity.User;
import com.congge.mapper.UserMapper;
import com.congge.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public User getById(String id) {
        return userMapper.getById(id);
    }

}

service startup class

@SpringBootApplication
@EnableFeignClients
@MapperScan("com.congge.mapper")
public class BizProviderApp {

    public static void main(String[] args) {
        SpringApplication.run(BizProviderApp.class,args);
    }

}

4.2.5 Service Provider Interface Test

Here nacos is used as the service registry, so before starting the service, you need to start nacos

Start the provider's service, and then the browser calls the test interface, and the following effect shows that the integration is completed;

4.2.6 Service consumer core code

The project directory structure depends on the same as that of the producer, so I won’t repeat it here

Add a Feign interface class

import com.congge.entity.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.Map;

@FeignClient(name = "biz-provider-service",path = "/user")
public interface UserFeignService {

    @GetMapping("/getById")
    public User get(@RequestParam("id") String id);

}

Add a test interface. The service implementation class is omitted here for convenience. It is recommended to add an implementation class in actual development

@RestController
public class BizMockController {

    @Autowired
    private UserFeignService userFeignService;

    //localhost:8082/getFromRemote
    @GetMapping("/getFromRemote")
    public Object getFromRemote(){
        return userFeignService.get("001");
    }


}

The core configuration file is mainly to configure the service name of a project to register with nacos;


server:
  port: 8082

spring:
  application:
    name: biz-consumer-service

  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #服务注册中心地址

service startup class

@SpringBootApplication
@EnableFeignClients
public class BizConsumerApp {

    public static void main(String[] args) {
        SpringApplication.run(BizConsumerApp.class,args);
    }
}

4.2.7 Service Consumer Interface Test

After the above steps are completed, start the consumer service, call it through the test interface provided above, and see the following effect, indicating that the consumer calls the remote service through openfeign to complete;

5. springcloud-alibaba integrates openfeign and is compatible with dubbo

Going back to the last original appeal in Chapter 3, what should I do when the project needs to adapt to the architecture adjustment and introduce the dubbo framework? The effect of the transformation is that for the service consumer, the original openfeign has been used to continue to use, and at the same time, the openfeign call can be replaced with a dubbo call, and then some adjustments to the above two module codes can be made;

5.1 Service Provider Transformation

5.1.1 Add dubbo dependency

Note that what is directly introduced here is the dubbo integrated by springcloud instead of dubbo dependencies separately, or you can import it separately, but you need to pay attention to the version matching problem (cautiously)

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

By clicking in, you can find that the dubbo version 2.7.8 is used here, and in this version, dubbo does not need to rely on zk when configuring, so I did not quote zk or curator related dependencies;

5.1.2 Add dubbo related configuration

The configuration of dubbo only adds basic configuration information here, I believe that students who have used it should be familiar with it, mainly a dubbo protocol, port, plus the business implementation class package path scanned by dubbo;

dubbo:
  protocol:
    name: dubbo
    port: 20881
  scan:
    base-packages: com.congge.service.impl.dubbo

5.1.3 Code modification

After dubbo is introduced, in order to facilitate the development of clear package directories and reduce subsequent maintenance costs, the directory structure of the project is adjusted as follows:

Regarding the directory structure, the following supplementary instructions are also a kind of practical experience in production:

  • Dubbo's implementation class is recommended to be separated from the project's own business implementation class;
  • The business implementation class of this project mainly writes its own business for the current project to use;
  •  Dubbo's business implementation class provides service implementation separately for other callers to use;
  • In order to reduce coding redundancy and maintenance costs, for the same or highly reusable logic, it is recommended to take out a separate package directory, and write general business logic in this directory to be referenced by two implementation classes;

Add the dubbo implementation class, where UserDubboApiService is the service interface defined in the public module;

import com.congge.entity.User;
import com.congge.service.UserDubboApiService;
import com.congge.service.UserService;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;

@DubboService
public class UserDubboApiServiceImpl implements UserDubboApiService {

    @Autowired
    private UserService userService;

    @Override
    public User getById(String id) {
        User dbUser = userService.getById(id);
        return dbUser;
    }

}

The code of the service provider has been transformed here, and the transformation of the consumer is next.

5.2 Transformation of service consumers

The general steps are similar to the production side, and the introduction of dubbo dependencies is the same as above

5.2.1 Configuration file modification

To supplement the configuration of dubbo, just add the following paragraph

dubbo:
  protocol:
    name: dubbo
    port: 20882

5.2.2 Add test interface

Add a test interface for calling through the dubbo interface

@RestController
public class BizMockController {

    @Autowired
    private UserFeignService userFeignService;

    //localhost:8082/getFromRemote
    @GetMapping("/getFromRemote")
    public Object getFromRemote(){
        return userFeignService.get("001");
    }

    @DubboReference(retries = 0, timeout = 10000)
    private UserDubboApiService userDubboApiService;

    //localhost:8082/getFromDubbo
    @GetMapping("/getFromDubbo")
    public Object getFromDubbo(){
        return userDubboApiService.getById("002");
    }

}

5.2.3 Interface Test

Start the services of the producer and the consumer respectively, call the above-mentioned newly added interface, and see the effect below to show that the remote service can also be successfully called through dubbo;

In summary, through the above modification, the effect from using openfeign alone to being compatible with dubbo at the same time is completed. Of course, there are two points that need to be emphasized again:

1) Version compatibility issues, which is also the easiest place to step on the compatibility with the springboot version of the current project when actually introducing new external components;

2) After dubbo is introduced, how to manage the business realization of the project itself and the business realization of dubbo more elegantly;

Sixth, write at the end of the text

This paper explains in detail how to introduce dubbo in openfeign from a technical architecture adjustment problem that may be encountered in production practice, so that the current service provider is compatible with these two service call modes. In fact, In actual projects, the external factors may be more complicated than this, but it can be used as a reference to provide a solution. Finally, thank you for watching. Students who need source code can go to download: source code address

Guess you like

Origin blog.csdn.net/zhangcongyi420/article/details/130755351