用springcloud zuul ribbon集群服务的时候遇到的坑
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用springcloud zuul ribbon集群服务的时候遇到的坑相关的知识,希望对你有一定的参考价值。
参考技术A 使用zuul网关做服务映射的时候,部署了3个相同service 端口分别是:8769 8770 8771 当我们断掉8769服务的时候,ribbon按理说会认定8769断掉了,从而后面的请求不会再命中8769这个服务端口。然而并不是想的那样,还是一样会命中失败的服务。直接跳坑了~做集群映射离不开eureka,以上三个服务都注册在eureka,当8769断掉后,eureka自身有心跳检测,默认是15分钟,如果服务在15分钟内没有响应则认定该服务出现故障,即下线该服务。在这期间ribbon把请求还是一样会均衡各个集群节点,因为它获取节点是否正常是通过eureka中心得到的,所以eureka如果没有下线服务,那么ribbon会一直认为该服务在线。那么这种情况怎么处理呢?
在eureka项目yml 设置eureka.server.enableSelfPreservation = false 关闭自我保护机制
在service项目yml 设置 eureka.instance.leaseRenewalIntervalInSeconds = 5
leaseExpirationDurationInSeconds = 10
Eureka+Feign+Ribbon+Zuul+Hystrix+Config+Bus构建一套SpringCloud项目
Eureka - 注册中心
Eureka是Netflix开发的服务发现框架,SpringCloud将它集成在自己的子项目spring-cloud-netflix中,实现SpringCloud的服务发现功能。Eureka包含两个组件:Eureka Server和Eureka Client。
服务的提供者首先把自身的服务实例注册到server中
服务的消费者去注册中心获取服务列表
消费者调用服务的提供者
在服务启动后,将会向Eureka Server发送心跳,默认周期为30秒,如果Eureka Server在多个心跳周期内没有 接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90 秒)。
搭建EurekaServer微服务
依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
配置
server:
port: 8001
eureka:
client:
register-with-eureka: false #是否将自己注册到Eureka服务中 因为自己本身就是所以无需注册
fetch-registry: false #是否从Eureka中获取注册信息
service-url: #Eureka客户端与服务端进行交互的地址
defaultZone: http://127.0.0.1:${server.port}/eureka/
在启动类上面加入注解@EnableEurekaServer
eureka客户端
依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
配置
eureka:
instance:
true :
client:
:
defaultZone: http://127.0.0.1:8001/eureka/
在启动类上面加入注解@EnableEurekaClient
Feign - 服务调用
Feign用于微服务之间的调用
依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
在调用方的启动类上加注解
但是
public interface UserClient {
public String getUserById( String id);
}
@FeignClient注解用于指定从哪个服务中调用功能 ,注意:里面的名称与被调用的服务 名保持一致,并且不能包含下划线
在这里Feign只有接口,为什么可以使用?原因是自动实现了FeignClient接口
Hystrix - 熔断器
如图,我们发现Feign里面集成了Hystrix:
配置
feign:
hystrix:
enabled: true #启动熔断器
创建熔断的实现类
public class UserClientImpl implements UserClient {
public String getUserById(String id) {
return "系统故障,请稍后重试";
}
}
添加fallback参数,指定其实现类,实现服务降级
@FeignClient(value = "springcloud-user",fallback = UserClientImpl.class)
Ribbon - 负载均衡
如图所示,我们发现Eureka已经集成了Ribbon:
Ribbon默认使用的负载均衡策略是轮询,此外还有随机策略等
Zuul - 网关
为什么需要网关?
如果客户端直接和微服务进行通信,会存在一下问题:
1.客户端会多次请求不同微服务,增加客户端的复杂性
2.存在跨域请求,在一定场景下处理相对复杂
3.认证复杂,每一个服务都需要独立认证
4.难以重构,随着项目的迭代,可能需要重新划分微服务,如果客户端直接和微服务通 信,那么重构会难以实施
5.某些微服务可能使用了其他协议,直接访问有一定困难 上述问题,都可以借助微服务网关解决。
微服务网关是介于客户端和服务器端之间的中间层,所有的外部请求都会先经过微服务网关。
Zuul是Netflix开源的微服务网关,他可以和Eureka,Ribbon,Hystrix等组件配合使 用。Zuul组件的核心是一系列的过滤器,这些过滤器可以完成以下功能:
1. 身份认证和安全: 识别每一个资源的验证要求,并拒绝那些不符的请求
2.审查与监控:在边缘位置追踪有意义的数据和统计结果,从而带来精确的生产视图
3.动态路由:动态将请求路由到不同后端集群
4.压力测试:逐渐增加指向集群的流量,以了解性能
5.负载分配:为每一种负载类型分配对应容量,并弃用超出限定值的请求
6.静态响应处理:边缘位置进行响应,避免转发到内部集群
7.多区域弹性:跨域AWS Region进行请求路由,旨在实现ELB(ElasticLoad Balancing)使 用多样化
整合zuul之后架构图:
依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring‐cloud‐starter‐netflix‐zuul</artifactId>
</dependency>
配置
zuul:
routes:
:
path: /user/** #配置请求url的请求规则
serviceId: springcloud-user #指定Eureka注册中心中的服务id
:
path: /student/**
serviceId: springCloud-student
加入网关之后的授权中心流程
SpringCloud - 集中配置组件
Spring Cloud Config为分布式系统中的外部化配置提供服务器和客户端支持。使用Config Server,您可以集中管理所有环境中应用程序的外部属性。客户端和服务器上的概念与SpringEnvironment和PropertySource抽象,因此它们非常适合Spring应用程序,但可以与以任何语言运行的任何应用程序一起使用。当应用程序从开发人员迁移到测试人员并进入生产过程时,您可以管理这些环境之间的配置,并确保应用程序具有在迁移时需要运行的所有内容。服务器存储后端的默认实现使用git,因此它轻松支持带标签的配置环境版本,并且可以通过各种工具来访问这些内容来管理内容。添加替代实现并将其插入Spring配置很容易。
将微服务中的配置文件提交到代码托管中心,并且删除项目中的配置文件
搭建配置中心微服务
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
启动类添加注解
@EnableConfigServer
配置
spring:
application:
name: eu-config
cloud:
config:
server:
git:
uri:
配置客户端
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring‐cloud‐starter‐config</artifactId>
</dependency>
添加bootstrap.yml
spring:
cloud:
config:
name: user
profile: dev
label: master
uri: http://127.0.0.1:9009
SpringCloudBus - 消息总线
当我们更新了代码托管平台中的配置文件时,我们再去测试,发现并不能立刻更新到代码工程中,只有重新启动程序才会读取配置。那我们如果想在不重启微服务的情况 下更新配置如何来实现呢? 我们使用SpringCloudBus来实现配置的自动更新。
在配置中心微服务加入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-bus</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-binder-rabbit</artifactId>
</dependency>
配置application.yml
spring:
rabbitmq:
host: 192.168.206.133
management: #暴露触发消息总线的地址
endpoints:
web:
exposure:
include: bus-refresh
在客户端添加消息总线
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-bus</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-binder-rabbit</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
在代码托管中心的各个配置文件中添加:
spring:
rabbitmq:
host: 192.168.206.133
以上是关于用springcloud zuul ribbon集群服务的时候遇到的坑的主要内容,如果未能解决你的问题,请参考以下文章
springcloud微服务实战:Eureka+Zuul+Feign/Ribbon+Hystrix Turbine+SpringConfig+sleuth+zipkin
SpringCloud——Eureka Feign Ribbon Hystrix Zuul等关键组件的学习与记录
Eureka+Feign+Ribbon+Zuul+Hystrix+Config+Bus构建一套SpringCloud项目