微服务技术栈
- 注册中心
- 配置中心
- 服务集群
- 服务网关
- 数据库
- 分布式缓存
- 分布式搜索
- 消息队列
- 分布式日志服务
- 系统监控链路追踪
- 持续集成(自动化部署)
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6xidqUEV-1662454500890)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662122178534.png)]
学习内容
微服务治理
- 注册发现
- 远程调用
- 负载均衡
- 配置管理
- 网关路由
- 系统保护
- 流量控制
- 服务授权
- 熔断降级
- 分布式事务
- TCC模型
- AT模型
- Seata
异步通信技术
- MO消息模型
- SpringAMQP
- 消息堆积问题
- 消息可靠性
- 仲裁队列
- 延迟队列
- 镜像集群
- 数据持久化
缓存技术
- 缓存穿透、雪崩
- SpringDataRedis
- Redis主从复制
- OpenResty
- 缓存数据同步
- Nginx本地缓存
- Redis持久化
- 多级缓存分层
- Redis分片集群
- Lua脚本
- Redis数据结构
DevOps
- Dockerfile
- DockerCompose
- DrayLog
- Jenkins
- GrayLog
- SkyWalking
- Docker的使用
- Kubernetes
搜索技术
- DSL语句
- ES集群
- RestAPI
- 集群脑裂
- 竞价排名
- 聚合统计
- 自动补全
- 地理坐标
- 拼音分词
认识微服务
-
单体架构
将业务的所有功能集中在一个项目中开发,打包成一个部署
-
分布式架构
根据业务功能对系统进行拆分,每个业务模块作为独立项目开发,称为一个服务
-
分布式架构需要考虑的问题
- 服务拆分粒度如何
- 服务集群地址如何维护
- 服务之间如何实现远程调用
- 服务健康状态如何感知
-
微服务
是一种经过良好架构设计的分布式架构方案
-
微服务特征
- 单依职责:微服务拆分粒度更小,每一个服务都对应唯一的业务能力,做到单一职责,避免重复业务开发
- 面向服务:微服务对外暴露业务接口
- 自治:团队独立,独立技术,数据独立,部署独立
- 隔离性强:服务调用做好隔离,容错,降级,避免出现级联问题
-
微服务结构
国内知名微服务技术:SpringCloud ,阿里巴巴的Dubbo
-
springcloud实现各种微服务组件,并实现了自动装配,开箱即用
- 服务注册与发现 Eureka、Nacos、Consul
- 服务远程调用 OpenFeign、Dubbo
- 统一网关路由 SpringCloudGateway、Zuul
- 服务链路监控 Zipkin、Sleuth
- 流控、降级、保护 Hystix、Sentinel
-
springcloud与springboot版本一一对应
服务拆分及远程调用
-
服务拆分注意事项
- 微服务需要根据业务模块开发,做到单一职责,不要重复开发相同的业务
- 微服务数据独立,不要访问其它微服务的数据库
- 微服务可以将自己的业务暴露为接口。供其它微服务调用
-
远程调用方式分析
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MOPxK1wk-1662454500891)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662345002730.png)]
-
注册RestTemplate
-
调用方法,发送远程调用服务
-
-
微服务调用方式
- 基于RestTemplate发起的http请求实现远程调用
- http请求做远程调用是与语言无关的调用,只要知道对方的ip、端口、接口路径、请求参数即可
-
提供者与消费者
- 服务提供者:一次业务中,被其它微服务调用的服务(提供接口给其他微服务)
- 服务消费者:一次业务中,调用其他微服务的服务(调用其他微服务提供的接口)
- 提供者与消费者的角色是相对的
Eureka注册中心
服务调用出现的问题
-
服务消费者如何获取服务提供者的地址信息
- 服务提供者启动时向eureka注册自己的信息
- eureka保存这些信息
- 消费者根据服务名称向eureka拉取提供者信息
-
如果有多个服务提供者,消费者该如何选择
服务消费者利用负载均衡算法(nginx),从服务列表中挑选一个
-
消费者如何得知服务提供者的健康状态
- 服务提供者会每隔30秒向EurekaServer发送心跳请求,报告健康状态
- eureka会更新服务列表信息,心跳不正常会被剔除
- 消费者就可以拉取到最新的消息
Eureka
- eureka-server 注册中心
- eureka-client
- consumer 服务消费者
- provider 服务提供者
- 作用
- 注册服务中心
- 拉去服务
- 心跳续约,每30秒1次
实践
搭建eureka
-
创建项目,引入依赖
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WQNtIGFW-1662454500892)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662346473502.png)]
-
编写启动类,添加@EnableEurekaServer注解
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SOvxkZZf-1662454500892)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662346700567.png)]
-
添加application.yml文件,编写配置
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0JX8eaYz-1662454500893)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662346548174.png)]
注册服务
-
在客户端中添加客户端依赖
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lya9iUhm-1662454500893)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662346985149.png)]
-
在application.yml文件中,编写配置
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h1F5kwvy-1662454500893)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662347041077.png)]
服务发现
服务拉取是基于服务名称获取服务列表,然后再对服务列表做负载均衡
-
访问的url路径中,服务名代替ip和端口
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vQgMbBDT-1662454500894)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662348195331.png)]
-
在服务消费者的项目启动类中的RestTemplate中添加负载均衡注解
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8887ebOX-1662454500894)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662348320004.png)]
Ribbon负载均衡
负载均衡原理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wVjPQggA-1662454500894)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662348674216.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kttCdMYB-1662454500895)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662349270405.png)]
负载均衡策略
-
Ribbon的负载均衡规则是IRule接口定义的,每一个子接口都是一种规则
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P1oDX3La-1662454500895)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662349425604.png)]
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xTgipAkb-1662454500895)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662349454253.png)]
-
调整负载均衡策略的两种方式
-
代码方式,全局配置:在客户端的启动类中,定义一个新的IRule
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7ySeFaOG-1662454500896)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662349582698.png)]
-
配置文件方式,局部配置:可指定服务名,针对某个服务
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-74bMXuL8-1662454500896)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662349843555.png)]
-
饥饿加载
- Ribbon默认采用懒加载,即第一次访问时才会创建LoadBalanceClient,请求时间会很长
- 饥饿加载则会在项目启动时创建,降低第一次访问的耗时,通过配置开启饥饿加载
- 指定饥饿加载的服务器名称
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fBzq9Bwb-1662454500896)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662350595353.png)]
Nacos注册中心
安装
配置
-
引入springcloudAlibaba的管理依赖
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yD2ON4NH-1662454500896)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662351325616.png)]
-
添加nacos客户端依赖
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AtnYkKKy-1662454500897)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662351379840.png)]
-
配置nacos地址信息
nacos服务分级存储模型
-
一级服务、二级集群、三级实例
-
服务跨集群调用问题
- 服务调用尽可能选择本地集群,跨集群调用延迟较高
- 本地集群不可访问时,再去访问其它集群
-
服务集群属性
-
修改application.yml,添加相应配置
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jpebLWdg-1662454500897)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662356689016.png)]
-
在nacos控制台可以看到集群变化
-
负载均衡
根据器群负载均衡
-
修改客户端的application.yml,设置集群名
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C6odIFuT-1662454500897)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662357206547.png)]
-
修改客户端的负载均衡Irule为NacosRule,这个规则会优先寻找与自己同集群的服务
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-772I3fr6-1662454500898)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662357311562.png)]
-
注意将该客户端的权重都设置为1
根据权重负载均衡
-
实际情况
服务器设备性能有差异,部分实例所在机器性能较好,另一些较差,我们希望性能好的机器承担更多的用户请求
-
nacos提供了权重配置来控制访问频率,权重越大则访问频率越高
-
在nacos控制台可以设置实例的权重值,一般为0-1之间
环境隔离
-
nacos中服务存储和数据存储的最外层都是一个名为namespace的东西,用来做最外层隔离
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HRKhwGrd-1662454500898)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662358315331.png)]
-
修改服务的命名空间
在配置文件中添加命名空间的id
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RqElA0yH-1662454500898)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662358489132.png)]
-
不同namespace中的服务互相不可见
nacos注册中心细节分析
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fbjsTChM-1662454500898)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662358844171.png)]
-
注册服务信息
-
定时拉取服务pull
-
主动推送变更消息push
-
服务列表缓存
-
远程调用
-
临时实例采用心跳检测
-
非临时实例nacos主动询问
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lNIjjyn4-1662454500899)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662358954224.png)]
nacos与eureka的异同
- 相同点
- 都支持服务注册和服务拉取
- 都支持服务提供者心跳方式做健康检测
- 不同点
- nacos支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时采用主动检测模式
- 临时实例心跳不正常会被剔除,非临时实例则不会被剔除
- nacos支持服务列表变更的消息推送模式,服务列表更新更及时
- nacos集群默认采用ap方式,当集群中存在非临时实例是,采用cp模式,eureka采用ap方式
nacos配置管理
统一配置管理
-
配置更改热更新
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wmRhcCle-1662454500899)(F:\我的文档\笔记本\1662359591730.png)]
-
配置获取的步骤
-
引入nacos的配置管理客户端依赖
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1ecIWv43-1662454500899)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662360125025.png)]
-
在resource目录添加一个bootstrap.yml文件,这个文件是引导文件,优先级高于application.yml
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tT2z4Wyc-1662454500899)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662360240127.png)]
-
配置自动刷新
nacos 中的配置文件变更后,微服务无法重启就可以感知,不过需要通过配置来实现,有两种方式
-
方式一:在@Value注入的变量所在的类上添加注解@RefreshScope
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E4ktIPno-1662454500899)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662360782935.png)]
-
方式二:使用@ConfigurationProperties注解
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jmWIl4Gu-1662454500900)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662361021174.png)]
-
注意
- 不是所有的配置都适合放到配置中心,维护起来比较麻烦
- 建议将一些关键参数,需要运行时调整的参数放到nacos配置中心,一般都是自定义配置
多配置管理
-
微服务启动时会从nacos中读取多个配置文件
-
多种配置文件优先级
服务名-profile.yaml>服务名称.yaml>本地配置
nacos集群搭建
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sahmWFxC-1662454500900)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662362145605.png)]
-
搭建数据库,初始化数据库表结构
-
下载nacos安装包
-
配置nacos
-
进入nacos的conf目录,修改配置文件cluster.conf.example,重命名为cluster.conf,并添加集群的ip:端口号
如
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kGeXcafh-1662454500900)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662362607441.png)]
-
修改application.properties文件,添加数据库配置
如
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KSdWy34O-1662454500900)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662362645452.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gicxKH3n-1662454500901)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662362693637.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ze9n88Mw-1662454500901)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662362724239.png)]
-
-
启动nacos集群
打开bin目录,双击startup.cmd
-
nginx反向代理
-
修改conf/nginx.conf文件
如
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eEhr46Ri-1662454500901)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662362952892.png)]
-
双击.exe文件启动
-
http客户端Feign
RestTemplate方式调用存在的问题
- 代码可读性差,编程体验不统一
- 参数复杂url难以维护
- Feign是一个声明式的http客户端,其作用就是帮助我们优雅地实现http请求的发送,解决以上问题
使用Feign的步骤如下
-
引入依赖
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WGJVJ6eR-1662454500901)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662363442056.png)]
-
在客户端的启动类中添加注解开启Feign的功能
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aMFDlIeN-1662454500902)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662363488100.png)]
-
编写Feign客户端
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QxXw4Isg-1662454500902)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662363553851.png)]
主要是基于SpringMVC的注解来声明远程调用的信息,如
- 服务名称
- 请求方式
- 请求路径
- 请求参数
- 返回值类型
自定义Feign的配置
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iP8rs5Oi-1662454500902)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662364131986.png)]
一般我们需要配置的是日志级别
自定义Feign的配置有两种方式
-
方式一:配置文件方式
-
全局生效
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NuRmFjHp-1662454500902)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662364244195.png)]
-
局部生效
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9rUmod6N-1662454500903)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662364267076.png)]
-
-
方式二:java代码方式,需要先声明一个Bean
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4Q4F4bMj-1662454500903)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662364313973.png)]
-
全局配置。把它放到@EnableFeginClient注解中
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D59MsmtP-1662454500903)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662364377777.png)]
-
局部配置,把它放到@FeignClient注解中
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D1uw86Bs-1662454500903)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662364414890.png)]
-
Feign性能优化
-
Feingn底层的客户端实现
- URLConnection:默认实现,不支持连接池
- Apache HTTPClient:支持连接池
- OKHttp:支持连接池
-
因此优化Feign的性能主要包括
- 使用连接池代替默认的URLConnection
- 日志级别,最好使用basic或none
-
连接池配置
-
引入HttpClient依赖
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ysd88Y4L-1662454500903)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662365642799.png)]
-
配置连接池
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iGyitQcZ-1662454500904)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662365671105.png)]
-
Feign的最佳实践
-
方式一(继承):给消费者的FeignClient和提供者的controller定义统一的父接口作为标准 (不推荐,造成紧耦合)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7GilzSaa-1662454500904)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662366234665.png)]
-
方式二(抽取):将FeignClient抽取为独立模块,并且把接口有关的POJO、默认的Feign配置都放到这个模块中,提供给消费者使用
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G0XGm93I-1662454500904)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662366526218.png)]
实现方式二,抽取FeignClient
-
首先创建一个module。命名为feign-qpi,然后引入feign的starter依赖
-
将消费者中编写的生产者客户端,bean、默认Feign配置都赋值到feign-api项目中
-
在消费者中引入feign-api依赖
-
修改消费者中的与上述三个组件有关 的import部分,改成导入feign-api中的包
-
重启测试
-
当定义的FeignClient不再SpringbootApplication的扫描包范围内,这些FeignClient无法使用,有两种解决方案
-
方式一:指定FeignClient所在包
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZHiNWW8c-1662454500904)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662367336806.png)]
-
指定|FeignClient字节码(推荐)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-56h7Rk6e-1662454500905)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662367367357.png)]
-
Gateway网关
网关功能
-
身份认证和权限校验
-
服务路由,负载均衡
-
请求限流
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UnWOqQqy-1662454500905)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662367865004.png)]
网关技术实现
- 两种实现方式
- gateway:基于spring5中提供能webflux,属于响应式实现,具备更好的性能
- zuul:基于servlet实现,属于阻塞式编程
搭建网关Gateway
-
创建新的module,引入依赖,之后创建启动类
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1f859mcU-1662454500905)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662368171100.png)]
-
编写路由配置及nacos地址
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jNzFAUIL-1662454500905)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662368541795.png)]
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UuJ6AOn9-1662454500905)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662368779968.png)]
路由断言工厂Route Predicate Factory
-
网关路由可以配置的内容包括
- 路由id:路由唯一标示
- uri:路由目的地址,支持lb和http两种
- predicates:路由断言,判断请求是否符合要求,符合则要转发到路由目的地
- filters:路由过滤器,处理请求或响应
-
我们在配置文件中写的断言规则只是字符串,这些字符串会被Predicate Factory读取并处理,转变为路由判断的条件
-
spring提供的断言工厂
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YziXsIpK-1662454500906)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662369803730.png)]
路由过滤器GatewayFilter
-
GatewayFilter是网关中提供的一种过滤器,可以对进入网关的请求和微服务的响应做处理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6SvF3abs-1662454500906)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662370112916.png)]
-
实现方式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nR2TiRmA-1662454500906)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662370233572.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XFldI01M-1662454500906)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662370290676.png)]
默认过滤器
如果要对所有路由都生效,则可以将过滤器工厂写到default
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-54E5tCGv-1662454500907)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662370414637.png)]
全局过滤器
-
全局过滤器作用也是处理一切进入网关的请求和微服务响应,如GatewayFilter作用一样
-
区别在于GatewayFilter通过配置定义,处理逻辑是固定的。而GlobalFilter的逻辑需要自己写代码实现
-
定义方式是实现GlobalFilter接口
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tV6BhuiT-1662454500907)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662370742822.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-043vbq15-1662454500907)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662371042308.png)]
过滤器执行顺序
-
请求进入网关会碰到三类过滤器:当前路由过滤器、DefaultFilter、GlobalFilter
-
请求路由后,会将当前路由过滤器和DefaultFilter、GlobalFilter,合并到一个过滤器链(集合)中,排序后一次执行每个过滤器
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-db0TqnAu-1662454500907)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662371512354.png)]
-
每一个过滤器都必须指定一个int类型的order值,order值越小,优先级越高,执行顺序越靠前
-
GlobalFilter通过实现Ordered接口,或者添加@Order注解来指定order值,由我们自己指定
-
路由过滤器和defalutFilter的order由Spring指定,默认是按照声明顺序从1递增
-
当过滤器的order值一样时,会按照defaultFilter>路由过滤器>GlobalFilter的顺序执行
跨域问题处理
-
跨域:域名不一致就是跨域,主要包括
- 域名不同
- 域名相同,端口不同
-
跨域问题:浏览器进制请求的发起者与服务端发生跨域Ajax请求,请求被浏览器拦截的问题
-
解决方案:COPS
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dlmj1aAw-1662454500908)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662372009201.png)]
Docker
初识Docker
Docker
-
项目部署问题
大型项目组件较多,运行环境也较为复杂,部署时会遇到一些问题
- 依赖关系复杂,容易出现兼容性问题
- 开发、测试、生产环境有差异
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sh3QCTqD-1662454500908)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662372433824.png)]
-
Docker如何解决兼容性问题
- 将应用的Libs(函数库)、Deps(依赖)、配置与应用一起打包
- 将每个应用放到一个隔离容器去运行,避免互相干扰
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-klRnahtd-1662454500908)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662372561513.png)]
- 操作系统的结构
- 内核与硬件交互,提供操作硬件的指令
- 系统应用封装啮合指令为函数,便于程序员调用
- 用户基于系统函数库实现功能
-
总结
- 解决大型项目依赖关系复杂,不同组件依赖的兼容性问题
- Docker允许开发中将应用,依赖,函数库,配置一起打包,形成可移植镜像
- Docker应用运行在容器中,使用沙箱机制,相互隔离
- Docker如何解决开发,测试,生产环境有差异的问题
- Docker镜像中包含完整运行环境,包括系统函数库,仅依赖系统的Linux内核,因此可以在任意Linux操作系统上运行
- 解决大型项目依赖关系复杂,不同组件依赖的兼容性问题
-
Docker是一个快速交付,运行应用的技术
- 可以将程序及其依赖,运行环境一起打包成一个镜像,可以迁移到任何Linux操作系统
- 运行时利用沙箱机制形成隔离容器,各个应用互不干扰
- 启动,移除都可以通过一行命令完成,方便快捷
Docker与虚拟机
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9Kn6FNN4-1662454500908)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662376132485.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hbI0zlXK-1662454500909)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662376147189.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dlzks63A-1662454500909)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662376162668.png)]
- Docker是一个系统进程,虚拟机是在操作系统中的操作系统
- Docker体积小,启动速度快,性能好;虚拟机体积大,启动速读慢,性能一般
镜像和容器
- 镜像:Docker将应用程序及其所需要的依赖,含数据,环境,配置文件打包在一起,称为镜像
- 容器:镜像中的应用程序运行后形成的进程就是容器,只是Docker会给容器做隔离,对外不可见
Docker和DcokerHub
- DockerHub:Docker镜像的托管品台,这样的平台称为Docker Registry
- 国内也有类似于DockerHub的公开服务,比如网易云镜像服务,阿里云镜像库等
Docker架构
Docker是个CS架构的程序,由两部分组成
- 服务端:Docker守护进程,负责处理Docker指令,管理镜像,容器等
- 客户端:通过命令或RestAPI向Docker服务端发送指令,可以在本地或远程向服务端发送指令
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8ZGijVuq-1662454500909)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662376942017.png)]
Docker安装
Docker基本操作
镜像相关命令
-
镜像名称一般分为两部分组成:[repository]:[tag]
-
在没有指定tag时,默认是latest,代表最新版本
-
常见命令
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fLYVxTkJ-1662454500909)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662377840703.png)]
容器相关命令
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JEvmoBTo-1662454500909)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662379036316.png)]
docker run常见命令参数
- –name:指定容器名称
- -p:指定端口映射
- -d:让容器后台运行
查看容器日志命令
- docker logs
- 添加-f参数可以持续查看日志
查看容器状态
- docker ps
- 添加-a参数查看所有状态的容器
删除容器
- docker rm
- 不能删除运行中容器,除非添加-f参数
进入容器
- 命令是docker exec -it [容器名] [要执行的命令]
- exce命令可以进入容器修改文件,但是在容器内修改文件是不推荐的
数据卷
容器与数据耦合的问题
-
不便于修改
当我们要修改Nginx的html内容时,需要进入容器内部修改,很不方便
-
数据不可复用
在容器内的修改对外是不可见的。所有修改对新创建的容器是不可复用的
-
升级维护困难
数据在容器内,如果要升级容器必然删除容器,所有数据都跟着删除了
数据卷
-
是一个虚拟目录,直线宿主机文件系统中的摸个目录
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eBbyFNDO-1662454500910)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662382657601.png)]
-
数据卷操作的基本语法
docker volume [COMMAND]
- create 创建一个volume
- inspect 显示一个或多个volume信息
- ls 列出所有的volume
- prune 删除未使用的volume
- rm 删除一个或多个指定的volume
挂载数据卷
-
方式一:基于数据卷
- 我们在创建容器时,可以通过-v参数来挂在一个数据卷到某个容器目录
- 如果容器运行时volume不存在,会自动被创建出来
-
方式二:基于目录
语法类似基于数据卷,将宿主机目录直接挂载到容器
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x0xdMply-1662454500910)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662385192170.png)]
-
比较
- docker run的命令中通过-v参数直接挂载文件或目录到容器中
- -v volume名称:容器内目录
- -v 宿主机文件:容器内文件
- -v 宿主机目录:容器内目录
- 数据卷挂载与目录直接挂载的
- 数据卷挂载耦合度低,由docker来管理目录,但是目录较深,不好找
- 目录改在耦合度高,需要我们自己管理目录,不过目录容易寻找查看
- docker run的命令中通过-v参数直接挂载文件或目录到容器中
DockerFile自定义镜像
-
镜像结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TnA88eln-1662454500910)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662385616525.png)]
-
镜像是分层结构,每一层称为一个Layer
- BaseImage层:包含基本的系统函数库,环境变量,文件系统
- Entrypoint:入口,是镜像中应用启动的命令
- 其他:在BaseImage基础上添加依赖,安装程序,完成整个应用的安装和配置
-
自定义镜像
DockerCompose
-
什么是DockerCompose
基于Compose文件帮助我们快速地部署分布式应用,而无需手动一个个创建和运行容器
-
Compose是一个文本文件,通过指令定义集群中每个容器如何运行
-
部署
- 新建运行文件,在其中编写docker-compose文件
- 修改项目的数据库,nacos地址都命名为docker-compose中服务名
- 使用maven打包工具,将项目中的每个微服务都打包为app.jar
- 将打包好的app.jar拷贝到运行中每一个对应的子目录中
- 将运行文件上传至虚拟机,利用docker-compose up -d来部署
Docker镜像仓库
-
常见镜像仓库
- 公共仓库,例如Docker官方的Docker Hub,国内也有一些云服务商提供类似于Docker Hub的公开服务,比如网易云镜像服务,DaoCloud镜像服务,阿里云镜像服务等
- 除了使用公开仓库外,用户还可以在本地搭建私有Docker Registry。企业直接的镜像最好是采用私有Docker Registry来实现
-
搭建镜像仓库
- 简化版镜像仓库
- 带有图形化界面版本
- 配置Docker信任地址
-
在私有镜像仓库推送或拉取镜像
-
重新tag(版本)本地镜像,名称前缀为私有仓库的地址:192.168.150.101:8080/
docker tag nginx:latest 192.168.150.101:8080/nginx:1.0
-
推送镜像
docker push 192.168.150.101:8080/nginx:1.0
-
拉取镜像
docker pull 192.168.150.101:8080/nginx:1.0
-
-
总结
- 推送本地镜像到仓库前都必须重命名(docker tag)镜像,以镜像仓库地址为前缀
- 镜像仓库推送前需要把仓库地址配置到docker服务的daemon.json文件中,被docker信任
- 推送使用docker push命令
- 拉取使用docker pull命令
异步通讯技术
初识MQ
同步通讯和异步通讯
-
同步调用问题
-
优点:时效性强,可以立即得到结果
-
微服务间基于Feign的调用就属于同步方式,存在一些问题
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-enVsKK8f-1662454500910)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662431272981.png)]
- 耦合度高:每次加入新的需求,都要修改原来的代码
- 性能下降:调用者需要等待服务提供者响应,如果调用链过长则响应时间等于每次调用的时间之和
- 资源浪费:调用链中的每个服务在等待响应过程中,不能释放请求占用的资源,高并发场景下会极度浪费系统资源
- 级联失败:如果服务提供者出现问题,所有调用方都会跟着出现问题,如同多米诺骨牌一样,迅速到最后整个微服务群故障
-
-
异步调用方案
-
缺点
- 依赖于Broker的可靠性,安全性,吞吐能力
- 架构复杂,业务没有明显的流程线,不好追踪管理
-
异步调用常见的就是事件驱动模式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pdNjMMDA-1662454500911)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662435580877.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-85g5QrY5-1662454500911)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662435772339.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BLqjKExo-1662454500911)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662435800209.png)]
- 服务解耦。耦合度低
- 性能提升。吞吐量提高
- 故障隔离,服务没有强依赖关系
- 流量削峰
-
什么是MQ
- MQ(MessageQueue),中文是消息队列,字面来看就是存放消息的队列,也就是时间驱动架构中的Broker
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Fe8m2emb-1662454500911)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662436657241.png)]
RabbitMQ
介绍和安装
-
概述:基于Erlang语言开发的开源消息通信中间件
-
安装
-
方式一:在线拉取
docker pull rabbitmq:3-management
-
方式二:本地加载
本地镜像上传至虚拟机后,使用命令加载镜像即可
docker load -i mq.tar
-
执行命令来运行MQ程序
-
-
结构和概念
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-najlxYnA-1662454500912)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662437495474.png)]
- channel:操作MQ的工具
- exchange:路由消息到队列中
- queue:缓存消息
- virtual host:虚拟主机,是对queue,恶心嫦娥等资源的逻辑分组
常见消息模型
-
基本消息队列(BasicQueue)
只包括三个角色
- publisher:消息发布者,将消息发送到队列queue
- queue:消息队列,负责接收并缓存消息
- consumer:订阅队列,处理队列中的消息
- 消息发送流程
- 建立connection
- 创建channel
- 利用channel声明队列
- 利用channel向队列发送消息
- 基本消息接收流程
- 建立connecting
- 创建channel
- 利用channel声明队列
- 定义consumer的消费行为handleDelivery()
- 利用channel将消费者与队列绑定
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZYQ5XTlT-1662454500912)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662442773085.png)]
-
工作消息队列(WorkQueue)
可以提高消息的处理速度,避免消息堆积
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qD9UmzxE-1662454500912)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662444909593.png)]
-
发布订阅(Public、Subscribe)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JYwWazjg-1662454500912)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662445993804.png)]
根据交换机类型不同分为三种
- 广播(Fanout Exchange)
- 路由(Direct Exchange)
- 话题(Topic Exchange)
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jp9IpQB0-1662454500913)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662437930002.png)]
SpringAMQP
消息队列
-
AMQP:Advanced Message Queuing Protocol,是用于在应用程序或之间传递业务消息的开发标准。该协议与语言和平台无关,更符合微服务中独立性的要求
-
Spring AMQP:是基于AMQP协议定义的一套API规范,提供了模板来发送和接收消息。包含两部分,其中spring-amqp是基础抽象,spring-rabbit是底层默认实现
-
消息发送
-
在父工程中引入spring-amqp依赖
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k6mJsHv3-1662454500913)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662444038240.png)]
-
在publisher服务中利用RabbitTemplate发送消息到队列中
-
编写配置文件,添加RabbitMQ地址
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8Io5RPRk-1662454500913)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662444099415.png)]
-
新建测试类,利用convertAndSent()发送消息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6zKxaWpc-1662454500913)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662444307511.png)]
-
-
在consumer服务中绑定消息队列
-
编写配置信息,添加mq连接消息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qPcHEgc9-1662454500914)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662444434480.png)]
-
新建方法,编写消息方法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pvbtmR7W-1662454500914)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662444486671.png)]
-
-
消息一旦消费就会从队列中删除,RabbitMQ没有消息回溯功能
-
Work Queue工作队列
- 多个消费者绑定到一个队列,同一条消息只会被一个消费者处理
- 消息预取限制
- 修改application.yml文件,设置preFetch这个值,可以控制预取消息上限
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q0JrnQtz-1662454500914)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662445651260.png)]
FanoutExchange广播
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zuDnptL6-1662454500914)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662446302081.png)]
- 步骤
- 在consumer服务声明Exchange,Queue,Binding
- 在consumer服务声明两个消费者
- 在publisher服务发送消息到FountExchange
- 交换机的作用
- 接收publisher发送的消息
- 将消息按照规则路由到与之绑定的消息队列
- 不能缓存消息,路由失败,消息丢失
- FanoutExchange的会将消息路由到每个绑定的队列
- 声明队列、交换机、绑定关系的Bean是什么
- Queue
- FanoutExchange
- Bingding
DirectExchange发布订阅
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BvCea8v4-1662454500915)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662447402906.png)]
-
将接收到的消息根据规则路由到指定的Queue
- 每发一个Queue都与Exchange设置一个BindingKey
- 发布者发送消息时,指定消息的RoutingKey
- Exchange将消息路由到BingingKey与消息RoutingKey一致的队列
-
实现
- 在consumer服务声明Exchange,Queue
- 在publisher服务发送消息到DirectExchange
-
Direct交换机与Fanout交换机的差异
- Fanout交换机将消息路由给每一个与之绑定的队列
- Direct交换机根据RoutingKey判断路由给哪个队列
- 如果多个对列具有相同的RoutingKey,则与Fanout功能类似
-
基于@RabbitListener注解声明队列和交换机有哪些常见注解
- @Queue
- @Exchange
TopicExchange发布订阅
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8iZsSZKs-1662454500915)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662448462610.png)]
- 与DirectExchange类似,去呗在于routingKey必须是多个单词的列表,并且以 . 分割
- Queue与Exchange指定BingingKey时可以使用通配符
- #: 代指0个或多个单词
- *: 代指一个单词
消息转换器
-
在SpringAMQP的发送方法中,接收消息的类型是Object,也就是说我们可以发送任意对象类型的消息,SpringAMQP对帮我们序列化为字节后发送
-
Spring的对象消息默认实现是基于ObjectOutputStream完成序列化的,如果要修改只需要定义一个MessageConverter类型的Bean即可,推荐使用JSON方式序列化
-
发送方和接收方必须使用相同的MessageConverter
-
步骤
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gImAqOgn-1662454500915)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662449316576.png)]