SpringCloud(上)

80 阅读9分钟
  • Spring cloud
  • 一站式微服务解决方案
  • 单体、垂直、SOA、微服务
  • 微服务思想优缺点;是SOA的升华,拆分更加细致,整合
  • 优点:
  • 1.很小,便于特定业务功能聚焦
  • 2.便于敏捷开发,小团队合作实施
  • 3.便于重用和模块之间的组装
  • 4.可以用不同语言开发
  • 5.更容易引入新技术
  • 6.更好实现Devops开发运维一体化
  • 缺点:
  • 1.分布式复杂难以管理,服务数量增加,维护困难
  • 2.分布式链路难以跟踪
  • spring cloud是一系列框架的集合(一种规范):
  • 服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等
  • 利用spring boot开发便利性简化了微服务架构的开发
  • 第一代(SCN是netflix公司)
  • Eureka/Ribbon/Hystrix/Spring Cloud Config/Feign/Stream/Sleuth/Zipkin
  • 第二代(SCA阿里巴巴)
  • Nacos/Dubbo LB/Sentinel/Gateway/Nacos/Apollo/Dubbo RPC/seata
  • 体系结构:
  • API调用-》API网关-》熔断/Feigin/Ribbon-》服务(注册服务,配置中心、接收消息更新配置)
  • RestTemplate可以调用rest远程接口
  • 案例问题分析:
  • 1.url硬编码(服务自动注册与发现)
  • 2.服务提供者只有一个,需要消费者自己实现负载均衡(负载均衡)
  • 3.消费者不清楚提供者的状态(熔断)
  • 4.如果服务异常无法及时发现(熔断)
  • 5.RestTemplate是否有优化空间,能否像DUBBO一样(远程过程调用)
  • 6.多服务统一认证如何实现(统一认证)
  • 7.配置文件(配置中心)
  • 。。。
  • Spring Cloud核心组件
  • Feign(远程调用)=(RestTemplate+Ribbon+Hystrix)
  • 注册中心对比
  • poll模式(主动拉取)和push模式(推送)(ZK)
  • Zookeeper是CP
  • Nacos支持AP/CP切换
  • Eureka(AP)注册中心
  • poll模式
  • 基础架构:
  • 消费者(定期拉取服务列表)《=注册中心(server:需要自己创建工程启动)《=服务提供者(注册,renew心跳)
  • 消费者=>调用服务提供者
  • 主要包含两个组件Server(集群)和Client
  • 服务提供者默认每隔30s续约一次。如果90s没有续约则剔除,client会缓存server的信息,即使所有的server都宕机,也可以从缓存中获取
  • Eureka应用和高可用
  • 引入spring cloud综合版本依赖
  • 引入eureka-server依赖(JDK9之后要引入jaxb依赖)
  • 配置yml文件,启动类加@Eureka的注解
  • client配置
  • prefer-ip-address:显示ip,为了兼容
  • instance-id:实例名称
  • Eureka元数据
  • 1.标准元数据:如主机名、Ip端口等
  • 2.自定义元数据:
  • metadata-map:可以在调用时获取自定义元数据
  • Eureka服务端自我保护
  • 假如服务提供者与注册中心网络有问题,不一定提供者不可用,15分钟内85%节点都没有正常心跳,就会进入自我保护机制,此时不会剔除提供者,任然可以接受新服务的注册,但是不会同步
  • Eureka源码解析:
  • Server启动过程
  • 1.利用SpringBoot自动装配EurekaServerAutoConfiguration自动配置类
  • 容器中需要有Market这个bean,是由@EnableEurekaServer来注入的
  • 配置类注入一个Controller接口(后台界面)
  • PeerAwareInstanceRegistry(集群模式下的注册器,所有服务器都是对等的)
  • PeerEurekaNodes(辅助封装对等节点相关的信息)
  • SmartLifecycle在Spring的Bean创建完成后做一些事情(start方法)
  • EurekaServerBootstrap的initEurekaServerContext方法
  • 为非ioc容器提供获取serverContext对象的接口
  • 某一个server实例启动的时候,从集群其他的server靠背注册信息过来,每一个server对弈其他server来说也是客户端
  • 更改实例状态为UP,对外提供服务,启动定时器,默认每隔
  • 秒剔除
  • 注册实例,存放注册表
  • Server服务暴露策略
  • 1.启动过程中注册了jersey框架,类似MVC框架
  • 配置Jersey注解
  • 设置Path(类似于requestmapping
  • 扫描包以及子包(类似于companent-scan),例如ApplicationResource
  • 2.ApplicationResource.addInstance注册实例接口
  • 3.同步实例信息到对等节点
  • Server服务续约
  • 1.InstanceResource.renewLease接口
  • 本地renew操作
  • 同步u到其他peer节点
  • Client客户端初始化
  • 1.EurekaClientAutoConfiguration自动配置类
  • 自动装配会自动注入一个maker所以可以不加注解
  • 2.读取配置文件
  • 3.注册自己到EurekaServer
  • eurekaClient方法实例化客户端对象,返回CloudEurekaClient
  • 从注册中心获取服务实例列表
  • 注册自己到注册中心(向server端发起rest请求,使用jersey发起addInstance)
  • 4.开启定时任务(心跳续约)
  • 服务下架
  • eurekaClient方法注解,在服务下线的时候调用shutdown方法
  • 关闭监听器,定时任务等。调用server的下架请求
  • Ribbon负载均衡
  • 负载均衡分为服务端负载均衡和客户端负载均衡
  • nginx/f5是服务端负载均衡
  • Ribbon是客户端负载均衡(客户端从注册中心拉到服务列表,根据算法在客户端实现负载均衡)
  • Eureka包含Ribbon的Jar包
  • 在RestTemplate加一个@LoadBalance注解
  • 调用时候直接用服务名,ribbon会自动用负载均衡策略调用
  • 默认是轮询策略
  • RoundRobinRule:轮询
  • RandomRule:随机
  • RetryRule:重试
  • BestAvailabnleRule:最小连接数策略
  • AvailabilityFilteringRule:扩展轮询策略,判断超时和超限
  • ZoneAvoidanceRule:扩展轮询,过滤超时和连接数多的server
  • 修改负载均衡策略
  • ribbon:
  • NFLoadBalancerRuleClassName:XXX
  • 利用拦截器按照负载均衡算法选择服务
  • Ribbon源码:
  • 声明RestTemplate集合,注入所有resttemplate,给resttemplate添加拦截器LoadBalancerInterceptor。
  • Intercept方法:
  • 1.获取uri和host
  • 2.RibbonBalancerClient.excute
  • 获取负载均衡器
  • 通过均衡器选择一个server
  • 封装Ribbon对象执行
  • Hystrix熔断器
  • 针对微服务中的雪崩效应
  • 解决雪崩效应的方案
  • 1.服务熔断
  • @HystrixCommand注解配置响应时长
  • 打开Hystrix功能@EnableHystrix或者@EnableCircuitBreaker
  • 2.服务降级
  • 定义一个降级的方法
  • 添加fallback降级方法配置
  • 3.服务限流
  • Hystrix
  • 包裹请求
  • 跳闸机制
  • 资源隔离
  • 监控
  • 回退机制
  • 自我修复
  • Hystrix舱闭模式:线程池隔离策略
  • 为每个标记@HystrixCommand方法单独配置线程池,避免某个请求过多导致其他服务不可用
  • 添加属性threadPoolKey配置不一样的
  • threadpoolproperties属性coreSize线程数和maxQueueSize等待队列长度
  • Hystrix跳闸和自我修复
  • 时间窗口内(可以配置)
  • 是否达到最小请求数(可以配置)
  • 错误数量是否达到阈值(可以配置)
  • 跳闸后活动窗口(可以配置)
  • http://localhost:8090/actutor/health
  • Hystrix仪表盘:
  • 需要单独创建一个项目
  • 或者/actirtor/hystrix.stream返回数据
  • 服务要注册一个Servlet
  • Hystrix聚合监控(多实例和多服务)
  • 新建引入Turbine项目:收集hystrix数据流
  • 配置文件配置需要聚合的服务名称
  • @EnableTurbine开启聚合功能
  • Hystrix源码
  • @EnablecircuitBreaker
  • SpringFactoryImportSelector父类构造获取子类传递到父类的泛型
  • selectImports加载注解类配置的自动配置类注入
  • HystrixCircuitBreakerConfiguration
  • 注入HystrixCommondAspect切面
  • 获取配置注解的方法属性元数据
  • 创建一个HsytrixyInvokable
  • Feign远程调用组件
  • 可以替代restTemplate远程调用
  • 类似于DUBBO,消费者拿到提供者的接口,像调用本地方法一样远程调用
  • 支持SpringMVC(OpenFeign)
  • 消费者引入openfeign的start依赖
  • @EnableFeignClients开启客户端功能
  • 创建一个接口添加@FeignClient注解配置服务名称
  • 在接口中配置需要调用的http接口
  • Feign对Ribbon负载均衡的支持
  • 默认请求超时时长1秒
  • 可以配置ribbon
  • Feign的日志输出
  • Feign支持Hytix熔断配置:定义一个类实现Client接口
  • GateWay网关组件(取代Zuul)
  • 性能是zuul的1.6倍
  • 有路由(反向代理)、鉴权、流量控制、熔断、路径重写、日志监控等功能
  • 在负载均衡下游
  • 1.路由:由一个id和目标url组成。有一系列断言和过滤器组成匹配路由
  • 2.断言:匹配条件
  • 3.过滤器:切面执行业务逻辑
  • Gateway Client->handler mapping->WebHandler->Filter->Server
  • GateWay内置断言匹配
  • 时间类断言、Cookie类断言、Header断言、Host断言、Method、Path...
  • 动态路由:
  • uri可以配置一个服务注册中心lb://xxxxx
  • 过滤器分为单路由过滤器(GateWayFilter)和全局过滤器(GlobalFilter)
  • 全局过滤器实现GlobalFilter和Orderd(优先级)接口
  • GateWay多实例高可用
  • Nginx代理到多实例GATEWAY服务上
  • Spring Cloud Config分布式配置中心
  • 1.需要自己开发一个项目,发布服务
  • 2.注册到注册中心
  • 配置中心和git或者私服交互
  • @EnabledConfigServer开启配置中心功能
  • 配置文件注册到Eureka
  • 配置仓库信息
  • Config客户单引入依赖,在bootstap.yml中配置
  • cloud.config.name
  • cloud.config.profile
  • xxx
  • 手动刷新配置信息:
  • 配置文件加management.endpoints.web.exposure.include:/refresh
  • management.endpoints.web.exposure.include:'*'
  • 使用类上添加@RefreshScope注解
  • 手动调用refresh接口实现手动刷新
  • 自动刷新配置信息:
  • 1.结合Bus消息总线实现自动更新(支持rabbitMQ和kafka)
  • 2.用zk做配置中心也可以实现存储加通知配置变更
  • 引入bus-amqp的依赖
  • 需要调用一次bus刷新实现所有客户端同步
  • Stream消息驱动组件
  • 解决问题:
  • 屏蔽掉不同MQ消息中间件之间的差异,方便切换
  • 目前支持RabbitMQ和kafka
  • 通过Binder来交换数据,用Intput和output来输入输出消费者和生产者数据
  • 切换不同的MQ只用切换Binder就可以
  • input和output针对应用程序来说的
  • 注解
  • @Input@Output@streamlistener@enablebinding
  • 集群环境下,多台机器重复消费队列数据问题:消费组,同一个消费组串行消费.
  • 分组消费,MQ会持久化数据,消费者宕机期间重启后可以继续消费
  • ****SpringCloud经典问题
  • 1.Eurek服务发现慢的问题:服务上下线感知慢,原因是主动拉取数据有间隔,Server有一级缓存(30s)和二级缓存(180s)
  • 解决方案:
  • 服务端可以缩短缓存刷新事件,可以将只读缓存关闭,客户端可以把拉取时间配置短,
  • 2.组件超时问题:组件过多,多个超时时间。hystrix超时时间大于Ribbon的超时时间
  • pvkxkibfyvexbjcf