springboot 整合dubbo3开发rest应用的场景分析

目录
  • 一、前言
  • 二、dubbo适用场景
    • 1、内部单体应用微服务化
    • 2、应用服务更多面向内部服务间调用
    • 3、对服务管理趋于精细化
  • 三、dubbo微服务治理过程中的一个难题
  • 四、与springboot的整合使用
    • 1、公共pom依赖
    • 2、common-service 模块
    • 3、provider-demo 模块
      • pom依赖
      • 核心配置文件
      • 服务实现类
      • 启动类
    • 4、consumer-demo 模块
  • 4、接口测试
    • 4.1 启动zookeeper服务
    • 4.2 启动provider服务
    • 4.3 启动consumer服务
    • 4.4 接口测试

一、前言

作为微服务治理生态体系内的重要框架 dubbo,从出身到现在历经了十多年的市场检验而依旧火热,除了其自身优秀的设计,高性能的RPC性能,以及依托于springcloud-alibaba的这个背后强劲的开源团队支撑,在众多的微服务架构选型中,成为很多架构设计者们不可或缺的选择之一。

二、dubbo适用场景

关于dubbo的具体技术点,本篇不做过多介绍,网上的参考资料较多,下面谈几点使用dubbo的技术选型场景,提供参考:

1、内部单体应用微服务化

很多创业型公司,一开始喜欢采用单体服务,随着业务量增大,单体架构很难支撑随之而来的业务并发量,为了减少单体应用向微服务转型的难度,dubbo是一个不错的选择,相比 springcloud 或者springcloud-alibaba,dubbo可以说在极少依赖过多微服务组件的基础上就可以完成微服务化的过渡。

2、应用服务更多面向内部服务间调用

如果你所在的系统或平台,在大多数情况下,需要面对的是微服务之间的调用,而很少对外提供服务接口,dubbo肯定是首选。我们知道springcloud走的是http协议,相对dubbo来说,在同样的网络环境下,dubbo底层使用的是netty,从传输性能上来说更加高效。

3、对服务管理趋于精细化

dubbo发展到当前的3.X版本,经过漫长的迭代和优化,目前来说已经提供了一整套完善的服务治理方案,细化到对某个服务接口参数调优都有着成熟的解决方案,即存在很多人力可控的因素,这一点来说,对比springcloud来说,有着很强的优势。

三、dubbo微服务治理过程中的一个难题

下面是一张常见的使用dubbo进行微服务治理的内部业务架构图,从这幅图至少可以得出下面几点信息:

系统中的应用都是 Java应用,dubbo对Java应用的支撑性本身就很好;各个应用之间将自身的服务通过dubbo注册到注册中心;各应用之间通过dubbo统一从注册中心调用其他应用的服务;

从上面的解读来看,相信对大多数同学来说,使用Java应用采用dubbo进行服务治理也就是上面的模式,而且用的也顺手,但是如果出现了下面的需求该怎么办呢?

下面这张图表达的业务场景是:随着平台规模的做大,比如引入了大数据应用,或者其他周边的计算类应用,但这些新的非Java类的应用也希望从现有的服务注册中心里面调用服务接口,这就给dubbo服务治理带来了一个毕竟难处理的问题,我们知道dubbo走的不是http,而是有一套自己的协议栈,而且在使用dubbo的时候,通常的做法是别的应用引入服务提供者jar进行调用;

因此当出现下面这样的跨语言调用时,目前来看,一个毕竟常见的解决方案就是,服务提供方提供rest接口,即http接口,这样带来的问题就是,服务提供方势必要提供两套服务解决方案;

相信这也是不少同学在使用dubbo过程中可能会遇到的场景之一,但是好在dubbo在2.7X之后,提供了基于rest协议的实现,就这点来说,在这个场景下,可以说带来了极大的便利,简而言之,开发者无需提供两套服务接口,而是基于dubbo一个框架的基础上,通过配置不同的协议来完成一个服务接口,支撑多种外部协议的调用;

接下来,通过实际的案例演示下基于 dubbo的2.7.X的版本,整合springboot完成一个rest应用开发和调用的案例;

四、与springboot的整合使用

完成的工程目录结构如下

  • common-service,公共服务接口,实体类的模块;
  • consumer-demo,服务消费方应用;
  • provider_demo,服务提供方应用;

1、公共pom依赖

该模块用于统一定义和管理各类组件的版本号,可以根据需要酌情引用或补充其他的依赖;

    <properties>
        <spring-boot.version>2.3.1.RELEASE</spring-boot.version>
        <dubbo.version>2.7.5</dubbo.version>
    </properties>

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

            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-dependencies-bom</artifactId>
                <version>${dubbo.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo</artifactId>
                <version>${dubbo.version}</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.springframework</groupId>
                        <artifactId>spring</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>javax.servlet</groupId>
                        <artifactId>servlet-api</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>log4j</groupId>
                        <artifactId>log4j</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
        </dependencies>
    </dependencyManagement>

2、common-service 模块

基础pom依赖,这里只需要引入lombok即可;

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

定义一个实体类 User ,注意这里一定要实现序列化接口,高版本的dubbo默认的序列化协议对这里有严格的要求;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {

    private static final long serialVersionUID = 8728327146677888239L;

    private String userId;
    private String userName;
    private String address;

}

定义服务接口 UserService ,并定义2个方法

import com.congge.entity.User;

public interface UserService {

    User getByUserId(String userId);

    String sayHello(String name);

}

使用maven命令或idea自带命令,将 common-service 编译并安装到本地仓库;

3、provider-demo 模块

该模块主要结构如下

pom依赖

    <dependencies>

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

        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>2.7.5</version>
        </dependency>

        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-jaxrs</artifactId>
            <version>3.0.19.Final</version>
        </dependency>

        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>1.1.0.Final</version>
        </dependency>

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

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

        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo</artifactId>
        </dependency>

        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-dependencies-zookeeper</artifactId>
            <version>2.7.5</version>
            <type>pom</type>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-rpc-http</artifactId>
            <version>2.7.5</version>
        </dependency>

        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-metadata-report-zookeeper</artifactId>
            <version>2.7.5</version>
        </dependency>
    </dependencies>

核心配置文件

spring.application.name=dubbo-provider
server.port=8081

dubbo.scan.base-packages=com.congge.service
dubbo.application.name=dubbo-provide

dubbo.registry.address=zookeeper://127.0.0.1:2181

dubbo.protocols.p1.id=dubbo-one
dubbo.protocols.p1.name=dubbo
dubbo.protocols.p1.port=20881
dubbo.protocols.p1.host=0.0.0.0

dubbo.protocols.p2.id=rest-two
dubbo.protocols.p2.name=rest
dubbo.protocols.p2.port=8082
dubbo.protocols.p2.host=0.0.0.0

服务实现类

注意,类上面的 Service 注解是dubbo的,同时,里面的 protocol 同时支持 dubbo协议和rest协议,这也是dubbo 2.7.X之后的新特性;

而使用 Path 注解,就很像我们在一个Controller接口类上面定义的请求路径;

import com.congge.entity.User;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.config.annotation.Service;
import org.apache.dubbo.rpc.RpcContext;
import org.apache.dubbo.rpc.protocol.rest.support.ContentType;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;

@Service(version = "rest", protocol = {"p2","p1"})
@Path("user")
public class ProviderRestService implements UserService {

    @GET
    @Path("getByUserId")
    @Produces({ContentType.APPLICATION_JSON_UTF_8, ContentType.TEXT_XML_UTF_8})
    @Override
    public User getByUserId(@QueryParam("userId")String userId) {
        return new User(userId,"zhangsan","杭州");
    }

    @GET
    @Path("sayHello")
    @Produces({ContentType.APPLICATION_JSON_UTF_8, ContentType.TEXT_XML_UTF_8})
    @Override
    public String sayHello(@QueryParam("name") String name) {
        System.out.println("执行了rest服务" + name);
        URL url = RpcContext.getContext().getUrl();
        return String.format("%s: %s, Hello, %s", url.getProtocol(), url.getPort(), name);
    }

}

启动类

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

4、consumer-demo 模块

pom依赖和provider里面保持一致即可

核心配置文件

spring:
  application:
    name: dubbo-consumer

server:
  port: 8083

dubbo:
  registry:
    address: zookeeper://127.0.0.1:2181

接口层 MyUserController

这里为了演示方便,定义了一个控制器,方便后面的测试,这里写了两种方式的接口,即通过默认的dubbo协议调用方式,以及采用rest接口方式调用,所以注入了 RestTemplate ,相信有过微服务开发经验的同学能看懂;

import com.congge.entity.User;
import com.congge.service.UserService;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class MyUserController {

    @Autowired
    private RestTemplate restTemplate;

    @Reference(version = "rest")
    private UserService demoService;

    //http://localhost:8083/getUser
    @GetMapping("/getUser")
    public Object getUserInfo(){
        String result = demoService.sayHello("hello provider");
        return result;
    }

    //http://localhost:8083/getUserById
    @GetMapping("/getUserById")
    public Object getUserById(){
        User dbUser = demoService.getByUserId("001");
        return dbUser;
    }

    //http://localhost:8083/getByRest
    @GetMapping("/getByRest")
    public Object getByRest(){
        User forObject = restTemplate.getForObject("http://localhost:8082/user/getByUserId?userId=0001", User.class);
        return forObject;
    }
}

启动类

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);
    }
}

4、接口测试

4.1 启动zookeeper服务

4.2 启动provider服务

4.3 启动consumer服务

4.4 接口测试

模拟正常的dubbo接口调用,调用接口:http://localhost:8083/getUser ,浏览器执行调用

模拟rest接口调用,调用接口:http://localhost:8083/getByRest ,执行调用观察效果

通过上述的案例演示,我们了解了如何使用dubbo的rest协议开发一个服务接口,可以这么讲,有了这种rest协议之后,对于服务提供端来说,同样的服务实现类既可以作为dubbo服务暴露出去,同样可以rest的方式被调用,这对于跨平台,跨语言的应用来说,无疑是一种很好的选择;

但是上面演示的方式仅仅是其中一种,更详细的dubbo rest 开发可以参考 dubbo rest开发规范说明,本篇到这里就结束了,感谢观看!

到此这篇关于springboot 整合dubbo3开发rest应用的文章就介绍到这了,更多相关springboot 整合dubbo3内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • SpringBoot与Dubbo整合的方式详解

    1. 使用默认application.properties和注解的方式 导入dubbo-starter,在application.properties配置属性,使用@Service注解来暴露服务,使用@Reference来引用服务.具体可参考 Dubbo整合SpringBoot,这里截取部分代码方便理解. 属性在application.properties中配置 服务提供方使用@Service注解暴露服务 部分配置如"timeout"等可以在注解上添加 服务消费方使用@Referenc

  • spring/springboot整合dubbo详细教程

    一.基本使用 需求: 某个电商系统,订单服务需要调用用户服务获取某个用户的所有地址: 我们现在需要创建两个服务模块进行测试 模块 功能 订单服务web模块 创建订单等 用户服务service模块 查询用户地址等 测试预期结果: 订单服务web模块在A服务器,用户服务模块在B服务器,A可以远程调用B的功能. 二.spring整合dubbo 以下使用XML 配置的方式,更多配置方式见官方文档 2.1 spring-common模块: 公共接口层(model,service,exception-),定

  • SpringBoot通过整合Dubbo解决@Reference注解问题

    首先检查一下你的spring boot版本是多少? 如果是2.X 不用看了,spring boot 2.x 必定会出现这个问题, 改为 1.5.9 或其他1.x版本,目前生产环境建议使用1.x版本. <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9

  • springboot2.0整合dubbo的示例代码

    写在前面: 使用springboot作为web框架,方便开发许多,做分布式开发,dubbo又不可少,那么怎么整合在一起呢, 跟我学一遍,至少会用 注意,springboot2.0和springboot1.x与dubbo整合不一样, 1.环境 1.新建一个空的maven项目,作为父工程,新建moudle,,service(接口层,及实现层,没有具体分,),web(web层,springboot项目) 项目结构如下 父pom如下 <properties> <project.build.sou

  • 使用SpringBoot开发Restful服务实现增删改查功能

    在去年的时候,在各种渠道中略微的了解了SpringBoot,在开发web项目的时候是如何的方便.快捷.但是当时并没有认真的去学习下,毕竟感觉自己在Struts和SpringMVC都用得不太熟练.不过在看了很多关于SpringBoot的介绍之后,并没有想象中的那么难,于是开始准备学习SpringBoot. 在闲暇之余的时候,看了下SpringBoot实战以及一些大神关于SpringBoot的博客之后,开始写起了我的第一个SpringBoot的项目.在能够对SpringBoot进行一些简单的开发Re

  • springboot 整合dubbo3开发rest应用的场景分析

    目录 一.前言 二.dubbo适用场景 1.内部单体应用微服务化 2.应用服务更多面向内部服务间调用 3.对服务管理趋于精细化 三.dubbo微服务治理过程中的一个难题 四.与springboot的整合使用 1.公共pom依赖 2.common-service 模块 3.provider-demo 模块 pom依赖 核心配置文件 服务实现类 启动类 4.consumer-demo 模块 4.接口测试 4.1 启动zookeeper服务 4.2 启动provider服务 4.3 启动consume

  • SpringBoot整合Web开发之文件上传与@ControllerAdvice

    目录 本章概要 文件上传 单文件上传 多文件上传 @ControllerAdvice 全局异常处理 添加全局数据 请求参数预处理 本章概要 文件上传 @ControllerAdvice 文件上传 Java 中的文件上传一共涉及两个组件,一个是 CommonsMultipartResolver,另一个是 StandardServletMultipartResolver ,其中 CommonsMultipartResolver 使用 commons-fileupload 来处理 multipart

  • Spring Boot整合Zookeeper实现分布式锁的场景分析

    目录 一.Java当中关于锁的概念 1.1.什么是锁 1.2.锁的使用场景 1.3.什么是分布式锁 1.4.分布式锁的使用场景 二.zk实现分布式锁 2.1.zk中锁的种类: 2.2.zk如何上读锁 2.3.zk如何上写锁 2.4.⽺群效应 三.springboot整合分布式锁 温馨提示:本篇文章要求掌握zk的数据结构,以及临时序号节点! zk实现分布式锁完全是依靠zk节点类型当中的临时序号节点来实现的 一.Java当中关于锁的概念 1.1.什么是锁 锁是用来控制多个线程访问共享资源的方式,一般

  • springboot项目监控开发小用例(实例分析)

    Spring Boot Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置.通过这种方式,Spring Boot致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者. SpringBoot简介 SpringBoot是由Pivotal团队在2013年开始研发.2014年4月发布第一个版本的全新开源的轻量

  • SpringBoot集成Redisson实现延迟队列的场景分析

    使用场景 1.下单成功,30分钟未支付.支付超时,自动取消订单 2.订单签收,签收后7天未进行评价.订单超时未评价,系统默认好评 3.下单成功,商家5分钟未接单,订单取消 4.配送超时,推送短信提醒 ...... 对于延时比较长的场景.实时性不高的场景,我们可以采用任务调度的方式定时轮询处理.如:xxl-job 今天我们采用一种比较简单.轻量级的方式,使用 Redis 的延迟队列来进行处理.当然有更好的解决方案,可根据公司的技术选型和业务体系选择最优方案.如:使用消息中间件Kafka.Rabbi

  • springboot运行到dokcer中 dockerfile的场景分析

    目录 1.场景 2.编写springboot项目打包上传linux服务器 2.1将jar包和docker放到同一个目录 2.2编写dockerfile 3.运行dockerfile 4.查看镜像 5.运行镜像 6.运行 1.场景 stringboot - > spring boot .jar -> dockerfile---> run dokcerfile 2.编写springboot 项目打包上传linux服务器 2.1 将jar 包和 docker放到同一个目录 -rw-r--r--

  • Springboot整合MongoDB的Docker开发教程全解

    1 前言 Docker是容器开发的事实标准,而Springboot是Java微服务常用框架,二者必然是会走到一起的.本文将讲解如何开发Springboot项目,把它做成Docker镜像,并运行起来. 2 把Springboot打包成Docker镜像 Springboot的Web开发非常简单,本次使用之前讲解过的Springboot整合MongoDB的项目,请参考 实例讲解Springboot整合MongoDB进行CRUD操作的两种方式,文章中有源码:MongoDB的安装请参考:用Docker安装

  • SpringBoot整合Mybatis注解开发的实现代码

    官方文档: https://mybatis.org/mybatis-3/zh/getting-started.html SpringBoot整合Mybatis 引入maven依赖 (IDEA建项目的时候直接选就可以了) <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <ve

  • Idea开发工具之SpringBoot整合JSP的过程

    SpringBoot体系内推荐使用Thymeleaf作为前端页面模板.jsp还得自己整合一下. 1.项目结构 对比以前的项目结构,main目录下多了webapp目录,用来存放jsp文件. webapp目录为我们手动创建,所以需要在IDEA中进行配置,指定webapp目录为项目的Web资源目录. 首先在main目录下创建一个webapp目录 点击这个小图标(这里没有的可以File->Project Structure 或使用快捷键Ctrl+Alt+Shift+S) 接下来跟着图片教程一步步走 我们

  • SpringBoot整合RabbitMQ及生产全场景高级特性实战

    目录 摘要 整合 依赖与配置 生产者配置消息队列规则 生产者发布消息 消费者监听消息 摘要 整合场景含 topic 工作模式(通过 routingKey 可满足简单/工作队列/发布订阅/路由等四种工作模式)和 confirm(消息确认).return(消息返回).basicAck(消息签收).basicNack(拒绝签收).DLX(Dead Letter Exchange死信队列)实现延时/定时任务等. 整合 依赖与配置 以下内容消费者同生产者 <parent> <groupId>

随机推荐