springcloud学习网站:
https://springcloud.cc/spring-cloud-netflix.html
中文API文档:https://springcloud.cc/spring-cloud-dalston.html
SpringCloud中国社区:http://springcloud.cn
SpringCloud中文网:https://springcloud.cc
Eureka
- 介绍:Eureka是Netflix的一个子模块,是核心模块之一。eureka是基于Rest的服务,用于服务注册与发现,对微服务很重要。有了服务注册与发现,只需要使用服务的标识符就可以访问到服务,而不需要修改服务调用的配置文件,功能类似于Dubbo的注册中心,比如Zookeeper。
- 原理:CAP原则
C - consistency 强一致性 A - availability 可用性 P - partition tolerance 分区容错性
根据CAP原则分成了三大类:CA原则,CP原则 和 AP原则。
CA - 单点集群,满足一致性,可用性,通常在可拓展性上不太强大
CP - 满足一致性,分区容错性的系统,通常性能不是特别的高
AP - 满足可用性,分区容错性,通过对数据一致性要求低一些。
所以,分布式系统考虑到集群的拓展,只能选择CP 或者 AP 。
Zookeeper 保证CP
当向注册中心查询服务列表时,我们可以容忍注册中心返回的是几分钟以前的注册信息,但不能接受服务直接挂掉,调不可用,也就是说,服务注册功能对可用性的要求高于一致性。
但是zk会出现这样一种情况,当master主节点因为网络故障与其他节点失去联系时,剩余节点会重新进行leader选举,问题在于选举leader的时间太长,30~120s且选举期间整个zk集群都是不可用的。这就导致在选举期间注册服务瘫痪,在云部署的环境下,因网络问题使得zk集群失去master节点很大概率会发生的事情。虽然服务能够最终恢复,但是漫长的选举时间导致的注册长期不可用时不能容忍的。
Eureka 保证AP
eureka 看明白了这一点,因此在设计时就先保证可用性。Eureka各个节点都是平等的,几个节点挂掉不会影响正常节点的工作,剩余的节点依然可以提供注册和查询服务。而eureka客户端再向某个eureka服务端注册时如果发现连接失败,则会自动切换至其他节点。只要有一台eureka server 是ok的,就能保证服务可用(保证服务可用)。只不过查询到的信息可能不是最新的(不保证强一致性)。除此之外,eureka还有一种自我保护机制,如果在15分钟内超过85%的节点都没有正常的心跳,那么eureka就认为客户端与注册中心出现了网络故障,此时会出现如下几种情况:
1、eureka 不会从注册列表中移除因为长时间没收到心跳而应该过期的服务。
2、eureka 仍然能够接受新服务的注册和查询请求,但是不会被同步到其他节点上(即保证当前节点依然可用)
3、当网络稳定时,当前实例新的注册信息会被同步到其他节点中,因此,eureka可以很好的应对网络故障导致部分节点失去联系的情况而不会像zk那样使整个注册服务瘫痪。
- 实现需要的东西
1、Eureka依赖:spring-cloud-starter-eureka-server
spring-cloud-starter-eureka
2、Eureka配置:
#Eureka配置
eureka:
instance:
hostname: eureka7001.com #Eureka服务端的实例名称
client:
register-with-eureka: false #表示是否向eureka注册中心注册自己
fetch-registry: false #fetch-registry如果为false,则表示自己为注册中心
service-url: #监控页面~
#单机:defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
#集群(关联):
defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
#Eureka的配置,说明服务注册到哪里
eureka:
client:
service-url:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
instance:
instance-id: springcloud-provider-dept8002 #修改Eureka上的默认描述信息
3、使用注解:
@EnableEurekaServer //EnableEurekaServer 服务端的启动类,可以接受别人注册进来
@EnableEurekaClient //在服务启动后,自动注册到Eureka中
Ribbon
- 介绍
属于进程内负载均衡。Ribbon是Netflix发布的云中间层服务开源项目,其主要功能是提供客户端实现负载均衡算法。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说,Ribbon是一个客户端负载均衡器,我们可以在配置文件中Load Balancer后面的所有机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器,我们也很容易使用Ribbon实现自定义的负载均衡算法。
Ribbon是一个为客户端提供负载均衡功能的服务,它内部提供了一个叫做ILoadBalance的接口代表负载均衡器的操作,比如有添加服务器操作、选择服务器操作、获取所有的服务器列表、获取可用的服务器列表等等。 - 实现需要的东西
1、Ribbon依赖:spring-cloud-starter-ribbon
2、Ribbon配置:获取eureka服务就行
#Eureka配置
eureka:
client:
register-with-eureka: false #不向Eureka中注册自己
service-url:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
3、使用注解
@RibbonClient(name = "SPRINGCLOUD-PROVIDER-DEPT",configuration = KuangRule.class)
@LoadBalanced //Ribbon -- 配置负载均衡实现RestTemplate
Ribbon和Feign
- Feign和Ribbon同样是用于客户端负载均衡,但是实现方式有所不同。
Ribbon是在resttemplate通过 微服务标识名 调用微服务访问,Feign是通过 接口和注解 调用微服务访问。
Feign使用到的注解:
@FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT",fallbackFactory = DeptClientServiceFallbackFactory.class) @EnableFeignClients(basePackages = "com.kuang.springcloud")
- 在Feign的实现下,我们只需要创建一个接口并使用注解的方式来配置它(类似于以前Dao接口上标注Mapper注解,现在是一个微服务接口上面标注一个Feign注解),即可完成对服务提供方的接口绑定,简化了使用spring cloud Ribbon时,自动封装服务调用客户端的开发量。
- Feign集成了Ribbon,利用Ribbon维护了微服务的服务列表信息,并且通过轮询实现了客户端的负载均衡,而与Ribbon不同的是,通过Feign只需要定义服务绑定接口且以声明式的方法实现了服务调用。
Hystrix
- Hystrix是一个用于处理分布式系统的延迟和容错的开源库。在分布式系统中,许多依赖不可避免的会调用失败,比如超时、异常等,Hystrix能够保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。
当某个微服务单元发生故障之后,通过Hystrix的故障监控,向调用方返回一个服务预期、可处理的备选响应(FallBack),而不是长时间的等待或抛出调用方法无法处理的异常,这样就保证了服务调用方的线程不会被长时间的占用,从而避免了故障在分布式系统中的蔓延。 - 服务熔断和服务降级
服务熔断:服务端~ 某个服务超时或者异常,引起熔断(熔断会触发备用方法,为客户端返回错误提示信息)。
服务降级:客户端~ 如果客户对某个服务的访问量突然增大,从整体网站请求负载考虑,会将访问量少的服务停掉,将资源都用在访问多的服务上。此时在请求停掉服务的客户端,准备一个FallbackFactory,返回一个默认值(缺省值)。如此虽然整体的服务水平下降了,但是都好歹能用~ - Hystrix实现需要的
需要的依赖:
spring-cloud-starter-hystrix
spring-cloud-starter-hystrix-dashboard
需要的注解:
@EnableCircuitBreaker //服务提供端添加对熔断(Hystrix)的支持
//服务提供端启动类增加一个Servlet
@Bean
public ServletRegistrationBean hystrixMetricsStreamServlet(){
ServletRegistrationBean registrationBean = new ServletRegistrationBean(new HystrixMetricsStreamServlet());
registrationBean.addUrlMappings("/actuator/hystrix.stream");
return registrationBean;
}
@EnableHystrixDashboard //开启客户端监控,与服务端监控actuator搭配使用
Zuul
- Zuul提供了代理、路由、过滤三大功能,对请求的路由和过滤是两个最主要的功能。其中路由功能负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础。而过滤器功能则负责对请求的处理过程进行干预,是实现请求校验,服务聚合等功能的基础。Zuul和Rureka进行整合,将Zuul自身注册为Eureka服务治理下的应用,同时从Eureka中获得其他微服务的消息,使以后对微服务的访问都是通过Zuul跳转后获得。
- Zuul实现需要的
所需依赖:spring-cloud-starter-zuul
所需配置:
zuul:
routes:
mydept.serviceId: springcloud-provider-dept
mydept.path: /mydept/**
ignored-services: springcloud-provider-dept #忽略此路径,不能使用此路径访问了
# ignored-services: "*" 忽略全部真实路径
prefix: /kuang #设置公共的前缀
所需注解:@EnableZuulProxy //启动类处启动网关Zuul
RestTemplate
- GET 请求
在 RestTemplate 中,和 GET 请求相关的方法有如下几个:
这里的方法一共有两类,getForEntity 和 getForObject,每一类有三个重载方法。
getForEntity
既然 RestTemplate 发送的是 HTTP 请求,那么在响应的数据中必然也有响应头,如果开发者需要获取响应头的话,那么就需要使用 getForEntity 来发送 HTTP 请求,此时返回的对象是一个 ResponseEntity 的实例。这个实例中包含了响应数据以及响应头。
getForObject
getForObject 方法和 getForEntity 方法类似,getForObject 方法也有三个重载的方法,参数和 getForEntity 一样,因此这里我就不重复介绍参数了,这里主要说下 getForObject 和 getForEntity 的差异,这两个的差异主要体现在返回值的差异上, getForObject 的返回值就是服务提供者返回的数据,使用 getForObject 无法获取到响应头。 - POST 请求
和 GET 请求相比,RestTemplate 中的 POST 请求多了一个类型的方法,如下:
postForEntity
在 POST 请求中,参数的传递可以是 key/value 的形式,也可以是 JSON 数据。postForEntity 方法第一个参数是请求地址,第二个参数 map 对象中存放着请求参数 key/value,第三个参数则是返回的数据类型。当然这里的第一个参数 url 地址也可以换成一个 Uri 对象,效果是一样的。**POST请求中,当第二个参数类型为 MultiValueMap 的实例时以 key/value 的形式发送,如果是一个普通对象,则会被转成 json 发送。**在 post 请求中,也可以按照 get 请求的方式去传递 key/value 形式的参数,传递方式和 get 请求的传参方式基本一致。
postForObject
postForObject 和 postForEntity 基本一致,就是返回类型不同而已。
postForLocation
postForLocation 方法的返回值是一个 Uri 对象,因为 POST 请求一般用来添加数据,有的时候需要将刚刚添加成功的数据的 URL 返回来,此时就可以使用这个方法,一个常见的使用场景如用户注册功能,用户注册成功之后,可能就自动跳转到登录页面了,此时就可以使用该方法。
注意:postForLocation 方法返回的 Uri 实际上是指响应头的 Location 字段,所以,provider 中 register 接口的响应头必须要有 Location 字段(即请求的接口实际上是一个重定向的接口),否则 postForLocation 方法的返回值为null。