分布式-dubbo的入门

本文涉及的产品
云原生网关 MSE Higress,422元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
注册配置 MSE Nacos/ZooKeeper,118元/月
简介: 分布式-dubbo的入门

提供一个简单的例子:完成下订单,减库存的功能

一、提供服务暴漏的接口,代码如下:

  1. package com.rm.dubbo.service.api;


  2. import com.rm.dubbo.service.pojo.Orders;

  3. public interface OrdersService {

  4.    /**
  5.     * @Description: 根据订单id查询订单
  6.     */
  7.    public Orders getOrder(String orderId);

  8.    /**
  9.     * @Description: 下订单
  10.     */
  11.    public boolean createOrder(String itemId);

  12. }

用的Mybatis的逆向工程,所以这里生成Orders类和Oreders的条件的类,和对应的mapper.xml的文件,工程如下:

有一个这个api是需要给对应的实现类来引用的。而且在分布式中式服务化的,所以把订单服务放一个子模块,工程的结构如下:

二、加入相应的依赖:

①、由于dubbo2.5.3是阿里维护的最后的一个版本,用的人是最多的。dubbo启动的时候是依赖spring的版本的,dubbo的默认的版本是2.5.6的版本是非常的低的,所以要排除掉。

②、order-service是依赖order-api的,所以也要把order-api的版本控制给引入order-service中。

  1. <dependencies>
  2.        <dependency>
  3.            <groupId>com.rm.dubbo</groupId>
  4.            <artifactId>rm-order-api</artifactId>
  5.        </dependency>

  6.        <!-- Mybatis -->
  7.        <dependency>
  8.            <groupId>org.mybatis</groupId>
  9.            <artifactId>mybatis</artifactId>
  10.        </dependency>
  11.        <dependency>
  12.            <groupId>org.mybatis</groupId>
  13.            <artifactId>mybatis-spring</artifactId>
  14.        </dependency>
  15.        <dependency>
  16.            <groupId>com.github.miemiedev</groupId>
  17.            <artifactId>mybatis-paginator</artifactId>
  18.        </dependency>
  19.        <dependency>
  20.            <groupId>com.github.pagehelper</groupId>
  21.            <artifactId>pagehelper</artifactId>
  22.        </dependency>
  23.        <!-- MySql -->
  24.        <dependency>
  25.            <groupId>mysql</groupId>
  26.            <artifactId>mysql-connector-java</artifactId>
  27.        </dependency>
  28.        <!-- 连接池 -->
  29.        <dependency>
  30.            <groupId>com.alibaba</groupId>
  31.            <artifactId>druid</artifactId>
  32.        </dependency>

  33.        <!-- Spring -->
  34.        <dependency>
  35.            <groupId>org.springframework</groupId>
  36.            <artifactId>spring-context</artifactId>
  37.        </dependency>
  38.        <dependency>
  39.            <groupId>org.springframework</groupId>
  40.            <artifactId>spring-beans</artifactId>
  41.        </dependency>
  42.        <dependency>
  43.            <groupId>org.springframework</groupId>
  44.            <artifactId>spring-webmvc</artifactId>
  45.        </dependency>
  46.        <dependency>
  47.            <groupId>org.springframework</groupId>
  48.            <artifactId>spring-jdbc</artifactId>
  49.        </dependency>
  50.        <dependency>
  51.            <groupId>org.springframework</groupId>
  52.            <artifactId>spring-aspects</artifactId>
  53.        </dependency>

  54.        <!-- 引入dubbo -->
  55.        <dependency>
  56.            <groupId>com.alibaba</groupId>
  57.            <artifactId>dubbo</artifactId>
  58.            <exclusions>
  59.                <exclusion>
  60.                    <artifactId>spring</artifactId>
  61.                    <groupId>org.springframework</groupId>
  62.                </exclusion>
  63.            </exclusions>
  64.        </dependency>
  65.        <dependency>
  66.            <groupId>org.apache.zookeeper</groupId>
  67.            <artifactId>zookeeper</artifactId>
  68.        </dependency>
  69.        <dependency>
  70.            <groupId>com.github.sgroschupf</groupId>
  71.            <artifactId>zkclient</artifactId>
  72.        </dependency>

  73.        <!-- zk 客户端依赖 -->
  74.        <dependency>
  75.            <groupId>org.apache.curator</groupId>
  76.            <artifactId>curator-framework</artifactId>
  77.        </dependency>
  78.        <dependency>
  79.            <groupId>org.apache.curator</groupId>
  80.            <artifactId>curator-recipes</artifactId>
  81.        </dependency>

  82.        <dependency>
  83.            <groupId>junit</groupId>
  84.            <artifactId>junit</artifactId>
  85.            <version>4.11</version>
  86.            <scope>test</scope>
  87.        </dependency>
  88.    </dependencies>

写对应的实现类,代码如下:

  1. package com.rm.dubbo.service.impl;

  2. import com.rm.dubbo.mapper.OrdersMapper;
  3. import com.rm.dubbo.service.api.OrdersService;
  4. import com.rm.dubbo.service.pojo.Orders;
  5. import org.slf4j.Logger;
  6. import org.slf4j.LoggerFactory;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.stereotype.Service;

  9. import java.util.UUID;

  10. @Service("ordersService")
  11. public class OrdersServiceImpl implements OrdersService {

  12.    final static Logger log = LoggerFactory.getLogger(OrdersServiceImpl.class);

  13.    @Autowired
  14.    private OrdersMapper ordersMapper;

  15.    @Override
  16.    public Orders getOrder(String orderId) {
  17.        return ordersMapper.selectByPrimaryKey(orderId);
  18.    }

  19.    @Override
  20.    public boolean createOrder(String itemId) {

  21.        // 创建订单
  22.        String oid = UUID.randomUUID().toString().replaceAll("-", "");
  23.        Orders o = new Orders();
  24.        o.setId(oid);
  25.        o.setOrderNum(oid);
  26.        o.setItemId(itemId);
  27.        ordersMapper.insert(o);
  28.        log.info("订单创建成功");
  29.        return true;
  30.    }

  31. }

三、由于需要把这个服务的接口注册到zk上,参考dubbo的官网,需要一个关于dubbo的配置文件,代码如下:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3.       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
  5.       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  6.       http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

  7.    <!-- 服务提供者的名称,唯一标识 -->
  8.    <dubbo:application name="order-provider"/>
  9.    <!-- 注册中心 -->
  10.    <dubbo:registry address="zookeeper://127.0.0.1:2181"/>
  11.    <!-- 指定暴露的服务端,默认的协议是dubbo-->
  12.    <dubbo:protocol name="dubbo" port="20881"/>
  13.    <!-- 定义暴露的服务接口,ref指的是对应的实现类 -->
  14.    <dubbo:service interface="com.rm.dubbo.service.api.OrdersService" ref="ordersService"/>
  15. </beans>

对应整个项目的结构如下:

然后测试下,启动这个服务,然后启动zk,控制台的信息打印如下:

其中注册打印的信息如下:dubbo默认的协议的是dubbo,用的是dubbo的统一的标准。

  1. Register: dubbo://169.254.18.74:20881/com.rm.dubbo.service.api.OrdersService?anyhost=true&application=order-provider&dubbo=2.5.3&interface=com.rm.dubbo.service.api.OrdersService&methods=createOrder,getOrder&pid=14544&revision=1.0-SNAPSHOT&side=provider&timestamp=1580444734532, dubbo version: 2.5.3, current host: 127.0.0.1

20881:是dubbo的端口号,169.254.18.74:本机的ip地址。com.rm.dubbo.service.api.OrderService:暴漏出接口的全路径。anyhost:true,代表任何机器都可以访问,没有权限。application=orderprovider:代表这个服务定义的名称。dubbo=2.5.3,dubbo的版本用的是2.5.3的版本。interface=com.rm.dubbo.service.api.OrderService&methods=createOrder,getOrder:这个告诉哪一个接口里的哪一个方法。pid:是当前进程的id。revision=1.0-SNAPSHOT:当前项目的版本。sid=provider代表是一种提供服务的角色。timestamp:毫秒值。后面的是dubbo的版本和主机。

然后查看下zk上的注册信息:

configurations节点:配置会话的 providers:配置服务提供者的,数组的原因是一个接口当中会有很多的实例,这样就可以做成负载均衡。 而在providers节点中的内容和控制台打印的内容是一样的,只不过是做了转义。这就是注册生成协议的信息。

同样也提供商品服务,工程结构如下:

提供暴漏出接口中的方法:

  1. package com.rm.dubbo.service.api;

  2. import com.rm.dubbo.service.pojo.Items;

  3. public interface ItemsService {

  4.    /**
  5.     * @Description: 根据商品id获取商品
  6.     */
  7.    public Items getItem(String itemId);

  8.    /**
  9.     * @Description: 查询商品库存
  10.     */
  11.    public int getItemCounts(String itemId);

  12.    /**
  13.     * @Description: 购买商品成功后减少库存
  14.     */
  15.    public void displayReduceCounts(String itemId, int buyCounts);

  16. }

同样也需要把这个服务注册到zk上。

然后提供相应的消费端,工程结构如下:

在接口BuyService接口中,提供相应的买商品的方法,代码如下:

  1. package com.rm.web.service;

  2. public interface BuyService {

  3.    /**
  4.     * @Description: 购买商品
  5.     */
  6.    public void doBuyItem(String itemId);

  7.    public boolean displayBuy(String itemId);
  8. }

对应的实现类如下:

  1. package com.rm.web.service.impl;

  2. import com.rm.dubbo.service.api.ItemsService;
  3. import com.rm.dubbo.service.api.OrdersService;
  4. import com.rm.web.service.BuyService;
  5. import org.slf4j.Logger;
  6. import org.slf4j.LoggerFactory;
  7. import org.springframework.stereotype.Service;

  8. import javax.annotation.Resource;

  9. @Service("buyService")
  10. public class BuyServiceImpl implements BuyService {

  11.    final static Logger log = LoggerFactory.getLogger(BuyServiceImpl.class);

  12.    @Resource
  13.    private ItemsService itemService;

  14.    @Resource
  15.    private OrdersService ordersService;

  16.    @Override
  17.    public void doBuyItem(String itemId) {
  18.        // 减少库存
  19.        itemService.displayReduceCounts(itemId, 1);

  20.        // 创建订单
  21.        ordersService.createOrder(itemId);
  22.    }

  23.    @Override
  24.    public boolean displayBuy(String itemId) {

  25.        int buyCounts = 5;

  26.        // 1. 判断库存
  27.        int stockCounts = itemService.getItemCounts(itemId);
  28.        if (stockCounts < buyCounts) {
  29.            log.info("库存剩余{}件,用户需求量{}件,库存不足,订单创建失败...",
  30.                    stockCounts, buyCounts);
  31.            return false;
  32.        }

  33.        // 2. 创建订单
  34.        boolean isOrderCreated = ordersService.createOrder(itemId);

  35.        // 3. 创建订单成功后,扣除库存
  36.        if (isOrderCreated) {
  37.            log.info("订单创建成功...");
  38.            itemService.displayReduceCounts(itemId, buyCounts);
  39.        } else {
  40.            log.info("订单创建失败...");
  41.            return false;
  42.        }
  43.        return true;
  44.    }

  45. }

然后消费端也需要把自己注册到zk上,也需要订阅上面的两个服务。所以dubbo的配置信息如下:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3.       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
  5.       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  6.       http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

  7.    <dubbo:application name="web-consumer"/>
  8.    <!-- 注册中心 -->
  9.    <dubbo:registry address="zookeeper://127.0.0.1:2181"/>
  10.    <!-- 引用暴露的服务ordersService和itemService如果和属性的名称相同,则按照名称来装配,否则按照类型装配。
  11.    interface的值指向接口的全路径,这样做之后把接口的实现类完全放到spring容器中去管理了-->
  12.    <dubbo:reference id="ordersService"  interface="com.rm.dubbo.service.api.OrdersService"/>
  13.    <dubbo:reference id="itemService" interface="com.rm.dubbo.service.api.ItemsService" />
  14. </beans>

然后启动消费端:返回的结果是200,代表购买成功。

由于是分布式的项目,数据库做成垂直的拆分。所以分成两个数据库。

这时刷新下数据库。

上面的过程就是dubbo的通过在tomcat容器中启动。一个简单的入门。晚上分享如何去写一个简单的rpc框架。

相关实践学习
基于MSE实现微服务的全链路灰度
通过本场景的实验操作,您将了解并实现在线业务的微服务全链路灰度能力。
相关文章
|
10小时前
|
负载均衡 监控 Dubbo
分布式框架-dubbo
分布式框架-dubbo
|
10小时前
|
存储 Dubbo 应用服务中间件
分布式-Dubbo-Dubbo的由来
分布式-Dubbo-Dubbo的由来
|
开发框架 负载均衡 Dubbo
带你读《Apache Dubbo微服务开发从入门到精通》—— 一、 Dubbo简介
带你读《Apache Dubbo微服务开发从入门到精通》—— 一、 Dubbo简介
882 3
带你读《Apache Dubbo微服务开发从入门到精通》—— 一、 Dubbo简介
|
监控 Dubbo Cloud Native
带你读《Apache Dubbo微服务开发从入门到精通》——三、 Dubbo核心特点(4)
带你读《Apache Dubbo微服务开发从入门到精通》——三、 Dubbo核心特点(4)
211 2
|
存储 Dubbo 网络协议
带你读《Apache Dubbo微服务开发从入门到精通》——三、 Dubbo核心特点(2)
带你读《Apache Dubbo微服务开发从入门到精通》——三、 Dubbo核心特点(2)
204 1
|
Dubbo Java 应用服务中间件
带你读《Apache Dubbo微服务开发从入门到精通》—— 一、 Dubbo服务发现设计
带你读《Apache Dubbo微服务开发从入门到精通》—— 一、 Dubbo服务发现设计
117 1
|
运维 Dubbo 数据可视化
带你读《Apache Dubbo微服务开发从入门到精通》——三、 Dubbo核心特点(1)
带你读《Apache Dubbo微服务开发从入门到精通》——三、 Dubbo核心特点(1)
259 1
|
负载均衡 Dubbo 数据可视化
带你读《Apache Dubbo微服务开发从入门到精通》——三、 Dubbo核心特点(3)
带你读《Apache Dubbo微服务开发从入门到精通》——三、 Dubbo核心特点(3)
256 4
|
Dubbo Java 应用服务中间件
带你读《Apache Dubbo微服务开发从入门到精通》—— 三、 Dubbo2协议(中)
带你读《Apache Dubbo微服务开发从入门到精通》—— 三、 Dubbo2协议(中)
77 1
|
JSON Dubbo fastjson
带你读《Apache Dubbo微服务开发从入门到精通》—— 三、 Dubbo2协议(下)
带你读《Apache Dubbo微服务开发从入门到精通》—— 三、 Dubbo2协议(下)
66 0