项目简介
项目背景
1)电商模式
2)谷粒商城
是一个B2C模式的电商平台,销售自营商品给客户。
架构图
1)项目微服务架构图
客户端->nginx集群->网关集群
2)微服务划分图
项目特色
- 前后端分离开发,并开发基于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
将文件中,关于监听端口、监听地址前的 # 号去除
开启允许远程登录
开启使用用户名密码来作为连接验证
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
1)下载镜像文件
sudo docker pull mysql:5.7
查看下载的镜像文件docker images
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
参数说明:
-
-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
以后台方式启动,以mysql:5.7
镜像启动
- 查看运行的容器
docker ps
- 进入容器内部
docker exec -it 容器id/容器名 /bin/bash
docker exec -it mysql /bin/bash
- 从宿主机连mysql容器
运行mysql容器后,可以在宿主机上连mysql
首先查看CentOS的IP
使用mysql客户端工具连接mysql server
配置字符集
在/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
完整的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
运行成功后,自动在浏览器打开
输入用户名密码和验证码,用户名密码都是admin
逆向工程使用
下载代码生成器项目
https://gitee.com/renrenio/renren-generator.git
整合进项目中
拷贝到我们项目根目录,删除renren-generator根目录下的.git目录
右键点击renren-generator,Add as Maven Project
加入聚合项目的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的数据库配置
主要是这两个文件
启动启动类
访问http://localhost:8082/
将所有数据展示在一页,然后点击生成代码按钮,会下载一个压缩包
默认会生成Java代码和Vue代码
我们先将所有main下的内容拷贝到product模块的main目录下,和已有目录合并。
测试product模块
数据库驱动
mysql驱动选择,我们的数据库安装的是5.7,5.7的数据库驱动官网建议使用8.0