@[toc]springcloud 学习笔记
什么是微服务
首先 微服务不是一种框架,他是一种架构思想, 将软件应用程序设计为独立部署的服务的一种特殊方式,微服务架构的系统是个分布式系统,按照业务领域划分为独立的服务单元,有自动化运维,容错,快速演进的特点,他能够解决单体架构的痛点,同时也能满足越来越复杂的业务需求.
单体架构的痛点
1. 业务越来越复杂,单体应用的代码量越来越大,新手接手代码的成本越来越高,重构代码的代价越来越大,很多人也不愿意重构代码,一般都接着别人的代码继续往下写.业务扩展的代价也越来越大
2. 随着用户越来越多,程序承受并发的频率越来越高,当体架构的并发能力有限
3. 测试的难度越来越大,单体应用的业务都在同个程序中,随着业务的扩张,复杂度增加,单体应用增加业务或者修改业务都可能给其他业务带来影响,导致测试难度增加
常用组件
1 服务注册与发现
Eureka 与zookeeper的区别
- zookeeper为什么不适合做注册中心
主要原因就是CAP原则,指的是在一个分布式系统中,
一致性(Consistency),
可用性(Availability),
分区容错性(partition Tolerance)(这个特性是不可避免的)
cap原则指的是这三个特性只能实现两种,不可能三者兼得
2 ribbon 负载均衡工具
什么是ribbon
一个基于负载HTTP 和 TCP 的客户端负载均衡工具,给一些任务分摊给不同的人操作,可以轻松的让我们将REST模板请求自动转换成客户端负载均衡的服务调用.
ribbon算法(轮询 hash 权重…)
ribbon是一个开源的项目.主要提供客户端负载均衡的算法和服务调用
ribbon可以结合resttemplate去使用 还可以结合OpenFeign去使用
轮询的算法类似于取模(例如三台机器,1%3=1,2%3=2,3%3=0…),请求次数与服务器台数去取模
i++是线程不安全的,
如果要实现现在安全,可以加锁,但是加锁会导致效率变低,如果一定要保证线程安全,可以加自旋锁CAS (没有线程的等待和唤醒的开销)
CAS的优点
在java层面是没有锁的,在jvm层面是有锁的, ** 缺点是在短暂时间内会到CPU飙升**
请求工具
- restTemplate 使用java.net.HttpUrlConnection 发的请求 很方便 不支持连接池
- HttpClient 支持连接池 效率更好 如果需要改 要添加对应的依赖
- okHttp 一般用于移动端 轻量级的请求
ribbon总结
起到承上启下的所用, 上: 从Eureka中拉取服务列表, 下:使用IRule算法实现客户端的负载均衡
3 feign (OpenFeign) 声明式的客户端
1.客户端调用服务端
- 首先要添加对应的依赖 ,并且写好服务端以及客户端
- 使用feign需要在启动类 添加注解 ** @EnableFeignClients 开启feign的客户端功能 帮助我们发起远程调用**
- 需要写一个接口,可以创建个feign包,在feign包下创建接口,添加对应的注解** @FeignClient ( value = “服务的应用名称”),不清楚的在yml中找服务名称** 直接copy服务端controller的方法放进来就可以了.
- feign的默认时间是1S, 超过1S就会报错
- feign只是封装了远程调用的工具,他的底层依旧是ribbon,所以需要给超时加长,需要去修改ribbon的超时时间
4 hystrix 熔断器
用来保护微服务不雪崩的办法
服务雪崩的概念
在分布式服务中,一个服务的宕机可能导致整个链路瘫痪 一般出现的错误 503 service unavailable(服务不可用),所以服务雪崩的核心本质就是线程没有及时回收
hystrix 快速入门
当有服务调用的时候,才会出现服务雪崩,所以常和 openFeign,Ribbon一起出现
1.添加依赖
2.写一个hystrix类实现feign接口,在feign接口中指定hystrix类
3.在yml文件中开启熔断器
feign.hystrix.enabled: true
链路追踪 Sleuth
链路追踪就是: 追踪微服务的调用路径
1链路追踪的由来
在微服务中,存在一个请求调用多个节点的情况,当请求出现问题,可以通过链路追踪判断问题,微服务中调用最好不要超过三层(比如: a-b-c 不要出现 a-b-c-d)
2 分布式链路调用的监控
sleuth +zipkin(zipkin就是一个可视化的监控控制台)
使用方式
启动 zipkin的jar包,在每个配置文件中添加sleuth配置以及zipkin的配置
admin 服务监控
一个微服务项目有N个微服务,admin-server管理端无需监控每一个服务,直接注册到注册中心,就可以获取所有的服务列表了
监控本质
就是心跳检测,类似打乒乓球,两边来回跳动,如果没有响应,说明服务挂了
使用方式
添加依赖 – 给服务注册到服务中心(在配置中心注册)
如果需要别的服务被监控 需要添加依赖
然后修改配置文件 (*号代表所有都被监控)
Gateway 网关
网关的作用
微服务存在很多端口(8080 8081等),前端不可能根据每个具体端口去调用,这个时候可以设置一个网关,让网关去做路由转发
**作用: ** 路由转发-安全控制(隐藏每个具体接口,防止攻击) - 负载均衡
zuul 也是网关
springcloud 不支持zuul2.0, 2.0是NIO 非阻塞io,所以后面用gateway更合适,1.0是Bio阻塞io
网关的三大核心概念
1.路由
2.断言
3.过滤 filter
gateway 与 Nginx 的区别
gateway 是项目级别的
Nginx 是服务器级别的
** 如果gateway不需要集群,Nginx可以不要,但是要做集群,必须要Nginx,中间可能存在80 81 82 的gateway 需要Nginx做转发**
网关的配置
还可以通过config自己配置
动态路由
如果存在多个服务且存在相同的请求路径, 就要结合eureka 注册中心,将gateway注册到注册中心,设置拉取服务列表的时间,配置文件中开启动态路由
predicate 断言工厂
Filter过滤器工厂
分类:
按生命周期分为两种
pre 在业务逻辑之前
post 在业务逻辑之后
按种类分也是两种
GatewayFilter 需要配置某个路由才能过滤,如果需要使用全局路由,需要配置DefaultFilters。
使用场景: 1、记录接口的访问次数 2、限流操作
GlobalFilter 全局过滤器,不需要配置路由,系统初始化配置到所有路由上
使用场景 : 1、黑名单校验 2、 全局token校验 3、参数校验(防止sql注入)
自定义全局过滤器 GlobalFilter(重点)
全局过滤器的有点在初始化时默认挂到所有路由上,可以用来过滤ip,限流等操作
实现过程
1、 要实现GlobalFilter接口
2、exchange 中可以拿到请求头 url 参数之类的东西
3、实现order接口,主要用来排序,越小越先行