入门级微服务项目搭建:八、集成远程调用框架Dubbo
Dubbo是阿里团队研发的一个rpc框架,在本项目中使用Dubbo来实现服务之间的连接、沟通,它的具体作用其实就是一个模块去调取另一个模块对外暴露的服务,只不过Dubbo不是基于http协议的,而是基于tcp协议的之上构建的rpc协议。其原理就不在本篇文章中过多阐述了,先实战将它集成到项目中吧。
1.新建订单模块
创建模块过程与之前类似,结构如下所示:
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***注解
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 创建公共接口模块
在该模块中我们将需要远程调用的方法,现在该模块中以接口的形式编写好,然后服务提供者实现该接口,真正对外提供服务,消费者直接使用即可。
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
总结:如上图所示,请求成功,说明Dubbo已经成功集成到项目中了。