爽易购商城--后台管理

一、项目简介

1、项目背景

1)、电商模式
市面上有5种常见的电商模式:B2B、B2C、C2B、C2C、O2O

  1. B2B模式

    Business to Business,是指商家之间的商业关系,如:阿里巴巴;

  2. B2C模式

    Business to Consumer,就是我们经常看到的供应商直接把商品卖给用户,即“商对客”模式,也就是通常说的商业零售,直接面向消费者销售产品和服务。如:苏宁易购、京东、天猫等;

  3. C2B模式

    Customer to Business,即消费者对企业。先有消费者提出需求,后有企业组织生产;

  4. C2C模式

    Customer to Consumer,客户之间的交易,如:淘宝、咸鱼等;

  5. O2O模式

    Online to Offline,即是将线下商务的机会与互联网结合,让互联网称为线下交易的前台。线上快速支付,线下优质服务。如:饿了么、美团、淘票票、京东到家等;

2、架构图

技术架构图
爽易购商城--后台管理_第1张图片
服务架构图
爽易购商城--后台管理_第2张图片

3、项目技术

  • 前后分离开发,基于vue的后台管理系统
  • SpringCloud全新解决方案
  • 应用监控、限流、网关、熔断降级等分布式方案
  • SpringBoot
  • SpringCloud
  • Nacos、Sentinel、Elasticsearch、git、redis、linux、vue、k8s

二、分布式基础概念

1、微服务

微服务架构风格,就像是把一个单独的应用程序开发为一套小服务,每个小服务运行在自己的进程中,并使用轻量级机制通信,通常是HTTP API。这些服务围绕业务能力来构建,并通过完全自动化部署机制来独立部署。这些服务可以使用不同的编程语言书写,以及不同数据存储技术,并保持最低限度的集中式管理。
简而言之:拒绝大型单体应用,基于业务边界进行服务微化拆分,各个服务独立部署运行。

2、集群&分布式&节点

集群是个物理形态,分布式是个工作方式。
只要是一堆机器,就可以叫集群,他们是不是一起协作工作,这个谁也不知道。
《分布式系统原理与规范》定义:

“分布式系统是若干独立计算机的集合,这些计算机对于用户来说就像单个相关系统”

分布式系统(distribution system)是建立在网络之上的软件系统。

分布式是指将不同的业务分布在不同的地方。

集群是指将几台服务器集中在一起,实现同一业务。

例如:京东是一个分布式系统,众多业务运行在不同的机器,所有业务构成一个大型业务集群。每一个小的业务,比如用户系统,访问压力大时一个服务器不够用,我们就应该将用户系统部署到多个服务器,也就是每一个业务系统都可以做集群。

分布式中的每一个节点都可以做集群。集群并不一定是分布式。

节点:集群中的一个服务器。

3、远程调用

在分布式系统中,各个服务可能处于不同主机,但服务之间不可避免要互相调用,我们称为远程调用。

SpringCloud中使用HTTP + JSON的方式来完成远程调用

爽易购商城--后台管理_第3张图片

4、负载均衡

分布式系统中,A服务调用B服务,B服务部署集群,A调用任意一个均可完成功能。

为了使每一台服务器都不要太忙或太闲,我们可以负载均衡的调用每一个服务器,提升网站的健壮性。

常见的负载均衡算法:

**轮询:**按照顺序访问每一台服务器。

**最小连接:**优先选择连接数最少,也就是压力最小的服务器。

**散列:**根据请求源IP的hash值来选择要转发的服务器。可以解决session的问题。

5、服务注册/发现&注册中心

A服务调用B服务,但不知道B服务在哪台服务器上,哪些是正常或下线的。解决这个问题可以引入注册中心;

爽易购商城--后台管理_第4张图片
我们可以实时感知到服务的状态,从而避免调用不可用的服务。

6、配置中心

爽易购商城--后台管理_第5张图片

每一个服务最终都有大量配置,并且每个服务都可能部署在多台服务器上。我们经常需要变更配置,因此工作量巨大。我们可以引入配置中心,让每个服务在配置中心获取自己的配置。

**配置中心用来集中管理微服务的配置信息 **

7、服务熔断&服务降级

在微服务架构中,微服务之间通过网络通信,存在相互依赖,当一个服务不可用,有可能出现雪崩效应。要防止这样的情况,必须要有容错机制。

1)、服务熔断

设置服务的超时,当被调用的服务经常失败到达某个阈值,我们可以开启断路保护机制,后来的请求不再去调用这个服务。本地直接返回默认数据。

2)、服务降级

在运维期间,当系统处于高峰期,系统资源紧张,我们可以让非核心业务奖及运行。

降级:某些服务不处理,或者简单处理——抛异常 | 返回Null、调用Mock数据、调用faullback处理逻辑。

8、API网关

在微服务架构中,API Gateway作为整体架构的重要组件,它抽象了微服务中都需要的功能,同时提供客户端负载均衡,服务自动熔断,灰度发布,统一认证,限流留空、日志统计等丰富功能,帮助我们解决很多API管理难题。

三、环境搭建

  1. 安装Linux虚拟机

    本次项目使用阿里的云服务器:ip:112.124.32.136

  2. 安装docker

  3. docker安装mysql

  4. docker安装redis

5、 开发环境

1. Maven

版本: 3.5.2

配置阿里云镜像

<mirrors>
  <mirror>
    <id>nexus-aliyunid>
    <mirrorOf>centralmirrorOf>
    <name>Nexus aliyunname>
    <url>http://maven.aliyun.com/nexus/content/groups/publicurl>
  mirror>
mirrors>

配置jdk1.8编译项目

<profiles>
    <profile>
        <id>jdk-1.8id>
        <activation>
            <activeByDefault>trueactiveByDefault>
            <jdk>1.8jdk>
        activation>
        <properties>
            <maven.compiler.source>1.8maven.compiler.source>
            <maven.compiler.target>1.8maven.compiler.target>
            <maven.compiler.compilerVersion>1.8maven.compiler.compilerVersion>
        properties>
    profile>
profiles>

2. Idea&vscode

idea安装插件:

  • lombok
  • mybatisx

vscode安装插件:

  • Auto Close Tag(自动补全标签 必备)
  • Auto Rename Tag(修改标签名 自动同步修改闭合标签的标签名 必备)
  • Chinese
  • ESLint
  • HTML CSS Support
  • HTML Snippets
  • JavaScript(ES6)code snippets(es6代码快捷键 也包含常用的console.log之类的 可以少码一点代码 提升效率)
  • Live Server
  • open in browser(用vscode写html相关代码的时候 可以下载这个插件 可以使用快捷键 Alt+B 打开默认浏览器 访问页面内容)
  • Vetur(如果写Vue项目 可以安装 可以高亮Vue代码 格式化代码等)
  • Bracket Pair Colorizer(给代码中的括号添加亮色 便于区分 这里截图有报错 是特意便于演示写的多组括号)
  • Class autocomplete for HTML (自动补全class="" 属性)
  • Debugger for Chrome (打断点 映射vscode上到Chrome上 方便调试 必备)
  • Draw.io Integration(强烈推荐 画流程图有它就够了 命名文件后缀为.drawio 写好了 可以组合 也可以导出为svg、png等格式 有提示箭头 拖拽就可以 可以左上角文件->导出->选格式导出)
  • Git Graph(强烈推荐 可以查看git提交历史 现在所处分支 提交内容明细 以及回滚删除分支等操作)
  • Beautify (美化代码)
  • .Image preview(现应用场景:在代码中写了图片链接,要这个这张图片的宽高 只需要悬停在链接上 就可以看到图片宽高信息 )
  • LeetCode(力扣刷算法题的插件 可以在这里既看到题目又可以编译自己的代码)
  • Markdown Preview Enhanced (可以编辑器内看markdown编译出来的效果)
  • Quokka.js(主要是基于js或者ts 在编辑器中快速查看键入代码的结果 很方便 不需要再打console控制台看)
  • REST Client(功能与postman一致 建立一个.http后缀的文件 把接口相关链接 请求方式 参数等放在里面 可以直接点Send Request或者快捷键 Ctrl+Alt+r就可以查看请求返回信息)
  • Codelf(起名)
  • local history(历史回退)
  • vscode-icons(图标美化)
  • Better Align(对齐)
  • change-case(规范化命名)

3. 安装git

  1. 下载:https://git-scm.com

  2. 配置用户名和邮箱

    进入git bash

    #配置用户名
    git config --global user.name "username" 
    #配置邮箱
    git config --global user.email "[email protected]"
    
  3. 配置ssh免密登录

    进入git bash

    ssh-keygen -t rsa -C "注册git的邮箱"
    # 三次回车结束
    #查看
    #一般用户目录会生成
    id_rsa
    id_rsa.pub
    #或者输入命令
    cat ~/.ssh/id_rsa.pub
    #登录gitee,在设置里找到SSH KEY将.pub文件内容贴进去
    #测试是否成功
    ssh -T [email protected]
    

爽易购商城--后台管理_第6张图片

4. 逆向工程创建

  1. 创建git仓库

    打开gitee,新建仓库

    名称:爽易购商城

    路径:https://gitee.com/candy-xiaojing/shuang-tesco-mall.git

  2. 创建idea工程

    打开idea,新建项目:shuang-tesco-mall

    选择来自版本控制的项目

    选择git,粘贴git路径,完成
    爽易购商城--后台管理_第7张图片

6、创建项目微服务

商品服务、仓储服务、订单服务、优惠券服务、用户服务

共同:

  1. **依赖:**web、openfeign
  2. **groupId:**com.qhit.shuang
  3. **包名:**com.qhit.shuang.xxx(product/ware/order/coupon/member)
  4. **模块名:**shuang-xxx((product/ware/order/coupon/member)
    爽易购商城--后台管理_第8张图片

.gitignore添加以下内容

**/mvnw
**/mvnw.cmd
**/.mvn
**/target/
.idea
**/.gitignore

提交:

四、后台管理系统

本项目的后台管理系统采用人人开源提供的后台系统快速进行搭建

进入gitee.com,搜索人人开源
爽易购商城--后台管理_第9张图片
renren-fast是基于Java的后台管理系统服务端代码

renren-fast-vue是基于vue的前端代码

部署进项目,启动
爽易购商城--后台管理_第10张图片
爽易购商城--后台管理_第11张图片
接下来使用renren-generator对各个模块进行代码生成
爽易购商城--后台管理_第12张图片
爽易购商城--后台管理_第13张图片

成功生成!

接下来创建公共模块shuang-common


<dependency>
    <groupId>com.baomidougroupId>
    <artifactId>mybatis-plus-boot-starterartifactId>
    <version>3.4.2version>
dependency>
<dependency>
    <groupId>org.projectlombokgroupId>
    <artifactId>lombokartifactId>
    <version>1.18.22version>
dependency>

<dependency>
    <groupId>mysqlgroupId>
    <artifactId>mysql-connector-javaartifactId>
    <version>8.0.21version>
dependency>
<dependency>
    <groupId>javax.servletgroupId>
    <artifactId>servlet-apiartifactId>
    <version>2.5version>
    <scope>providedscope>
dependency>

<dependency>
    <groupId>org.apache.httpcomponentsgroupId>
    <artifactId>httpcoreartifactId>
    <version>4.4.15version>
dependency>
<dependency>
    <groupId>commons-langgroupId>
    <artifactId>commons-langartifactId>
    <version>${commons.lang.version}version>
dependency>

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-aopartifactId>
dependency>    

五、技术整合

1、mybatis-plus

1)、引入依赖

<dependency>
  <groupId>com.baomidougroupId>
  <artifactId>mybatis-plus-boot-starterartifactId>
  <version>3.4.2version>
dependency>

2)、配置

  1. 配置数据源

    1)、导入数据库驱动

    
    <dependency>
      <groupId>mysqlgroupId>
      <artifactId>mysql-connector-javaartifactId>
      <version>8.0.21version>
    dependency>
    

    2)、在application.yml中配置数据源

    spring:
      # 数据源配置
      datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        driverClassName: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://112.124.32.136:3306/shuang_oms?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
        username: root
        password: root
    
  2. 配置mybatis-plus

    1)、启动类添加MapperScan注解

    @MapperScan("com.qhit.shuang.product.dao") //dao层接口全路径
    

    2)、application.yml中配置sql映射文件位置

    mybatis-plus:
    mapper-locations: classpath:/mapper/**/*.xml
    

2、微服务

1)、简介

SpringCloud的几大痛点

  • 部分组件停止维护和更新,给开发带来不便
  • 部分环境搭建复杂,没有完善的可视化界面,我们需要大量的二次开发和定制
  • 配置复杂,难以上手,部分配置差别难以区分和合理应用

SpringCloud Alibaba的优势

  • 性能强悍,设计合理,开源
  • 成套的产品搭配,完善的可视化界面
  • 搭建简单

结合Alibaba最终的技术搭配方案

  1. SpringCloud Alibaba - Nacos:注册中心 (服务发现和注册)
  2. SpringCloud Alibaba - Nacos:配置中心(动态配置管理)
  3. SpringCloud - Ribbon:负载均衡
  4. SpringCloud - Open Feign:远程调用(声明式HTTP客户端)
  5. SpringCloud Alibaba - Sentinel:服务容错(限流、降级、熔断)
  6. SpringCloud - Gateway:API网关(webflux编程模式)
  7. SpringCloud - Sleuth:调用链监控
  8. SpringCloud Alibaba - Seata:原Fescar,即分布式事务解决方案

github地址:https://github.com/alibaba/spring-cloud-alibaba

版本对应关系
爽易购商城--后台管理_第14张图片
Nacos是阿里巴巴开源的一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。使用Java编写,依赖Java环境

Nacos文档地址:https://nacos.io/zh-cn/docs/quick-start.html

2)、Nacos服务端

  1. 下载nacos-server

    https://github.com/alibaba/nacos/releases

  2. 启动nacos-server

    • 双击bin中的startup.cmd文件
    • 访问http://localhost:8848/nacos/
    • 使用默认的nacos/nacos进行登录

3)、注册中心

github文档:https://github.com/alibaba/spring-cloud-alibaba/wiki/Nacos-discovery

  1. 引入依赖
    <dependency>
      <groupId>com.alibaba.cloudgroupId>
      <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
    dependency>
    
  2. application.yml
    spring: 
      cloud:
        nacos:
          discovery:
          	# 连接注册中心进行注册
            server-addr: 127.0.0.1:8848
      application:
      	# 注册时的名字
        name: 服务名
    
  3. 启动类添加注解
    @EnableDiscoveryClient
    爽易购商城--后台管理_第15张图片

3)、远程调用

  1. 引入open-feign依赖

    <dependency>
      <groupId>org.springframework.cloudgroupId>
      <artifactId>spring-cloud-starter-openfeignartifactId>
    dependency>
    
  2. 编写本地接口作为远程方法映射

    @FeignClient("服务名:application.name")
    public interface 接口名:自定义|示例:feign/UserFeignService.java {
    
      @RequestMapping("远程方法全路径")
      public R list(@RequestParam Map<String, Object> params); // 远程方法签名
    }
    
  3. 开启远程调用功能

    启动类上添加注解

    @EnableFeignClients(basePackages = "映射接口所在包的全路径,以‘.’分隔")
    

4)、配置中心

github文档:https://github.com/alibaba/spring-cloud-alibaba/wiki/Nacos-config

  1. 引入依赖

    <dependency>
        <groupId>com.alibaba.cloudgroupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-configartifactId>
    dependency>
    
  2. bootstrap.properties

    • 优先于application.properties
    • 配置Nacos Server 地址
    • 配置服务名
    spring.application.name=当前服务名
    spring.cloud.nacos.config.server-addr=127.0.0.1:8848
    
  3. 创建服务端配置

    优先于本地配置爽易购商城--后台管理_第16张图片爽易购商城--后台管理_第17张图片

  4. RefreshScope
    在Controller类名上配上RefreshScope注解
    使用Value注解获取配置时可以动态刷新

细节

命名空间: 不同的命名空间下,可以存在相同的Group和Data ID,常用场景之一是不同环境的配置区分隔离,例如开发测试环境和生产环境的资源隔离等。
在bootstrap文件中修改要使用的命名空间

# 不配即默认:public空间
spring.cloud.nacos.config.namespace=命名空间ID(一长串)

配置集: 一组相关或不相关的配置项的集合称为配置集
配置组: 不同的Group下可以有相同的Data ID,相互隔离
在bootstrap文件中修改要使用的组名

spring.cloud.nacos.config.group=组名

配置集ID: 类似文件名,Data ID
在bootstrap文件中修改要使用的ID

spring.cloud.nacos.config.data-id=id名

最终配置:

spring.application.name=服务名
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
# 服务自动加载 服务名.properties 
# 默认加载默认空间和默认分组中的
# 指定了空间和组名后,会去取消默认,精确加载,若未找到,会去本地配置加载
spring.cloud.nacos.config.namespace=1eb9d3f3-ba68-43db-828b-784ac3e4859c
spring.cloud.nacos.config.group=组名

# extension-configs[0]:加载的第一个文件的配置
#获取当前命名空间下组名为test_group的data-id,并设置动态刷新
spring.cloud.nacos.config.extension-configs[0].data-id=data-id名
spring.cloud.nacos.config.extension-configs[0].group=DEFAULT_GROUP
spring.cloud.nacos.config.refresh-enabled=true

5)、API网关

爽易购商城--后台管理_第18张图片
当请求到达网关,网关会断言请求是否符合某个路由规则,若符合,就按照路由规则将请求路由到指定服务,中间会经过一系列过滤器

断言文档:https://docs.spring.io/spring-cloud-gateway/docs/2.2.9.RELEASE/reference/html/#gateway-request-predicates-factories

过滤器文档:https://docs.spring.io/spring-cloud-gateway/docs/2.2.9.RELEASE/reference/html/#gatewayfilter-factories

  1. 创建项目shuang-gateway
  2. 添加依赖
<dependency>
	<groupId>org.springframework.cloudgroupId>
	<artifactId>spring-cloud-starter-gatewayartifact>
dependency>
  1. 使用断言
spring:
  cloud:
    gateway:
      routes:
      - id: after_route	# 路由id
        uri: https://example.org	#路由地址
        predicates:
        #After断言:会匹配指定时间点之后的请求
        - After=2017-01-20T17:42:47.789-07:00[America/Denver]
  1. 使用过滤器
spring:
  cloud:
    gateway:
      routes:
      - id: add_request_header_route # 路由id
        uri: https://example.org #路由地址
        filters:
        # 添加请求头过滤器:将为请求头添加red,blue键值对
        - AddRequestHeader=X-Request-red, blue

前后端技术栈类比
爽易购商城--后台管理_第19张图片

六、前端

前端使用VueElementUI
vue官网文档:https://cn.vuejs.org/v2/guide/
ElementUI官网文档:https://element-plus.gitee.io/zh-CN/
Vue组件模板:https://www.cnblogs.com/songjilong/p/12635448.html

1、分类维护

1)、三级分类

爽易购商城--后台管理_第20张图片

  1. 在后台管理系统添加商品系统目录
    爽易购商城--后台管理_第21张图片

  2. 添加分类维护菜单
    爽易购商城--后台管理_第22张图片

  3. 创建category视图
    爽易购商城--后台管理_第23张图片

  4. 添加分类
    ElementUI官网的树形控件:https://element.eleme.cn/#/zh-CN/component/tree
    爽易购商城--后台管理_第24张图片
    爽易购商城--后台管理_第25张图片

  5. 增加单个增删改功能
    爽易购商城--后台管理_第26张图片

<el-button
          type="text"
          size="mini"
          @click="append(data)"
          v-if="node.level < 3" 
<dependency>
    <groupId>com.alibaba.cloudgroupId>
    <artifactId>spring-cloud-starter-alicloud-ossartifactId>
    <version>2.1.0.RELEASEversion>
dependency>
  • 配置AccessKey
    spring:
      cloud:
        alicloud:
          access-key: your-ak
          secret-key: your-sk
          oss:
            endpoint: oss-cn-hangzhou.aliyuncs.com #地域节点,此为示例
    
  • 3. 新增品牌

    1)、前端校验

    ElementUI表单校验:https://element.eleme.cn/#/zh-CN/component/form
    Form 组件提供了表单验证的功能,只需要通过 rules 属性传入约定的验证规则,并将 Form-Item 的 prop 属性设置为需校验的字段名即可。校验规则参见 async-validator
    爽易购商城--后台管理_第41张图片
    还可以自定义校验规则:爽易购商城--后台管理_第42张图片

    2)、后端校验

    前端校验方便用户的同时,也减轻了服务器压力
    但当恶意访问者绕过浏览器,通过Postman等类似工具进行访问时,前端校验未必有用,此时我们需要添加后端校验

    我们此次使用JSR303

    错误码

    自定义错误码以便快速精确定位错误
    放在公共模块以便所有模块使用
    BizCodeEnume

    4. 属性分组

    后端统一异常处理

    ExceptionControllerAdvice.java

    bug

    找不到python问题

    **问题描述:**在github上clone下的项目执行npm install时报python环境错误

    确保windows已安装node.js/vue/vue-cli

    一、cmd下运行npm install -globabl -production windows-build-tools一键安装

    1. python(v2.7 ,3.x不支持);
    2. visual C++ Build Tools,或者 (vs2015以上(包含15))
    3. .net framework 4.5.1

    二、在控制台输入:npm install -g node-gyp安装node-gyp
    三、安装后检查:node-gyp list 爽易购商城--后台管理_第43张图片
    最后到项目下执行npm install…成功。。。
    后记:
    如果还是提示“python找不到或者环境不对”

    npm config set python C:\Users\Administrator\.windows-build-tools\python27\python.exe
    

    跨域问题

    跨域:指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript施加的安全限制
    同源策略:是指协议,域名,端口都要相同,其中有一个不同都会产生跨域。
    爽易购商城--后台管理_第44张图片
    解决方案一:使用Nginx部署为同一域
    爽易购商城--后台管理_第45张图片
    解决方案二:配置当前请求允许跨域

    1. 添加响应头
      • Access-Control-Allow-Origin:支持哪些来源的请求跨域
      • Accss-Control-Allow-Methods:支持哪些方法跨域
      • Access-Control-Allow-Credentials:跨域请求默认不包含cookie,设置true包含
      • Access-Control-Expose-Headers:跨域请求暴漏的字段
        • CORS请求时,XMLHttpRequest对下国内的getResponseHeader()方法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma,如果想要拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。
      • Access-Control-Max-Age:表迷宫该响应的有效时间为多少秒。有效时间内,浏览器无需为同一请求再次发起预见请求。请注意,浏览器自身维护了一个最大有效时间,如果该首部字段的值超过了最大有效时间,将失效。

    你可能感兴趣的:(spring,cloud,java,spring,boot)