部分内容来源于其他作者,如侵删
注册服务与发现
消费者想要使用生产者提供的服务就必须知道,生产者在什么地方。生产者通过注册中心可以知道全部的生产者。
- 纯消费者可以不进行注册
Eurka
#保证高可用(A)和最终一致性
- 服务注册相比Eureka会稍慢一些。因为Consul的raft协议要求必须过半数的节点都写入成功才认为注册成功
- Leader挂掉时,重新选举期间整个consul不可用。保证了强一致性但牺牲了可用性。
服务注册server
- Eruka Client 向 Eurka server 注册,将自己的客户端信息交给Eurka server
- Eruka Client 向 Eurka server 发送心跳,证明服务还在正常运行
- 如果某个Eruka Client 不可用,则sever 剔除改client
服务发现client
- client 向 server 请求服务清单
- server 维护一份只读的服务清单返回给client
角色划分
- 注册中心Regsiter Service
- 服务提供者 Provide Service
- 服务消费者 Consumer Service
Consul
Consul强一致性©
- 服务注册相对要快,因为不需要等注册信息replicate到其他节点,也不保证注册信息是否replicate成功
- 当数据出现不一致时,虽然A, B上的注册信息不完全相同,但每个Eureka节点依然能够正常对外提供服务,这会出现查询服务信息时如果请求A查不到,但请求B就能查到。如此保证了可用性但牺牲了一致性。
负载均衡
客户端Ribbon
- Ribbon 是从 eureka 注册中心服务器端上获取服务注册信息列表,缓存到本地,然后在本地实现轮询负载均衡策略。
- 可以简单的理解成类似于 nginx的负载均衡模块的功能。
- 既在客户端实现负载均衡。
服务端 nginx
- nginx 是客户端所有请求统一交给 nginx,由 nginx 进行实现负载均衡请求转发,属于服务器端负载均衡。
- 负载均衡、反向代理,代理后端服务器。隐藏真实地址,防火墙,不能外网直接访问,安全性较高。属于服务器端负载均衡。
- 既请求由 nginx 服务器端进行转发。性能高5w/s。
对比
- nginx性能好,但ribbon可以剔除不健康节点,nginx剔除节点比较复杂。ribbon还可以配合熔断器一起工作
- ribbon是客户端负载均衡,nginx是服务端负载均衡。客户端负载均衡,所有客户端节点都维护自己要访问的服务端清单。服务端负载均衡的软件模块会维护一个可用的服务清单
- Nginx 适合于服务器端实现负载均衡 :Ribbon 适合与在微服务中 RPC 远程调用实现本地服务负载均衡
声明式服务调用Feign
工作在消费者上,程序调用服务的时候不必每次都配置url,request,反射。就像自动注入那样,程序员可以十分方便的调用生产者提供的服务。
- 程序启动,扫描所以带有@FeiginClient注解的代码
- 接口方法被调用的时,通过jdk代理来生成RequestTemplate模板对象
- 根据前者生成Http请求对象request对象
- Request对象交由client处理
- 调用内部服务也需要负载均衡,feign自带有Ribbon以实现负载均衡
服务容错保护Hystrix
服务雪崩
因为某个服务的崩溃而导致整个系统的不可使用
熔断
某个方法在一定时间内调用失败的次数达到某个阈值,将会熔断调用该方法将会直接返回异常而不是真实的调用。打工人连续加三天班,再加班就猝死了,这时候老板突然让你休息下,不给你增加新的任务了,先把手头的任务处理了,在处理新的。
- 保证系统可以在不崩溃的情况下,保持最高执行力
服务降级
熔断后需要降级来给用户一个友好的反馈,比如我想要选课,但是同时访问的人数太多导致了熔断,系统就提示我稍后在进入。我要求的服务从选课变成了简单提示,这就要服务降级
资源隔离
将系统中的生产者隔离起来,一个服务的提供者延迟升高或者失败,不会导致整个系统的失败。
API网关zuul
一个对于 消费者 的统一入口
简单配置
网关向注册中心进行注册,可直接拿到所有的消费者的信息(名称,ip,端口)
统一配置
zuul:
prefix: /zuul
这样所有的请求前就会加上/zuul
路由策略配置
你会发现前面的访问方式(直接使用服务名),需要将微服务名称暴露给用户,会存在安全性问题。所以,可以自定义路径来替代微服务名称,即自定义路由策略。
zuul:
routes:
consumer1: /FrancisQ1/**
consumer2: /FrancisQ2/**
这个时候就可以使用 localhost:9000/zuul/FrancisQ1/studentInfo/update 进行访问了。
服务名屏蔽
这个时候你别以为你好了,你可以试试,在你配置完路由策略之后使用微服务名称还是可以访问的,这个时候你需要将服务名屏蔽。
zuul:
ignore-services: "*"
路径屏蔽
Zuul 还可以指定屏蔽掉的路径 URI,即只要用户请求中包含指定的 URI 路径,那么该请求将无法访问到指定的服务。通过该方式可以限制用户的权限。
zuul:
ignore-patterns: **/auto/**
这样关于 auto 的请求我们就可以过滤掉了。
** 代表匹配多级任意路径
*代表匹配一级任意路径
敏感请求头屏蔽
默认情况下,像 Cookie、Set-Cookie 等敏感请求头信息会被 zuul 屏蔽掉,我们可以将这些默认屏蔽去掉,当然,也可以添加要屏蔽的请求头。
Zuul 的过滤功能
如果说,路由功能是 Zuul 的基操的话,那么过滤器 就是 Zuul的利器了。毕竟所有请求都经过网关(Zuul),那么我们可以进行各种过滤,这样我们就能实现 限流 ,灰度发布,权限控制 等等。
关于 Zuul 的其他
- Zuul 的过滤器的功能肯定不止上面我所实现的两种,它还可以实现 权限校验 ,包括我上面提到的 灰度发布 等等。
- Zuul 作为网关肯定也存在 单点问题 ,如果我们要保证 Zuul 的高可用,我们就需要进行 Zuul 的集群配置,这个时候可以借助额外的一些负载均衡器比如 Nginx 。
容器化
- docker
- k8s
服务链路跟踪Sleuth
分布式的系统,一个前端的请求伴随的可能是后端十几请求的调用,当链路中某个请求不可用导致整个请求不可用,这时就需要快速的定位故障点
Spring Cloud Sleuth为服务之间调用提供链路追踪。通过Sleuth可以很清楚的了解到一个服务请求经过了哪些服务,每个服务处理花费了多长。从而让我们可以很方便的理清各微服务间的调用关系。此外Sleuth可以帮助我们:
- 耗时分析: 通过Sleuth可以很方便的了解到每个采样请求的耗时,从而分析出哪些服务调用比较耗时;
- 可视化错误: 对于程序未捕捉的异常,可以通过集成Zipkin服务界面上看到;
- 链路优化: 对于调用比较频繁的服务,可以针对这些服务实施一些优化措施。
spring cloud sleuth可以结合zipkin,将信息发送到zipkin,利用zipkin的存储来存储信息,利用zipkin ui来展示数据。
配置中心
一个分布式的系统中,会有多台服务器,一旦配置文件需要修改就需要逐个修改,简直就是运维人员的噩梦,于是配置中心就出现了
Spring Cloud Config项目是一个解决分布式系统的配置管理方案。它包含了Client和Server两个部分,server提供配置文件的存储、以接口的形式将配置文件的内容提供出去,client通过接口获取数据、并依据此数据初始化自己的应用。
- 简单来说,使用Spring Cloud Config就是将配置文件放到统一的位置管理(比如GitHub),客户端通过接口去获取这些配置文件。
- 在GitHub上修改了某个配置文件,应用加载的就是修改后的配置文件。
还可以通过github的Webhooks功能来实现配置的同步,但是不满足生产环境
消息总线Bus
用于将服务和服务实例与分布式消息系统链接在一起的事件总线。在集群中传播状态更改很有用(例如配置更改事件)。
你可以简单理解为 Spring Cloud Bus 的作用就是管理和广播分布式系统中的消息 ,也就是消息引擎系统中的广播模式。当然作为 消息总线 的 Spring Cloud Bus 可以做很多事而不仅仅是客户端的配置刷新功能。