spring cloud netflix 组件小结

spring cloud netflix 组件小结

本文实践代码托管在:https://github.com/leishiguang/spring-cloud-demo

eureka 服务注册与发现

嗯,先说说注册中心,假如没有注册中心,如何管理多个服务?我们可能会在客户端提前配置服务端的地址。

但这样,没有注册中心,带来的问题有:

  1. 无法监控服务提供方的健康情况,接口服务器可能不固定,可能随时增删机器;
  2. 接口调用方无法知晓提供方的具体 ip 和 port 地址,除非手动调整接口调用者的代码;

那么,注册中心的存在意义,就是为了:

  1. 服务方当前是什么状态,是否健康?
  2. 服务方的地址有没有迁移,最新的是什么?
  3. 让修改客户端服务方列表的过程,变成自动进行;

这也是 eureka 的作用,它的执行流程如:
在这里插入图片描述
流程说明:

  1. 服务提供者启动时,定时向 EurekaServer 注册自己的服务信息(服务名、IP、端口…等等)
  2. 服务消费者启动时,后台定时拉取 EurekaServer 中存储的服务信息

集成和配置的一些 tips:

  1. 引入 spring-boot-starter-actuator,用以监控 spring boot 的一些端点;
  2. 引入 spring-boot-starter-web,可以通过 http 方式访访问监控主页;
  3. 引入 spring-cloud-starter-netflix-eureka-server,这样就有了 eureka 核心组件,就可以具有 eureka server 功能,供其它客户端进行接入了;
  4. 在启动类添加 @EnableEurkaServer 注解,这时就会自动的读取 EurekaServerMarkerConfiguration.class 配置,帮助我们实例化 eureka 服务;
  5. 在配置文件中执行 eureka 的相关配置,这就有许多了,常用比如:
spring.application.name,服务名称
server.port,服务端口
eureka.instance.hostname,当前实例名称
eureka.instance.intance-id,实例的id
eureka.client.fetch-registry,是否要拉取 eureka 的服务列表?
eureka.client.register-with-eureka,是否要把自己注册在eureka?
eureka.client.service-url.defalutZone,要选择的注册中心?

eureka.server.wait-time-in-ms-when-sync-empty,服务要同步数据的等待时间
eureka.server.enable-self-reservation,自我保护机制,是不是防止网络颤动时的服务下线,这一步虽然确保了自身的健壮性,但可能会保留已宕机的服务,好在有别的组件弥补了这部分的不足
eureka.server.peer-eureka-nods-update-interval-ms,服务同步时间,可以稍微设置长一些,因为我们不需要它那么快速的去同步

defaultZone 是一个区域的概念,可以指定对应的地区,比较适用于较大范围的服务器,这样客户端会优先调用同地区的服务,比如这么一个配置:

eureka.client.service-url.defalutZone = http://localhost:10000/eureka
eureka.client.service-url.zone1 = http://localhost:10002/eureka
eureka.client.availability-zones.china
:zone1

这样,在 china 节点,就会优先调用 10002 上注册的服务,如果调用不到,才会调用 10000 上注册的

嗯,顺利启动之后,便可以在配置好的服务地址,看到服务信息哦,如:
在这里插入图片描述
这时,只是 eureka 服务端启动了,如果要进行服务,还需要有:

  1. 服务提供方,即 eureka 服务节点
  2. 服务调用方,就是客户端,要发起服务的调用

那么,eureka 客户端的集成:

  1. 客户端引入 spring-cloud-starter-netfilx-eureka-client,便可以连接已存在的 eureka 服务,进行服务注册或者服务调用;
  2. 服务方注意配置 spring-application.name 服务名称
  3. 配置 eureka.client.service-url.defaultZone,或是其它的注册中心,把自己提供的服务,注册到 eureka 中去。服务调用方也这么配置,从该 eureka 中拉取服务
  4. 在调用时,使用 http://服务名/ 替代 ip 和 port,如:
@Autowired
private RestTemplate restTemplate;

@GetMapping("index")
public Object getIndex(){
    return restTemplate.getForObject("http://HELLOSERVER/",String.class,"");
}

那么,eureka 的核心知识有哪些呢?

  1. eureka 如何注册服务?
  2. 如何发现服务?
  3. 服务断开了怎么办?
  4. 服务名是怎么变成 ip+port 呢?
  5. 自我保护机制,网络颤动怎么办?
    在这里插入图片描述
    hashMap 保存服务信息之后,再拦截对应的服务调用,替换为具体的服务实例~

详细源码解析,下回分解 ?

ribbon 客户端负载均衡

前面说到,eureka 中,当服务提供方有多个的时候,要按什么样的规则去调用呢?

好比 nginx 可以对请求进行分流。当请求已经进入服务端之后,该服务端又要作为服务的调用方,去调用其它服务。这时候,要怎么做负载均衡呢?

这就是 ribbon 为我们做的事情,客户端负载均衡。

如何集成呢?这儿先看看如何在脱离 eureka 的情况下,进行 ribbon 负载均衡…

  1. 引入 spring-cloud-starter-netflix-ribbon,之后开始配置…
  2. (注意这儿没有与 eureka 集成)改造配置,声明可负载均衡的服务列表,声明 @RibbonClients 注解,声明 @LoadBlance 注解,调用时使用 LoadBanlancerClient,具体的配置看之后的代码示例咯…
  3. 通过 RibbonLoadBlanceClient 的 choose 方法获取到服务实例
  4. 通过服务实例得到的 ip + port 去调用服务…

那么,这里涉及到的 ribbon 核心知识:

  1. ribbon的结构和初始化过程?
  2. 如何发现有哪些服务实例?
  3. 怎么实现负载均衡策略?
  4. 容错机制有吗?

源码解析的部分靠后,这儿先简单的概括一些:
在这里插入图片描述

  • RibbonAutoConfiguration:自动装配
  • LoadBlancerClient:定义了各种方法,如 URL 获取,服务实例选择等。默认是 RibbonLoadBalancerClient
  • SpringClientFactory:内部包含了各种获取对象,如 loadbalancer、instance 等方法

ribbon 中,如果要自定义策略,实现 IRule 接口即可,官方提供了这么些负载均衡策略:
在这里插入图片描述
嗯,Ribbon 与 RestTemplate,前面介绍时,使用的是 LoadBanlancerClient,实际上,Ribbon 可以与 RestTemplate 很好的结合:

@Bean
@LoadBalanced
public RestTemplate template(){ return new RestTemplte() }

这样,就可以和 eureka 一样,通过服务名进行调用了。
详细源码解析,下回分解 ?

hystrix 服务容错机制

在微服务中,一个请求有可能是多个微服务协同处理的,多个微服务相互依赖。这时候,如果某个服务超时、网络不通,导致调用者阻塞,怎么办?总不能够全部的请求都积压在这一个服务上,占用大量资源,导致系统雪崩吧?

那,如何保护系统呢?一个服务不能用就不能用,不能因为这样,全盘系统都不能用了。

于是:

  1. 服务限流:服务消费者限制自身对某一服务能够发起的并发请求数量,超过数量则不调用;
  2. 熔断状态:熔断状态下,服务消费者不会发起对某一服务的调用;
  3. 服务降级:请求异常情况下,程序执行指定的降级策略(有点儿类似于异常捕获的catch代码块)

好比,在使用淘宝时,如果请求太大,会提示:服务忙,请稍后再试。

嗯,这三个东西要自己实现,还是有些麻烦的。那么,hystrix 就是现成可用的。

如何集成?

  1. 引入 spring-cloud-starter-netflix-hystrix 依赖
  2. 创建一个类继承 HystrixCommand,重写 fallback 方法;或者使用注解来进行配置…
  3. 通过这个类去代理相关请求;
  4. 出现问题后执行 fallback;

这儿要注意,熔断是在服务调用者端进行设计哦…

具体的配置,还参考示例…

那么,关于 hystrix 的核心:

  1. hystrix 资源隔离的思想
  2. 初始化流程
  3. 执行流程
  4. 和 spring cloud 集成
  5. hystrix 的监控 dashboard

在这里插入图片描述在这里插入图片描述
具体原理,下回分解咯 ?

feign 声明式接口调用

用 RestTemplte 可能还有些不顺手,那么,是不是可以有类似于普通的 java 接口调用呢?这就是 Feign 的来源了,它让 web 接口调用和普通 java 接口一样便携。

spring cloud 对 Feign 的增强和改造:

  1. 将 Spring MVC 的注解与 Feign 客户端的定义进行了结合;
  2. 支持使用 Spring Web 中的 HttpMessageConverters 对请求和响应进行编解码工作。

那么,要怎么使用(集成)呢?

  1. 引入 spring-cloud-starter-openfeign 依赖;
  2. 启动类中添加 @EnableFeignClients 注解;
  3. 定义一个接口,加上 @FeignClient 注解,把每个要 http 请求的方法,用接口方法替代;
  4. 在需要用 restTemplate 的地方,改用定义好的接口方法;

tips:在定义接口的时候,也可以与 hystrix 集成,添加 fallback 哦,在配置文件中加入 feign.hystrix.enabled=true 即可,具体的参见代码实践…

关于 Feign 的使用,接口定义的示例:

@Component
@FeignClient(name="helloserver",fallback = HelloDemoFallback.class)
public interface HelloDemoService {

    @RequestMapping(value = "",method = RequestMethod.GET)
    public String index();
}

使用示例:

@RestController
public class CustomerController {

    @Autowired
    HelloDemoService helloDemoService;


    @GetMapping("index")
    public Object getIndex(){
        return helloDemoService.index();
     }
}

那么,核心原理,比如如何初始化?
在这里插入图片描述
其本质是使用 FeignClientFactoryBean 生成代理对象,并交给 spring 托管…

zuul 微服务网关

后端的服务提供者越来越多了,各个服务者之间调用倒是挺开心的。但是,对于外部来说呢?

  • 外部客户端种类多,可能就没有集成服务注册发现的机制,无法发现服务;
  • 出于安全和 ip 资源考虑,服务提供方的地址并不会直接对公网进行开放;
  • 安全认证方面,是不是每个服务都需要实现权限认证呢…

zuul 网关应运而生,专门用以解决类似于上述典型问题。所有的外部请求先通过这个微服务网关,客户端只和网关进行交互,然后由网关进行各个微服务的调用。

这个过程就有点儿类似于 nginx 了,而它的特性有:

  1. 统一接入:为各种应用提供统一接入服务,高性能,高并发,高可靠,负载均衡,容灾切换;
  2. 协议适配:适配前端系统(http,websocket),后端业务系统 RPC,长短连接都支持。依据前端请求路由到相应的服务执行,并返回结果;
  3. 流量管控:限流、熔断、降级,路由一切容灾切换的应用;
  4. 安全防护:IP 黑名单,URL 黑名单,权限校验,防刷,恶意攻击等…

如果把整个微服务当作我们的家,网关就相当于是大门。

这儿容灾切换,指的是异地存在多个服务器,比如华南区、华北区,这种如果有一个区域宕机了,将自动把服务切换过去。尽量减少一个区域崩了之后,就完全无法用了。

zuul 本质上就是一个 web 应用,是一个 API Gateway 服务器。zuul 可以提供动态路由,监控,弹性,安全等边缘服务的框架。相当于是服务和所有 web 请求的大门。

zuul 能做什么?

  1. 认证和安全:识别每个需要认证的资源,拒绝不符合要求的请求;
  2. 性能监测:追踪并统计数据,提供精确的运行时状态数据;
  3. 动态路由:根据需要将请求动态路由(转发)到后端集群;
  4. 静态资源处理:直接负载均衡,预先为每种类型的请求分配容量,当请求超过容量时自动丢弃。

如何使用(集成)呢?

  1. 引入 spring-cloud-starter-netflix-zuul 相关依赖;
  2. 在启动类中添加 @EnableZuulProxy 注解开启 zuul 网关代理功能;或者添加 @EnableZuulServer 开启非代理模式的网关服务。
@EnableZuulProxy,实际上也继承了 @EnableZuulServer 的自动装配,扩展了 Server 的功能,主要区别是 Proxy 用动态代理的方式去转发路由。
  1. 配置,除了很通常的端口、应用名、注册中心外。也有 zuul 独有的,如:
zuul.host.connect-timeout-millis: http请求超时时间
zuul.host.socket-timeout-millis:socket请求超时时间
zuul.host.max-total-connections:最大连接数(连接池大小)
zuul.host.max-per-route-connections:每个 host 的最大连接数
zuul.ribbon-isolation-strategy: 隔离模式
zuul.semaphore.max-semaphores:最大并发数
zuul.routes... 路由配置

那么,zuul 的核心知识:

  1. zuul 的初始化和执行流程

  2. zuul 的路由定位流程

  3. .http 的执行流程

  4. 拓展应用:用户登陆,权限校验
    在这里插入图片描述
    三大类的 filter:

  5. 前置 filters,

  6. routing filters,用来执行请求,比如用 ribbon 封装,就是有一个 ribbon 的 routing filters。

  7. post filters,在请求之后执行,用于返回数据。

  8. 通常,如果有任意 filter 出错了,都会进到 error filter。

zuul 的初始化过程:
在这里插入图片描述
zuul 的 filter 执行流程:
在这里插入图片描述
zuul 的路由定位流程:
在这里插入图片描述
zuul 的请求流程:
在这里插入图片描述
具体的源代码分析,下回分解咯~
如果要扩展 zuul 功能,比如登陆验证,就看实践代码…

代码示例

一次完整的 spring cloud demo 实战,跳转 https://github.com/leishiguang/spring-cloud-demo

目前正在不断完善中…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值