Spring Boot微服务电商项目开发实战 --- 分布式开发要避的那些坑
今天已经进入第七讲了,整个微服务架构的搭建工作也基本完成。那到目前为止究竟使用了那些技术及实现了什么功能呢?我们先回顾一下。
使用的技术:SpringBoot、Dubbo、Zookeeper、Redis、Kafka
实现的功能:
1,Maven父子级项目,实现了分环境部署配置及服务端口号统一配置
2,Dubbo的集成接入、服务层分模块实现,提供者(四个)和消费者(一个)的配置及服务调用,微服务落地实现。
3,Maven子模块项目(接口及服务层)的版本号统一配置管理实现。
4,Redis的接入、单点登录及分布式缓存实现。
5,接口安全防范,令牌、签名及撒盐算法实现,过滤器对签名、token校验及拦截处理。
6,全局异常处理,Aop日志打印,防SQL注入拦截处理实现。
看到这些满满的干货,不知大家对最近我的系列文章还满意吗?接下来我会继续深入,慢慢探索和讲解实现电商微服务背后的技术应用及真相。
目前项目模块如下:
到目前为止,仅仅实现了四个微服务(提供者)用来项目实战的演示,随着后面的慢慢深入,微服务也会持续增多。今天,我要说说分布式项目中自己踩过的那些坑。
1,实体序列化问题
如果没做过分布式开发的小伙伴,这里一定得注意,如果你项目中的实体不序列化,就会造成无法实现远程过程调用,消费者在接收提供者服务返回的实体时,就会抛异常。
为什么一定要序列化呢?有人可能会说我之前做的项目,实体都没有序列化不是运行的好好的嘛。那是因为你之前的项目所有代码都在一个Web容器里运行,也就是说:你之前的整个项目就在一个JVM里。
但分布式项目就不一样了,提供者和消费者是在不同的web容器里运行(不同的JVM)。消费者在进行远程方法调用时,实际就是消费者的jvm在调用提供者jvm里的对象,但这个对象在消费者的jvm里并不存在,那要获取就得用Java对象序列化来解决。简而言之:序列化的作用就是为了不同jvm之间共享实例对象的一种解决方案。
2,分布式环境生成编号问题
这是我在项目中真真实实跳过的坑,根据之前多年项目的开发经验,一般编号(客户,商品、订单等编号)的生成规则基本都是借助于数据库的自增id实现,看似本来通用的解决方案,在分布式项目中,竟然是给自己埋坑。
之前的编号实现方式:在添加数据方法的Service实现里,先查询获得数据库最大ID对应的编号,然后给这个编号+1生成新编号作为当前新增数据的编号插入数据库。开始看着很完美,但后来突然有人反映编号重复,这就奇怪了?加班趴着debug代码,但就是找不出来问题的原因。面对这种突如其来的问题完全不知所措,不得不求助网络,各种搜索后才明白,是提供者集群惹的祸。
原因分析:当两个及以上并发请求同时进入集群中的不同提供者时,一个提供者的Service实现在生成编号并插入数据之前,另一个提供者的Service也查询了数据库并获取了跟前一个提供者获取相同的最大编号。导致两台服务最终生成的编号相同。那可能也有人说了,你先插入数据,然后根据插入数据生成的自增id再去生成编号更新数据库不就解决了。但你有没想过,更新数据库操作需要锁表,在高并发请求的情况下,这会造成很大的性能瓶颈。
目前流行的解决方案:雪花算法,是完全基于代码实现,不依赖数据库。
上图只是部分代码,我们看到这个工具类实现了单例模式,生成的编号是:时间(到毫秒)+ ip(后面取了4位) + 自增序列。
我来演示下效果吧,先写个main方法实例化工具类,并写for循环生成编号
我红框圈出来的,是在同一时间,虽然时间和四位ip相同,但后三位的自增序列值一直在递增。那如果服务端做集群呢,是不是编号又会重复?就算在同一时间的高并发请求,几个服务终端可能会生成时间相同、后三位序列号相同的编号,但是,不同终端通过ip最后获取的四位值肯定不同。所以不可能有重复出现。
3,日志统一打印问题
分布式环境中,如果每个服务的日志分散到各自服务所在机器上,那么以后如果线上出现异常或日志收集及分析检查时,会让你痛苦不已,集群和服务规模小还好,特别是在负载均衡后的多个服务实例,你无法确定某个请求被谁接收了,所以只能翻看每个实例的日志。
处理方案:Service业务实现层不要捕获异常,直接通过throws全部往外抛。
然后在接口层在做相应的统一处理,比如Aop里打印,或使用日志框架(如:ELK)统一收集等。这样如果你的服务层做了集群,线上报错你也不用纠结去哪个服务器看服务提供者的日志,你只要到对应接口层服务查看输出的日志或统一收集的地方去查看。
获取项目源代码,请扫码关注公众号,并发送Springboot获取。

Spring Boot微服务电商项目开发实战 --- 分布式开发要避的那些坑的更多相关文章
- Spring Boot微服务电商项目开发实战 --- 基础配置及搭建
根据SpringBoot实现分布式微服务项目近两年的开发经验,今天决定开始做SpringBoot实现分布式微服务项目的系列文章,帮助其他正在使用或计划使用SringBoot开发的小伙伴们.本次系列文章 ...
- Spring Boot微服务电商项目开发实战 --- 多环境部署配置、端口号统一配置及Dubbo提供者消费者实现
昨天已经搭建好了SpringBoot基于Maven的基础父子级项目,今天开始进入项目分模块及分布式实现.首先我们基于昨天的项目,在父级工程下建lyn-sys,lyn-customer,lyn-good ...
- Java 18套JAVA企业级大型项目实战分布式架构高并发高可用微服务电商项目实战架构
Java 开发环境:idea https://www.jianshu.com/p/7a824fea1ce7 从无到有构建大型电商微服务架构三个阶段SpringBoot+SpringCloud+Solr ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统(十九)——分布式事务之Saga模式
在之前的系列文章中聊过分布式事务的一种实现方案,即通过在集群中暴露actor服务来实现分布式事务的本地原子化.但是actor服务本身有其特殊性,场景上并不通用.所以今天来讲讲分布式事务实现方案之sag ...
- 微服务电商项目发布重大更新,打造Spring Cloud最佳实践!
Spring Cloud实战电商项目mall-swarm地址:转发+关注 私信我获取地址 系统架构图 系统架构图 项目组织结构 mall├── mall-common-- 工具类及通用代码模块├─ ...
- SpringBoot微服务电商项目开发实战 --- 模块版本号统一管理及Redis集成实现
上一篇文章总结了基于SpringBoot实现分布式微服务下的统一配置.分环境部署配置.以及服务端模块的分离(每一个提供者就是一个独立的微服务).微服务落地.Dubbo整合及提供者.消费者的配置实现.本 ...
- SpringBoot微服务电商项目开发实战 --- api接口安全算法、AOP切面及防SQL注入实现
上一篇主要讲了整个项目的子模块及第三方依赖的版本号统一管理维护,数据库对接及缓存(Redis)接入,今天我来说说过滤器配置及拦截设置.接口安全处理.AOP切面实现等.作为电商项目,不仅要求考虑高并发带 ...
- SpringBoot微服务电商项目开发实战 --- Redis缓存雪崩、缓存穿透、缓存击穿防范
最近已经推出了好几篇SpringBoot+Dubbo+Redis+Kafka实现电商的文章,今天再次回到分布式微服务项目中来,在开始写今天的系列五文章之前,我先回顾下前面的内容. 系列(一):主要说了 ...
- SpringBoot微服务电商项目开发实战 --- 全局异常处理
上一篇文章讲了Redis缓存的安全防范及Kafka的接入及消息实现,今天接着前面的内容基础说说项目的优化和基础配置,今天要讲的内容主要是Spring Boot项目中的全局异常处理.为什么要做这件事呢? ...
随机推荐
- day 36 初始前端 html语言
参考博客https://www.cnblogs.com/majj/p/9056951.html进行学习 html标签 特征: .空白折叠现象 .对空格和换行不敏感 .标签要严格封闭 p标签的嵌套 多注 ...
- Selenium多层级的iframe中元素的定位
很多时候我们遇到多层级的iframe就会想各种方法去获取iframe中的元素,但其实很简单就可以做到的,就是一级一级获取就可以了,获取至你需要的那个层级即可,下面看下实际的案例:(转) <fra ...
- 从BWM生产学习工厂模式
工厂模式应用非常之广,在JDK底层源码以及各大主流框架中随处可见,一般以Factory结尾命名的类,比如Mybatis中的SqlSessionFactory,Spring中的BeanFactory等, ...
- 查找节点(getAttribute())
getAttribute():方法将返回一个给定元素的一个给定属性节点的值: attributeValue = element.getAttribute(attributeName); 给定属性的名字 ...
- Java基础部分(11~20)
11."=="和 equals 方法究竟有什么区别? (单独把一个东西说清楚,然后再说清楚另一个,这样,它们的区别自然就出来了,混在一起说,则很难说清楚) ==操作符专门用来比较两 ...
- [学习笔记] [数据分析] 01.Python入门
1.安装Python与环境配置 ① ② 安装pip以及利用pip安装Python库 2.Anaconda安装 conda list 要在root环境下 3.常用数据分析库 ① Numpy 安装:con ...
- Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览
本文是Spring Cloud专栏的第一篇文章,了解本篇文章内容有助于更好的理解后面文章 一.网站架构演变过程 1-1.传统架构 传统的SSH架构,分为三层架构 web控制层.业务逻辑层.数 ...
- 区块链学习笔记:D02 区块链的技术发展历史和趋势
对于区块链的技术发展历史,其实在我的印象中也就对比特币有所了解,也听过什么火币之类的玩意,但是具体是什么.怎么运作的就不清楚了... 这次的内容首先是讲解了区块链的技术演进,一张图一目了然,虽然里面涉 ...
- 转:关于JAVA项目中CLASSPATH路径详解
在dos下编译Java程序,就要用到classpath这个概念,尤其是在没有设置环境变量的时候.classpath就是存放.class等编译后文件的路径. javac:如果当前你要编译的Java文件中 ...
- STM32F4 阿波罗寄存器 进阶版LED灯
上一节通过使用操作地址的方式进行了寄存器的操作,接下来通过两个部分,实现进阶版的操作寄存器(将寄存器的地址进行命名,然后使用名字进行调用 比如商场的A座5楼345号为卖玩具的,我们可以定义地址为sh ...