参考:
https://mp.weixin.qq.com/s/MJrahcDXwxgDr5zBdO3XWw
http://www.macrozheng.com/#/cloud/springcloud
Eureka
治理机制
在传统rpc远程调用中,服务与服务依赖关系,管理比较复杂,所以需要使用服务治理,管理服务与服务之间依赖关系,可以实现服务调用、负载均衡、容错等,实现服务发现与注册。
底层原理
默认情况下:
1.服务提供者每隔30秒发送心跳到注册中心
2.注册中心有一个线程,每隔60秒检查服务注册表,并将超时90秒的服务剔除
3.当服务注册表发送变化,会立马同步到ReadWrite缓存
4.有另外一个线程,每隔30秒,定时将ReadWrite缓存同步到ReadOnly缓存
5.服务消费者,每隔30秒,读取ReadOnly缓存,拉取注册表,缓存到服务消费者本地
6.如果使用ribbon,ribbon每隔30秒拉取服务消费者本地的注册表
参考:
https://www.cnblogs.com/shihaiming/p/11590748.html
与ZK对比
(1)服务注册发现的原理
Eureka:peer-to-peer,部署一个集群,但是集群里每个机器的地位是对等的,各个服务可以向任何一个Eureka实例服务注册和服务发现,集群里任何一个Euerka实例接收到写请求之后,会自动同步给其他所有的Eureka实例
ZooKeeper:服务注册和发现的原理,Leader + Follower两种角色,只有Leader可以负责写也就是服务注册,他可以把数据同步给Follower,读的时候leader/follower都可以读
(2)一致性保障:CP or AP
CAP,C是一致性,A是可用性,P是分区容错性
Eureka:AP
ZooKeeper:CP,在选举过程中不可用
(3)服务注册发现的时效性
Eureka:默认配置非常糟糕,服务发现感知要到几十秒,甚至分钟级别
ZooKeeper:时效性更好,注册或者是挂了,一般秒级就能感知到
(4)容量
Eureka:很难支撑大规模的服务实例,因为每个eureka实例都要接受所有的请求,实例多了压力太大,扛不住,也很难到几千服务实例
ZooKeeper:不适合大规模的服务实例,因为服务上下线的时候,需要瞬间推送数据通知到所有的其他服务实例,所以一旦服务规模太大,到了几千个服务实例的时候,会导致网络带宽被大量占用
一句话 都不适合大规模的服务实例。
生产环境需要优化的配置
- Eureka Server:
- Eureka Client:
Ribbon
Ribbon底层实现原理
1.首先使用DiscoveryClient从注册中心读取目标服务信息
2.然后根据策略选择其中的一个节点
3.然后返回给restTemplete进行调用
Nginx与Ribbon的区别
Ribbon 的几种负载均衡算法
Hystrix
- 服务降级:当客户端请求服务器端的时候,防止客户端一直等待,不会处理业务逻辑代码,直接返回一个友好的提示给客户端。
- 熔断机制:在高并发的情况下,如果请求达到一定极限(可以自己设置阔值)如果流量超出了设置阈值,然后直接拒绝访问,保护当前服务。使用服务降级方式返回一个友好提示,服务熔断和服务降级一起使用。
- 服务隔离:
因为Tomcat默认情况下只有一个线程池来维护客户端发送的所有的请求,这时候某一接口在某一时刻被大量访问就会占据tomcat线程池中的所有线程,其他请求处于等待状态,无法连接到服务接口。
Hystrix为隔离的服务开启一个独立的线程池,这样在高并发的情况下不会影响其他服务。服务隔离有线程池和信号量两种实现方式,一般使用线程池方式。 - 服务限流:对接口访问进行限制,常用服务限流算法令牌桶、漏桶。计数器也可以进行粗暴限流实现。
使用
Feign
OpenFeign 也是运行在消费者端的,使用 Ribbon 进行负载均衡,所以 OpenFeign 直接内置了 Ribbon。
使用
Zuul
原理
Zuul原理分析
(1):请求给zuulservlet处理(HttpServlet子类) zuulservlet中有一个zuulRunner对象,该对象中初始化了RequestContext(存储请求的数据),RequestContext被所有的zuulfilter共享;
(2):zuulRunner中有 FilterProcessor(zuulfilter的管理器),其从filterloader 中获取zuulfilter;
(3):有了这些filter之后, zuulservelet执行的Pre-> route-> post 类型的过滤器,如果在执行这些过滤器有错误的时候则会执行error类型的过滤器,执行完后把结果返回给客户端.
使用