谷粒商城--微服务分布式电商项目学习笔记

时间:2024-03-11 14:28:49

项目简介

项目背景

1)电商模式

2)谷粒商城

是一个B2C模式的电商平台,销售自营商品给客户。

架构图

1)项目微服务架构图

image-20200725075045044

客户端->nginx集群->网关集群

2)微服务划分图

image-20200725090220739

项目特色

  • 前后端分离开发,并开发基于vue的后台管理系统
  • SpringCloud全新的解决方案
  • 应用监控、限流、网关、熔断降级等分布式方案,全方位涉及
  • 透彻讲解分布式事务、分布式锁等分布式系统的难点
  • 分析高并发场景点编码方式,线程池,异步编排等使用
  • 压力测试与性能优化
  • 各种集群技术等区别以及使用
  • CI/CD使用

项目前置要求

  • 熟悉SpringBoot以及常见整合方案
  • 了解SpringCloud
  • 熟悉git、maven
  • 熟悉linux,redis,docker基本操作
  • 了解html,css,js,vue
  • 熟练使用idea开发项目

分布式基础概念

微服务

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

拒绝大型单体应用,基于业务边界进行服务微化拆分,各个服务独立部署允许

集群、分布式、节点

集群是个物理状态,分布式是个工作方式。

只要是一堆机器,就可以叫做集群,他们是不是一起协作干活,这个谁也不知道

《分布式系统原理与范型》定义:

分布式系统是若干独立计算机的集合,这些计算机对于用户来说就像单个系统,分布式系统是建立在网络之上的软件系统。

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

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

例如:京东是一个分布式系统,众多业务运行在不同的机器,所有业务构成一个大型的业务集群。

每个业务系统可以单独进行扩缩容,做集群。

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

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

远程调用

分布式系统各个服务可能处于不同的主机,但是服务之间不可避免的需要互相调用,就是远程调用。

Spring Cloud默认使用HTTP+JSON的方式完成远程调用

负载均衡

分布式系统中,A服务需要调用B服务,B服务在多台机器都存在,A调用任意一个服务器均可完成功能。

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

常见负载均衡算法:

轮询

最小连接

散列

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

对服务上下线感知,服务发现,从而避免调用不可用的服务

配置中心

配置集中管理,变更动态配置,实时生效

集中管理微服务的配置信息

服务熔断降级

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

1)服务熔断

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

2)服务降级

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

降级:某些服务不处理,或者简单处理(抛异常、返回NULL、调用Mock数据、调用Fallback处理逻辑)

API网关

提供客户端负载均衡,服务自动熔断,灰度发布,统一认证,限流流控,日志统计等功能。解决API管理难题。

环境搭建

下载安装Centos7

阿里云镜像下载地址https://mirrors.aliyun.com/centos/7.8.2003/isos/x86_64/

安装过程省略

配置仓库

1)备份

mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup

2)下载新的 CentOS-Base.repo 到 /etc/yum.repos.d/

wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo

3)运行 yum makecache 生成缓存

参考阿里云Centos镜像配置

https://developer.aliyun.com/mirror/centos?spm=a2c6h.13651102.0.0.3e221b11lumMFr

配置ssh

1)查看是否安装了ssh

yum list installed | grep openssh-server

2)安装ssh

yum install openssh-server

3)修改ssh配置

sudo vi /etc/ssh/ssh_config 

将文件中,关于监听端口、监听地址前的 # 号去除

image-20200726091401137

开启允许远程登录

image-20200726091435495

开启使用用户名密码来作为连接验证

image-20200726091500309

4)启动sshd服务

sudo service sshd start

5)检查 sshd 服务是否已经开启

ps -e | grep sshd

或者检查 22 号端口是否开启监听

netstat -an | grep 22

6)开启开机自启动

sudo systemctl enable sshd

7)检查是否加入了开机自启动

systemctl list-unit-files | grep sshd

安装Docker

官网参考地址:https://docs.docker.com/engine/install/centos/

1)写在旧版本

sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

2)设置仓库

sudo yum install -y yum-utils

sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo

3)安装DOCKER ENGINE

sudo yum install docker-ce docker-ce-cli containerd.io

4)运行Docker

sudo systemctl start docker

5)开机启动Docker

sudo systemctl enable docker

配置Docker阿里云镜像加速

https://developer.aliyun.com/mirror/docker-ce?spm=a2c6h.13651102.0.0.3e221b11qdbJJS

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-\'EOF\'
{
  "registry-mirrors": ["https://q10nwbtl.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

Docker安装MySQL

image-20200725221819330

1)下载镜像文件

sudo docker pull mysql:5.7

查看下载的镜像文件docker images

image-20200725222021079

2)创建实例并启动

docker run -p 3306:3306 --name mysql \
-v /mydata/mysql/log:/var/log/mysql \
-v /mydata/mysql/data:/var/lib/mysql \
-v /mydata/mysql/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7

参数说明:

  1. -p 3306:3306 端口映射

  2. --name mysql 容器别名

  3. 目录挂载

-v /mydata/mysql/log:/var/log/mysql \
-v /mydata/mysql/data:/var/lib/mysql \
-v /mydata/mysql/conf:/etc/mysql \
  1. -e MYSQL_ROOT_PASSWORD=root 初始化参数

  2. -d mysql:5.7以后台方式启动,以mysql:5.7镜像启动

  • 查看运行的容器

docker ps

image-20200725225402152

  • 进入容器内部

docker exec -it 容器id/容器名 /bin/bash

docker exec -it mysql /bin/bash

  • 从宿主机连mysql容器

运行mysql容器后,可以在宿主机上连mysql

首先查看CentOS的IP

image-20200725225925017

使用mysql客户端工具连接mysql server

image-20200725225959266

配置字符集

/mydata/mysql/conf目录新建文件my.cnf,内容如下:

[client]
default-character-set=utf8

[mysql]
default-character-set=utf8

[mysqld]
init_connect=\'SET collation_connection = utf8_unicode_ci\'
init_connect=\'SET NAMES utf8\'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake
skip-name-resolve

重启mysql容器

docker restart mysql

参数mysql是容器的别名

查看所有容器

docker container ls -a

Docker安装Redis

1)下载镜像文件

docker pull redis

2)创建实例并启动

mkdir -p /mydata/redis/conf

cd /mydata/redis/conf

touch redis.conf

docker run -p 6379:6379 --name redis \
-v /mydata/redis/data:/data \
-v /mydata/redis/conf/redis.conf:/etc/redis/redis.conf \
-d redis redis-server /etc/redis/redis.conf

3)交互模式,连接redis容器,运行redis客户端

docker exec -it redis redis-cli

4)设置aof持久化

vi redis.conf

添加内容:

appendonly yes

5)宿主机中使用客户端连接redis

image-20200726094802895

完整的redis配置

https://raw.githubusercontent.com/redis/redis/6.0/redis.conf

开机自启动容器

sudo docker update redis --restart=always
sudo docker update mysql --restart=always

开发环境配置

maven

git(ssh-keygen)

idea

idea插件(Mybatis插件)

vscode

vscode插件

创建项目

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

数据库设计

不建立外键

使用renren-fast快速开发后台管理系统

克隆项目到本地(包括前后端)

https://gitee.com/renrenio/renren-fast.git

https://gitee.com/renrenio/renren-fast-vue.git

将renren-fast加入聚合工程里

  • 右键点击pom.xml,然后选择add as maven project
  • 删除renren-fast工程里的.git目录
  • 修改数据库连接信息
spring:
    datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        druid:
            driver-class-name: com.mysql.cj.jdbc.Driver
            url: jdbc:mysql://10.211.55.11:3306/gulimall_admin?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
            username: root
            password: root
            initial-size: 10
            max-active: 100
            min-idle: 10
            max-wait: 60000
            pool-prepared-statements: true
            max-pool-prepared-statement-per-connection-size: 20
            time-between-eviction-runs-millis: 60000
            min-evictable-idle-time-millis: 300000
            #Oracle需要打开注释
            #validation-query: SELECT 1 FROM DUAL
            test-while-idle: true
            test-on-borrow: false
            test-on-return: false
            stat-view-servlet:
                enabled: true
                url-pattern: /druid/*
                #login-username: admin
                #login-password: admin
            filter:
                stat:
                    log-slow-sql: true
                    slow-sql-millis: 1000
                    merge-sql: false
                wall:
                    config:
                        multi-statement-allow: true

创建数据库并导入sql脚本到数据库

db/mysql.sql

启动后台项目

运行RenrenApplication

浏览器访问swagger

http://localhost:8080/renren-fast/swagger-ui.html

安装node

brew install node@10

echo \'export PATH="/usr/local/opt/node@10/bin:$PATH"\' >> ~/.zshrc

配置npm淘宝源

echo \'\n#alias for cnpm\nalias cnpm="npm --registry=https://registry.npm.taobao.org \
  --cache=$HOME/.npm/.cache/cnpm \
  --disturl=https://npm.taobao.org/dist \
  --userconfig=$HOME/.cnpmrc"\' >> ~/.zshrc && source ~/.zshrc

使配置生效

source .zshrc

安装前端依赖

进入renren-fast-vue根目录

运行

npm install chromedriver --chromedriver_cdnurl=http://cdn.npm.taobao.org/dist/chromedriver

再运行npm install

启动前端项目

npm run dev

运行npm run dev可能会遇到一些问题,也记录一下,毕竟浪费了时间

错误1:

ENOENT: no such file or directory, scandir \'/Users/kim/IdeaProjects/atguigu/renren-fast-vue/node_modules/node-sass/vendor\'

原因:网络原因,需要借助镜像或者XX手段

解决方法:

node-sass的github主页有方案:

npm install -g mirror-config-china --registry=http://registry.npm.taobao.org
npm install node-sass

错误2:

No parser no filepath given

解决方法:

指定parser,

在node_modules/vue-loader/lib/template-compiler/index.js文件中,指定parser

image-20200726200352603

运行成功后,自动在浏览器打开

输入用户名密码和验证码,用户名密码都是admin

image-20200726200514164

逆向工程使用

下载代码生成器项目

https://gitee.com/renrenio/renren-generator.git

整合进项目中

拷贝到我们项目根目录,删除renren-generator根目录下的.git目录

右键点击renren-generator,Add as Maven Project

image-20200726201746246

加入聚合项目的pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.atguigu.gulimall</groupId>
    <artifactId>gulimall</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>gulimall</name>
    <description>谷粒商城聚合工程</description>
    <packaging>pom</packaging>

    <modules>
        <module>gulimall-coupon</module>
        <module>gulimall-member</module>
        <module>gulimall-order</module>
        <module>gulimall-product</module>
        <module>gulimall-ware</module>
        <module>renren-fast</module>
        <module>renren-generator</module>
    </modules>

</project>

使用

公共依赖的导入

首先在common模块中引入一些公共依赖和公共类,因为renren-generator生成的类对这些类有依赖,这些类和依赖在renren-fast项目中。

由于内容较多,直接切换到master分支上tag为common的版本,然后:

  • 导入com.atguigu.common包下所有内容

  • 复制common模块下的pom.xml所有内容

改renren-generator的数据库配置

主要是这两个文件

image-20200726214646070

image-20200726214618107

image-20200726214739572

启动启动类

访问http://localhost:8082/

image-20200726215002964

将所有数据展示在一页,然后点击生成代码按钮,会下载一个压缩包

默认会生成Java代码和Vue代码

我们先将所有main下的内容拷贝到product模块的main目录下,和已有目录合并。

测试product模块

数据库驱动

mysql驱动选择,我们的数据库安装的是5.7,5.7的数据库驱动官网建议使用8.0

image-20200726215912866