们使用Spring Cloud Netflix中的Eureka实现了服务注册中心以及服务注册与发现;而服务间通过Ribbon或Feign实现服务的消费以及均衡负载。为了使得服务集群更为健壮,使用Hystrix的融断机制来避免在微服务架构中个别服务出现异常时引起的故障蔓延。
随着互联网的发展,网站应用的规模不断扩大。需求的激增,带来的是技术上的压力。系统架构也因此不断的演进、升级、迭代。从单一应用,到垂直拆分,到分布式服务,到SOA,以及现在火热的微服务架构,还有在Google带领下来势汹涌的Service Mesh。
集中式架构:代码耦合,开发维护困难,无法进行维护和扩展,单点容错率低,并发能力差。
垂直拆分:按功能拆分,系统间相互独立,造成重复开发,影响开发效率。
水平拆分:拆分为 web,service,mapper,但调用关系复杂,维护困难
注册中心:用来管理各个服务的调用关系,服务间会有依赖关系,一旦某个环节出错会影响较大
微服务:力度更细的分布式,每个服务都要对外暴露Rest风格服务接口API,做到与平台和语言无关,开发时实现团队独立和技术独立
服务间调用方式:
RPC:Remote Produce Call远程过程调用,类似的还有RMI。自定义数据格式,基于原生TCP通信,速度快,效率高。早期的webservice,现在热门的dubbo,都是RPC的典型代表。Http:缺点是消息封装臃肿,优势是对服务的提供和调用方没有任何技术限定,自由灵活,更符合微服务理念。现在热门的Rest风格,就可以通过http协议来实现。微服务框架:Springcloud,Dubbo。
如果你们公司全部采用Java技术栈,那么使用Dubbo作为微服务架构是一个不错的选择。相反,如果公司的技术栈多样化,而且你更青睐Spring家族,那么SpringCloud搭建微服务是不二之选。在我们的项目中,我们会选择SpringCloud套件,因此我们会使用Http方式来实现服务间调用。SpringCloud组件
Eureka:服务治理组件,包含服务注册中心,服务注册与发现机制的实现。(服务治理,服务注册/发现)Zuul:网关组件,提供智能路由,访问过滤功能Ribbon:客户端负载均衡的服务调用组件(客户端负载)Feign:服务调用,给予Ribbon和Hystrix的声明式服务调用组件 (声明式服务调用)Hystrix:容错管理组件,实现断路器模式,帮助服务依赖中出现的延迟和为故障提供强大的容错能力。(熔断、断路器,容错)基本架构:
服务注册中心:就是Eureka,提供服务注册和发现功能服务提供者:启动后向Eureka注册自己信息(地址,提供什么服务),可以是SpringBoot应用,也可以是其它任意技术实现,只要对外提供的是Rest风格服务即可。服务消费者:向Eureka订阅服务,Eureka会将对应服务的所有提供者地址列表发送给消费者,并且定期更新。心跳(续约):提供者定期通过http方式向Eureka刷新自己的状态集群实现高可用:多个Eureka Server之间也会互相注册为服务,当服务提供者注册到Eureka Server集群中的某个节点时,该节点会把服务的信息同步给集群中的每个节点,从而实现数据同步。因此,无论客户端访问到Eureka Server集群中的任意一个节点,都可以获取到完整的服务列表信息。
功能的实现:
服务注册:Eureka Server会把这些信息保存到一个双层Map结构中。 第一层Map的Key就是服务id,一般是配置中的spring.application.name属性第二层Map的key是服务的实例id。一般host+ serviceId + port,例如:locahost:service-provider:8081值则是服务的实例对象,也就是说一个服务,可以同时启动多个不同实例,形成集群。 服务续约:在注册服务完成以后,服务提供者会维持一个心跳(默认30秒,定时向EurekaServer发起Rest请求),告诉EurekaServer:“我还活着”。这个我们称为服务的续约(renew);如果超过一定时间(默认90秒)没有发送心跳,EurekaServer就会认为该服务宕机,会从服务列表中移除,这两个值在生产环境不要修改,默认即可。获取服务列表:当服务消费者启动时,会检测eureka.client.fetch-registry=true参数的值,如果为true,则会拉取Eureka Server服务的列表只读备份,然后缓存在本地。并且默认每隔30秒会重新获取并更新数据。服务下线:当服务进行正常关闭操作时,它会触发一个服务下线的REST请求给Eureka Server,告诉服务注册中心:“我要下线了”。服务中心接受到请求之后,将该服务置为下线状态。失效剔除:有些时候,我们的服务提供方并不一定会正常下线,可能因为内存溢出、网络故障等原因导致服务无法正常工作。Eureka Server需要将这样的服务剔除出服务列表。因此它会开启一个定时任务,每隔60秒对所有失效的服务(超过90秒未响应)进行剔除。自我保护:当一个服务未按时进行心跳续约时,Eureka会统计最近15分钟心跳失败的服务实例的比例是否超过了85%。在生产环境下,因为网络延迟等原因,心跳失败实例的比例很有可能超标,但是此时就把服务剔除列表并不妥当,因为服务可能没有宕机。Eureka就会把当前实例的注册信息保护起来,不予剔除。生产环境下这很有效,保证了大多数服务依然可用。但是这给我们的开发带来了麻烦, 因此开发阶段我们都会关闭自我保护模式。实际环境中,我们往往会开启很多个itcast-service-provider的集群。此时我们获取的服务列表中就会有多个,一般这种情况下我们就需要编写负载均衡算法,在多个实例列表中进行选择。Eureka中已经帮我们集成了负载均衡组件:Ribbon,简单修改代码即可使用。
默认的负载均衡策略是轮询,可以设置为随机为什么:微服务中,服务间调用关系错综复杂,一个服务出现问题,请求堵塞,用户不会得到响应,于是越来越多的用户请求到来,越来越多的线程会阻塞,服务器支持的线程和并发数有限,请求一直阻塞,会导致服务器资源耗尽,从而导致所有其它服务都不可用,形成雪崩效应。
是什么:Hystix是Netflix开源的一个延迟和容错库,用于隔离访问远程服务、第三方库,防止出现级联失败。
怎么做:线路隔离,服务熔断。
线路隔离:Hystrix为每个依赖服务调用分配一个小的线程池,如果线程池已满调用将被立即拒绝,返回错误信息(默认不采用排队,加速失败判定时间),并且会进行降级处理,这样子用户请求故障时,不会导致阻塞,至少返回一个提示信息。
服务降级:优先保证核心服务,而非核心服务不可用或弱可用。服务熔断:分布式系统应用这一模式之后,服务调用方可以自己进行判断某些服务反应慢或者存在大量超时的情况,能够主动熔断,防止整个系统被拖垮。不同于电路熔断,Hystrix可以在情况好转子厚自动重连。熔断状态机3个状态:
Closed:关闭状态,所有请求都正常访问。Open:打开状态,所有请求都会被降级。Hystix会对请求情况计数,当一定时间内失败请求百分比达到阈值,则触发熔断,断路器会完全打开。默认失败比例的阈值是50%,请求次数最少不低于20次。Half Open:半开状态,open状态不是永久的,打开后会进入休眠时间(默认是5S)。随后断路器会自动进入半开状态。此时会释放部分请求通过,若这些请求都是健康的,则会完全关闭断路器,否则继续保持打开,再次进行休眠计时怎么用: