【畅购电商】项目总结

发布于:2025-02-11 ⋅ 阅读:(96) ⋅ 点赞:(0)

目录

1. 电商项目架构图

1.1 系统架构

1.2 技术架构

2. 介绍电商项目

2.1 后台和前台、后端和前端

2.2 Vue全家桶包含哪些技术?

2.3 什么是Vuex?

2.4 什么是SSR

2.5 电商模式是什么?

2.6 枚举类

2.7 elasticsearch相关

2.8 gateway网关相关

2.9 nacos相关

2.10 定时任务

2.11 电商术语

3 项目中的业务

3.1 注册业务

3.2 权限任务业务

3.3 搜索业务

3.4 购物车业务

3.5 订单业务

3.6 支付业务

4. 项目中有哪些难点?你是如何解决的?

4.1 难点1:下单业务

4.2 难点2:支付业务

4.3 难点3:搜索

4.4 难点4:权限认证

5. 通过这个项目,你有哪些收获?

1. 电商项目架构图

  • 技术框架/技术选型

1.1 系统架构

  • 该项目是一个B2C的电商项目(类似小米商城、京东商城、天猫商城)

    • 允许客户通过网络购买商品

  • 该项目主要完成的是电商项目前台的开发。

    • 采用前后端分离的方式进行开发的

    • 前端:vue全家桶(Vue、Router、Vuex、Axios、Nuxt、SSR等技术)。

    • 后端:Spring Cloud Gateway 网关、Spring Cloud alibaba技术栈(nacos、sentinel 等)分布式微服务架构。

  • 该项目共有6个微服务(不考虑集群):

    • gateway网关服务

    • service-auth 认证服务

    • service-cart 购物车服务

    • service-orders 订单服务

    • service-search 搜索服务

    • service-web 核心业务(基本业务)服务

    • 扩展:

      • MQ服务(消息队列服务)

      • SMS服务(短信服务)

  • 本项目使用Nacos作为服务的注册与发现中心,以及信息的配置中心。

  • 使用企业级消息队列RabbitMQ进行消息通信、应用解耦、流量控制、流量削峰。

  • 采用企业级搜索引擎Elasticsearch实现商品的在线实时搜索。

  • 该项目的追求目标:高并发、高可用、高稳定 。

1.2 技术架构

  • 前端:

    • Node.js :前端的服务器,用于启动vue相关的内容。

    • Vue.js:前端使用的是vue相关的技术

    • Element UI :vue的前端框架,提供通用的组件,减少CSS、特效等编写。

    • Nuxt.js :vue的前端框架,用于解决SSR(服务端渲染)问题,易于SEO。

  • 运维技术:

    • Nacos:服务中心、配置中心

    • redis:数据存储中心

    • elasticsearch:搜索服务中心

    • docker:用于部署项目(会将项目部署到linux系统中,在通过docker进行具体的部署)

    • canal: https://github.com/alibaba/canal 自学

  • 分布式架构

    • spring boot :项目结构基础

    • spring cloud alibaba:微服务架构

    • jwt + RSA:鉴权中心,

      • jwt用于生成token,

      • RSA进行加密操作,用于辅助生成或校验token。

  • 持久化技术栈:

    • MyBatis Plus:用于取代MyBatis、通用Mapper,提供更优的工具、性能也有对应提升。

    • Spring data redis:用于简化Java对redis操作

    • spring data elasticsearch:用于简化java对es操作

  • 数据库:

    • mysql:免费的

    • MyCat:用于数据库分库分表的。

  • 外部接口:

    • 阿里大鱼:发送短信

    • 微信支付接口

2. 介绍电商项目

  • 介绍一下你最熟悉的项目?

  • 介绍一下最近完成的一个项目?

2.1 后台和前台、后端和前端

  • 前台和后台均可以采用前后端分离的方式进行开发,也就形成了对应的前端和后端。

  • 后台:提供给管理员使用。

    • 电商的后台模块:会员管理、分类管理、快报管理、广告管理、商品管理、订单管理、财务管理、报表管理。

    • 前端:element ui、element ui admin

    • 后端:spring boot、spring cloud、spring cloud alibaba

  • 前台:提供给用户使用。目前完成的电商项目只是部分,完成了前台部分。

    • 电商的前台模块:注册、认证、无限极分类、快报、搜索、购物车、订单、支付。

    • 前端:nuxt.js

    • 后端:spring cloud alibaba

2.2 Vue全家桶包含哪些技术?

  • vue:核心组件,主要用于数据的双向绑定。(html标签 与 vue data数据 进行 双向绑定)

    • 生命周期、计算属性、过滤器、监听器 等

  • router:路由,映射作用,使访问路径可以映射到对应的vue资源。

    • 请求拦截器、响应拦截器 等

  • vuex:状态管理,用于在多个组件之间共享数组。

  • element ui :vue的组件库,提供通用的组件(内含CSS样式、JS特效)

  • Nuxt:vue的框架,用于实现SSR技术。

  • axios:第三方ajax框架

2.3 什么是Vuex?

  • vuex是什么?

    • vue全家桶的一个组件,进行状态管理,也就是在组件之间进行数据的共享

  • vuex组件:状态state(死爹)、方法mutations(模特神)、功能actions、(模块modules、获得getters)

    • 状态state:相当于变量,用于存放数据

    • 方法mutations:用于操作变量,对变量的数据进行修改的

    • 功能actions:用于调用方法,可以进行ajax操作。

  • 如何使用?

    • 基本使用:

      • state:获得值 this.$store.state.变量 。一般与vue计算属性一起使用。

      • mutations:调用方法 this.$store.commit("方法名", 参数)。与vue method一起使用。

      • actions:调用功能 this.$store.dispatch("功能名", 参数)

    • 映射使用:

      • 导入:import {mapState, mapMutations, mapActions } from 'vuex'

      • state : 编写在计算属性处

computed: {
    ...mapState(['变量名']),
    变量名() {		//等效
        return this.$store.state.变量;
    },
    
}

mutations:编写在普通方法处

methods: {
    ...mapMutations(['方法名']),
    方法名(参数) {   //等效
        this.$store.commit("方法名", 参数)
    }
}

2.4 什么是SSR

  • SSR:服务端渲染技术,前端页面静态化技术,使ajax的数据与html标签不在分离,整合成一个整体。

    • 也就是说将ajax查询的结果,处理成静态页面。

  • nuxt.js 支持SSR技术,在页面加载前,通过asyncData进行ajax查询,并将查询结果合并定data区域,页面加载成功后,不需要再次查询。相当于静态页面。

  • 用途:用于解决SEO(搜索引擎优化)问题。

    • 搜索引擎提供的爬虫,优先爬取静态页面,为了提高网站的收录率,所以需要将动态页面转换成静态页面。

2.5 电商模式是什么?

  • B2C:商家-客户

    • 商家开发一个商城,并进行商品售卖。

    • 用户通过商城进行商品的购买。

    • 例如:唯品会、乐蜂网

  • B2B2C:商家A-商家B-客户

    • 商家B:开发一个商城,提供给商家A进行商品的售卖。商家B对商家A有监督等权利。

    • 商家A:入驻到商家B开发的商城,进行商品的售卖。

    • 客户:通过商城进行购买。

    • 例如:京东、天猫

  • C2B:客户-商家,客户提需求,商家进行定制。

    • 例如:尚品宅配

  • O2O:线上/线下,通过线上进行下单,通过线下进行交付。

    • 例如:美团外卖、饿了么

  • C2C:客户-客户,私人买卖。

    • 例如:瓜子二手车、转转、咸鱼。

2.6 枚举类

  • 枚举类的用途:限定指定类型的实例

    • 常量类是jdk1.4的技术

    • 枚举类是jdk1.5技术,用于取代常量类。如果没有参数,定义非常简单。

  • 枚举:通过参数,设置需要记录的信息

package com.czxy.changgou4.enum_demo;

/**
 * @author 桐叔
 * @email liangtong@itcast.cn
 * @description
 */
public enum Gender {
    MALE(1,"男男"),FEMALE(0,"女女");

    private Integer id;     //编号
    private String text;    //文本

    Gender(Integer id, String text) {
        this.id = id;
        this.text = text;
    }

    public Integer getId() {
        return id;
    }

    public String getText() {
        return text;
    }
}

常量类,与上面的枚举等效的功能。

package com.czxy.changgou4.enum_demo;

/**
 * @author 桐叔
 * @email liangtong@itcast.cn
 * @description
 */
public class GenderClass {
    public final static GenderClass MALE = new GenderClass(1, "男");
    public final static GenderClass FEMALE = new GenderClass(0, "女");

    private Integer id;     //编号
    private String text;    //文本

    public GenderClass(Integer id, String text) {
        this.id = id;
        this.text = text;
    }

    public Integer getId() {
        return id;
    }

    public String getText() {
        return text;
    }
}

测试

package com.czxy.changgou4.enum_demo;

/**
 * @author 桐叔
 * @email liangtong@itcast.cn
 * @description
 */
public class TestGender {
    public static void main(String[] args) {
        System.out.println(Gender.MALE.getId());

        System.out.println(GenderClass.FEMALE.getText());
    }
}

2.7 elasticsearch相关

  • elasticsearch的原理?

    • 将数据保存到es中时,es会对数据进行分词。

    • 每一个分词进行编号,在进行查询时,通过分词找到对应的编号,然后通过编号从索引库中找到对应的数据。

    • 此过程就是原理,此原理称为“倒排索引”

  • 为什么要使用elasticsearch?

    • 数据库mysql不能分词,es可以进行分词搜索。

      • 数据库可以对指定的字段进行模糊查询,也就是某个字段

      • es进行全文分词检索。比mysql更灵活。

    • es专业搜索,可以处理海量的数据,且速度很快。电商项目有海量的商品,需要es进行搜索。

  • 为什么要使用IK分词器?

    • 默认es对单字进行分词。

    • 实际需要时,根据词组进行分词。需要特定的中文分词器。

2.8 gateway网关相关

  • gateway网关的功能?网关的作用?

    1. 动态路由

    2. 负载均衡

    3. 鉴权

2.9 nacos相关

  • nacos的作用?

    • 微服务的注册中心:可以通过服务的名字获得对应服务位置

    • 微服务的配置中心:将yml或properties配置文件中的内容,抽取到nacos中,通过修改nacos,相当于修改yml或properties文件。

  • 为什么需要nacos?

    • 微服务架构,都需要一个注册中心,管理所有的微服务。方便通过服务名称获得每一个服务的真实的IP地址+端口号。项目之间只需要记录服务名即可,服务的真实地址和端口号可以随意改变。

    • 需要给自己的微服务选择一个注册中心。

    • 常见的注册中心:nacos、eureka、dubbo的zookeeper 等

    • nacos是alibaba提供额技术支持,经历过双十一的实战考验,优先选择。

2.10 定时任务

什么是SpringTask?

  • SpringTask 是一个定时任务组件。

  • 可以在指定的时间周期内,完成指定的任务。

  • 一般情况采用的是cron表达式。

@Scheduled(cron = “0-5 * * ? * *”)

cron表达式

分7部分:秒 分 时 日期 月 周 年?
常用6部分:秒 分 时 日期 月 周, 且“日期”和“周”存在冲突问题,需要忽略其中一个,使用?。
,  或,例如:1,2,3
-  至,例如:1-5
/  每,例如:0/5
*  任意

2.11 电商术语

  • SKU、SPU

    • SKU:stock keeping unit(库存量单位),进出库的最小单位,不能分隔。也就是具体的一个产品。

    • SPU:Standard Product Unit(标准产品单位),一组可复用产出特性,相当于一个小的分类。

  • PV、UV

    • PV:Page View 页面浏览量,每访问一个页面就记录一次,同一个用户,同一个页面,访问多次,也记录多次。访问的累积量。

    • UV:unique visitor 独立房客,同一个IP地址,在同一天内访问的次数。

3 项目中的业务

3.1 注册业务

  • 为什么使用验证码?

    • 防止用户的恶意点击

    • 防止程序恶意访问

  • 验证码有几种形式?

    • 静态图片验证码(jpeg图)

    • 动态图片验证码(gif图)

    • 邮件验证码

    • 短信验证码

    • 特殊验证码(滑动图片部分、9宫格、选择若干汉字 等)

  • 验证码是否有有效时长?如果有是多久?

    • 有,一般5分钟

    • 在后端存放到redis中有效时长。

  • 为什么使用倒计时?时长多久?

    • 防止用户恶意点击、误点击

    • 短信存在延迟,需要有一个接收的时间

    • 时长一般为60秒,不建议太长,用户不乐意等待

    • 减少对服务器的访问次数,从而降低服务器请求压力

  • 描述一下实现倒计时的基本思路?

    • 一共需要使用3个变量:btnDisabled、seconds、timer

    • seconds变量,用于进行倒计时,如果为零,将重置所有状态

    • btnDisabled变量,用于控制按钮是否可以,倒计时阶段不能用

    • timer变量,用于记录轮询,当倒计时为零时,停止轮询。

  • 倒计时结束后,验证码是否仍有效?

    • 有效,倒计时为60秒,发送验证码时,在redis中存5分钟,此时仍有效。

  • 倒计时结束后,是否还可以发送验证码?

    • 可以,60秒倒计时后,按钮就可以点击了。

  • 短信发送失败的原因,及其解决方案?

    • 阿里大鱼余额不足,无法发送。检查余额,及时充钱。

    • 短信服务没有响应。检查对应短信服务,是否可以访问。

    • 第三方软件不可用。检查redis、mq等是否可用

    • 前端ajax没有发送成功。检查ajax路径、参数等,前端没有绑定ajax

  • Redis的数据类型有哪些?

    • redis有5种数据类型

    • string类型:字符串,在redis最常用的类型,可以存放任意数据,通常转换成json即可。一键一值。

    • list:有序集合,一键多值,值可以重复。

    • set:无序,一键多值,值不可以重复。

    • zset:有序不可重复的集合。一键多值。

    • hash:键值对

  • 验证码如何在redis唯一标识的?是否还有其他方案?

    • 需要用户填写用户名/手机号,redis唯一标识固定串+手机号固定串+用户名

      • 弊端:用户没有填写手机号前,不能点击获得验证码的。在用户填写验证码后,失去焦点时,进行ajax请求

    • 常见方案:

      • 每一个用户第一次访问页面时,给其分配一个随机数,记录再浏览器端(cookie、localStorage)

      • 之后每次访问,都将携带该随机数,用随机数表示当前用户。

3.2 权限任务业务

  • 权限认证使用的框架是什么?

    • JWT: JSON Web Tokens , 目前最流行的跨域身份验证解决方案

  • JWT的理解?JWT鉴权的流程

  • 加密方式有哪些?

    • Base64:使用64个可打印字符来表示二进制数据,从而进行数据的加密和解密。

    • MD5: Message Digest Algorithm 消息摘要算法, 任意长度的数据字符串转化成短小的固定长度的值

    • SHA: Secure Hash Algorithm,安全散列算法

    • RSA:一种非对称加密算法,需要一对密钥,一个用于加密,另一个用于解密。

  • 登录成功后,用户信息如何保存?

    • 在微服务系统中,保存sessionStorage中

  • 如果数据存放到vuex中,如何解决刷新页面数据丢失的问题?

    • 方案1:不是公共组件:页面在pages目录下,可以nuxt.js提供 fetch进行操作。

    • 方案2:是公共组件:组件在components目录下,借助第三方进行存储(cookie、localStorage、sessionStorage)

      • 选择1:sessionStorage存放数据,如果vuex中没有,将sessionStorage同步过去。

      • 选择2:vuex中actions模块就可以发送ajax,从而同步数据。

  • 白名单是什么?如果使用?

    • 白名单中的路径,无需鉴权校验,可以直接放行。

3.3 搜索业务

  • elastisearch是如何搜索的

    • 首先需要创建索引,

    • 然后springboot-data-elasticsearch提供了丰富的API,进行查找所有、分页查找、排序,

    • 还可以直接编写方法名,根据方法名搜索,

    • 如果还不能满足需求,还可以使用NativeSearchQueryBuilder进行自定义查询

      • withQuery 条件查询,通过 boolQueryBuilder进行组合查询

        • matchQuery:分词查找

        • termQuery: 精确匹配

        • rangeQuery:范围搜索

      • withSort :排序查询

      • withPageable :分页查询

  • 项目中的搜索业务是如何实现的?

    • 电商项目中,搜索商品,我们实现了,根据三级分类搜索、关键字搜索,同时根据品牌、规格和规格选项、价格范围、销量降序、价格升序/降序、评论降序、上架时间降序等等条件进行组合搜索

  • elasticsearch中的数据来自哪里?如何存进去的?

    • elasticsearch中的数据会保存两份,一份是来自mysql,一份是来自elasticsearch,

  • 代码同步:将mysql中的数据同步到elasticsearch中

3.4 购物车业务

  • 购物车业务是商城非常核心的业务之一,跟购物车相关的功能有哪些?

    • 加入购物车

    • 修改购物车商品数量

    • 修改购物车商品打钩状态

    • 删除购物车中的商品

  • 为什么使用localStorage?localStorage的优势?有哪些劣势?

    • localStorage的存储量比cookie大,突破了cookie4k的限制

    • localStorage属于永久性直接存储到本地,相当于一个前端页面的数据库,相比于 cookie 可以节约带宽

    • 劣势:

      • 浏览器的大小不统一,并且在 IE8 以上的 IE 版本才支持 localStorage 这个属性。

      • 目前所有的浏览器中都会把localStorage的值类型限定为string类型,这个在对我们日常比较常见的JSON对象类型需要一些转换。

      • localStorage在浏览器的隐私模式下面是不可读取的。

      • localStorage本质上是对字符串的读取,如果存储内容多的话会消耗内存空间,会导致页面变卡。

  • localStorage和sessionStorage的区别?

    • localStorage 本地存储,属于永久性。只要浏览器不清空浏览器缓存,数据就可以长期保存。

    • sessionStorage 会话存储,属于临时存储。浏览器端会话结束,数据就被清空。

  • 为什么登录的情况下,将数据放入redis,而不是放入mysql?

    • redis的优势是读写速度都快,写入mysql需要更多的时间,并发能力还没有redis强。

    • 对于加入购物车的功能,操作很频繁,可以通过redis快速的写入、修改、获取,符合业务需求

3.5 订单业务

  • 下单的业务是啥?项目如何实现下单功能的?下单流程是啥?

    • 页面点击"提交"按钮,此时后端下单就开始执行了,流程中需要处理的业务非常多

    • 第一个:需要生成订单的编号,考虑到分布式系统订单量庞大,如何防止订单编号重复呢?我们采用了雪花算法,雪花算法是推特开源的分布式ID生成器,在高并发场景下,可以有效的保证id唯一

    • 第二个:需要根据地址编号addressId发起远程调用,请求address的详细信息,在我们的订单表中,我们是保存了每个订单的详细收货地址信息的,为什么订单需要重复保存收获地址信息呢?不是保存地址编号呢?因为地址信息是可以修改的,如果保存的是地址编号,后期地址信息发生改变的话,我这个订单的地址信息也就发生了改变,这与当时下单需要寄送的地址是冲突的

    • 第三个:获取token,解析userId,根据userId去redis中取出数据。因为下单的商品数据来自redis,下单直接将redis中购物车中打钩的商品数据,保存为订单商品

    • 第四个:保存订单、保存订单商品数据。

    • 第五个:扣减库存,包括mysql、elasticsearch、redis;下单成功,对于mysql,需要修改sku的库存信息;对于elasticsearch,需要修改库存信息;对于redis,删除已经下单成功的商品信息,

    • 第六个:对于第四个业务和第五个业务,要么全部成功,要么全部失败,在SpringCloud微服务架构下,涉及到多个服务间的业务调用,所以我们采用了分布式事务seata来保证数据的一致性和完整性

  • 事务的特性?

    1. 什么是事务?

      在一组(ABCD)业务逻辑操作中,要么全部成功,要么全部失败。

    2. 事务有哪些特性?

      ACID 4个特性

      原子性:一个事务是一个不可分割的整体

      一致性:一个事务前后,数据时一致性的,也称为数据完整性。

      隔离性:两个事务之间的并发访问问题

      持久性:事务一旦操作,不能再改变。

    3. 隔离性有哪些问题?

      脏读:一个事务读到了另一个事务没有提交的数据

      不可重复读:一个事务读到了另一个事务已经提交的数据(更新)

      虚读/幻读:一个事务读到了另一个事务已经提交的数据(添加),理论信息

    4. 如果解决隔离性的问题?

      采用隔离级别来进行问题的解决。共4种隔离级别

      1. read uncommitted 读未提交:一个事务读到了另一个事务没有提交的数据。

      解决了0个问题,存在脏读、不可重复读、虚读等3个问题。

      1. read commmitted 读已提交:一个事务读到了另一个事务已经提交的数据

      解决了脏读等1个问题,存在不可重复读、虚读等2个问题。

      1. repeatable read 可重复读:在一个事务中,读到的数据时一致的。

      解决了脏读、不可重复读等2个问题,存在虚读等1个问题。

      1. serializable 串行化:单事务,一次只能有一个事务。

      解决了脏读、不可重复读、虚读等3个问题,存在0个问题。

    5. 隔离级别的安全与性能对比?

      安全:read uncommitted < read commmitted < repeatable read < serializable

      性能:read uncommitted > read commmitted > repeatable read > serializable

    6. 常见数据库的默认隔离级别

      mysql:repeatable read

      Oracle:read commmitted

  • 分布式事务事务模型?

    • 分布式事务的四种模式:XA 、AT、TCC、Saga、

  • XA模式:基于XA协议的两阶段提交

    • 优点:事务的强一致性,满足ACID原则。常用数据库都支持,实现简单。

    • 缺点:因为一阶段需要锁定数据库资源,等待二阶段结束才释放,性能较差。

    • AT模式:是一种无侵入的分布式事务解决方案。 阿里seata框架,实现了该模式

    • 优点:

      • 一阶段完成直接提交事务,释放数据库资源,性能比较好

      • 利用全局锁实现读写隔离

      • 没有代码侵入,框架自动完成回滚和提交

      • 缺点:

        • 两阶段之间属于软状态,属于最终一致,可能会引起脏写

      • 框架的快照功能会影响性能,但比XA模式要好很多

    • TCC模式: 根据自己的业务场景实现 Try、Confirm 和 Cancel 三个操作补偿机制。

      • 优点:

        • 一阶段完成直接提交事务,释放数据库资源,性能好

        • 相比AT模型,无需生成快照,无需使用全局锁,性能最强

        • 不依赖数据库事务,而是依赖补偿操作,可以用于非事务型数据库

      • 缺点:

        • 有代码侵入,需要人为编写try、Confirm和Cancel接口,太麻烦

        • 软状态,事务是最终一致

        • 需要考虑Confirm和Cancel的失败情况

  • Saga模式: 是长事务解决方案。

3.6 支付业务

电商项目使用的是什么支付?是如何完成支付的?

  • 微信支付

  • 你还了解哪些支付方式?

    • 微信支付

    • 支付支付

    • 银联支付

  • 支付成功的回调,是如何调用本地方法的?

    • 内网穿透技术

4. 项目中有哪些难点?你是如何解决的?

4.1 难点1:下单业务

  1. 涉及到多个多个微服务,多个业务的操作,需要向订单order 表、订单商品order-goods表新增数据,扣减sku的库存、更新elasticsearch的数据、更新redis的数据等等操作

  2. 这些操作要么全部成功,要么全部失败,所有需要采用分布式事务进行控制,

4.2 难点2:支付业务

  1. 微信服务器通知我们的服务器修改订单状态,由于开发的时候是内网,如何通知呢?我查了很多资料,最终发现通过内网穿透工具解决

  2. 项目后端如何通知项目前端根据订单状态进行页面跳转呢?采用websocket,以前没有接触过,自学了websocket,解决了这个问题

4.3 难点3:搜索

elasticsearch搜索,我们实现类跟京东、淘宝几乎一样的功能,搜索条件非常多、需要根据三级分类、关键字、品牌、规格和规格选项、价格排序、销量排序、上架时间排序、评论排序、分页等等功能,前后端都要事先,功能复杂,难度系数大

4.4 难点4:权限认证

  1. 如何保证用户信息的安全?采用MD5+SHA加密密码的方式,即使数据的用户信息被盗,盗用者也无法获取用户的密码信息

  2. 如何保证jwt的安全?JWT通过撒盐的方式,增加破解的难度

  3. 如何保证各个微服务的安全?通过jwt进行鉴权和授权,jwt解析失败,无法访问某些微服务

5. 通过这个项目,你有哪些收获?

  1. 第一次做这么大的项目,从业务逻辑、代码量都有很多提升

  2. 解决bug的能力

  3. 接触到了更多的新技术

  4. 自学了很多新技术

  5. 沟通、合作很重要


网站公告

今日签到

点亮在社区的每一天
去签到