微服务架构是一种架构模式或者说是一种架构风格,不同于集中式的服务管理机制,它提倡将单一应用程序划分成一组小的服务,根据业务拆分成一个一个的服务,每个服务都围绕着具体业务进行构建并且运行在其独立的自己的进程中。服务之间通常是基于HTTP的RESTful API的轻量级的通信机制交互。每个服务能够被独立地部署到预生产环境、生产环境等。
优点:微服务可使用不同的语言开发,开发效率提高,一个服务可以专一的只干一件事。
1.复杂度⾼:服务调⽤要考虑被调⽤⽅故障、过载、消息丢失等各种异常情况,代码逻辑更加复杂;对于微服务间的事务性操作,因为不同的微服务采⽤了不同的数据库,将⽆法利⽤数据库本身的事务机制保证⼀致性,需要引⼊⼆阶段提交等技术。
2.运维复杂:系统由多个独⽴运⾏的微服务构成,需要⼀个设计良好的监控系统对各个微服务的运⾏状态进⾏监控。运维⼈员需要对系统有细致的了解才对够更好的运维系统。
3.通信延迟:微服务之间调⽤会有时间损耗,造成通信延迟。
1)与分布式系统相关的复杂性-这种开销包括网络问题,延迟开销,带宽问题,安全问题。
2)服务发现-服务发现工具管理群集中的流程和服务如何查找和互相交谈。它涉及一个服务目
录,在该目录中注册服务,然后能够查找并连接到该目录中的服务。
3)冗余-分布式系统中的冗余问题。
4)负载平衡 --负载平衡改善跨多个计算资源的工作负荷,诸如计算机,计算机集群,网络链
路,中央处理单元,或磁盘驱动器的分布。
5)性能-问题 由于各种运营开销导致的性能问题。
1远程过程调用(Remote Procedure Invocation)
只支持请求/响应的模式,要求客户端和服务端在请求过程中必须都是可用的
2异步消息
支持很多通信机制比如通知、请求/异步响应、发布/订阅、发布/异步响应;
SOA(全称:Service Oriented Architecture),中文意思为 “面向服务的架构”,
1.微服务去中心化,去掉ESB企业总线。微服务不再强调传统SOA架构里面比较重的ESB企业服务总线,同时SOA的思想进入到单个业务系统内部实现真正的组件化
2.Docker容器技术的出现,为微服务提供了更便利的条件,比如更小的部署单元,每个服务可以通过类似Node或者Spring Boot等技术跑在自己的进程中。
3.SOA注重的是系统集成方面,而微服务关注的是完全分离。
Netflix OSS 开源组件集成,包括Eureka、Hystrix、Ribbon、Feign、Zuul等核心组件。
1.Eureka:服务治理组件,包括服务端的注册中心和客户端的服务发现机制;
2.Ribbon:负载均衡的服务调用组件,具有多种负载均衡调用策略;
3.Hystrix:服务容错组件,实现了断路器模式,为依赖服务的出错和延迟提供了容错能力;
4.Feign:基于Ribbon和Hystrix的声明式服务调用组件;
5.Zuul:API网关组件,对请求提供路由及过滤功能。
6.Spring Cloud Config:分布式统一配置管理;
1SpringBoot专注于快速方便的开发单个个体微服务。
2SpringCloud是关注全局的微服务协调整理治理框架,它将SpringBoot开发的一个个单体微服务整合并管理起来,为各个微服务之间提供配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策竞选、分布式会话等等集成服务。
3SpringBoot可以离开SpringCloud独立使用开发项目,但是SpringCloud离不开SpringBoot,属于依赖的关系.
4SpringBoot专注于快速、方便的开发单个微服务个体,SpringCloud关注全局的服务治理框架。
服务调用方式:Dubbo是RPC,SpringCloud是RestApi;
注册中心:Dubbo 是zookeeper,SpringCloud是Eureka,也可以是ZooKeeper
服务网关:Dubbo本身没有实现,只能通过其他第三方技术整合,SpringCloud有Zuul路由网关,作为路由服务器,进行消费者的请求分发,SpringCloud支持断路器,与git完美集成配置文件支持版本控制,事务总线实现配置文件的更新与服务自动装配等等一系列的微服务架构要素。
服务注册是让所有微服务将自己的信息注册到注册中心,服务发现在真正发起服务调用前,调用方需要从注册中心拿到相应服务可用的IP和端口列表,即服务发现。
Eureka作为SpringCloud的服务注册功能服务器,它是服务注册中心,系统中的其他服务使用Eureka的客户端将其连接到Eureka Service中,并且保持心跳,这样工作人员可以通过EurekaService来监控各个微服务是否运行正常。
通过集群注册多台 Eureka ,然后把SpringCloud服务互相注册,客户端从Eureka获取信息时,按照Eureka的顺序来访问。
默认情况下,如果 Eureka Service 在一定时间内没有接收到某个微服务的心跳, Eureka Service 会进入自我保护模式,在该模式下Eureka Service 会保护服务注册表中的信息,不在删除注册表中的数据,当网络故障恢复后,Eureka Servic 节点会自动退出自我保护模式。
可以从注册中心中根据服务别名获取注册的服务器信息。
1.ZooKeeper中的节点服务挂了就要选举 在选举期间注册服务瘫痪,虽然服务最终会恢复,但是选举期间不可用的, 选举就是改微服务做了集群,必须有一台主其他的都是从
2.Eureka各个节点是平等关系,服务器挂了没关系,只要有一台Eureka就可以保证服务可用,数据都是最新的。 如果查询到的数据并不是最新的,就是因为Eureka的自我保护模式导致的
3.Eureka本质上是一个工程,而ZooKeeper只是一个进程
4.Eureka可很好的应对因网络故障导致部分节点失去联系的情况,而不会像ZooKeeper一样使得整个注册系统瘫痪
5.ZooKeeper保证的是CP,Eureka保证的是AP;
网关相当于一个网络服务架构的入口,所有网络请求必须通过网关转发到具体的服务。
统一管理微服务请求,权限控制、负载均衡、路由转发、监控、安全控制黑名单和白名单等。
Zuul是对SpringCloud提供的成熟对的路由方案,他会根据请求的路径不同,网关会定位到指定的微服务,并代理请求到不同的微服务接口,他对外隐蔽了微服务的真正接口地址。 三个重要概念:动态路由表,路由定位,反向代理。
1)动态路由表:Zuul支持Eureka路由,手动配置路由,这俩种都支持自动更新
2)路由定位:根据请求路径,Zuul有自己的一套定位服务规则以及路由表达式匹配
3)反向代理:客户端请求到路由网关,网关受理之后,在对目标发送请求,拿到响应之后在给客户端,它可以和Eureka,Ribbon,Hystrix等组件配合使用。
对外暴露,权限校验,服务聚合,日志审计等
网关是对所有服务的请求进行分析过滤,过滤器是对单个服务而言。
Nginx、Zuul、Gateway
Zuul是java语言实现的,主要为java服务提供网关服务,尤其在微服务架构中可以更加灵活的对网关进行操作。Nginx是使用C语言实现,性能高于Zuul,但是实现自定义操作需要熟悉lua语言,对程序员要求较高,可以使用Nginx做Zuul集群。
Zuul是SpringCloud集成的网关,使用Java语言编写,可以对SpringCloud架构提供更灵活的服务。
考虑到API接口的分类可以将API接口分为开发API接口和内网API接口,内网API接口用于局域网,为内部服务器提供服务。开放API接口用于对外部合作单位提供接口调用,需要遵循Oauth2.0权限认证协议。同时还需要考虑安全性、幂等性等问题。
crun():过滤器的具体业务逻辑
shouldFilter():判断过滤器是否有效
filterOrder():过滤器执行顺序
filterType():过滤器拦截位置
通过path配置拦截请求,通过ServiceId到配置中心获取转发的服务列表,Zuul内部使用Ribbon实现本地负载均衡和转发。
使用Nginx的upstream设置Zuul服务集群,通过location拦截请求并转发到upstream,默认使用轮询机制对Zuul集群发送请求。
SpringCloudGateway是SpringCloud官方推出的第二代网关框架,取代Zuul网关。网关作为流量的,在微服务系统中有着非常作用,网关常见的功能有路由转发、权限校验、限流控制等作用。使用了一个RouteLocatorBuilder的bean去创建路由,除了创建路RouteLocatorBuilder可以让你添加各种predicates和filters,predicates断言的意思,顾名思义就是根据具体的请求的规则,由具体的route去处理,filters是各种过滤器,用来对请求做各种判断和修改。
Feign 是一个声明web服务客户端,这使得编写web服务客户端更容易将我们需要调用的服务方法定义成抽象方法保存在本地就可以了,不需要自己构建Http请求了,直接调用接口就行了,不过要注意,调用方法要和本地抽象方法的签名完全一致。
Feign
RestTemplate
Ribbon
调用方式同:Ribbon需要我们自己构建Http请求,模拟Http请求然后通过RestTemplate发给其他服务,步骤相当繁琐而Feign则是在Ribbon的基础上进行了一次改进,采用接口的形式,将我们需要调用的服务方法定义成抽象方法保存在本地就可以了,不需要自己构建Http请求了,直接调用接口就行了,不过要注意,调用方法要和本地抽象方法的签名完全一致。
简单来说: 先将集群,集群就是把一个的事情交给多个人去做,假如要做1000个产品给一个人做要10天,我叫10个人做就是一天,这就是集群,负载均衡的话就是用来控制集群,他把做的最多的人让他慢慢做休息会,把做的最少的人让他加量让他做多点。在计算中,负载平衡可以改善跨计算机,计算机集群,网络链接,中央处理单元或磁盘驱动器等多种计算资源的工作负载分布。负载平衡旨在优化资源使用,最大化吞吐量,最小化响应时间并避免任何单一资源的过载。使用多个组件进行负载平衡而不是单个组件可能会通过冗余来提高可靠性和可用性。负载平衡通常涉及专用软件或硬件,例如多层交换机或域名系统服务器进程。
Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法;Ribbon客户端组件提供一系列完善的配置项,如连接超时,重试等。简单的说,就是在配置文件中列出后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随即连接等)去连接这些机器。我们也很容易使用Ribbon实现自定义的负载均衡算法。(有点类似Nginx)
Nginx是反向代理同时可以实现负载均衡,nginx拦截客户端请求采用负载均衡策略根据upstream配置进行转发,相当于请求通过nginx服务器进行转发。Ribbon是客户端负载均衡,从注册中心读取目标服务器信息,然后客户端采用轮询策略对服务直接访问,全程在客户端操作。
Ribbon使用discoveryClient从注册中心读取目标服务信息,对同一接口请求进行计数,使用%取余算法获取目标服务集群索引,返回获取到的目标服务信息。@LoadBalanced注解的作用开启客户端负载均衡。
当一个服务调用另一个服务由于网络原因或自身原因出现问题,调用者就会等待被调用者的响应;当更多的服务请求到这些资源导致更多的请求等待,发生连锁效应(雪崩效应)。
断路器有三种状态
1)打开状态:一段时间内 达到一定的次数无法调用 并且多次监测没有恢复的迹象 断路器完全打开 那么下次请求就不会请求到该服务;
2)半开状态:短时间内 有恢复迹象 断路器会将部分请求发给该服务,正常调用时断路器关闭;
3)关闭状态:当服务一直处于正常状态 能正常调用;
Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等。当某个服务单元发生故障之后,熔断器会向调用方返回一个符合预期的、可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要地占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩,以提高分布式系统的弹性。5秒内20次调用失败就会启动熔断机制。熔断机制的注解是@HystrixCommand。
服务降级:接口调用失败就调用本地的方法返回一个空
服务熔断:接口调用失败就会进入调用接口提前定义好的一个熔断的方法,返回错误信息
服务隔离:隔离服务之间相互影响
服务监控:在服务发生调用时,会将每秒请求数、成功请求数等运行指标记录下来。
雪崩效应是在大型互联网项目中,当某个服务发生宕机时,调用这个服务的其他服务也会发生宕机,大型项目的微服务之间的调用是互通的,这样就会将服务的不可用逐步扩大到各个其他服务中,从而使整个项目的服务宕机崩溃.发生雪崩效应的原因有以下几点
1)单个服务的代码存在bug.
2)请求访问量激增导致服务发生崩溃(如大型商城的枪红包,秒杀功能).
3)服务器的硬件故障也会导致部分服务不可用.
一般使用使用Hystrix框架,实现服务隔离来避免出现服务的雪崩效应,从而达到保护服务的效果。当微服务中,高并发的数据库访问量导致服务线程阻塞,使单个服务宕机,服务的不可用会蔓延到其他服务,引起整体服务灾难性后果,使用服务降级能有效为不同的服务分配资源,一旦服务不可用则返回友好提示,不占用其他服务资源,从而避免单个服务崩溃引发整体服务的不可用.
因为Tomcat默认情况下只有一个线程池来维护客户端发送的所有的请求,这时候某一接口在某一时刻被大量访问就会占据tomcat线程池中的所有线程,其他请求处于等待状态,无法连接到服务接口。
1)服务降级:当客户端请求服务器端的时候,防止客户端一直等待,不会处理业务逻辑代码,直接返回一个友好的提示给客户端。
2)服务熔断是在服务降级的基础上更直接的一种保护方式,当在一个统计时间范围内的请求失败数量达到设定值(requestVolumeThreshold)或当前的请求错误率达到设定的错误率阈值(errorThresholdPercentage)时开启断路,之后的请求直接走fallback方法,在设定时间(sleepWindowInMilliseconds)后尝试恢复。
3)服务隔离就是Hystrix为隔离的服务开启一个独立的线程池,这样在高并发的情况下不会影响其他服务。服务隔离有线程池和信号量两种实现方式,一般使用线程池方式。
Hystrix实现服务降级的功能是通过重写HystrixCommand中的getFallback()方法,当Hystrix的run方法或construct执行发生错误时转而执行getFallback()方法。
SpringCloudBus就像一个分布式执行器,用于扩展的SpringBoot应用程序的配置文件,但也可以用作应用程序之间的通信通道;
SpringCloudBus 不能单独完成通信,需要配合MQ支持;
SpringCloudBus一般是配合SpringCloudConfig做配置中心的;
SpringCloudConfig实时刷新也必须采用SpringCloudBus消息总线;
SpringCloud Config为分布式系统中的外部配置提供服务器和客户端支持,可以方便的对微服务各个环境下的配置进行集中式管理。Spring CloudConfig分为ConfigServer和ConfigClient两部分。ConfigServer负责读取配置文件,并且暴露Http API接口,ConfigClient通过调用ConfigServer的接口来读取配置文件。
Apollo、ZooKeeper、SpringCloudConfig。
动态变更项目配置信息而不必重新部署项目。
SpringCloudConfig实时刷新采用SpringCloudBus消息总线。