微服务虽然解决了传统单体式应用各个模块之间强耦合的缺点,但同时也引出了新问题,由于微服务各个服务之间是独立部署的,并且一般情况下一个服务往往会依赖多个其他服务,并且服务之间的调用更多的是依赖不稳定的网路,所以对于微服务架构来说,服务之间相互调用的稳定性就显的更为重要,为了保证系统能更稳定运行,我们常会对服务做一些保护措施,常用的措施有负载均衡、熔断、限流、降级、重试等。

一、  负载均衡

1.概念

1.1.对于负载均衡这个概念我们应该不陌生,负载均衡就是分发请求流量到不同的服务器,负载均衡分为两种:

1.1.1.服务端负载:服务器端负载均衡是对客户透明的,用户请求到LB服务器,真正的Application服务器是由LB服务器分发控制的,目前的实现有软件(ngnix,HA Proxy等)和硬件(F5等)。

1.1.2客户端负载:是客户端软件的一部分,客户端获知到可用的服务器列表按一定的均衡策略,分发请求。

我们这次重点看下客户端负载,客户端软负载核心:

服务发现,发现依赖服务的列表。

服务选择规则,在多个服务中如何选择一个有效服务。

服务监听,检测失效的服务,高效剔除失效服务。

1.2.由于我们本次采用Spring Cloud体系,因此负载均衡组件就采用Spring Cloud体系下的 Ribbon, Spring Cloud Ribbon 是一个客户端负载均衡的组件,主要提供客户端的软件负载均衡算法

负载均衡策略:

1.2.1.RandomRule:随机策略,从服务实例清单中随机选择一个服务实例。获得可用实例列表upList和所有实例列表allList,并通过rand.nextInt(serverCount)函数来获取一个随机数,并将该随机数作为upList的索引值来返回具体实例。

1.2.2.RoundRobinRule:轮询策略,按照线性轮询的方式依次选择每个服务实例。通过AtomicInteger nextServerCyclicCounter对象实现,每次进行实例选择时通过调用incrementAndGetModulo函数实现递增。

1.2.3.RetryRule:重试策略,具备重试机制的实例选择。内部定义了RoundRobinRule,并实现了对RoundRobinRule进行反复尝试的策略,若期间能够选择到具体的服务实例就返回,若选择不到就根据设置的尝试结束时间为阈值,当超过该阈值后就返回null。

1.2.4.WeightedResponseTimeRule:权重策略,根据实例的运行情况来计算权重,并根据权重来挑选实例,以达到更优的分配效果。通过定时任务为每个服务进行权重计算,平均响应时间小的权重区间(总平均响应时间-实例平均响应时间)就大,实力选择根据权重范围随机选择,落在哪个区间则选择哪个实例。

1.2.5.BestAvailableRule:最佳策略,通过遍历负载均衡器中维护的所有服务实例,会过滤掉故障的实例,并找出并发请求数最小的一个,选出最空闲的实例。

1.2.6.AvailabilityFilteringRule:可用过滤策略:先过滤出故障的或并发请求大于阈值一部分服务实例,然后再以线性轮询的方式从过滤后的实例清单中选出一个。

1.2.7.ZoneAvoidanceRule:区域感知策略:使用主过滤条件(区域负载器,选择最优区域)对所有实例过滤并返回过滤后的实例清单,依次使用次过滤条件列表中的过滤条件对主过滤条件的结果进行过滤,判断最小过滤数(默认1)和最小过滤百分比(默认0),满足条件则使用RoundRobinRule选择实例。

2.实操

负载均衡主要是在消费端进行配置,消费端我们采用feignClient进行调用服务

2.1.   pom中添加引用

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-eureka</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-feign</artifactId>

</dependency>

2.2.   启动类添加下面注解

@EnableEurekaClient

@EnableFeignClients

2.3.   消费者客户端配置

@FeignClient(value="image-server-service")

public interface IImageServerClient {

@RequestMapping(value = "/upload")

UploadImageResponseModel upload(@RequestBody UploadImageRequestModel request);

}

在使用@FeignClient注解的时候 是默认使用了ribbon进行客户端的负载均衡的,那么如果我们想要更改策略的话,可以在config里面添加配置,根据自己需求进行配置,如下:

@Bean

public IRule ribbonRule(){

//AbstractLoadBalancerRule

//AvailabilityFilteringRule

//BestAvailableRule

//ClientConfigEnabledRoundRobinRule

//PredicateBasedRule

//RandomRule

//RetryRule

//RoundRobinRule

//WeightedResponseTimeRule

//ZoneAvoidanceRule

return new RoundRobinRule();

}

2.4.0节点热插拔测试

下面服务启动两个实例,我们进行请求,发现可以根据负载策略进行请求,

然后关闭其中一个实例,系统可以正常调用,然后再重新启动关闭的实例,系统也会重新进行分配请求过去

注:默认配置下,客户端跟注册中心的心跳时间比较长,如果不修改的话,会造成短时间内负载会继续分配请求到关闭实例下面,建议可以对下面配置根据具体情况进行重新配置,保证服务异常情况下能及时从注册中心移除

注册中心配置:

# 是否开启保护模式,默认为true

eureka.server.enable-self-preservation=false

# eureka server清理无效节点的时间间隔,默认60000毫秒,即60秒

eureka.server.eviction-interval-timer-in-ms=4000

消费端配置:

#每间隔1s,向服务端发送一次心跳,证明自己依然”存活“默认为30秒

eureka.instance.lease-renewal-interval-in-seconds=1

#告诉服务端,如果我2s之内没有给你发心跳,就代表我“死”了,将我踢出掉。默认为90秒

eureka.instance.lease-expiration-duration-in-seconds=2

二、  熔断

1.概念

在微服务架构中通常会有多个服务层调用,基础服务的故障可能会导致级联故障,进而造成整个系统不可用的情况,这种现象被称为服务雪崩效应。服务雪崩效应是一种因“服务提供者”的不可用导致“服务消费者”的不可用,并将不可用逐渐放大的过程。

Spring cloud 体系下的断路器为Hystrix,下面我们就只看下Hystrix的特点:

1.1.断路器机制

断路器很好理解, 当Hystrix Command请求后端服务失败数量超过一定比例(默认50%), 断路器会切换到开路状态(Open). 这时所有请求会直接失败而不会发送到后端服务. 断路器保持在开路状态一段时间后(默认5秒), 自动切换到半开路状态(HALF-OPEN). 这时会判断下一次请求的返回情况, 如果请求成功, 断路器切回闭路状态(CLOSED), 否则重新切换到开路状态(OPEN). Hystrix的断路器就像我们家庭电路中的保险丝, 一旦后端服务不可用, 断路器会直接切断请求链, 避免发送大量无效请求影响系统吞吐量, 并且断路器有自我检测并恢复的能力.

1.2.Fallback

Fallback相当于是降级操作. 对于查询操作, 我们可以实现一个fallback方法, 当请求后端服务出现异常的时候, 可以使用fallback方法返回的值. fallback方法的返回值一般是设置的默认值或者来自缓存.

2.实操

因为熔断只是作用在服务调用这一端,因此我们只需要改动消费端项目相关代码就可以。因为,Feign中已经依赖了Hystrix所以在maven配置上不用做任何改动。

2.1.开启熔断机制

在启动类上添加下面注解:

@EnableHystrix

2.2.创建回调类

创建HelloRemoteHystrix类继承与HelloRemote实现回调的方法

@Component

public class HelloRemoteHystrix implements HelloRemote{

@Override

public String hello(@RequestParam(value = "name") String name) {

return "hello" +name+", this messge send failed ";

}

}

2.3.添加fallback属性

在HelloRemote类添加指定fallback类,在服务熔断的时候返回fallback类中的内容。

@FeignClient(name= "spring-cloud-producer",fallback = HelloRemoteHystrix.class)

public interface HelloRemote {

@RequestMapping(value = "/hello")

public String hello(@RequestParam(value = "name") String name)

}

2.4.   测试

断开服务,进行调用,系统会走降级方法

然后重新启动服务,系统自动正常调用

Spring Cloud服务保护的更多相关文章

  1. 使用Spring Cloud Gateway保护反应式微服务(二)

    抽丝剥茧,细说架构那些事——[优锐课] 接着上篇文章:使用Spring Cloud Gateway保护反应式微服务(一) 我们继续~ 将Spring Cloud Gateway与反应式微服务一起使用 ...

  2. 使用Spring Cloud Gateway保护反应式微服务(一)

    反应式编程是使你的应用程序更高效的一种越来越流行的方式.响应式应用程序异步调用响应,而不是调用资源并等待响应.这使他们可以释放处理能力,仅在必要时执行处理,并且比其他系统更有效地扩展. Java生态系 ...

  3. Spring Cloud 服务端注册与客户端调用

    Spring Cloud 服务端注册与客户端调用 上一篇中,我们已经把Spring Cloud的服务注册中心Eureka搭建起来了,这一章,我们讲解如何将服务注册到Eureka,以及客户端如何调用服务 ...

  4. 【spring cloud】在spring cloud服务中,打包ms-core失败,报错Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.0.4.RELEASE:repackage (default) on project

    在spring cloud服务中,有一个ms-code项目,只为所有的微服务提供核心依赖和工具类,没有业务意义,作为核心依赖使用.所以没有main方法,没有启动类. 在spring cloud整体打包 ...

  5. Spring Cloud 服务网关Zuul

    Spring Cloud 服务网关Zuul 服务网关是分布式架构中不可缺少的组成部分,是外部网络和内部服务之间的屏障,例如权限控制之类的逻辑应该在这里实现,而不是放在每个服务单元. Spring Cl ...

  6. spring cloud 服务注册中心eureka高可用集群搭建

    spring cloud 服务注册中心eureka高可用集群搭建 一,准备工作 eureka可以类比zookeeper,本文用三台机器搭建集群,也就是说要启动三个eureka注册中心 1 本文三台eu ...

  7. 【spring cloud】spring cloud服务发现注解之@EnableDiscoveryClient与@EnableEurekaClient

    spring cloud服务发现注解之@EnableDiscoveryClient与@EnableEurekaClient的区别

  8. spring cloud服务间调用feign

    参考文章:Spring Cloud Feign设计原理 1.feign是spring cloud服务间相互调用的组件,声明式.模板化的HTTP客户端.类似的HttpURLConnection.Apac ...

  9. Spring Cloud服务注册中心交付至kubernetes

    前言 服务发现原则: 各个微服务在启动时,会将自己的网络地址等信息注册到服务发现组件中,服务发现组件会存储这些信息 服务消费者可以从服务发现组件中查询到服务提供者的网络地址,并使用该地址来远程调用服务 ...

随机推荐

  1. 面试题。线程pingpong的输出问题

    第一种情况:public class Main { public static void main(String args[]) { Thread t = new Thread() { public ...

  2. LeetCode Linked List Easy 83. Remove Duplicates from Sorted List

    Description Given a sorted linked list, delete all duplicates such that each element appear only onc ...

  3. 2018-8-10-git-push-错误-hook-declined-

    title author date CreateTime categories git push 错误 hook declined lindexi 2018-08-10 19:16:52 +0800 ...

  4. 低版本vsphere部署高版本导出的OVF 报“硬件系列vmx-13不受支持“解决办法

    用文本编辑器之类的工具  打开ovf模板 然后下拉20多行左右 找到vmx-13这条报错内容 将13更改为数字较低的值 例如11,12

  5. Windows下Maven安装 + eclipse集成

    一.什么是maven? Maven是一个项目管理工具,能方便的帮我们下载jar包,告别传统手动导包的方式. 二.maven仓库 maven中有中央仓库,本地仓库,私服三个概念 1.中央仓库是maven ...

  6. datagrid+toolbar 不分页 显示

    1 新建DataGrid.js文件 /*** * * *el: table id * ***/ function showDataGrid(el) { $(el).datagrid({ title: ...

  7. 初识localstorage用法

    最近在做一个类似填报信息的页面,一共有8页,当点击切换到下一页的时候要求把上一页的数据存到本地,以便下次切换到这个页面的时候自动把值填上去,并且在最后一页提交数据的时候直接用localstorage里 ...

  8. 【持久层】Druid简介

    Druid首先是一个数据库连接池.Druid是目前最好的数据库连接池,在功能.性能.扩展性方面,都超过其他数据库连接池,包括DBCP.C3P0.BoneCP.Proxool.JBoss DataSou ...

  9. 存储-docker存储(12)

    storage driver 和 data volume 是容器存放数据的两种方式 storage driver方式 docker info | grep "Storage Driver&q ...

  10. docker常见启动参数

    dockerd启动参数详解: dockerd \ --bip \ #设置docker0网段 --selinux-enabled=false \ #关闭selinux --insecure-regist ...