版本配置(避免冲突换版本麻烦):
SpringBoot : 2.6.13
SpringCloud alibaba : 2021.0.5.0
nacos : 2.2.0
nacos依赖 : 2021.0.5.0
bootstrap : 3.1.1
打开查看spring alibaba、springcloud、springboot对应版本
1.微服务入门
(1).单体架构与分布式架构
单体架构: 将业务的所有功能集中在一个项目中开发,打成一个包部署
优点: 架构简单、部署成本低 ; 缺点: 耦合度高
项目打包部署到Tomcat,用户直接访问。用户量增加后就多部署几台服务器形成集群。随着互联网发展、一个APP或Web通常都用有相当多的模块,因此出现了 分布式架构
分布式架构: 根据业务功能对系统进行拆分,每个业务模块作为独立项目开发,称为一个服务。
优点: 降低服务耦合、有利于服务升级拓展 ;
由于分布式架构的特性我们也出现了一些思考:
服务拆分粒度如何?
服务集群地址如何维护?
服务之间如何实现远程调用?
服务健康状态如何感知?
为了解决分布式带来的问题,微服务出现了
(2).微服务
微服务是一种经过良好架构设计的分布式架构方案,微服务架构特征:
单一职责: 微服务拆分粒度更小,每一个服务都对应唯一的业务能力,做到单一职责,避免重复业务开发
面向服务: 微服务对外暴露业务接口
(由于不同模块部署在不同服务器、无法直接调用)
自治: 队独立、技术独立、数据独立、部署独立
隔离性强: 服务调用做好隔离、容错、降级,避免出现级联问题
(避免某个模块宕机造成影响)
(3).总结
单体架构特点?
简单方便,高度耦合,扩展性差,适合小型项目。例如: 学生管理系统
分布式架构特点?
松耦合,扩展性好,但架构复杂,难度大。适合大型互联网项目,例如:京东、淘宝
微服务:一种良好的分布式架构方案
优点: 拆分粒度更小、服务更独立、耦合度更低缺点:架构非常复杂,运维、监控、部署难度提高
2.微服务结构
(1).微服务结构
在微服务架构中,配置中心和注册中心是两个重要的组件。
配置中心用来统一管理项目中所有配置,各种参数、各种开关,全部都放到一个集中的地方进行统一管理,并提供一套标准的接口。当各个服务需要获取配置的时候,就来「配置中心」的接口拉取。
注册中心则是用来管理服务实例的注册和发现的。各个服务实例在启动时会向注册中心注册自己的信息(如IP地址和端口号),其他服务实例可以通过注册中心来发现并调用这些服务12。
(2).微服务技术对比
(3).企业需求
(4).SpringCloud
3.服务拆分及远程调用
(1).服务拆分注意事项
1.不同微服务,不要重复开发相同业务
2.微服务数据独立,不要访问其它微服务的数据库
3.微服务可以将自己的业务暴露为接口,供其它微服务调用
(2).微服务远程调用
1.基于RestTemplate发起的http请求实现远程调用
2.http请求做远程调用是与语言无关的调用,只要知道对方的ip、端口、接口路径、请求参数即可。
(3).微服务远程调用Demo
假设存在两个微服务: 用户模块
与 订单模块
,两个模块的数据库表中有一个 id字段
相同
用户访问订单模块
后同时也会返回用户信息。因此用户访问订单模块之后,也需要后端去访问用户模块获取用户信息。之后将信息结合返回给用户。
①: 注册RestTemplate进入IOC
①: 修改service层
(4).提供者与消费者
服务提供者: 一次业务中,被其它微服务调用的服务。(提供接口给其它微服务)
服务消费者: 一次业务中,调用其它微服务的服务。(调用其它微服务提供的接口)
一个服务既可以是提供者也可以是消费者,要根据具体的业务和情况来判断
第三点Demo中,我们服务在请求服务的时候,restTemplate访问的地址是固定的。
可在实际开发中通常都会有好几个环境,开发,测试等等环境。每个环境的地址都在变化
因此出现了几个问题:
1.服务消费者该如何获取服务提供者的地址信息?
2.如果有多个服务提供者,消费者该如何选择?
因此引出我们的 Eureka注册中心
(5).Eureka作用
消费者该如何获取服务提供者具体信息?
①:服务提供者启动时向eureka注册自己的信息
②:eureka保存这些信息
③:消费者根据服务名称向eureka拉取提供者信息
如果有多个服务提供者,消费者该如何选择?
①:服务消费者利用负载均衡算法,从服务列表中挑选一个
消费者如何感知服务提供者健康状态?
①:服务提供者会每隔30秒向EurekaServer发送心跳请求,报告健康状态
②:eureka会更新记录服务列表信息,心跳不正常会被剔除
③:消费者就可以拉取到最新的信息
在Eureka架构中,微服务角色有两类
EurekaServer:服务端,注册中心
记录服务信息
心跳监控
EurekaClient:客户端
Provider: 服务提供者,例如案例中的 user-servicea
注册自己的信息到EurekaServer
每隔30秒向EurekaServer发送心跳
consumer:服务消费者,例如案例中的 order-service根据服务名称从EurekaServer拉取服务列表
基于服务列表做负载均衡,选中一个微服务后发起远程调用
(6).搭建EurekaServer
如何把微服务也注册到Eureka,都是一个套路,加依赖、配置yml
可以在Eureka中部署多个实例。这样可以提高系统的可靠性和容错能力
服务拉取
1.搭建EurekaServer
引入eureka-server依赖
添加@EnableEurekaServer注解
在application.yml中配置eureka地址
2.服务注册
引入eureka-client依赖
在application.yml中配置eureka地址
3.服务发现
引入eureka-client依赖
在application.yml中配置eureka地址
给RestTemplate添加@LoadBalanced注解
用服务提供者的服务名称远程调用
整个过程当中我们只需要配置好Eureka,就自动做到了负载均衡、拉取服务,那么这些事情到底是怎么完成的呢?
(7).Ribbon负载均衡
①:负载均衡流程
②:负载均衡策略
Ribbon的负载均衡规则是一个叫做IRule的接口来定义的,每一个子接口都是一种规则
③:负载均衡策略
Ribbon默认是采用懒加载,即第一次访问时才会去创建LoadBalanceClient,请求时间会很长.而饥饿加载则会在项目启动时创建,降低第一次访问的耗时,通过下面配置开启饥饿加载:
1.Ribbon负载均衡规则
规则接口是IRule
默认实现是ZoneAvoidanceRule,根据zone选择服务列表,然后轮询
2.负载均衡自定义方式
代码方式:配置灵活,但修改时需要重新打包
配置方式:直观,方便,无需重新打包发布但是无法做全局配置
3.饥饿加载
开启饥饿加载
指定饥饿加载的微服务名称
(8).Nacos注册中心
①:Nacos基础Linux的安装配置
下载Nacos安装配置教程
②:服务注册到Nacos
<!--父工程管理依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2021.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--Nacos客户端依赖包-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2021.1</version>
</dependency>
代码的道路哪有一帆风顺,这里提一下我遇到的问题
Caused by: java.lang.ClassNotFoundException: org.springframework.boot.Bootstrapper
这个报错主要原因是springcloud与springboot版本之间的问题。
打开查看spring alibaba、springcloud、springboot对应版本
③:demo演示
④:Nacos服务分级存储模型
⑤:服务跨集群调用问题
服务调用尽可能选择本地集群的服务,跨集群调用延迟较高
本地集群不可访问时候、再去访问其他集群
⑥:服务集群属性
⑥:根据集群负载均衡
⑦:根据权重负载均衡
实际部署中会出现这样的场景
服务器设备性能有差异,部分实例所在机器性能较好,另一些较差,我们希望性能好的机器承担更多的用户请求
Nacos提供了权重配置来控制访问频率,权重越大则访问频率越高
包括服务器的升级、我们可以使用权重来使得某个微服务无人访问,然后停机升级。这样也不会影响正在使用的用户
实例的权重控制
Nacos控制台可以设置实例的权重值,0~1之间
同集群内的多个实例,权重越高被访问的频率越高
权重设置为0则完全不会被访问
⑧:环境隔离 - namespace
Nacos中服务存储和数据存储的最外层都是一个名为namespace的东西,用来做最外层隔离
搭建过程
Nacos环境隔离
namespace用来做环境隔离
每个namespace都有唯一id
不同namespace下的服务不可见
⑨:nacos注册中心细节分析
⑩:临时实例与非临时实例
临时实例的情况下,如果你终止程序,过30s,到nacos中查看就会发现爆红然后直接消失(被nacos踢出)
非临时实例终止程序,nacos中查看该服务爆红,但不会踢出。重新启动非临时实力即可
nacos与eureka的区别
1.Nacos与eureka的共同点
都支持服务注册和服务拉取
都支持服务提供者心跳方式做健康检测
2.Nacos与Eureka的区别
Nacos支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时实例采用主动检测模式
临时实例心跳不正常会被剔除,非临时实例则不会被剔除
Nacos支持服务列表变更的消息推送模式,服务列表更新更及时
Nacos集群默认采用AP方式,当集群中存在非临时实例时,采用CP模式 ; Eureka采用AP方式
(9).微服务架构组件
①:Nacos配置管理
配置更改热更新注
: Nacos配置文件中的内容不是随便写的,不是把项目中的yml配置文件拉进去就可以了,我们只写一些通用的、需要热更新的内容。
像数据库地址一般都是固定的,就不必写。
data ID: 服务器名-开发环境-后缀名
如此一来我们就配置好了,接下来就需要将微服务连接上配置
②:统一配置管理
服务获取配置的步骤、顺序如下:注意:
springboot 2.4以后,bootstrap默认关闭,你需要添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
<version>3.1.1</version>
</dependency>
这个配置在微服务本地配置是不存在的,也是刚刚在nacos当中的配置。
输出的日期与nacos配置当中一直,这就 说明我们确实获取到了nacos中的配置
③:热更新配置
④:多环境配置共享
共享前提: 微服务的bootstrap配置名相同
spring:
application:
name: orderService
关于配置的拆分管理
⑤:nacos集群搭建
点击观看
1.搭建MySQL集群并初始化数据库表
2.下载解压nacos
3.修改集群配置(节点信息)、数据库配置
4.分别启动多个nacos节点
5.nginx反向代理
⑥:RestTemplate方式调用存在的问题
这样的代码可读性差、参数复杂URL难以维护
⑦:Feign声明式http客户端
feignclient 客户端名字根据你服务名来的,可以要yml文件中查看,需要调用哪个服务就放哪个名字进去
⑧:自定义Feign配置
方式一是配置文件,feign.client.config.xxx.loggerLevel
如果xxx是default则代表全局
如果xxx是服务名称,例如userservice则代表某服务
方式二是java代码配置Logger.Level这个Bean
如果在@EnableFeignClients注解声明则代表全局
如果在@FeignClient注解中声明则代表某服务
⑨:Feign性能调优
Feign底层的客户端实现
URLConnection: 默认实现,不支持连接池
Apache HttpClient: 支持连接池
OKHttp: 支持连接池我们知道没有连接池的情况下,需要每次都重连和断开,影响性能
因此优化Feign的性能主要包括:
使用连接池代替默认的URLConnection
日志级别,最好用basic或none
如何添加HttpClient?
4.更进一步
(1).统一网关Gateway
①:为什么需要网关
②:搭建网关服务
网关作用流程
③:路由断言工厂
关于断言工厂为什么不是过滤器
断言工厂是用来匹配请求的,比方说有很多微服务交由网关管理。
每个微服务都有不同的断言 工厂配置,有的微服务必须几点之前、有的微服务必须什么IP
当前端发来URL,请求的时候,URL会跟配置中比较
满足断言工厂配置条件的才能找到对应的服务并响应
如果你访问localhost:88/hello?url=baidu
它会自动跳转到,www.baidu.com/hello
④:路由过滤器GatewayFilter
⑤:全局过滤器GlobalFilter
全局过滤器的作用也是处理一切进入网关的请求和微服务响应,与GatewayFilter的作用一样。
⑥:过滤器执行顺序
请求进入网关会碰到三类过滤器: 当前路由的过滤器、DefaultFilter、GlobalFilter
请求路由后,会将当前路由过滤器和DefaultFilter、GlobalFilter,合并到一个过滤器链 (集合)中,排序后依次执行每个过滤器
1、 每一个过滤器都必须指定一个int类型的order值,order值越小,优先级越高,执行顺序越靠前
2、 GlobalFilter通过实现Ordered接口,或者添加@Order注解来指定order值,由我们自己指定
3、 路由过滤器和defaultFilter的order由Spring指定,默认是按照声明顺序从1递增
4、 当过滤器的order值一样时,会按照 defaultFilter > 路由过滤器>GlobalFilter的顺序执行
⑦:跨域问题处理
**跨域:**域名不一致就是跨域,主要包括:
域名不同: www.taobao.com 、www.taobao.org
域名相同: 端口不同: localhost:8080、 localhost:8081
跨域问题: 浏览器禁止请求的发起者与服务端发生跨域ajax请求,请求被浏览器拦截的问题
解决方案: CORS
(2).Docker
①:初始Docker
Docker是一个快速交付应用、运行应用的技术
1.可以将程序及其依赖、运行环境一起打包为一个镜像
可以迁移到任意Linux操作系统
2.运行时利用沙箱机制形成隔离容器,各个应用互不干扰
3.启动、移除都可以通过一行命令完成,方便快捷
②:Docker与虚拟机
Docker和虚拟机的差异
docker是一个系统进程 ; 虚拟机
是在操作系统中的操作系统
docker体积小、启动速度快、性能好 ; 虚拟机
体积大、启动速度慢、性能一般
③:镜像和容器
镜像(Image): Docker将应用程序及其所需的依赖、函数库、环境、配置等文件打包在一起,称为镜像。
容器(Container): 镜像中的应用程序运行后形成的进程就是容器,只是Docker会给容器做隔离,对外不可见。
④:镜像和容器
Docker是一个CS架构的程序,由两部分组成:
服务端(server): Docker守护进程,负责处理Docker指令,管理镜像、容器等
客户端(client): 通过命令或RestAPI向Docker服务端发送指令。可以在本地或远程向服务端发送指令
⑤:Docker安装与常用命令
关于Docker的安装
⑥:数据卷
(3).MQ
①:同步与异步
同步通讯的优点:时效性强、可以立即得到结果
同步存在的问题:耦合度高
每次加入新的需求,都要修改原来的代码性能下降
调用者需要等待服务提供者响应,如果调用链过长则响应时间等于每次调用的时间之和。资源浪费
调用链中的每个服务在等待响应过程中,不能释放请求占用的资源,高并发场景下会极度浪费系统资源级联失败
如果服务提供者出现问题,所有调用方都会跟着出问题如同多米诺骨牌一样,迅速导致整个微服务群故障
②:异步调用方案
此时支付服务不需要像同步调用时、停下来等待其他服务完成再返回。而是可以直接返回
以往如果你需要在支付服务中调用其他服务,由于是同步调用,你必须等待其他服务响应。
一旦需要增加某个服务,你又要修改代码。耦合度很高,但是现在你只需要让服务订阅Broker就可以流量削峰
③:什么是MQ
MQ(MessageQueue): 中文是消息队列,字面来看就是存放消息的队列。也就是事件驱动架构中的Broker。
(4).RabbitMQ快速入门
①:RabbitMQ
RabbitMQ安装
docker run -d --name rabbitmq -e RABBITMQ_DEFAULT_USER=root -e RABBITMQ_DEFAULT_PASS=123456 -p 15672:15672 -p 5672:5672 -p 25673:25673 -p 61613:61613 -p 1883:1883 rabbitmq:management
②:SpringAMQP
当预取值改为1、消费者会等响应完一条消息之后再从队列中取一条消息。这样一来就做到了“能者多劳”的效果
③:发布、订阅
发布订阅模式与之前案例的区别就是允许将同一消息发送给多个消费者。实现方式是加入了exchange(交换机)
绑定队列与交换机:
④:DirectExchange
描述下Direct交换机与Fanout交换机的差异?
Fanout交换机将消息路由给每一个与之绑定的队列
Direct交换机根据RoutingKey判断路由给哪个队列
如果多个队列具有相同的RoutingKey,则与Fanout功能类似
基于@RabbitListener注解声明队列和交换机有哪些常见注解?
@Queue
@Exchange
⑤:TopicExchange!
文章来源:https://www.toymoban.com/news/detail-805389.html
⑥:SpringAMQP消息转换器
文章来源地址https://www.toymoban.com/news/detail-805389.html
到了这里,关于【SpringCloud】最全最细!微服务框架的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!