Dubbo与springboot的整合

1 篇文章 0 订阅
1 篇文章 0 订阅

前言

公司最近要做一个新的项目,打算使用分布式的架构,目前最火的大概是dubbo和springcloud两家,最后使用了dubbo作为分布式的框架,然而同事一直以来都是使用springboot,所以看了一下dubbo的官方文档,又在网上查了一下资料,把整个过程记录一下。

开发环境

操作系统:win10

IDE:IntelliJ IDEA Ultimate

必要工具:务必保证安装了jdk8或以上、maven

一、注册中心

Dubbo作为一个RPC框架,它能把各个微服务集中起来,靠的就是注册中心——即服务提供者(被调用)把自己的服务注册到注册中心,服务消费者(主动调用)去注册中心订阅。Dubbo支持的注册中心有很多:Multicast、Zookeeper、Nacos、Redis、Simple,官方推荐使用Zookeeper。

zookeeper下载地址:https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.4.14/

下载成功后直接解压,到conf目录下把zoo_sample.cfg重命名为zoo.cfg,并且修改里面的内容dataDir的属性,这个属性是用来指定zookeeper的数据存放位置的。然后到bin目录下双击zkServer.cmd文件启动zookeeper服务,这时可以看到zookeeper服务启动成功,端口号是2181。

顺便说一下,因为我们还处于开发的阶段,所以注册中心暂时也不需要搭建成集群。但是注册中心作为dubbo中一个最重要的组件,为了保证服务的高可用,在生产环境必须要做集群,这里就不关注zookeeper集群搭建了,可以自行查阅相关资料。

二、场景模拟

为了更易于理解,我在这里模拟一个场景,比如说我们的电商系统,用户下单成功后想查看自己的订单,这个时候我们除了给用户返回订单的基本信息(比如订单号、下单时间、商品id,商品数量)之外,我们还应该返回商品的一些简略的信息,比如商品名,商品缩略图。其中商品名和商品缩略图的数据应该是属于商品详情服务的,与订单相关的数据才是订单服务的。那种在这个场景下,订单服务是服务消费者(主动调用),商品服务是服务提供者(被调用)。

有了这个场景,我们就可以开始了。说明一下,由于本文只是为了整合,所以就不连接数据库了,直接模拟一些数据即可。

三、创建项目

(1)创建空项目

在IDEA中新建项目,选择左侧最下面的Empty Project,填好项目名。创建好的project如下,什么也没有。

(2)创建api项目

在dubbo文档的最佳实践中,官方建议我们分包:

建议将服务接口、服务模型、服务异常等均放在 API 包中,因为服务模型和异常也是 API 的一部分,这样做也符合分包原则:重用发布等价原则(REP),共同重用原则(CRP)。

我们先创建一个api的module:File -> New -> Module...

选择左侧的maven,勾选Create from aom archetype,选中下面的org.apache.maven.archetypes:maven-archetype-quickstart

点击Next后填好GroupId和ArtifactId然后一直Next到完成,模块创建好之后把pom文件的<build>节点的内容删掉。ok,到此接口的项目就创建完成。

接下来是创建对象和接口。创建pojo包和service包,pojo下放一个Spu类,service放一个SpuService接口

Spu.java的代码如下:

public class Spu implements Serializable {
    private String spuId;
    private String spuName;
    private String spuImage;

    // 省略getter和setter方法
}

(记得一定要implements Serializable接口,不然会因为对象不能序列化而报错)

SpuService.java的代码如下:

public interface SpuService {

    /**
     * 根据商品id获取详情信息
     * */
    List<Spu> getSpuDetails(List<String> spuIds);

}

项目结构如下:

到此,api模块就完成了。

(2)创建spu-service-provider项目

同样,新建一个module,但是这次选择的是spring initializr,因为我们的服务提供者是一个springboot项目。然后我们需要在pom文件中添加两个依赖,第一个是我们的apimodule的依赖,另一个是dubbo的依赖,添加好之后的pom文件如下:

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.spareyaya.mall</groupId>
    <artifactId>spu-service-provider</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spu-service-provider</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.spareyaya.mall</groupId>
            <artifactId>mall-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>0.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

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

</project>

接下来需要实现接口

创建service.impl包,在该包下创建一个SpuServiceImpl类,代码如下:

package com.spareyaya.mall.spuserviceprovider.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.spareyaya.mall.pojo.Spu;
import com.spareyaya.mall.service.SpuService;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Component
@Service
public class SpuServiceImpl implements SpuService {
    @Override
    public List<Spu> getSpuDetails(List<String> spuIds) {
        // 实际这里应该会根据spuIds的值去缓存或者数据库中查出相关商品的信息,
        // 再封装好返回,这里只是为了演示,就直接返回两条假数据
        List<Spu> spus = new ArrayList<>(2);
        Spu spu = new Spu();
        spu.setSpuId("1000");
        spu.setSpuName("我是商品1000的商品名");
        spu.setSpuImage("我是商品1000的商品缩略图的链接");
        spus.add(spu);
        spu = new Spu();
        spu.setSpuId("1001");
        spu.setSpuName("我是商品1001的商品名");
        spu.setSpuImage("我是商品1001的商品缩略图的链接");
        spus.add(spu);
        return spus;
    }
}

这里值得注意的是,类上的注解@Component是spring的注解,表示这是一个bean,而@Service是dubbo的注解,表示这是作为服务提供者对外暴露的服务接口。

最后在启动类加上@EnableDubbo注解开启dubbo

最后的最后,需要加上配置,在resources/application.properties中(如果习惯用yml文件的就是application.yml)加上相关配置:

dubbo.application.name=user-service-provider
dubbo.registry.protocol=zookeeper
dubbo.registry.address=127.0.0.1:2181

dubbo.protocol.name=dubbo
dubbo.protocol.port=20880

到此,服务提供者的项目也完成了。

(3)创建order-consumer项目

创建方法和spu-service-provider基本一致,不过因为我们还需要在服务消费者中接收请求,所以在创建项目的时候需要加上Spring Web的依赖,同样需要添加mall-api这个module和dubbo的依赖。在resources/application.properties中添加配置:

dubbo.application.name=order-consumer
dubbo.registry.protocol=zookeeper
dubbo.registry.address=127.0.0.1:2181

同样也需要在启动类添加@EnableDubbo注解。

接下来就可以调用提供者里的方法了。

创建pojo包和controller包,并在pojo包下创建Order类和OrderDetail类,在controller包下创建OrderController类,完成后项目结构和这三个类的代码如下:

Order.java

public class Order {
    private String orderId;
    private List<OrderDetail> orderDetail;

    // 省略getter和setter方法
}

OrderDetail.java

public class OrderDetail {
    private String orderId;
    private String spuId;
    private String spuName;
    private String spuUrl;
    private int price;
    private int amount;

    // 省略了getter和setter方法
}

OrderController.java

@RestController
public class OrderController {

    @Reference
    private SpuService spuService;

    @RequestMapping("/getOrderDetails")
    public Order getOrderDetails(@RequestParam("orderId") String orderId) {
        // 正常情况下,需要通过用户的登录token认证和上传的订单号,现在订单服务中查询订单的相关信息,
        // 再把通过调用商品服务中的方法把商品的信息查询回来,最后把数据合并、返回,这里为了方便就只
        // 演示调用的过程,忽略实际业务操作
        List<Spu> spus =  spuService.getSpuDetails(new ArrayList<>());
        Order order = new Order();
        order.setOrderId(orderId);
        List<OrderDetail> orderDetails = new ArrayList<>();
        for (Spu spu : spus) {
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setSpuId(spu.getSpuId());
            orderDetail.setSpuName(spu.getSpuName());
            orderDetail.setSpuImage(spu.getSpuImage());
            orderDetail.setPrice(12.99F);
            orderDetail.setAmount(3);
            orderDetails.add(orderDetail);
        }
        order.setOrderDetail(orderDetails);
        return order;
    }
}

这里的@Reference是dubbo包下的,表示这里需要使用服务提供者的服务。

至此,服务消费者也完成。

四、启动&测试

(1)启动zookeeper,如果在第一步的注册中心介绍还没有启动zookeeper,可以参考第一步

(2)启动服务提供者,找到启动类的main方法,直接运行(就是启动一个Spring Boot项目)

(3)启动服务消费者,启动方法同上

提供者和消费者都启动成功后就可以测试了,在浏览器访问http://127.0.0.1:8080/getOrderDetails?orderId=w123628可以看到返回结果:

五、题外话

(1)如果在windows下开发的觉得每次都要手动去启动zookeeper很麻烦,可以把zookeeper做成windows服务并设置开机启动,这样就不用每次启动而且出现一个黑黑的控制台窗口了.

(2)本文只是讲述了Spring Boot集成Dubbo的过程,而无论是服务提供者还是服务消费者还是spring boot项目,所以如果需要用spring boot的功能还是一样的用法,比如集成mybatis,通过注解的方法使用mybatis等。

(3)在实际开发中,一个模块可能既是服务提供者,也是服务消费者。

(4)本文并没有提供dubbo后台的部署过程,实际上,可视化服务治理是dubbo一个很重要的功能,可以在后台查看各个微服务的运行状态,可以对服务进行断开、降级、监控各个服务并发量等等。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值