入门级微服务项目搭建:八、集成远程调用框架Dubbo

Dubbo是阿里团队研发的一个rpc框架,在本项目中使用Dubbo来实现服务之间的连接、沟通,它的具体作用其实就是一个模块去调取另一个模块对外暴露的服务,只不过Dubbo不是基于http协议的,而是基于tcp协议的之上构建的rpc协议。其原理就不在本篇文章中过多阐述了,先实战将它集成到项目中吧。

1.新建订单模块

创建模块过程与之前类似,结构如下所示:

远程查看微服务的 Deployment 配置文件_dubbo

OrderController:

package com.wcc.systemorder.controller;

import com.wcc.mallcloudcommon.result.Result;
import com.wcc.systemorder.service.OrderService;
import lombok.RequiredArgsConstructor;
import org.bouncycastle.cms.PasswordRecipientId;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author wcc
 * @createTime 2024年05月16日 15:48:00
 */
@RestController
@RequestMapping("/order")
@RequiredArgsConstructor
public class OrderController {
    private final OrderService orderService;

    @PostMapping("/create_order")
    public Result createOrder(Integer userId)
    {
        return orderService.createOrder(userId);
    }
}

OrderService:

package com.wcc.systemorder.service;

import com.wcc.mallcloudcommon.result.Result;

/**
 * 订单 业务层接口
 * @author wcc
 * @createTime 2024年05月16日 15:01:00
 */
public interface OrderService {
    Result createOrder(Integer userId);
}

OrderServiceImpl:

package com.wcc.systemorder.service.impl;

import com.wcc.mallcloudapi.service.RemoteUserService;
import com.wcc.mallcloudcommon.domain.Order;
import com.wcc.mallcloudcommon.domain.User;
import com.wcc.mallcloudcommon.result.Result;
import com.wcc.systemorder.dao.OrderMapper;
import com.wcc.systemorder.service.OrderService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;

/**
 *	订单 业务层接口实现类
 * @author wcc
 * @createTime 2024年05月16日 15:03:00
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class OrderServiceImpl implements OrderService {
    private final OrderMapper orderMapper;

    @Override
    public Result createOrder(Integer userId) {
        try{
            // TODO: 2024/5/16 调用用户模块查询用户信息 
            Order order=new Order();
            order.setUserId(userId);
            order.setOrderCode("M"+System.currentTimeMillis());
            order.setPrice(new BigDecimal(10.00));
            order.createInit();
            orderMapper.insert(order);
            return Result.success("创建订单成功");
        }catch (Exception e){
            log.error("创建订单失败",e);
            return Result.error("创建订单失败");
        }
    }
}

OrderMapper:

package com.wcc.systemorder.dao;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wcc.mallcloudcommon.domain.Order;
import org.apache.ibatis.annotations.Mapper;

/**
 * 订单 dao层接口
 * @author wcc
 * @createTime 2024年05月16日 14:59:00
 */
@Mapper
public interface OrderMapper extends BaseMapper<Order> {
}

common模块中新增Order实体类:

package com.wcc.mallcloudcommon.domain;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;

/**
 * 订单实体类
 * @author wcc
 * @createTime 2024年05月16日 14:02:00
 */
@Data
@TableName("m_order")
public class Order extends BaseDomain implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * id自动递增
     */
    @TableId(type= IdType.AUTO)
    private Integer id;
    /**
     * 订单编号
     */
    private String orderCode;
    /**
     * 用户id
     */
    private Integer userId;
    /**
     * 订单金额
     */
    private BigDecimal price;
    /**
     * 订单状态(0:未完成,1:已完成)
     */
    private Integer status;
    /**
     * 订单创建时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date orderDate;

    /**
     * 创建初始化
     */
    public void createInit(){
        this.setStatus(0);
        this.setOrderDate(new Date());
        this.setDelFlag(0);
        this.setCreateDate(new Date());
        this.setUpdateDate(new Date());
    }

}

2.数据库新建m_order表

sql语句如下:

CREATE TABLE `m_order` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `order_code` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '订单编号',
  `price` decimal(10,2) DEFAULT NULL COMMENT '订单总价',
  `status` int DEFAULT NULL COMMENT '订单状态(0:未完成,1:已完成)',
  `user_id` int DEFAULT NULL COMMENT '用户id',
  `order_date` timestamp NULL DEFAULT NULL COMMENT '订单创建时间',
  `remark` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '备注',
  `del_flag` int DEFAULT NULL COMMENT '是否删除(0:未删除,1:已删除)',
  `create_date` timestamp NULL DEFAULT NULL COMMENT '创建时间',
  `update_date` timestamp NULL DEFAULT NULL COMMENT '修改时间',
  `create_by` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '创建者',
  `update_by` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '修改者',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='订单';

3.集成Dubbo

3.1 用户模块和订单模块的启动类加上***@EnableDubbo***注解

远程查看微服务的 Deployment 配置文件_User_02

远程查看微服务的 Deployment 配置文件_架构_03

3.2 yml配置文件中添加dubbo配置

用户模块:

#dubbo配置
dubbo:
  application:
    name: system-user
  registry:
    address: nacos://127.0.0.1:8848
    parameters:
      namespace: 65c5f8cb-1afd-420a-b725-f24cedc22475
    username: nacos
    password: nacos
  protocol:
    name: dubbo
    port: 15000

订单模块:

#dubbo配置
dubbo:
  application:
    name: system-order
  registry:
    address: nacos://127.0.0.1:8848
    username: nacos
    password: nacos
    parameters:
      namespace: 65c5f8cb-1afd-420a-b725-f24cedc22475
  protocol:
    name: dubbo
    port: 15001

3.3 创建公共接口模块

在该模块中我们将需要远程调用的方法,现在该模块中以接口的形式编写好,然后服务提供者实现该接口,真正对外提供服务,消费者直接使用即可。

远程查看微服务的 Deployment 配置文件_spring_04

RemoteUserService:

package com.wcc.mallcloudapi.service;

import com.wcc.mallcloudcommon.domain.User;

/**
 * 用户远程调用接口层
 * @author wcc
 * @createTime 2024年05月16日 14:29:00
 */
public interface RemoteUserService {
    User queryUserById(Integer id);
}

3.4 服务提供者实现接口,对外暴露服务

在本项目现在的示例中,用户模块作为服务提供方。具体实现代码如下:

package com.wcc.systemuser.dubbo;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wcc.mallcloudapi.service.RemoteUserService;
import com.wcc.mallcloudcommon.domain.User;
import com.wcc.systemuser.dao.UserMapper;
import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboService;

/**
 * 用户 远程调用实现类
 * @author wcc
 * @createTime 2024年05月16日 14:53:00
 */
@DubboService
@RequiredArgsConstructor
public class RemoteUserServiceImpl implements RemoteUserService {
    
    private final UserMapper userMapper;
    
    @Override
    public User queryUserById(Integer id) {
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("id", id).eq("del_flag", 0));
        return user;
    }
}

3.5 消费者消费服务

package com.wcc.systemorder.service.impl;

import com.wcc.mallcloudapi.service.RemoteUserService;
import com.wcc.mallcloudcommon.domain.Order;
import com.wcc.mallcloudcommon.domain.User;
import com.wcc.mallcloudcommon.result.Result;
import com.wcc.systemorder.dao.OrderMapper;
import com.wcc.systemorder.service.OrderService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;

/**
 * 订单 业务层接口实现类
 * @author wcc
 * @createTime 2024年05月16日 15:03:00
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class OrderServiceImpl implements OrderService {
    private final OrderMapper orderMapper;

    @DubboReference
    private RemoteUserService remoteUserService;

    @Override
    public Result createOrder(Integer userId) {
        try{
            User user = remoteUserService.queryUserById(userId);
            if(ObjectUtils.isEmpty(user)){
                return Result.error("创建订单失败,用户不存在");
            }
            Order order=new Order();
            order.setUserId(userId);
            order.setOrderCode("M"+System.currentTimeMillis());
            order.setPrice(new BigDecimal(10.00));
            order.createInit();
            orderMapper.insert(order);
            return Result.success("创建订单成功");
        }catch (Exception e){
            log.error("创建订单失败",e);
            return Result.error("创建订单失败");
        }
    }
}

4.测试Bubbo

远程查看微服务的 Deployment 配置文件_微服务_05

远程查看微服务的 Deployment 配置文件_架构_06

总结:如上图所示,请求成功,说明Dubbo已经成功集成到项目中了。