写在开篇:本内容仅用于个人学习,如有侵扰,联系删除
简介
一、项目背景
1)电商模式
市面上有五种常见电商模式:B2B、B2C、C2B、C2C、O2O。
1.B2B模式
B2B(Business to Business),是指商家与商家建立的商业关系。如:阿里巴巴。
2.B2C模式
B2C(Business to Consumer),即供应商直接把商品卖给用户——”商对客“模式,也就是通常说的商业零售,直接面向消费者销售产品和服务。如:苏宁易购,京东,天猫,小米商城。
3.C2B模式
C2B(Customer to Business),即消费者对企业。先有消费者需求生产而后有企业生产,即先有消费者提出需求,后有生产企业按照需求组织生产。
4.C2C模式
C2C(Customer to Customer),客户之间自己把东西放到网上去卖,如:淘宝,咸鱼。
5.O2O模式
O2O(Online to Online),即将线下商务的机会与互联网结合在了一起,让互联网成为线下交易的前台。线上快速支付,线下优质服务。如:饿了么,美团,淘票票,京东到家。
二、谷粒商城
谷粒商城是一个B2C模式的电商平台,销售自营商品给客户。
1)项目架构图
1.分布式基础概念
微服务
微服务架构风格,就像是把一个单独的应用程序开发为一套小服务,每个小服务运行在自己的进程中,并使用轻量级机制通信,通常是HTTP API。这些服务围绕业务能力来构建,并通过完全自动化部署机制来独立部署。这些服务使用不同的编程语言书写,以及不同的数据存储技术,并保持最低限度的集中式管理。
即拒绝大型单体应用,基于业务边界进行服务微化拆分,各个服务独立部署运行。
集群&分布式&节点
集群是个物理形态,分布式是个工作方式。
只要是一堆机器,就可以叫集群,它们是不是一起协作着干活,这个都不清楚。
分布式是指将不同的业务分布在不同的地方。
集群指将几台服务器集中在一起,实现同一业务。
例如:京东是一个分布式系统,众多业务运行在不同的机器上,所有业务构成了一个大型的业务集群。每个小的业务,如用户系统,访问压力过大时一台服务器就不够了,我们就应该将用户系统部署到多个服务器,也就是每个业务系统也可以做集群化。
分布式中的每个节点都可以做集群,但集群不一定就是分布式的。
远程调用
在分布式系统中,每个服务可能处于不同的主机,但服务之间不可避免需要相互调用,我们称为远程调用。
SpringCloud中使用HTTP+JSON的方式完成远程调用。
负载均衡
分布式系统中,A服务需要调用B服务,B服务在多台机器中都存在,A调用任意一个服务器均可完成功能。
为了使得每个服务器都不要太忙或者太闲,我们可以负载均衡调用每一个服务器,提升网站的健壮性。
常见的负载均衡算法:
轮询:为第一个请求选择健康池中的第一个后端服务器,然后按顺序往后依次选择,直到最后一个,然后循环。
最小连接:优先选择连接数最少,也就是压力最小的后端服务器,在会话较长的情况下可以考虑采取这种方法。
散列:根据请求源的IP的散列(hash)来选择要转发的服务器。这种方式可以一定程度上保证特定用户能连接到相同的服务器。如果你的应用需要处理状态而要求用户能连接到和之前相同的服务器,可以考虑这种方式。
服务注册/发现&注册中心
A服务调用B服务,A服务并不知道B服务当前在哪几台服务器有,哪些正常的,那些服务器已经下线。解决这个问题可以引入注册中心:
如果某些服务下线,我们其他人可以实时感知到其他服务的状态,从而避免调用不可用的服务。
配置中心
每个服务最终都有大量的配置,并且每个服务都可能部署在多台机器上。我们经常要变更配置,就可以让每个服务在配置中心获取自己的配置。
服务熔断&服务降级
在微服务架构中,微服务之间通过网络进行通信,存在相互依赖,当其中一个服务不可用时,有可能会造成雪崩效应,要防止这样的情况,必须要有容错机制来保护服务。
1)服务熔断
设置服务的超时,当被调用的服务经常失败到达某个阈值,我们可以开启断路保护机制,后来的请求不再去调用这个服务。本地直接返回默认的数据。
2)服务降级
在运维期间,当系统处于高峰期,系统资源紧张,我们可以让非核心业务降级运行。
降级:某些服务不处理,或者简单处理(抛异常,返回NULL,调用Mock数据,调用Dallback处理逻辑)。
API网关
在微服务架构中,API Gateway作为整体架构的重要组件,它抽象了微服务中部需要的公共功能,同时提供了客户端负载均衡,服务自动熔断,灰度发布,统一认证,限流流控,日志统计等丰富功能,帮助我们解决很多API管理难题。
2.项目微服务架构图
3.项目微服务划分图
2)项目技术&特色
前后端分离开发,开发基于vue的后台管理系统
SpringCloud全新的解决方案
应用监控,限流,网关,熔断降级等分布式方案,全方位涉及
透彻讲解分布式事务,分布式锁等分布式系统的难点
分析高并发场景的编码方式,线程池,异步编排等使用
压力测试与性能优化
各种集群技术的区别以及使用
CI/CD使用
...
3)项目前置要求
熟悉SpringBoot以及常见整合方案
了解SpringCloud
熟悉git,maven
熟悉linux,redis,docker基本操作
了解html,css,js,vue
熟练使用idea开发项目
环境搭建
一、安装linux虚拟机
1)下载&安装 VirtualBox,要开启 CPU 虚拟化
2)下载&安装 Vagrant
Vagrant 官方镜像仓库
Vagrant 下载
1.打开window cmd窗口(建议不要在C盘),运行
Vagrant init centos/7
即可初始化一个 centos7 系统.
2.运行
Vagrant up
即可启动虚拟机。系统root用户的密码是vagrant
3.vagrant其他常用命令
vagrant ssh:自动使用vagrant用户连接虚拟机。
vagrant upload source [destinatioon] [name | id]:上传文件
虚拟机网络设置
1.网络地址转换-端口转发(默认,但不是固定IP,不方便)
2.修改vagrantfile
修改35行的config.vm.network "private_network",ip:"192.168.xx.10",这个ip需要在windows的ipconfig或者ipconfig /all命令中查到vitualbox的ip,然后更改xx位置,使得ip保持一致。配置完后使用vagrant reload命令重启虚拟机。
在虚拟机中ip addr就可以查看到地址了。互相ping也能ping通。
二、在linux里安装docker
虚拟化容器技术。Docker基于镜像,可以秒级启动各种容器,每种容器都是一个完整的运行环境,容器之间相互隔离。
1.docker安装
//卸载系统之前的docker
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
//安装docker依赖的包
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
//安装社区版docker
sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
2.docker启动
//启动docker
sudo systemctl start docker
//查看docker版本
docker -v
//docker开机自启动
sudo systemctl enable docker
//查看镜像
sudo docker images
3.配置docker阿里云镜像加速
//镜像加速
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://g7cf9pld.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
三、docker安装MySQL
安装和创建实例:
//安装MySQL
sudo docker pull mysql:5.7
//创建实例并启动
sudo 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
参数说明(--name指定容器名字 -v目录挂载 -p指定端口映射 -e设置mysql参数 -d后台运行)
-p 3306:3306:将容器的 3306 端口映射到主机的 3306 端口
-v /mydata/mysql/conf:/etc/mysql:将配置文件夹挂载到主机
-v /mydata/mysql/log:/var/log/mysql:将日志文件夹挂载到主机
-v /mydata/mysql/data:/var/lib/mysql/:将配置文件夹挂载到主机
-e MYSQL_ROOT_PASSWORD=root:初始化 root 用户的密码
切换root用户
su root
password:vagrant(默认的)
查看docker正在运行的容器
//会列出出正在运行的容器信息
docker ps
//会列出当前服务器中所有的容器,无论是否在运行
docker ps -a
a.尝试连接失败时,需要关闭防火墙(未解决,舍弃)
systemctl stop firewalld
参考:Linux的systemctl命令详解及如何(永久)关闭SElinux和firewalld防火墙-优快云博客
b.设置用户 root 可以在任意 IP 下被访问(无法启动MySQL问题没有解决,舍弃)
grant all privileges on *.* to root@"%" identified by "密码";
参考:Mysql5.7设置允许外部访问_修改mysql 5.7对外开放-优快云博客
关于无法成功运行MySQL的解决办法
修改运行
docker run \
-d -p 3306:3306 \
-v /usr/local/mysql/conf:/etc/mysql/conf.d \
-v /usr/local/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=root \
--name mysql mysql:5.7
参考:docker安装mysql容器创建成功但无法启动问题_docker mysql容器无法启动-优快云博客
如何删除 Docker 容器?@慕课网 原创_慕课网_手记 (imooc.com)
此问题解决后,SQLyog连接成功
进入MySQL容器内部时
//进入容器内部
docker exec -it mysql bin/bash
问题:进入容器内部,显示的是-bash-4.2#
而不是root@主机名 + 路径的显示方式。原因是根目录下缺失几个配置文件,从默认配置中拷贝过来就解决了。
Linux 命令终端提示符显示 bash-4.2# 解决方法 - 公博义 - 博客园 (cnblogs.com)
修改MySQL的配置文件
//进入mysql配置文件,修改mysql字符编码
vi /mydata/mysql/conf/my.conf
[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
四、docker安装redis
在root用户下:
1.下载镜像文件
//下载镜像文件
docker pull redis
2.创建实例并启动
直接运行时,挂载会把redis.conf当作目录,而不是文件,因此要预先把文件创建好。
mkdir -p /mydata/redis/conf
touch /mydata/redis/conf/redis.conf
docker pull redis
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
redis默认不持久化,所有数据存储在内存中。
设置持久化:在配置文件中输入appendonly yes,配置完后要重启。
五、开发环境统一
1.Maven
安装配置参考:Maven的安装与配置(包含所有细节)_maven安装及配置教程-优快云博客
maven官网下载bin.tar.gz和bin.zip以及src.tar.gz和src.zip的区别_maven src与bin区别-优快云博客
遇到问题:之前配置过的环境变量出错
配置maven问题:The JAVA_HOME environment variable is not defined correctly-优快云博客
在maven的config.xml中进行配置:
//阿里云镜像
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
//配置 jdk1.8 编译项目
<profile>
<id>jdk-1.8</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>
</profiles>
修改idea中setting下maven的主路径和用户设置文件。
2.IDEA和VSCode
idea 安装 lombok 和 mybatisx 插件
下载vsCode用于前端管理系统。在vsCode里安装插件。
Auto Close Tag:自动闭合 HTML/XML 标签
Auto Rename Tag:自动完成另一侧标签的同步修改
Chinese (Simplified) Language Pack for Visual Studio Code:中文语言包
EsLint:语法纠错
HTML CSS Support:让 html 标签上写 class 智能提示当前项目所支持的样式
HTML Snippets:html 快速自动补全
JavaScript(ES6) code snippets:ES6语法智能提示以及快速输入 ,除 js 外还支持ts, .jsx, .html, .vue,省去了配置其支持各种包含 js 代码文件的时间
Live Server:以内嵌服务器方式打开
Open in browser:浏览器快速打开
Vetur:语法高亮、智能感知、Emmet 等 包含格式化功能, Alt+Shift+F(格式化全文),Ctrl+K Ctrl+F(格式化选中代码,两个 Ctrl需要同时按着)
3.配置git
1.下载 git : https://git-scm.com
下载git客户端,右键桌面Git bash Here
2.配置 git ,进入 git bash
//配置用户名,注册名字或者自己名字都可以,无要求
git config --global user.name "username"
//配置邮箱,注册账号时使用的邮箱
git config --global user.email "XXXXX@XXX.com"
3.配置SSH免密登录
进入 git bash;使用:ssh-keygen -t rsa -C "xxxxx@xxxxx.com"命令,连续三次回车。
cat ~/.ssh/id_rsa.pub获得完整公钥
登录进入 gitee,在设置里面找到 SSH KEY 将.pub 文件的内容粘贴进去
最后使用 ssh -T git@gitee.com 测试是否成功即可
4.项目结构创建&提交到码云
1)从 gitee 初始化一个项目
在IDEA中New–Project from version control–git–复制刚才项目的地址,例如https://gitee.com/leifengyang/gulimall.git
New Module -> Spring Initializer -> com.atguigu.gulimall
Artifact:gulimall-product -> Next -> 选择web:Spring Web
Spring Cloud Routing:OpenFeign,新版本的IDEA再加上Cloud LoadBalancer
同方法建立其他四个模块:
商品服务-product
存储服务-ware
订单服务-order
优惠券服务-coupon
用户服务-member
5.数据库初始化
将各个模块数据导入数据库。
数据来自:谷粒商城数据库源码SQL_谷粒商城数据库代码-优快云博客
遇到的问题:
在新建数据库时电脑固定发生蓝屏,根据终止代码和失败的操作数据查到是因为用了最新版的virtualbox,是一个官方的BUG,于是下载旧版本才成功。
终止代码:PAGE_FAULT_IN_NONPAGED_AREA
失败的操作:VBoxNetAdp6.sys
快速开发
一、人人开源搭建后台管理系统
数据来源:人人开源 (gitee.com)
下载代码请复制以下命令到终端执行(桌面右键点击Git Bash Here)
git clone https://gitee.com/renrenio/renren-fast.git
git clone https://gitee.com/renrenio/renren-fast-vue.git
将拷贝到桌面的“renren-fast”删除“.git”后,剪贴到“gulimall”工程根目录下,然后将它作为gulimall的一个module。
创建“gulimall_admin”的数据库,执行“renren-fast/db/mysql.sql”的sql脚本。
在"application.yml"里确认默认为dev环境,修改“application-dev.yml”中连接mysql的url和用户名密码。
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.56.10:3306/gulimall_admin?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
username: root
password: root
运行RenrenApplication.java。
1).安装Node.js
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。
http://nodejs.cn/api/
我们关注与 node.js 的 npm 功能就行;
NPM 是随同 NodeJS 一起安装的包管理工具, JavaScript-NPM , Java-Maven。
1.官网下载安装 node.js,并使用 node -v 检查版本
下载地址:Node.js — Download Node.js® (nodejs.org)
我选择了版本12.22.12且windows下载,下载完安装。
命令行输入node -v检查配置
node -v
2.配置 npm 使用淘宝镜像
npm config set registry http://registry.npm.taobao.org/
3.在VSCode中打开vue文件,在终端输入
npm install
npm run dev
进行运行。
【途中遇到问题多试试评论区的方法,大部分都是因为node和sass版本不匹配。sass版本的修改在项目文件中的package.json中,而非nodejs文件夹。
重新尝试时记得将项目文件中的node_modules文件删除。
运行成功但不显示验证码,要连接虚拟机数据库,多试几次。】
2).逆向工程搭建&使用
1.克隆renren-generator
git clone https://gitee.com/renrenio/renren-generator.git
将文件中的.git删除,然后导入父工程,并在父工程中的pom.xml中添加renren-generator为子模块。
修改renren-generator中pom.xml
2.修改renren-generator配置文件中的数据库信息
a、修改renren-generator的配置文件application.yml,配置自己的数据源,注意修改数据库名:如gulimall_pms(生成商品系统)
server:
port: 81
# mysql
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
#MySQL配置
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.56.10:3306/lanbaimall_wms?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: root
b、修改生成信息generator.properties
#代码生成器,配置信息
mainPath=com.vince
#包名
package=com.vince.gulimall
moduleName=product
#作者
author=vince
#Email
email=xxxxx@qq.com
#表前缀(类名不会包含表前缀)
tablePrefix=pms_
3.运行项目并生成代码
访问localhost:81(建议不要使用80端口),选中所有表,生成代码
4.解压生成代码并复制到guli-product
把解压生成的mian文件夹复制到guli-product/src下
3).gulimall-common
项目右击创建公共模块(new modules)
在项目pom.xml中添加<module>gulimall-common</module>
在common项目的pom.xml中添加:
<!-- mybatisPLUS-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>
<!--简化实体类,用@Data代替getset方法-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.16</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
<scope>compile</scope>
</dependency>
把每个微服务里公共的类和依赖放到common里。
在product项目中的pom.xml中加入下面内容:
<dependency>
<groupId>com.atguigu.gulimall</groupId>
<artifactId>gulimall-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
4).用同种方式生成其他各模块的增删改查代码
5).SpringCloud Alibaba简介
结合SpringCloud Alibaba 最终的技术搭配方案:
SpringCloud Alibaba -Nacos:注册中心(服务发现/注册)
SpringCloud Alibaba -Nacos:配置中心(动态配置管理)
SpringCloud-Ribbon:负载均衡
SpringCloud-Feign:声明式HTTP客户端(调用远程服务)
SpringCloud Alibaba-Sentinel:服务容错(限流、降级、熔断)
SpringCloud-Gateway:API网关(webflux编程模式)
SpringCloud-Sleuth:调用链监控
SpringCloud Alibaba-Seata:原Fescar,即分布式事务解决方案
netflix把feign闭源了,spring cloud开了个open feign
项目中引入SpringCloud Alibaba依赖
注意:版本号要与SpringBoot版本号对应,具体看官方文档
官方GitHub项目地址及版本说明:spring-cloud-alibaba
spring-cloud:2020.0.5
spring-boot:2.5.4
Spring Cloud Alibaba:2021.1
Nacos:1.3.1
JDK:1.8
在common的pom.xml中加入
<!--依赖管理,在dependencies引入SpringCloud Alibaba相关依赖不需要引入版本号了-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2021.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
PS:A&Q
Q:maven的clean不报错,但是install提示程序包xxx不存在,具体是在constant文件的import中
A:一直以为是版本问题,但是尝试修改后还是报错,于是我索性将引用包从renren-fast中复制粘贴过来,constant也自动帮我修改了模块内部的路径。
install成功
maven install 或 package 时 ,执行警告报错:
[WARNING] The POM for com.xx-base:jar:1.0 is missing, no dependency information available
[ERROR] Failed to execute goal on project xx-mobi: Could not resolve dependencies for project com.xx-mobi:jar:1.0: Failed to collect dependencies at xx-base:jar:1.0: Failed to read artifact descriptor for xx-base:jar:1.0: Could not find artifact xx-root:pom:1.0 in geotoolrepo...
报错也得以解决
Q:运行报错:
Exception in thread "main" java.lang.IllegalArgumentException: Cannot instantiate interface org.springframework.context.ApplicationListener : org.springframework.boot.context.logging.ClasspathLoggingApplicationListener
at org.springframework.boot.SpringApplication.createSpringFactoriesInstances(SpringApplication.java:439)...
A:通过pom的对比在pom.xml文件里修改为
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<!--<version>${spring-cloud.version}</version>-->
<version>2020.0.5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Q:导入Alibaba依赖后又出现上一个报错信息,并提示java.lang.UnsupportedClassVersionError: com/alibaba/cloud/nacos/logging/NacosLoggingAppRunListener has been compiled by a more recent version of the Java Runtime
A:回溯无Alibaba依赖状态便不报错,开始猜测是nacos版本的问题,换了几个都不行。
解决:修改Alibaba依赖版本
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<!--<version>2023.0.1.0</version>-->
<version>2021.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
成功运行。
Q:路径重写后,验证码图片仍然报错503
A:503的是服务未找到,因为lb是进行负载均衡 引入 spring-cloud-starter-loadbalancer 依赖就好