2024年海量订单系统微服务开发:订单接口管理后台微服务开发、集成测试,2024年最新程序员必学

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化的资料的朋友,可以戳这里获取

orderQo .setsize(size);

if(CommonUtils.isNotNull (userid)){

orderQo.setUserid(userid);

}

if(CommonUtils.isNotNull (merchantid)){

orderQo.setMerchantid (merchantid);

}

if(CommonUtils.isNotNull(status)){

orderQo.setStatus(status);

if(CommonUtils.isNotNull (start)){

SimpleDateFormat sdf = new SimpleDateFormat ("yyyy-MM-dd

HH:mm: ss");

orderQo .setstart(sdf.parse(start));

}

if(CommonUtils.isNotNull (end)){

SimpleDateFormat sdf = new SimpleDateFormat ("yyyy-MM-dd

HH:mm:sS");

orderQo .setEnd(sdf.parse(end));

}

return orderService.findAll (orderQo);}catch (Exception e){

e.printStackTrace()😉

return null;

CPostMapping()

public Mono save (CRequestBody Ordergo orderQo) throws Exception{

Order order = CopyUtil.copy(orderQo,Order.class);

ListdetailList=

CopyUtil.copyList(orderQo.get0rderDetails(),OrderDetail.class);

order.setOrderDetails(detailList);

Mono response = orderService.save (order).then();

log.info(“新增=”+ response);

return response;

}

}

由于使用反应式的编程方法,所以不管是哪一种接口的设计,最后都必须返回一个异步序列,例如 Mono或者Flux。

对于分页查询,则必须检测每个查询参数,只有非空,才提供相关的查询条件。注意日期类型的参数,因为在传输过程中只能使用文本方式,所以最后在提交查询条件时必须将其转换为日期类型的数据。

在订单生成的设计中,因为接收的参数是查询对象OrderQo,所以最终必须将其转换成文档Order。每一个订单明细都必须进行转换。

订单的分布式事务管理

==========

集中式的数据管理可以在一个事务中完成,所以能保证数据的高一致性。微服务的多服务架构,使得数据可以由不同的微服务进行分散管理,所以想要保证数据的一致性,就必须有合理的设计。

对于订单来说,订单的状态变化与库存、物流、评价等各个服务息息相关,所以订单的状态变化,会涉及分布式事务管理的问题。比如当买家撤销订单时,库存服务的商品存量必须改变。

对于分布式事务管理,我们可以依据CAP原理的BASE理论实现数据最终一致性设计。

CAP (Consistency,Availability,Partition Tolerance)即一致性、可用性和分区容错性,三者不可兼得。

BASE(Basically Available,Soft State,Eventually Consistent)即基本可用、软状态和最终一致性。BASE是对CAP中一致性和可用性进行权衡的结果。

在微服务设计中,数据最终一致性设计主要使用两种方法实现,一种是通过接口调用实现实时同步操作,另一种是使用消息通道以事件响应的方式进行异步处理。

这里,我们以订单取消为例,使用异步消息传输,实现分布式事务管理的数据最终一致性设计。

订单取消的消息生成

首先,在order-restapi模块的项目对象模型配置中引入AMQP的消息组件依赖,代码如下所示:

org.springframework.cloud

spring-cloud-starter-bus-amap

其次,在配置文件中,设置连接RabbitMQ服务器的配置,代码如下所示:

spring:

rabbitmq:

addresses: amap://localhost:5672username: develop

password: develop

服务地址、端口、用户名和密码等参数需根据RabbitMQ的安装和配置进行设定。

下面,我们创建一个消息发送器MessageSender,用来发送 MQ (Message Queue),代码如下所示:

@service

public class MessageSender {

private static Logger logger =

LoggerFactory.getLogger (MessageSender.class);

@Autowired

private AmqpTemplate amqpTemplate;

public void OrderUpdateMsg (0rderQo orderQo){

MessageProperties messageProperties = new MessageProperties();

messageProperties.setDeliveryMode(MessageDeliveryMode.PERSISTENT);messageProperties.setContentType(“UTF-8”);

String json = new Gson().toJson(orderQo);

Message message = new Message (json.getBytes(),messageProperties);

amapTemplate.send (“ordermsg.update”, message);//接收端必须使用相同队列

logger.info(“发送订单变更消息:{}”, json) ;

}

}

这里使用查询对象 OrderQo发送了一个完整的订单信息。

注意,这里的消息队列的名称设定为“ordermsg.update”,所以,消息接收方必须使用这个队列名称才能接收订单状态变化的相关信息。

最后,我们在订单修改这个接口中,使用消息发送器生成一条异步消息,代码如下所示:

@RestController

@RequestMapping (“/order”)@Slf4j

public class OrderRestController {

@Autowired

private OrderService orderService;

@Autowired

private MessageSender messageSender;

CPutMapping()

public Mono update (@RequestBody OrderQo orderQo) throws Exception{

Order order = CopyUtil.copy(orderQo, Order.class);

order.setModify(new Date());

List<0rderDetail> detailList =

CopyUtil.copyList(orderQo.get0rderDetails(),OrderDetail.class);

order.setorderDetails(detailList);

Mono response = orderService.save(order).then();

//发送 MQ消息,通知订单修改

messageSender.OrderUpdateMsg(orderQo);

log.info(“修改=”+ response);

return response;

}

}

上面就是在分布式事务设计中消息生产方的一个设计实例。接下来,我们看看消息消费者是如何接收消息的,以完成一次分布式事务的过程。

订单取消的库存变化处理

接收订单取消的消息处理是在库存管理项目goods-microservice的goods-restapi模块中实现的。其中,MQ的组件依赖和服务器连接的配置与前面的基本相同。

在库存接口微服务应用中,我们只需设计一个订单消息接收器MessageOrderReceiver,就可以完成消息监听、消息接收、消息处理的相关操作,代码如下所示:

@component

public class MessageOrderReceiver {

private static Logger logger=

LoggerFactory.getLogger (MessageOrderReceiver.class);

@Autowired

private GoodsService goodsService;

@RabbitListener(queuesToDeclare = CQueue (value = “ordermsg.update”))public void orderUpdate (byte[] body) {

logger.info(“----------订单变更消息处理----------”);try {

OrderQo orderQo =new Gson ().fromJson (new String (body,“UTF-8”),

OrderQo.class);

if(orderQo != null) {

logger.info(“接收订单更新消息,订单编号=”+orderQo.getorderNo());

if (orderQo.getStatus() !=null && orderQo.getStatus() <0){

List<0rderDetailQ0> list = orderQo.getorderDetails();

for (orderDetailQo orderDetailQ0 : list) {

Goods goods =

goodsService.getById(orderDetailQo.getGoodsid());

if(goods != null){

Integer num= goods.getBuynum() != null &&

goods.getBuynum() >0?

goods.getBuynum() - 1 :0;

goods.setBuynum (num) ;

goodsservice.update(goods);

logger.info(“更新了商品购买数量,商品名称=”+

goods.getName ());

}

}

}

}

}

catch (Exception e) {

e.printStackTrace();

}

}

}

这里我们监听了消息队列“ordermsg.update”,将接收的消息转换成查询对象OrderQo,这样,即可根据订单状态和订单明细中的商品数据,决定是否执行商品库存存量减少的操作,完成一次分布式事务管理的整个流程。

订单管理后台微服务开发

===========

订单管理后台微服务是为商家提供的一个PC端的Web微服务应用,它的设计在订单微服务项目的order-web模块中。在这个模块中,含有微服务接口调用和页面设计等内容,与前面章节中类目管理和库存管理项目的设计大同小异。这里只针对一些不同点进行详细介绍,其他方面可以参照前面章节。

订单查询主页设计

订单后台主页控制器 OrderController的设计代码如下所示:

@RestController

@RequestMapping(" /order")

public class OrderController {

private static Logger logger =

LoggerFactory.getLogger(0rderController.class);

@Autowired

private OrderRestService orderRestservice;

CRequestMapping(value=“/index”)

public ModelAndView index (ModelMap model) throws Exceptionl

//订单状态枚举集合

StatusEnum[] statuses = StatusEnum.values();model .addAttribute( “statuses”, statuses);

return new ModelAndview( “order/index”);

@RequestMapping (value=“/{id}”)

public ModelAndview findById (@PathVariable String id,ModelMap model)

String json = orderRestService.findById(id);

OrderQo orderQo =new Gson().fromJson(json,OrderQo.class);

model .addAttribute (“status”,

StatusEnum.valueOf(orderQo. getStatus()).getName ());

model.addAttribute( " order",orderQo);

return new ModelAndView(“order/show”);

}

@RequestMapping(value = “/list”)

public Page<Map<String,0bject>> findAll(Ordergo orderQo) throws Exception {

String json = orderRestService.findPage (orderQo);

Pageable pageable = PageRequest.of (orderQo.getPage(),orderQo.getSize (),

null);

List<0rderQo> list = new Gson() .fromJson(json,new

TypeToken<List<0rderQ0>>(){}.getType());

for(0rderQo order : list){

order.setStatusStr (StatusEnum. valueOf (order.getStatus()) .getName ());

}

String count =orderRestService.getCount();

return new PageImpl(list, pageable, new Long (count));

}

}

这几个方法中都用到了订单状态的枚举类型集合StatusEnum,使用这个集合,为我们在订单查询和参数转换中提供很多方便。

其中在分页查询中,调用了两次订单接口,一次用来取得订单列表,另一次用来取得订单总数。通过这个总数,才能计算出总的页数。另外,对于列表中订单状态的显示,在这里提前进行了转换处理,这样在后面的页面设计中,就可以直接使用。

基于订单状态的枚举集合,主页页面设计中的查询条件设计代码如下所示:

  • 全部

    img
    img
    img

    既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!

    由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

    需要这份系统化的资料的朋友,可以戳这里获取

    t">订单状态

    全部

    [外链图片转存中…(img-LTSs2KRk-1715166321005)]
    [外链图片转存中…(img-onXfxQL7-1715166321005)]
    [外链图片转存中…(img-0I7OSxjs-1715166321005)]

    既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!

    由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

    需要这份系统化的资料的朋友,可以戳这里获取

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值