【微服务】springboot 整合 dubbo3.0

前言

随着云原生的兴起,越来越多的微服务化改造在演进过程中也开始提上日程,微服务治理框架能否很好的兼容和支持云原生的体系,也成为很多架构设计者考虑的重要因素;

在微服务治理框架中,dubbo作为一款优秀的服务治理框架,随着dubbo3.0的发布,通过增加的新特性,为云原生的支持带来了福音,也为dubbo2.X过渡到3.0提供了更多好用,且性能高效的亮点;

dubbo3.0新特性介绍

官网新特性介绍 ,下面结合官网的介绍做一些关于 dubbo3.x的新特性总结。

一、注册模型的改变

我们知道,dubbo2.X版本,服务都是以接口的形式注册到注册中心(如zk)。一个接口在注册中心中就是一个数据节点,多个接口就注册多个节点。

当dubbo提供的服务非常多的时候,会给注册中心带来非常大的读写压力,比如在并发量较高的时候,消费端因服务寻址耗费的时间会拉长。而在dubbo3.0版本中对这个问题进行了优化。

dubbo3.0引入服务级别的注册

在dubbo3.0中,只需将应用名和对应的ip、端口注册到注册中心即可。无需再对每个接口进行注册(可通过配置参数进行选择)。以此来减少注册中心的压力。

但是只注册应用,如何查找消费端具体调用的是哪个服务呢?

于是dubbo3.0引入了元数据服务的概念。

具体做法就是,接口提供的服务映射关系,都存在了元数据服务里。元数据服务的数据可以默认存在dubbo内部实现的一个服务里,也可以手动指定存入ZK等服务中。

这样,消费端通过注册中心获取服务列表,然后通过元数据服务映射具体某个接口,进行远程调用。

由此可见,尽管在3.0中以应用纬度进行了注册,看似减轻了注册中心的压力,但引入了元数据服务,也提高了使用的复杂度。

二、引入Triple协议

Dubbo3.0新引入了Triple协议。Triple协议可以视为gRPC协议的copy版本。

什么是gRPC?

如果你在了解dubbo3.0之前,或者说没听过gRPC,说明你所涉及的业务或者数据量不需要用到gRPC来达到很高的性能的。所以Triple协议所带来的性能的提升对你而言也是可有可无的。

dubbo认为,http1.X版本性能比较低,主要是因为协议的数据格式复杂,解析带来的一定的性能瓶颈,所以http2.0对性能进行了提升。

而Triple协议是基于http2.0的高性能的基础上,又支持gRPC的远程调用,更具兼容性。这就是Triple协议的特性。
 

其实在dubbo2.X版本时,dubbo协议是默认的协议,而在3.0版本,Triple协议成为了默认协议。

相比dubbo协议,Triple协议的特点有:

  • triple协议兼容了gPRC(Triple服务可以直接调用gRPC服务,反过来也可以);
  • dubbo协议不是基于的HTTP,不够通用,triple协议底层基于HTTP所以更通用(比如跨语言、跨异构系统实现起来比较方便);
  • dubbo协议不支持流式调用;
  • 三、跨语言调用

    跨语言调用对于dubbo来说可以说是一个很大的突破,3.0 支持go语言,python语言等应用进行接口的调用。

    涉及到跨语言调用的服务接口,可考虑使用dubbo作为服务。可以使用protobuf格式的数据作为数据传输格式,来进行跨语言调用。

    四、SpringCloud的互通

    至目前而已,经管两者之间可以实现互通,但是Dubbo3.0与SpringCloud的互通方式也是很繁琐,但看趋势以后的发展肯定会很方便的和SpringCloud进行互通。让我们拭目以待。

    dubbo3.0与springboot的整合
     

    接下来演示下与springboot的整合,方便后续在业务中快速运用,完整结构如下:

    1. 统一定义服务接口和实体类,被其他工程模块引用;
    2. consumer,服务消费方模块;
    3. provider,服务提供方模块;

     

    common-service 模块

    pomy依赖

            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.8</version>
            </dependency>

    服务接口

    import com.congge.entity.User;
    
    public interface UserService {
    
        User getByUserId(String userId);
    
    }
    

    实体类

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class User implements Serializable {
    
        private static final long serialVersionUID = 8728327146677888239L;
    
        private String userId;
        private String userName;
        private String address;
    
    }

    provider模块

     

    1、pom依赖

        <dependencies>
    
            <dependency>
                <groupId>com.congge</groupId>
                <artifactId>common-service</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
                <version>2.6.6</version>
            </dependency>
    
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.22</version>
            </dependency>
    
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-spring-boot-starter</artifactId>
                <version>3.0.7</version>
            </dependency>
    
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-rpc-dubbo</artifactId>
                <version>3.0.7</version>
            </dependency>
    
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-rpc-rest</artifactId>
                <version>3.0.6</version>
            </dependency>
    
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-registry-zookeeper</artifactId>
                <version>3.0.7</version>
            </dependency>
    
        </dependencies>

    2、核心配置文件

    ## 这里的配置属性只是基础配置,如需更多功能配置,请自行扩展
    dubbo:
      application:
        name: dubbo-provider
      registry:
        address: zookeeper://127.0.0.1:2181
      protocol:
        name: dubbo
        port: 20880

    3、服务实现类

    @DubboService
    public class UserServiceImpl implements UserService {
    
        // 模拟数据
        private static final List<User> USERS = Arrays.asList(
                new User("001", "张三", "北京市东城区"),
                new User("002", "李四", "杭州市西湖区"),
                new User("003", "王五", "武汉市汉口区")
        );
    
        @Override
        public User getByUserId(String userId) {
            User user = USERS.stream().filter(item -> item.getUserId().equals(userId)).findFirst().get();
            return user;
        }
    
    }

    4、启动类

    import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    @EnableDubbo
    public class ProviderApp {
    
        public static void main(String[] args) {
            SpringApplication.run(ProviderApp.class, args);
        }
    
    }

    consumer模块

     

    1、pom依赖

        <dependencies>
    
            <dependency>
                <groupId>com.congge</groupId>
                <artifactId>common-service</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
                <version>2.6.6</version>
            </dependency>
    
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.22</version>
            </dependency>
    
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-spring-boot-starter</artifactId>
                <version>3.0.7</version>
            </dependency>
    
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-rpc-dubbo</artifactId>
                <version>3.0.7</version>
            </dependency>
    
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-rpc-rest</artifactId>
                <version>3.0.9</version>
            </dependency>
    
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-registry-zookeeper</artifactId>
                <version>3.0.7</version>
            </dependency>
    
        </dependencies>

    2、核心配置文件

    dubbo:
      application:
        name: dubbo-consumer
      registry:
        address: zookeeper://127.0.0.1:2181
      protocol:
        name: dubbo
        port: 20880
    
    # 由于zookeeper启动时要占用8080端口,我们要显示指定端口,要不然会端口冲突
    server:
      port: 8081

    3、接口层

    为了模拟外部调用效果,这里提供一个接口类

    import com.congge.entity.User;
    import com.congge.service.MyUserService;
    import com.congge.service.UserService;
    import org.apache.dubbo.config.annotation.DubboReference;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class UserController {
    
        /*@DubboReference
        private UserService userService;*/
    
        @Autowired
        private MyUserService myUserService;
    
        //http://localhost:8081/user/dubbo?userId=001
        @GetMapping("/user/dubbo")
        public Object getByUserIdV1(@RequestParam("userId") String userId) {
            return myUserService.getUserFromDubbo();
        }
    
        //http://localhost:8081/user/rest?userId=001
        @GetMapping("/user/rest")
        public Object getByUserIdV2(@RequestParam("userId") String userId) {
            return myUserService.getUserFromRest();
        }
    
    }
    

    4、业务实现层

    import com.congge.entity.User;
    import org.apache.dubbo.config.annotation.DubboReference;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.stereotype.Service;
    import org.springframework.web.client.RestTemplate;
    
    @Service
    public class MyUserService {
    
        @Autowired
        private RestTemplate restTemplate;
    
        @DubboReference
        UserService userService;
    
        public User getUserFromDubbo(){
            User user = userService.getByUserId("001");
            return user;
        }
    
        public Object getUserFromRest() {
            User user = restTemplate.getForObject("http://localhost:8082/user/001",User.class);
            return user;
        }
    }

    5、启动类

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class ConsumerApp {
    
        public static void main(String[] args) {
            SpringApplication.run(ConsumerApp.class, args);
        }
    
    }

    功能测试

    1、启动zookeeper服务

     

    2、分别启动生产端和消费端的服务

    3、浏览器调用接口模拟

     通过上面的案例,我们完成了dubbo3.0与springboot的整合使用,希望对看到的你有用哦。

    物联沃分享整理
    物联沃-IOTWORD物联网 » 【微服务】springboot 整合 dubbo3.0

    发表评论