承蒙各位的厚爱,得到了250+的star,我倍感惊喜~不过这个项目我是存在很大的遗憾的,一直想重构下代码并且留下完整的笔记,也让一些联系我的朋友有点难以下手。但是我又担心没有此能力,会对大家造成误导。现在呢,我新开辟了一个新项目,仓库地址为:https://github.com/sunweiguo/xiaoxiaoxudeshop
这个项目我跟着大牛老师做一做,并且我会根据自己的理解进行代码的重构(我觉得有很多值得优化的点,还有就是支付,我还是想用原生的接入方式而不是课程中说的接入它的支付中心,所以我打算还是用支付宝扫码支付作为支付手段,以及其他的一些点,比如图片上传啥的),最终我会像模像样地部署到云服务器上。
最最重要的一点是:单体架构从0到1的过程,我会完整记录笔记,一步一个截图。目前已经有了四个笔记,还在努力更新中~
我写在这里的原因,一方面是希望帮助到一些朋友,另一方面也是勉励自己,毕竟不为收入,只为做些对自己、对他人有意义的事情。所以还是希望看到的朋友多多star,多多留下宝贵意见。其他就不多说了。。。
前方图片高能...更有几十兆gif演示动画,图片全部存放于七牛云上。
2019/5/8 演示网站不可用。关于这个电商后端的功能实现(第一期项目),我做过笔记,可以看看:http://note.youdao.com/noteshare?id=35c4469a6d7257d8233eb1441e2edd49
一直以来都是学习慕课的实战视频,虽然也跟着做出了一些东西,但是思路都是别人提供好的,脱离了老师,我一直在问自己一个问题:能不能独立地按照自己的思路做出一些东西来?
带着这个想法,我想,做一个开源项目对于我来说还是很遥远,但是,我想从改造现有项目开始,逐步开启个人独立开发的序幕。
在去年,即2017年年底,我在慕课上学习了这两门课程:
第一期项目实现了比较简单的电商业务,整合SSM,并且部署到云端。
第二期实现了tomcat集群,配合redis实现分布式session,还有一些定时任务、redis分布式锁、maven环境隔离的一些东西,还涉及很多spring和springmvc的有用的机巧。
整体感觉是:一期实现业务,二期对于一期的提高不是太大,跟分布式无太大关系,仅仅实现了单点登陆和分布式session存储而已。
个人感觉下一期的课程应该是springCloud的分布式改造,进行服务拆分和治理。所以,在整合这两个课程的基础上用springCloud进行微服务治理。
整体效果演示:
上面个gif有68兆,翻墙的话(我用的是免费的谷歌插件:SetupVPN,偶尔用用还是不错的),可以很快加载出来,但是不翻墙基本上没这个耐心等了。下面贴个小一点的gif:
部分页面截图:
后台管理系统为:http://admin.oursnail.cn 用户名为 admin 密码为 1234567 请不要乱改数据哦!
经过一遍遍测试,商城还是存在一些无伤大雅的bug,但是主要还是锻炼自己的能力嘛!
下订单的时候,报错:商品不存在或库存不足,是因为我模拟的秒杀,所以商品的库存要提前预置于redis中,后端管理系统的商品管理页面有预置库存的按钮。
新增商品的时候,对于上传图片,需要耐心等待一会,需要等待FTP服务器上传完毕,给一个返回信息(Map,是图片的文件名)才能真正显示(对于富文本中的图片上传,在上传之后需要等待一会,时间与小图上传差不多,否则直接保存不报错,但是前端看不到图,因为还没上传完毕,url还没回传回来)
普通注册的账号,没有管理员权限,所以不能登陆后台管理系统。
后来做了eureka集群,但是配置文件还是只指向其中一个eureka
在学习的视频中,一期只是实现业务功能,单体架构,一个tomcat。二期对其做了集群,并且解决了集群模式下session存储问题,实现了比较简单的单点登陆功能。架构如下:
对于上面的架构来说,只是做了一些集群进行优化,随着业务的发展,用户越来越多,用户服务等其他服务必然要拆分出来独立成为一个服务,这样做的好处是,一方面一个团队负责一个服务可以提高开发效率,另外,对于扩展性也是非常有利的,但是也是有缺点的,会带来很多的复杂性,尤其是引入了分布式事务,所以不能为了分布式而分布式,而是针对不同的业务场景而采用合适的架构。
微服务的实现,主要有两种,国内是阿里系的以dubbo+zookeeper为核心的一套服务治理和发现生态。另一个则是大名鼎鼎的spring cloud栈。
spring cloud并不是像spring是一个框架,他是解决微服务的一种方案,是由各种优秀开源组件共同配合而实现的微服务治理架构。下面的图是我构思的项目结构图:
最前面是Nginx
,这里就作为一个静态资源映射和负载均衡,nginx
中有几个配置文件,分别为www.oursnail.cn.conf
,这个主要是对zuul
网关地址做一个负载均衡,指向网关所在的服务器,并且找到前台页面所在位置对页面进行渲染。admin.oursnail.cn.conf
,这个主要是配置后端以及后端的页面文件;img.oursnail.cn.conf
是对图片服务器地址进行映射。
然后是zuul
网关,这里主要是用来限流、鉴权以及路由转发。
再后面就是我们的应用服务器啦。对服务器进行了服务追踪(sleuth
),实现了动态刷新配置(spring cloud config
+bus
)等功能。以http restful
的方式进行通信(openFeign
),构建起以eureka
为注册中心的分布式架构。
每个服务都是基于springboot
打造,结合mybatis
持久层操作的框架,完成基本的业务需求。springboot
基于spring
,特点是快速启动、内置tomcat
以及无xml
配置。将很多东西封装起来,引入pom就可以直接使用,比如springMVC
就基本上引入starter-web
即可。
由于资源的原因,只有三台最低配的服务器,所以本来想做的基于ES的全文检索服务没有做,也没有分库分表。
至于定时任务以及Hystrix服务熔断和降级,比较简单,就不做了。
下面详细介绍每个模块实现的大体思路(仅供参考,毕竟应届生,真实项目没做过):
关于用户模块,核心的功能是登陆。再核心是如何验证以及如何存储用户信息。这里采取的方案为:
对于用户注册,我这里就是用户名(昵称),那么如何保证不重复呢(高并发)?这里还是用了分布式锁来保证的。
对于未登陆章台下用户修改密码,逻辑为:
针对这些问题,我想说一下我的思路。
对于幂等性,这里产生幂等性的主要原因在于MQ的重传机制,可能第一个消息久久没有发出去,然后重新发送一条,结果第一条消息突然又好了,那么就会重复发两跳,对于用户来说,只下一次单,但是服务器下了多次订单。网上解决这个问题的思路是创建一张表,如果是重复的订单号,就不可能创建多次了。还有一种可能方案是用分布式锁对该订单号锁住一段时间,由于只是锁住订单号,所以不影响性能,在这一段时间内是不可以再放同一个订单号的请求进来。
对于MQ消息不丢失,只能是订阅模式了。消息发出去之后,消费端给MQ回复一个接收到的信息,MQ本次消费成功,给订阅者一个回复。
对于全局唯一ID生成,这里用的是雪花算法,具体介绍可以看我的笔记
对于分布式事务,比较复杂,这里其实并没有真正处理,对于数据库扣减库存和数据库插入订单,他们在不同的数据库,廖师兄比较倾向的方式是:
这一切的基础还是需要有一个可靠的消息服务,确保消息要能送达。
针对redis预减库存存在的并发问题,这里的思路是用lua+redis,在预减之前判断库存是否够,这两个操作要在一个原子操作里面才行,lua恰好可以实现原子性、顺序性地操作。
这里对接的是支付宝-扫码支付,用到是支付宝沙箱环境。支付的扫码支付详细流程在这里聊一聊哈。
商户前台将商品参数发送至商户后台,商户后台生成内部订单号并用于请求支付平台创建预下单,支付平台创建完预订单后将订单二维码信息返还给商户,此时用户即可扫取二维码进行付款操作。
内部订单号:这是相对于支付宝平台而言的,这个订单号是我们商城自己生成的,对于我们商城来说是内部订单号,但是对于支付宝来说是外部订单号。
将一系列的数据按照支付宝的要求发送给支付宝平台,包括商品信息,生成的验签sign,公钥;支付宝去将sign解密,进行商品的各种信息校验。校验通过,同步返回二维码串。
支付业务流程图:
在获取支付的二维码串之后,用工具包将其转换未二维码展示给用户扫码。
用户扫码后,会收到第一次支付宝的回调,展示要支付的金额,商品信息等。
用户输入密码成功后,正常情况会收到支付宝的第二次回调,即支付成功信息。
但是也可能会由于网络等原因,迟迟收不到支付宝的回调,这个时候就需要主动发起轮询去查看支付状态。
在支付成功之后,接收回调的接口要记得返回success
告诉支付宝我已经收到你的回调了,不要再重复发给我了。接收回调的接口也要做好去除重复消息的逻辑。
这个流程是多么地简单而理所当然!
对应于代码层面,其实就是两个接口,一个是用户点击去支付按钮,此时发起预下单,展示付款二维码,另一个是接收支付宝回调:
预下单:
接收支付宝支付状态回调:
安装redis、zookeeper、mysql、jdk、nginx以及rabbitMQ。
对代码进行maven-package操作。打包成jar包。将其放到服务器上:
执行nohup java -jar snailmall-user-service.8081 > user-service.out &
后台启动即可。
补充:针对配置刷新,修改了github信息,用
postman
请求http://xxxxx:8079/actuator/bus-refresh
触发更新。本改造是基于快乐慕商城一期和快乐慕商城二期的基础上进行改造。所以需要在其业务基础上改造会比较顺手。关于微服务,尤其是电商中的一些处理手段,很多思路都是学习于码吗在线中分布式电商项目。再加上慕课网廖师兄的spring cloud微服务实践。
只要阅读readme
文档即可。代码仓库为:https://github.com/sunweiguo/snailmall-front
学习不仅要有输入,更要有自己的输出,实践是提升的捷径!