文章目录
- 分布式三高商城系统
- 一、系统架构演变
- 1、服务架构的演变
- 1.1单体架构
- 1.2集群
- 1.3垂直化
- 1.4服务化
- 1.5微服务化
- 微服务和SOA的区别
- 2、微服务架构的需求
- 2.1RPC框架
- 2.2注册中心
- 2.3负载均衡
- 2.4配置中心
- 2.5网关
- 2.6限流、降级、缓存
- 2.7Bus
- 2.8链路监控
- 二、项目介绍
- 1、项目架构
- 1.1系统架构图
- 1.2业务组成
- 1.3技术栈
- 1.4项目结构
- 三、项目环境准备
- 1、虚拟机环境
- 通过vagrant安装虚拟机
- xshell远程连接
- 2、Docker环境安装
- 卸掉原有环境
- 安装对应的依赖环境和镜像地址
- 安装过慢设置镜像
- 直接安装docker CE
- 启动docker服务
- 查看docker的版本
- yum更新
- 开机启动docker
- 3、基本软件安装
- 3.1MySQL软件安装
- 3.2Redis安装
- 3.3开发环境
- 3.4Git安装
- 4、后端系统搭建
- 4.1码云创建基本项目
- 4.2IDEA关联及项目clone
- 4.3创建微服务
- 4.4版本忽略信息
- 4.5提交微服务到码云
- 4.6创建数据库并导入数据库表
- 4.6后端管理系统搭建
- 4.6.1后端项目
- 4.6.2前端项目
- 4.6.3generator项目
- 4.6.4商品系统生成
- 4.6.5MyBatisPlus的整合
- mall-commons模块
- mall-product模块
- 4.6.6生成其他模块代码
- 5、微服务环境
- 5.1SpringCloudAlibaba介绍
- 5.2nacos注册中心
- 5.2.1nacos服务搭建
- 5.2.2nacos服务注册
- 5.2.3nacos在docker容器中安装
- 5.3OpenFegin服务调用
- 5.3.1商品服务定义接口
- 5.3.2订单服务中调用
- 5.4nacos配置中心
- 5.4.1配置中心的基本使用
- 5.4.2命名空间和配置分组
- 5.4.3配置拆分
- 5.5网关Gateway
- 5.5.1网关基本介绍
- 5.5.2网关应用
分布式三高商城系统
一、系统架构演变
1、服务架构的演变
1.1单体架构
单体架构中使用经典的三层模型,即表现层、业务处理层、数据访问层。
单体架构只适合于初期,且访问量比较低的情况下使用。
优点:性价比高,开发速度快,成本低。
1.2集群
针对单个服务器无法满足日增的业务访问量,可以考虑集群化处理。
集群部署显著增强服务的处理能力,同时利用nginx提供的负载均衡机制分发请求,用户体验没有改变。
1.3垂直化
上面的集群部署是可以解决一部分的服务器压力,但是随着用户访问量的增多,集群节点增加到一定阶段的时候,作用就已经不是太大了,因为将所有的业务都集中在一起,造成耦合度很高,这时我们可以考虑业务的拆分,来提高系统的性能。
所谓的垂直应用架构,就是将原来的一个应用拆成互不相干的几个应用,以提升效率。
比如电商平台,如果用户访问增加但是又并不是对所有的模块都会有比较大的访问量,可能对用户管理和订单管理的影响比较大对消息中心的影响就比较小,那么我们就希望只多增加几个订单模块,而不增加消息模块,再比如CMS应用宕机了,其他的应用也不想被受影响;此时单体应用就做不到了, 垂直架构就应运而生了。
服务垂直化拆分后可以大大提高整体的处理效率,但是也会出现很多冗余的代码。比如用户系统要操作订单库,要操作商品库,订单系统也有可能要操作用户库和商品库等。
1.4服务化
针对垂直化拆分出现的问题,出现一种解决方案(Service-Oriented Architecture,SOA)
SOA是一种设计方法,其中包括多个服务,而服务之间通过配合最终会提供一系列功能,一个服务通常以独立的形式存在于操作系统进程中,服务之间通过网络调用,而非采用进程内调用的方式进行通信。
业务重用,共享服务。
1.5微服务化
在SOA基础上继续演进就是我们所讲的微服务。SOA的服务更细粒度的拆分后就是微服务。
对基础运维能力要求越来越高,虚拟化、容器化等。
微服务和SOA的区别
1、思想上:微服务的目的是为了解耦而SOA的目的是为了实现数据的互通和共享。
2、协议:微服务会使用一些轻量级的协议(Restful API)
3、基础设施要求,微服务更加强调开发运维的持续交付。
2、微服务架构的需求
2.1RPC框架
在微服务架构中,服务与服务之间的调用我们肯定要通过相关的RPC(Remote Procedure Call)框架来实现。
常用的RPC框架有:Dubbo,Google的GRPC,Apache的Thrift,微博的Motan,京东的EasyRPC等。我们通过RPC框架可以调用服务提供者提供的服务,但前提是我们得找到这个服务。通常我们的服务部署都是集群多节点的部署,所以在消费者这端就不会直接写死代码。这时就涉及服务的发现问题,此时就需要另一个组件注册中心了。
2.2注册中心
注册中心实现服务地址管理功能,解决服务动态感知(上线、下线)
2.3负载均衡
客户端可以通过Ribbon来实现负载均衡,负载均衡的策略可以是:轮询、随机、根据响应的时间来计算权重的轮询等。
2.4配置中心
在微服务架构中我们有很多个服务,而每个服务都是有单独的配置文件的。里面有很多配置信息是相关联的,对于后期的更新维护会有很大的不便,这时配置中心就上场了。常用的配置中心有:apollo|nacos|disconf|zookeeper|diamond|spring cloud config
2.5网关
网关可以帮助我们完成用户请求的入口,路由转发。完成统一授权、日志记录、权限认证、限流、熔断操作。
2.6限流、降级、缓存
在现实的微服务架构中很难满足所有用户的请求,这时可以通过一些措施来保证我们的核心服务的正常运转。
限流:sentinel、hystrix
降级:主动降级(订单评论、广告关闭)、被动降级
缓存:降低数据源访问频率、Redis等
容错机制:服务出现挂机,宕机之后的处理机制。
2.7Bus
Bus消息总线,实现异步化的通信机制。
2.8链路监控
因为微服务中的服务实在是太多了,为了能更好的监控每个服务的情况,肯定就需要链路监控服务,我们可以通过sleuth + zipkin来实现应用层监控、系统级监控。
二、项目介绍
三高是指:高性能、高可用、高并发
1、项目架构
1.1系统架构图
1.2业务组成
1.3技术栈
- SpringBoot
- SpringCloudAlibaba(Nacos,Seata,Sentinel)
- MyBatisPlus
- MySQL
- Docker
- Redis
- ElasticSearch
- Skywalking
- RocketMQ
- Vue+ElementUI
- JMeter
- 阿里对象存储OSS
- Nginx
…
1.4项目结构
三、项目环境准备
1、虚拟机环境
可以通过VMWare来安装,但是通过VMWare安装大家经常会碰到网络ip连接问题,为了减少额外的环境因素影响,Docker内容的讲解我们会通过VirtualBox结合Vagrant(二者需相应版本,否则vagrant启动没法用virtual box引导)来安装虚拟机。
VirtualBox官网:https://www.virtualbox.org/
Vagrant官网:https://www.vagrantup.com/
Vagrant镜像仓库:https://app.vagrantup.com/boxes/search
安装VirtualBox和Vagrant,傻瓜式安装。安装完成后需要重启计算机。
在cmd命令窗口输入 vagrant
命令弹出如下内容表示 vagrant
安装成功
通过vagrant安装虚拟机
- 创建一个空目录,目录中不能含中文。cmd切换到该目录中,然后执行:
vagrant init centos/7
;会生成Vagrantfile文件 - 执行
vagrant up
第一次执行会远程下载相关镜像文件,并启动虚拟机。 - 连接虚拟机使用
vagrant ssh
。
网络配置
修改对应的Vagrantfile
查看当前主机给虚拟机分配的网关的网段
修改后的ip为:169.254.252.10
xshell远程连接
浏览添加私钥:D:\centosnods\mall-node.vagrant\machines\default\virtualbox\private_key
sudo -i切换至root用户
2、Docker环境安装
虚拟化、容器化部署
参考官方文档安装:https://docs.docker.com/engine/install/centos/
卸掉原有环境
yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine
安装对应的依赖环境和镜像地址
sudo yum install -y yum-utils--远程文件传输yum install -y lrzsz --网络排查yum install -y net-tools sudo yum-config-manager \--add-repo \https://download.docker.com/linux/centos/docker-ce.repo
安装过慢设置镜像
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
直接安装docker CE
sudo yum install -y docker-ce docker-ce-cli containerd.io
启动docker服务
sudo systemctl start docker
查看docker的版本
sudo docker version
yum更新
yum makecache fast
开机启动docker
sudo systemctl enable docker
3、基本软件安装
3.1MySQL软件安装
项目软件统一安装在 /mydata
目录下
docker pull mysql:5.7.34 稳定版本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.34docker ps -adocker rm -f mysqldocker rmidocker logs mysql
修改MySQL的配置文件 vim /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=utf8collation-server=utf8_unicode_ciskip-character-set-client-handshakeskip-name-resolve
docker restart [container id]
3.2Redis安装
docker pull redismkdir -p /mydata/redis/conftouch /mydata/redis/conf/redis.confdocker run -d -p 6379:6379 --name mall-redis -v /mydata/redis/data:/data -v /mydata/redis/conf:/etc/redisredis redis-server /etc/redis/redis.conf[root@manager-node conf]# docker exec -it 4e redis-cli127.0.0.1:6379> keys *(empty array)127.0.0.1:6379>
容器自启动
[root@localhost ~]# docker update --restart=always mysqlmysql[root@localhost ~]# docker update --restart=always mall-redismall-redis
3.3开发环境
JDK环境
开发工具:IDEA2020 + WebStorm2020
3.4Git安装
配置信息
git config --global user.name "lgj" git config --global user.email "871426518@qq.com"
关联码云,生成对应的公钥和私钥,在用户目录下
ssh-keygen -t rsa -C "871426518@qq.com"
然后把公钥中的内容复制到码云中去
通过 ssh -T git@gitee.com
来连接测试
4、后端系统搭建
4.1码云创建基本项目
创建完成
4.2IDEA关联及项目clone
下载Gitee插件
登录码云账号
clone项目到本地
项目成功clone
4.3创建微服务
首先创建几个基础的微服务(商品,订单,会员,库存,活动)
完成5个模块的创建
可以通过父工程来统一管理
4.4版本忽略信息
注意:新项目不要迅速git add,那样会把.gitignore文件也纳入管理,无法去除无用文件。
4.5提交微服务到码云
4.6创建数据库并导入数据库表
字符集:utf8mb4 + 排序规则:utf8mb4_general_ci
4.6后端管理系统搭建
前端:Vue + ElementUI
后端:Springboot + MyBatisPlus + SpringMVC
开源:renren ,ruoyi
本项目中会通过人人开源中提供的模板项目来快速的实现项目的构建:https://gitee.com/renrenio
4.6.1后端项目
下载下来的renren-fast解压后拷贝到项目的父工程的根目录下
修改人人-fast相关的数据库配置信息,查看数据库的连接信息,并修改
然后创建对应的数据库,名称为 renren_fast,根据提供的sql脚本,创建对应的表结构
更新对应数据库账号及密码
项目java版本5的调整
有可能设置失效多检查下,把其他数据库的驱动依赖注销掉。
将renren-fast的代码提交到码云中。
注意:
4.6.2前端项目
解压renren-fast-vue-master.zip
使用WebStorm2020打开,执行npm install
导入系统成功
4.6.3generator项目
更改数据库配置
调整生成类包路径
4.6.4商品系统生成
首先把生成的相关的模板文件拷贝到商品模块中。然后我们会发现代码有相关的错误提示,原因是缺少了renren-fast中的相关的依赖
可以创建一个commons模块来存放所有的微服务需要的公共内容。
新建一个maven公共module:mall-commons
在product项目中引入commons的依赖
lombok插件安装
4.6.5MyBatisPlus的整合
mall-commons模块
在mall-commons新增共同依赖
mall-product模块
在mall-product模块下增加数据库配置
MallProductApplication增加Mapper接口的映射
@SpringBootApplication// 指定Mapper接口对应的路径@MapperScan("com.msb.mall.product.dao")public class MallProductApplication {public static void main(String[] args) {SpringApplication.run(MallProducetApplication.class, args);}}
测试数据
@SpringBootTestclass MallProductApplicationTests {@AutowiredBrandService brandService;@Testvoid contextLoads() {BrandEntity entity = new BrandEntity();entity.setName("IQOO");brandService.save(entity);}@Testvoid selectAll() {List<BrandEntity> list = brandService.list();for (BrandEntity brandEntity : list) {System.out.println(brandEntity);}}@Testvoid selectById(){BrandEntity brandEntity = brandService.getOne(new QueryWrapper<BrandEntity>().eq("brand_id",2));System.out.println(brandEntity);}}
4.6.6生成其他模块代码
同理通过generator代码生成其它模块的代码
端口占用
1.查询指定端口: netstat -ano | findstr “端口号”2.根据进程PID查询进程名称: tasklist | findstr “进程PID号”3.根据PID杀死任务: taskkill /F /PID “进程PID号”或者 根据进程名称杀死任务: taskkill -f -t -im “进程名称”
修改数据库名称
生成参数配置
生成各模块代码
每个模块下都需要整合mybatis配置,按照product模块配置即可
配置各模块的服务端口
各模块服务启动测试
正常启动,说明各模块写的无问题,代码提交到远程,ok !!!
5、微服务环境
在SpringCloud出现之前,微服务架构我们也能够解决。但是选择五花八门,比较乱,针对这种情况,SpringCloud整合一套微服务的解决方案。
SpringCloud生态提供了快速构建微服务的技术组件。https://spring.io/projects/spring-cloud-netflix
版本 关键词描述
- SR (发行版)
- RC (后续发行版本)
- M1/M2(PRE) 里程碑
- GA 稳定版
- BUILD-XXX 开发版
SpringCloud和SpringBoot的关联关系
大版本对应:
Spring Cloud | Spring Boot |
---|---|
Angel版本 | 兼容Spring Boot 1.2.x |
Brixton版本 | 兼容Spring Boot 1.3.x,也兼容Spring Boot 1.4.x |
Camden版本 | 兼容Spring Boot 1.4.x,也兼容Spring Boot 1.5.x |
Dalston版本、Edgware版本 | 兼容Spring Boot 1.5.x,不兼容Spring Boot 2.0.x |
Finchley版本 | 兼容Spring Boot 2.0.x,不兼容Spring Boot 1.5.x |
Greenwich版本 | 兼容Spring Boot 2.1.x |
Hoxtonl版本 | 兼容Spring Boot 2.2.x |
在实际开发过程中,我们需要更详细的版本对应:
Spring Boot | Spring Cloud |
---|---|
1.5.2.RELEASE | Dalston.RC1 |
1.5.9.RELEASE | Edgware.RELEASE |
2.0.2.RELEASE | Finchley.BUILD-SNAPSHOT |
2.0.3.RELEASE | Finchley.RELEASE |
2.1.0.RELEASE-2.1.14.RELEASE | Greenwich.SR5 |
2.2.0.M4 | Hoxton.SR4 |
SpringCloud版本是和SpringBoot有关联关系的,官网中可以查看:https://docs.spring.io/spring-cloud/docs/current/reference/html/
netflix已停止维护,不建议使用。
5.1SpringCloudAlibaba介绍
SpringCloudAlibaba GitHub地址:https://github.com/alibaba/spring-cloud-alibaba/
中文网站对应的地址:https://github.com/alibaba/spring-cloud-alibaba/blob/master/README-zh.md
- 注册中心:Nacos
- 配置中心:Nacos
- 负载均衡:Ribbon
- 声明式服务调用:OpenFegin
- 服务容错:Sentinel
- 网关服务:Gateway
- 链路监控:Sleuth
- 分布式事务:Seata
SpringCloudAlibaba和SpringBoot的对应版本
针对于SpringCloudAlibaba的版本关系,我们需要调整各模块的SpringBoot和SpringCloud的版本
然后我们在mall-commons服务中设置SpringCloudAlibaba的依赖管理
<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>
5.2nacos注册中心
Nacos 是阿里巴巴开源的一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。
5.2.1nacos服务搭建
首先在nacos的github中下载相关的安装文件:https://github.com/alibaba/nacos/releases/tag/2.0.2
版本需与docker支持的最新版本对应,以免出现各种问题
右键运行startup.cmd
后端服务正常启动
访问:http://localhost:8848/nacos
说明服务启动成功。
5.2.2nacos服务注册
相关说明地址:https://github.com/alibaba/spring-cloud-alibaba/blob/2.2.x/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/readme-zh.md
首先,修改 pom.xml 文件,引入 Nacos Discovery Starter。
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency>
使用 @EnableDiscoveryClient 注解开启服务注册与发现功能。如果放在应用启动入口只会生效一次,如果每次都能看到更新需放在相应的controller层。
需要在配置问中配置注册中心的相关信息
重启服务,我们就可以在注册中心中发现对应的服务注册信息了
相同步骤完成其他几个模块的服务注册
5.2.3nacos在docker容器中安装
为了使用的方便,我们将Nacos安装到Docker容器中
docker hub官网:https://hub.docker.com/r/nacos/nacos-server
首先我们需要拉取对应的镜像文件
docker pull nacos/nacos-server:2.0.2docker run -d --env MODE=standalone --name nacos -v /mydata/nacos/conf:/home/nacos/conf -p 8848:8848 nacos/nacos-server:2.0.2
安装过程如果出现如下报错
那么就把windows中的安装文件中的conf目录的文件上传到虚拟机中
然后再重启一下
docker rm -f nacosdocker ps -adocker run -d --env MODE=standalone --name nacos -v /mydata/nacos/conf:/home/nacos/conf -p 8848:8848 nacos/nacos-server:2.0.2
重启成功 默认的账密码:nacos nacos
修改各模块的注册地址,重启服务。
docker中设置nacos服务自启动:
docker update --restart=alwaysnacos
5.3OpenFegin服务调用
OpenFegin是一个声明式的服务调用组件。本质上是封装的Ribbon实现的。
5.3.1商品服务定义接口
在mall-product模块中写好可供外部调用的接口方法
5.3.2订单服务中调用
引入openfeign相关依赖
服务调用成功
5.4nacos配置中心
5.4.1配置中心的基本使用
首先添加对应的依赖,因为其他的微服务也需要向配置中心中获取配置信息,所以对应的依赖我们添加在了commons模块中
nacos配置中心新增配置生效,需在对应的controller层@RefreshScope
新增文件名称必须为bootstrap.properties,Data-ID为:mall-order.properties
5.4.2命名空间和配置分组
为每个模块新建一个相应的空间
如果我们需要加载对应的配置组中的信息,那么同样的需要在bootstrap.properties中设置对应的配置组信息
5.4.3配置拆分
我们现在是将某个服务中的所有的配置都写在了同一个配置文件中。为了方便管理,我们可以将配置信息拆分到配置中心中。
我们可以将配置文件中的数据源,mybatis的配置信息以及其他的信息拆分开来
需要在bootstrap.properties指定
5.5网关Gateway
5.5.1网关基本介绍
文档:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/
在微服务架构里,服务的粒度被进一步细分,各个业务服务可以被独立的设计、开发、测试、部署和管理。这时,各个独立部署单元可以用不同的开发测试团队维护,可以使用不同的编程语言和技术平台进行设计,这就要求必须使用一种语言和平台无关的服务协议作为各个单元间的通讯方式。
本系统中我们选择的是Gateway作为我们的网关组件,Spring Cloud Gateway是Spring官方基于Spring 5.0,Spring Boot 2.0和Project Reactor等技术开发的网关,Spring Cloud Gateway旨在为微服务架构提供一种简单而有效的统一的API路由管理方式。Spring Cloud Gateway作为Spring Cloud生态系中的网关,**目标是替代ZUUL,其不仅提供统一的路由方式,并且基于Filter链的方式提供了网关基本的功能,例如:安全,监控/埋点,和限流等。
网关有几个非常重要的概念:
- Route(路由):这是网关的基本构建块,它由一个ID,一个目标URI,一组断言和一组过滤器定义,如果断言为真,则路由匹配
- Predicate(断言):是Java8中提供的函数式接口,用来判断是否路由匹配的
- Filter(过滤器):对断言匹配的请求和响应进行修改处理
5.5.2网关应用
创建module
因为网关服务路由的时候需要去注册中心中发现相关的服务所以需要完成Nacos注册中心的配置
放开注解,并排除相关数据源启动时的自动装配
然后根据对应的路由规则测试即可:
http://localhost:8070/?url=baidu
http://localhost:8070/?url=jd