Dubbo学习系列之六(微服务架构实战)
看了最近文章的反馈,似乎波澜不惊的样子,应该是看官觉得都是小菜,那我就直上硬菜,人狠话不多,开始!
准备:Idea201902/JDK11/ZK3.5.5/Gradle5.4.1/RabbitMQ3.7.13/Mysql8.0.11/Lombok0.26/Erlang21.2/postman7.5.0
难度:新手--战士--老兵--大师
目标:1,模拟商城系统,订单服务RPC调用库存服务,同时物流服务 RPC调用订单服务(订单服务双重身份) 2.订单服务通过MQ消息机制与物流服务通信
步骤:
1.整体架构分析:
三服务:订单business,库存stock,物流logistics,business服务两个核心方法,一是未付订单处理,二是支付订单处理。stock服务一个核心方法,更新库存。logistics服务一个存快递单核心方法。四模块:common是公共模块,business

2.数据库设计,具体见sql脚本,5个table,其中delivery是快递,item是商品,order_detail是订单商品明细,

来个代表,order表字段设计,id做PK,BIGINT自增,order_id做订单号,为啥这么设计?id仅是PK,自增,有利于mysql的索引查询效率,mysql是按PK有序存储,pk简单有序,非常利于索引树查找,order_id具有业务含义,变化,值复杂,兼职做PK效率不高,反例就是直接使用自增id做订单号,等需要DB迁移时,就呵呵了,试想迁入的DB也有自增id字段。。。

3.mbg生成, RabbitMQ,Cors,统一异常,统一响应,均见往期文章,
4.改造下之前的MQ组件,com.biao.mall.common.service.MsgConsumer,将其中的URL变量去掉,放到sendPost参数中,注意这里是个json字符串,这样的妙处就是MsgConsumer完全作为一个独立的收消息组件了,只要有MQ消息,就处理,并根据json字符串的URL,发往目标URL,“高内聚,低耦合”,完美!反例就是将MQ消息接收放到各服务端。

5.写了两个BO(BusinessObject),业务对象,用于抽象对应真实的业务场景,只有与具体实际业务相关的属性。好处就是减少信息暴露风险,瘦身传输对象,还有如VO,DTO等,如下为OrderBO:

6. 写com.biao.mall.common.service.DubboOrderService,
两个方法,因是update,都加了事务注解,自动使用spring的事务管理,

7.写DubboOrderService实现,
com.biao.mall.business.impl.DubboOrderServiceImpl
只看重点:保存未付款订单方法,

前端传来一个orderBO,生成订单流程:使用雪花算法取得order_id,(见下节文章),然后就是写入数据库一个订单。常见的就是一个订单里多个商品,所以for循环处理,生成多个orderDetail,保存进DB。mbp的CRUD很方便,拿来就用,这里的 stockService即是RPC调用对象,不是spring的bean注入模式。

库存处理要注意,先看看剩余量,搞出库存负数就要和boss说拜拜了!
减库存模式:下单即减,下单加锁。下单即减,就直接减掉库存了,订单取消再返回来,简单粗暴。下单加锁,下单即锁住部分库存,不能用,但库存的数量包括锁住的,订单取消,只是取消锁住的部分。适用场景不同,下单即减在库存充足使用,下单加锁在秒杀,库存有限使用。我采用使用锁模式。12306就是典型的锁模式。
8.那既然调用到了stock服务,就来写service:
com.biao.mall.common.service.DubboStockService
updateStockRPC是DubboOrderServiceImpl中调用的,还有个updateStock,开发过程中废弃了,因不能RPC使用,因为参数QueryWrapper不支持RPC传递,MBP的缺陷?!

9.写stock服务的实现
com.biao.mall.stock.impl.DubboStockServiceImpl
注意点:updateById和update都是dao方法,但前者每次只更新一个,后者,呵呵,qw为null的话,全表update,务必保证qw非空!

10.再回来写com.biao.mall.business.impl.DubboOrderServiceImpl
订单付款处理:增加了快递服务的MQ逻辑,直接写入URL,并封装进消息。

for循环展开,里面一个细节:不需要if判断了?留给看官吧,

11. 写快递服务:com.biao.mall.common.service.DubboDeliveryService

12,写快递logistics服务com.biao.mall.logistic.impl.DubboDeliveryServiceImpl
的实现:RPC调用方式,

13.最后各模块的展开的全家福:

13.主体流程应该是:

14. 让马儿欢快地跑起来!启动:zk-->business-->stock-->logistics,可以看到服务已经成功注册到zk:

15.postman给个测试,模拟前端:第一条流程

16.订单数据库:

其他数据库就不一一细看了,
17.第二条流程测试:可以看到响应的是一个我们封装的对象。

18.项目源码地址:其中的day08
https://github.com/xiexiaobiao/dubbo-project.git
项目复盘记:
1.这个demo做出来,花了5个晚上,完全是从New-->Project开始的,一句话:纸上得来终觉浅,绝知此事要躬行!
2.dubbo的微服务架构,其实最核心就是这些,实际生产中就是服务更多,通信方式更多,并常有集群和负载均衡,其他一些中间件等。
3.Lombok不兼容典型表现,虽然实体类加了@Data,

4.既然是老兵级别,我想说些细节:a.字符串判空用StringUtil.isEmpty(); b.对象比较用Object.equals(), c.时间属性全部更新为localDateTime,代替Date,为了线程安全,d.对MQ做了抽象集中, e.实体属性用Integer f.表字段设计细节,
5.一个偶然发现,druid和mbg的版本要搭配好,否则出现,druid无法解析Date-->LocalDateTime
>>>>attempting to get column 'gmt_create' from result set. Cause: java.sql.SQLFeatureNotSupportedException
亲测:mbg3.1.2+druid1.1.18报错。mbg3.1.2+druid1.1.19正常!
5.如果前端传入就是非ISO格式,不带T的日期,我就是硬杠这个问题!经诊断,原因就是fastjson不能解析这个格式。解决:添加能解析的日期格式:com.biao.mall.common.util.MyDateFormat,并注入:com.biao.mall.common.conf.WebConfig

6.对DB中自增长的字段,务必要在entity上加上@TableId(type = IdType.AUTO),这个mbp也不会给自动加上,要手动设置。
测试:去掉后,insert前打印实体:DubboOrderEntity{ id=null, gmtCreate=2019-08-16T00:00,gmtModified=null,orderId='360059542158184448', >>>>>>>>> java.lang.IllegalArgumentException: argument type mismatch>>>>可见 id =null,导致无法insert,
添加后: ==> Preparing: INSERT INTO dubbo_order ( gmt_create, order_id, detail_id, order_desc, user_id ) VALUES ( ?, ?, ?, ?, ? ),可见,insert语句忽略了id字段,这正是想要的效果!
6.双重@service注解:有点意思! 测试完全ok。听说dubbo的@service不能和@Transactional 同时存在,有待验证!

7.模块间不能循环依赖,如 A-->B,B-->A,会提示出错:Circular dependency between the following tasks:
解决方法:将B中的部分转移到A,或到公共模块,避免循环。
8.遇到错误 >>> qos-server can not bind localhost:22222,
知识点:Qos=Quality of Service,qos是Dubbo的在线运维命令,可以对服务进行动态的配置、控制及查询,原因:provider已经使用了默认的qos端口导致consumer启动时使用默认的出错,配置为不同的端口即可。
9.遇到错误>>>com.alibaba.dubbo.rpc.RpcException: Unsupported client type: curator, supported client type is grizzly mina netty netty3 netty4
可能的问题:org.apache.curator 依赖未加入模块依赖
10.遇到错误提示:

问题分析:这里提示键值重复,我在DB中将该字段设置为UQ,目的是防止重复,这里却产生了问题,因为mybatis的单表默认方法:dubboStockDao.update(stockEntity,qw)生成的SQL是除了PK外,直接set其他所有字段,导致无法更新。解决:1.dao中自己写update方法,除去UQ字段 2,更好的:DB中的字段,都不要使用UQ,应该在应用层处理,这是个原则,DB只存数据,尽量少逻辑
11.其实上面这个项目有个重大的bug,各位看官可以思考下,且看我下回分解。
12.码字N小时,上头了.
往期文章推荐:

Dubbo学习系列之六(微服务架构实战)的更多相关文章
- springcloud与docker微服务架构实战--笔记
看了<微服务那些事>之后,Spring boot和Spring Cloud的关系理清楚了,Spring cloud各个模块的作用也了解了. 但是,Spring cloud 与Docker的 ...
- 庐山真面目之六微服务架构Consul集群、Ocelot网关集群和Nginx版本实现
庐山真面目之六微服务架构Consul集群.Ocelot网关集群和Nginx版本实现 一.简介 在上一篇文章<庐山真面目之五微服务架构Consul集群.Ocelot网关和Nginx版本实 ...
- 《Spring Cloud与Docker微服务架构实战》配套代码
不才写了本使用Spring Cloud玩转微服务架构的书,书名是<Spring Cloud与Docker微服务架构实战> - 周立,已于2017-01-12交稿.不少朋友想先看看源码,现将 ...
- Dubbo和Spring Cloud微服务架构比较
Dubbo 出生于阿里系,是阿里巴巴服务化治理的核心框架,并被广泛应用于中国各互联网公司:只需要通过 Spring 配置的方式即可完成服务化,对于应用无入侵,设计的目的还是服务于自身的业务为主. 微服 ...
- Dubbo 和 Spring Cloud微服务架构 比较及相关差异
你真的了解微服务架构吗?听听八年阿里架构师怎样讲述Dubbo和Spring Cloud微服务架构. 微服务架构是互联网很热门的话题,是互联网技术发展的必然结果.它提倡将单一应用程序划分成一组小的服务, ...
- Spring Cloud与Docker微服务架构实战 PDF版 内含目录
Spring Cloud与Docker微服务架构实战 目录 1 微服务架构概述 1 1.1 单体应用架构存在的问题1 1.2 如何解决单体应用架构存在的问题3 1.3 什么是微服务3 1.4 微服务 ...
- Dubbo和Spring Cloud微服务架构'
微服务架构是互联网很热门的话题,是互联网技术发展的必然结果.它提倡将单一应用程序划分成一组小的服务,服务之间互相协调.互相配合,为用户提供最终价值.虽然微服务架构没有公认的技术标准和规范或者草案,但业 ...
- dubbo和dubboX与微服务架构(dubbo一)
一.传统三层架构模式的缺陷 三层架构(3-tier architecture) 通常意义上的三层架构就是将整个业务应用划分为:界面层(User Interface layer)web.业务逻辑层(Bu ...
- 你真的了解微服务架构吗?听听八年阿里架构师怎样讲述Dubbo和Spring Cloud微服务架构
微服务架构是互联网很热门的话题,是互联网技术发展的必然结果.它提倡将单一应用程序划分成一组小的服务,服务之间互相协调.互相配合,为用户提供最终价值.虽然微服务架构没有公认的技术标准和规范或者草案,但业 ...
随机推荐
- Python-车牌识别
一.车牌识别系统的用途与技术车牌识别系统(Vehicle License Plate Recognition,VLPR) 是计算机视频图像识别技术在车辆牌照识别中的一种应用.车牌识别在高速公路车辆管理 ...
- matlab实现PSNR
目录 1.PSNR原理 2.PSNR的matlab实现代码 3.针对彩色图像的PSNR的matlab代码 @ 1.PSNR原理 PSNR,峰值信噪比,通常用来评价一幅图像压缩后和原图像相比质量的好坏, ...
- js杂项积累
主要内容: 一 浏览器重定向Http请求跨域 二 html select标签 可以设置属性multipe,变为多选 三 document.wirte只应在script标签的顶层代码中使用.不能放在函数 ...
- 基于Win服务的标签打印(模板套打)
最近做了几个项目,都有在产品贴标的需求 基本就是有个证卡类打印机,然后把产品的信息打印在标签上. 然后通过机器人把标签贴到产品上面 标签信息包括文本,二维码,条形码之类的,要根据对应的数据生成二维码, ...
- GO富集分析示例【华为云技术分享】
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/devcloud/article/detai ...
- #华为云·寻找黑马程序员#微服务-你真的懂 Yaml 吗?
在Java 的世界里,配置的事情都交给了 Properties,要追溯起来这个模块还是从古老的JDK1.0 就开始了的. "天哪,这可是20年前的东西了,我居然还在用 Properties. ...
- pop 与 popitem
pop给出一个键弹出值 popitem弹出一个项 >>> a.pop(2)'two'>>> a{1: 'one', 3: 'three', 4: 'four'}&g ...
- flutter最简单轻量便捷的路由管理方案NavRouter
大家好,我是CrazyQ1,今天给大家推荐一个路由管理方案,用的非常不错的,叫nav_router. 项目地址是:https://github.com/fluttercandies/nav_route ...
- 机器学习python*(深度学习)核心技术实战
Python实战及机器学习(深度学习)技术 一,时间地点:2020年01月08日-11日 北京(机房上课,每人一台电脑进行实际案例操作,赠送 U盘拷贝资料及课件和软件)二.课程目标:1.python基 ...
- 设计模式GOF23(行为型模式)
场景: – 公司里面,报销个单据需要经过流程: • 申请人填单申请,申请给经理 • 小于1000,经理审查. • 超过1000,交给总经理审批. • 总经理审批通过 – 公司里面,请假条的审批过程: ...