springCloud图文详解
1.微服务入门
(1).单体架构与分布式架构
单体架构: 将业务的所有功能集中在一个项目中开发,打成一个包部署
优点: 架构简单、部署成本低 ; 缺点: 耦合度高
项目打包部署到Tomcat,用户直接访问。用户量增加后就多部署几台服务器形成集群。
随着互联网发展、一个APP或Web通常都用有相当多的模块,因此出现了 分布式架构
分布式架构: 根据业务功能对系统进行拆分,每个业务模块作为独立项目开发,称为一个服务。
优点: 降低服务耦合、有利于服务升级拓展 ;
1 | |
(2).微服务
微服务是一种经过良好架构设计的分布式架构方案,微服务架构特征:
单一职责: 微服务拆分粒度更小,每一个服务都对应唯一的业务能力,做到单一职责,避免重复业务开发
面向服务: 微服务对外暴露业务接口
(由于不同模块部署在不同服务器、无法直接调用)
自治: 队独立、技术独立、数据独立、部署独立
隔离性强: 服务调用做好隔离、容错、降级,避免出现级联问题
(避免某个模块宕机造成影响)
(3).总结
1 | |
2.微服务结构
(1).微服务结构

1 | |
(2).微服务技术对比

(3).企业需求

(4).SpringCloud

3.服务拆分及远程调用
(1).服务拆分注意事项
1 | |
(2).微服务远程调用
1 | |
(3).微服务远程调用Demo
假设存在两个微服务: 用户模块 与 订单模块,两个模块的数据库表中有一个 id字段相同
用户访问订单模块后同时也会返回用户信息。因此用户访问订单模块之后,也需要后端去访问用户模块获取用户信息。之后将信息结合返回给用户。
①: 注册RestTemplate进入IOC
①: 修改service层
(4).提供者与消费者
服务提供者: 一次业务中,被其它微服务调用的服务。(提供接口给其它微服务)
服务消费者: 一次业务中,调用其它微服务的服务。(调用其它微服务提供的接口)
一个服务既可以是提供者也可以是消费者,要根据具体的业务和情况来判断
1 | |
因此引出我们的 Eureka注册中心
(5).Eureka作用

1 | |
在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注解
用服务提供者的服务名称远程调用
1 | |
(7).Ribbon负载均衡
①:负载均衡流程

②:负载均衡策略
Ribbon的负载均衡规则是一个叫做IRule的接口来定义的,每一个子接口都是一种规则

③:负载均衡策略
Ribbon默认是采用懒加载,即第一次访问时才会去创建LoadBalanceClient,请求时间会很长.而饥饿加载则会在项目启动时创建,降低第一次访问的耗时,通过下面配置开启饥饿加载:
1 | |
(8).Nacos注册中心
①:Nacos基础Linux的安装配置
下载[Nacos安装配置教程](https://blog.csdn.net/Mr_7777777/article/details/123133036?ops_request_misc=%7B%22request%5Fid%22%3A%22168535604516782425117446%22%2C%22scm%22%3A%2220140713.130102334..%22%7D&request_id=168535604516782425117446&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-2-123133036-null-null.142^v88^control_2,239^v2^insert_chatgpt&utm_term=Nacos Linux&spm=1018.2226.3001.4187)


②:服务注册到Nacos
1 | |
代码的道路哪有一帆风顺,这里提一下我遇到的问题Caused by: java.lang.ClassNotFoundException: org.springframework.boot.Bootstrapper
这个报错主要原因是springcloud与springboot版本之间的问题。
打开查看spring alibaba、springcloud、springboot对应版本
③:demo演示


④:Nacos服务分级存储模型

⑤:服务跨集群调用问题
服务调用尽可能选择本地集群的服务,跨集群调用延迟较高
本地集群不可访问时候、再去访问其他集群
⑥:服务集群属性

⑥:根据集群负载均衡

⑦:根据权重负载均衡
实际部署中会出现这样的场景
服务器设备性能有差异,部分实例所在机器性能较好,另一些较差,我们希望性能好的机器承担更多的用户请求
Nacos提供了权重配置来控制访问频率,权重越大则访问频率越高
包括服务器的升级、我们可以使用权重来使得某个微服务无人访问,然后停机升级。这样也不会影响正在使用的用户
1 | |
⑧:环境隔离 - namespace
Nacos中服务存储和数据存储的最外层都是一个名为namespace的东西,用来做最外层隔离
搭建过程



1 | |
⑨:nacos注册中心细节分析

⑩:临时实例与非临时实例

1 | |
nacos与eureka的区别
1 | |
(9).微服务架构组件
①:Nacos配置管理
配置更改热更新
注: Nacos配置文件中的内容不是随便写的,不是把项目中的yml配置文件拉进去就可以了,我们只写一些通用的、需要热更新的内容。
像数据库地址一般都是固定的,就不必写。
data ID: 服务器名-开发环境-后缀名
如此一来我们就配置好了,接下来就需要将微服务连接上配置
②:统一配置管理
服务获取配置的步骤、顺序如下:

注意: springboot 2.4以后,bootstrap默认关闭,你需要添加依赖
1 | |


这个配置在微服务本地配置是不存在的,也是刚刚在nacos当中的配置。
输出的日期与nacos配置当中一直,这就 说明我们确实获取到了nacos中的配置
③:热更新配置


④:多环境配置共享
1 | |


关于配置的拆分管理

⑤:nacos集群搭建
1.搭建MySQL集群并初始化数据库表
2.下载解压nacos
3.修改集群配置(节点信息)、数据库配置
4.分别启动多个nacos节点
5.nginx反向代理

⑥:RestTemplate方式调用存在的问题

这样的代码可读性差、参数复杂URL难以维护
⑦:Feign声明式http客户端

feignclient 客户端名字根据你服务名来的,可以要yml文件中查看,需要调用哪个服务就放哪个名字进去
⑧:自定义Feign配置



1 | |
⑨:Feign性能调优
Feign底层的客户端实现
URLConnection: 默认实现,不支持连接池
Apache HttpClient: 支持连接池
OKHttp: 支持连接池我们知道没有连接池的情况下,需要每次都重连和断开,影响性能
因此优化Feign的性能主要包括:
使用连接池代替默认的URLConnection
日志级别,最好用basic或none
如何添加HttpClient?



4.更进一步
(1).统一网关Gateway
①:为什么需要网关


②:搭建网关服务


网关作用流程
③:路由断言工厂

关于断言工厂为什么不是过滤器
1 | |

如果你访问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安装与常用命令
⑥:数据卷


(3).MQ
①:同步与异步
同步通讯的优点:时效性强、可以立即得到结果
同步存在的问题:耦合度高
每次加入新的需求,都要修改原来的代码性能下降
调用者需要等待服务提供者响应,如果调用链过长则响应时间等于每次调用的时间之和。资源浪费
调用链中的每个服务在等待响应过程中,不能释放请求占用的资源,高并发场景下会极度浪费系统资源级联失败
如果服务提供者出现问题,所有调用方都会跟着出问题如同多米诺骨牌一样,迅速导致整个微服务群故障
②:异步调用方案

1 | |
以往如果你需要在支付服务中调用其他服务,由于是同步调用,你必须等待其他服务响应。
一旦需要增加某个服务,你又要修改代码。耦合度很高,但是现在你只需要让服务订阅Broker就可以流量削峰
③:什么是MQ
MQ(MessageQueue): 中文是消息队列,字面来看就是存放消息的队列。也就是事件驱动架构中的Broker。
(4).RabbitMQ快速入门
①:RabbitMQ
1 | |
②:SpringAMQP






当预取值改为1、消费者会等响应完一条消息之后再从队列中取一条消息。这样一来就做到了“能者多劳”的效果
③:发布、订阅
发布订阅模式与之前案例的区别就是允许将同一消息发送给多个消费者。实现方式是加入了exchange(交换机)
绑定队列与交换机:
④:DirectExchange



1 | |
⑤:TopicExchange!



⑥:SpringAMQP消息转换器


