单体架构中使用经典的三层模型,即表现层、业务处理层、数据访问层。
单体架构只适合于初期,且访问量比较低的情况下使用。
优点:性价比高,开发速度快,成本低。
针对单个服务器无法满足日增的业务访问量,可以考虑集群化处理。
集群部署显著增强服务的处理能力,同时利用nginx提供的负载均衡机制分发请求,用户体验没有改变。
上面的集群部署是可以解决一部分的服务器压力,但是随着用户访问量的增多,集群节点增加到一定阶段的时候,作用就已经不是太大了,因为将所有的业务都集中在一起,造成耦合度很高,这时我们可以考虑业务的拆分,来提高系统的性能。
所谓的垂直应用架构,就是将原来的一个应用拆成互不相干的几个应用,以提升效率。
比如电商平台,如果用户访问增加但是又并不是对所有的模块都会有比较大的访问量,可能对用户管理和订单管理的影响比较大对消息中心的影响就比较小,那么我们就希望只多增加几个订单模块,而不增加消息模块,再比如CMS应用宕机了,其他的应用也不想被受影响;此时单体应用就做不到了, 垂直架构就应运而生了。
服务垂直化拆分后可以大大提高整体的处理效率,但是也会出现很多冗余的代码。比如用户系统要操作订单库,要操作商品库,订单系统也有可能要操作用户库和商品库等。
针对垂直化拆分出现的问题,出现一种解决方案(Service-Oriented Architecture,SOA)
SOA是一种设计方法,其中包括多个服务,而服务之间通过配合最终会提供一系列功能,一个服务通常以独立的形式存在于操作系统进程中,服务之间通过网络调用,而非采用进程内调用的方式进行通信。
业务重用,共享服务。
在SOA基础上继续演进就是我们所讲的微服务。SOA的服务更细粒度的拆分后就是微服务。
1、思想上:微服务的目的是为了解耦而SOA的目的是为了实现数据的互通和共享。
2、协议:微服务会使用一些轻量级的协议(Restful API)
3、基础设施要求,微服务更加强调开发运维的持续交付。
在微服务架构中,服务与服务之间的调用我们肯定要通过相关的RPC(Remote Procedure Call)框架来实现。
常用的RPC框架有:Dubbo,Google的GRPC,Apache的Thrift,微博的Motan,京东的EasyRPC等。我们通过RPC框架可以调用服务提供者提供的服务,但前提是我们得找到这个服务。通常我们的服务部署都是集群多节点的部署,所以在消费者这端就不会直接写死代码。这时就涉及服务的发现问题,此时就需要另一个组件注册中心了。
注册中心实现服务地址管理功能,解决服务动态感知(上线、下线)
客户端可以通过Ribbon来实现负载均衡,负载均衡的策略可以是:轮询、随机、根据响应的时间来计算权重的轮询等。
在微服务架构中我们有很多个服务,而每个服务都是有单独的配置文件的。里面有很多配置信息是相关联的,对于后期的更新维护会有很大的不便,这时配置中心就上场了。常用的配置中心有:apollo|nacos|disconf|zookeeper|diamond|spring cloud config
网关可以帮助我们完成用户请求的入口,路由转发。完成统一授权、日志记录、权限认证、限流、熔断操作。
在现实的微服务架构中很难满足所有用户的请求,这时可以通过一些措施来保证我们的核心服务的正常运转。
限流:sentinel、hystrix
降级:主动降级(订单评论、广告关闭)、被动降级
缓存:降低数据源访问频率、Redis等
容错机制:服务出现挂机,宕机之后的处理机制。
Bus消息总线,实现异步化的通信机制。
因为微服务中的服务实在是太多了,为了能更好的监控每个服务的情况,肯定就需要链路监控服务,我们可以通过sleuth + zipkin来实现应用层监控、系统级监控。
三高是指:高性能、高可用、高并发
可以通过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 init centos/7
;会生成Vagrantfile文件vagrant up
第一次执行会远程下载相关镜像文件,并启动虚拟机。vagrant ssh
。修改对应的Vagrantfile
修改后的ip为:169.254.252.10
浏览添加私钥:D:\centosnods\mall-node.vagrant\machines\default\virtualbox\private_key
sudo -i切换至root用户
虚拟化、容器化部署
参考官方文档安装: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
sudo yum install -y docker-ce docker-ce-cli containerd.io
sudo systemctl start docker
sudo docker version
yum makecache fast
sudo systemctl enable docker
项目软件统一安装在 /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.34
docker ps -a
docker rm -f mysql
docker rmi
docker 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=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake
skip-name-resolve
docker restart [container id]
docker pull redis
mkdir -p /mydata/redis/conf
touch /mydata/redis/conf/redis.conf
docker run -d -p 6379:6379 --name mall-redis -v /mydata/redis/data:/data -v /mydata/redis/conf:/etc/redis redis redis-server /etc/redis/redis.conf
[root@manager-node conf]# docker exec -it 4e redis-cli
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379>
容器自启动
[root@localhost ~]# docker update --restart=always mysql
mysql
[root@localhost ~]# docker update --restart=always mall-redis
mall-redis
JDK环境
开发工具:IDEA2020 + WebStorm2020
配置信息
git config --global user.name "lgj"
git config --global user.email "[email protected]"
关联码云,生成对应的公钥和私钥,在用户目录下
ssh-keygen -t rsa -C "[email protected]"
然后把公钥中的内容复制到码云中去
通过 ssh -T [email protected]
来连接测试
创建完成
下载Gitee插件
首先创建几个基础的微服务(商品,订单,会员,库存,活动)
完成5个模块的创建
注意:新项目不要迅速git add,那样会把.gitignore文件也纳入管理,无法去除无用文件。
字符集:utf8mb4 + 排序规则:utf8mb4_general_ci
前端:Vue + ElementUI
后端:Springboot + MyBatisPlus + SpringMVC
开源:renren ,ruoyi
本项目中会通过人人开源中提供的模板项目来快速的实现项目的构建:https://gitee.com/renrenio
下载下来的renren-fast解压后拷贝到项目的父工程的根目录下
修改人人-fast相关的数据库配置信息,查看数据库的连接信息,并修改
然后创建对应的数据库,名称为 renren_fast,根据提供的sql脚本,创建对应的表结构
更新对应数据库账号及密码
注意:
解压renren-fast-vue-master.zip
使用WebStorm2020打开,执行npm install
导入系统成功
更改数据库配置
调整生成类包路径
首先把生成的相关的模板文件拷贝到商品模块中。然后我们会发现代码有相关的错误提示,原因是缺少了renren-fast中的相关的依赖
可以创建一个commons模块来存放所有的微服务需要的公共内容。
新建一个maven公共module:mall-commons
在product项目中引入commons的依赖
在mall-commons新增共同依赖
在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);
}
}
测试数据
@SpringBootTest
class MallProductApplicationTests {
@Autowired
BrandService brandService;
@Test
void contextLoads() {
BrandEntity entity = new BrandEntity();
entity.setName("IQOO");
brandService.save(entity);
}
@Test
void selectAll() {
List<BrandEntity> list = brandService.list();
for (BrandEntity brandEntity : list) {
System.out.println(brandEntity);
}
}
@Test
void selectById(){
BrandEntity brandEntity = brandService.getOne(new QueryWrapper<BrandEntity>().eq("brand_id",2));
System.out.println(brandEntity);
}
}
同理通过generator代码生成其它模块的代码
端口占用
1.查询指定端口: netstat -ano | findstr “端口号”
2.根据进程PID查询进程名称: tasklist | findstr “进程PID号”
3.根据PID杀死任务: taskkill /F /PID “进程PID号”
或者 根据进程名称杀死任务: taskkill -f -t -im “进程名称”
修改数据库名称
生成参数配置
生成各模块代码
每个模块下都需要整合mybatis配置,按照product模块配置即可
配置各模块的服务端口
各模块服务启动测试
正常启动,说明各模块写的无问题,代码提交到远程,ok !!!
在SpringCloud出现之前,微服务架构我们也能够解决。但是选择五花八门,比较乱,针对这种情况,SpringCloud整合一套微服务的解决方案。
SpringCloud生态提供了快速构建微服务的技术组件。https://spring.io/projects/spring-cloud-netflix
版本 关键词描述
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已停止维护,不建议使用。
SpringCloudAlibaba GitHub地址:https://github.com/alibaba/spring-cloud-alibaba/
中文网站对应的地址:https://github.com/alibaba/spring-cloud-alibaba/blob/master/README-zh.md
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>
Nacos 是阿里巴巴开源的一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。
首先在nacos的github中下载相关的安装文件:https://github.com/alibaba/nacos/releases/tag/2.0.2
版本需与docker支持的最新版本对应,以免出现各种问题
右键运行startup.cmd
访问:http://localhost:8848/nacos
说明服务启动成功。
相关说明地址: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.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
dependency>
使用 @EnableDiscoveryClient 注解开启服务注册与发现功能。如果放在应用启动入口只会生效一次,如果每次都能看到更新需放在相应的controller层。
需要在配置问中配置注册中心的相关信息
相同步骤完成其他几个模块的服务注册
为了使用的方便,我们将Nacos安装到Docker容器中
docker hub官网:https://hub.docker.com/r/nacos/nacos-server
首先我们需要拉取对应的镜像文件
docker pull nacos/nacos-server:2.0.2
docker 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 nacos
docker ps -a
docker run -d --env MODE=standalone --name nacos -v /mydata/nacos/conf:/home/nacos/conf -p 8848:8848 nacos/nacos-server:2.0.2
docker中设置nacos服务自启动:
docker update --restart=always nacos
OpenFegin是一个声明式的服务调用组件。本质上是封装的Ribbon实现的。
在mall-product模块中写好可供外部调用的接口方法
引入openfeign相关依赖
服务调用成功
首先添加对应的依赖,因为其他的微服务也需要向配置中心中获取配置信息,所以对应的依赖我们添加在了commons模块中
nacos配置中心新增配置生效,需在对应的controller层@RefreshScope
新增文件名称必须为bootstrap.properties,Data-ID为:mall-order.properties
为每个模块新建一个相应的空间
如果我们需要加载对应的配置组中的信息,那么同样的需要在bootstrap.properties中设置对应的配置组信息
我们现在是将某个服务中的所有的配置都写在了同一个配置文件中。为了方便管理,我们可以将配置信息拆分到配置中心中。
我们可以将配置文件中的数据源,mybatis的配置信息以及其他的信息拆分开来
文档: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链的方式提供了网关基本的功能,例如:安全,监控/埋点,和限流等。
网关有几个非常重要的概念:
创建module
因为网关服务路由的时候需要去注册中心中发现相关的服务所以需要完成Nacos注册中心的配置
http://localhost:8070/?url=baidu
http://localhost:8070/?url=jd