springcloud2

服务负载均衡

为了提供并发量,有时同一个服务提供者可以部署多个(商品服务)。这个客户端在调用时要根据一定的负责均衡策略完成负载调用。
在这里插入图片描述
1)服务提供者集群

2)服务消费者负载均衡都用

服务提供者集群-同一种服务(服务名)部署多个

实际生产就是同一种服务多部署几台服务器,开发时就是用端口来区分。

  1. 拷贝一份8001
  2. 修改主类-改名
  3. 改8002yml,端口
  4. 服务提供者
  5. 重启注册中心,和两个服务提供者

服务消费者常见负载均衡实现技术

Ribbon

在这里插入图片描述

Feign-更符合java的习惯

feign底层还是ribbon,只是进行了封装,让我们以接口的方式进行调用

可以统计实现接口的代理对象,通过代理对象完成完成调用。

Xxxx
地址
Yyyy()

Ribbon负载均衡调用

Ribbon是一个客户端负载均衡器,作用于服务消费者
Ribbon是Netflix发布的云中间层服务开源项目,主要功能是提供客户端负载均衡算法。Ribbon客户端组件提供一系列完善的配置项,如,连接超时,重试等。简单的说,Ribbon是一个客户端负载均衡器,我们可以在配置文件中列出load Balancer后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器,我们也很容易使用Ribbon实现自定义的负载均衡算法。

Ribbon是一个客户端负载均衡器,它可以按照一定规则来完成一种多台服务器负载均衡调用,这些规则还支持自定义

集成原理

在这里插入图片描述

负载均衡策略

ribbon通过服务名获取到服务列表后,要根据一定规则来选择一个服务实例来完成调用.这个规则就叫负载均衡策略.

扫描二维码关注公众号,回复: 9088409 查看本文章
  1. IRule
    通过配置不同IRule的子类,可以选择不同负载均衡策略,也就是从服务列表以特定策略选择一个服务来完成调用。当然也可以自定义。所以负载均衡策略可以分为内置和自定义。
  2. 内置负载均衡策略

内置负载均衡规则类 规则描述
RoundRobinRule(默认) 简单轮询服务列表来选择服务器。它是Ribbon默认的负载均衡规则。
AvailabilityFilteringRule 对以下两种服务器进行忽略:
(1)在默认情况下,这台服务器如果3次连接失败,这台服务器就会被设置为“短路”状态。短路状态将持续30秒,如果再次连接失败,短路的持续时间就会几何级地增加。
注意:可以通过修改配置loadbalancer..connectionFailureCountThreshold来修改连接失败多少次之后被设置为短路状态。默认是3次。
(2)并发数过高的服务器。如果一个服务器的并发连接数过高,配置了AvailabilityFilteringRule规则的客户端也会将其忽略。并发连接数的上线,可以由客户端的..ActiveConnectionsLimit属性进行配置。

WeightedResponseTimeRule 为每一个服务器赋予一个权重值。服务器响应时间越长,这个服务器的权重就越小。这个规则会随机选择服务器,这个权重值会影响服务器的选择。
ZoneAvoidanceRule 以区域可用的服务器为基础进行服务器的选择。使用Zone对服务器进行分类,这个Zone可以理解为一个机房、一个机架等。
BestAvailableRule 忽略哪些短路的服务器,并选择并发数较低的服务器。
RandomRule 随机选择一个可用的服务器。
Retry 重试机制的选择逻辑

Feign负载均衡

Feign是一个声明式的Web Service客户端,它的目的就是让Web Service调用更加简单。Feign提供了HTTP请求的模板,通过编写简单的接口和插入注解,就可以定义好HTTP请求的参数、格式、地址等信息。而Feign则会完全代理HTTP请求,我们只需要像调用方法一样调用它就可以完成服务请求及相关处理。Feign整合了Ribbon和Hystrix(关于Hystrix我们后面再讲),可以让我们不再需要显式地使用这两个组件。

总起来说,Feign具有如下特性:
可插拔的注解支持,包括Feign注解和JAX-RS注解;
支持可插拔的HTTP编码器和解码器;
支持Hystrix和它的Fallback;
支持Ribbon的负载均衡;
支持HTTP请求和响应的压缩。
这看起来有点像我们springmvc模式的Controller层的RequestMapping映射。这种模式是我们非常喜欢的。Feign是用@FeignClient来映射服务的。

Feign是以接口方式进行调用,而不是通过RestTemplate来调用,feign底层还是ribbon,它进行了封装,让我们调用起来更加happy.

Hystrix断路器

在理想状态下,一个应用依赖的服务都是健康可用的,我们可以正常的处理所有的请求。
在这里插入图片描述
当某一个服务出现延迟时,所有的请求都阻塞在依赖的服务Dependency I .
在这里插入图片描述
当依赖I 阻塞时,大多数服务器的线程池就出现阻塞(BLOCK),影响整个线上服务的稳定性
在这里插入图片描述
在复杂的分布式架构的应用程序有很多的依赖,都会不可避免地在某些时候失败。高并发的依赖失败时如果没有隔离措施,当前应用服务就有被拖垮的风险

雪崩现象:由于某些服务出问题,导致很多问题的现象就叫雪崩

解决方案

    对依赖做隔离,Hystrix就是处理依赖隔离的框架,同时也是可以帮我们做依赖服务的治理和监控.。
  	当我们使用了Hystrix时,Hystrix将所有的外部调用都封装成一个HystrixCommand或者			HystrixObservableCommand对象,这些外部调用将会在一个独立的线程中运行。我们可以将出现		问题的服务通过熔断、降级等手段隔离开来,这样不影响整个系统的主业务

Hystrix是保证微服务群健壮框架,做了隔离,熔断,降级等操作.最终达到不会由于某一个服务出问题而导致雪崩现象,让整体群死掉.

Hystrix简介

Hystrix是国外知名的视频网站Netflix所开源的非常流行的高可用架构框架。Hystrix能够完美的解决分布式系统架构中打造高可用服务面临的一系列技术难题。

Hystrix “豪猪”,具有自我保护的能力。hystrix 通过如下机制来解决雪崩效应问题。

资源隔离(限流):包括线程池隔离和信号量隔离,限制调用分布式服务的资源使用,某一个调用的服务出现问题不会影响其他服务调用。

熔断:当失败率达到阀值自动触发降级(如因网络故障/超时造成的失败率高),熔断器触发的快速失败会进行快速恢复。

降级机制:超时降级、资源不足时(线程或信号量)降级,降级后可以配合降级接口返回托底数据。

缓存:提供了请求缓存、请求合并实现。

原理分析-命令模式

Hystrix使用命令模式(继承HystrixCommand(隔离)类)来包裹具体的服务调用逻辑(run方法), 并在命令模式中添加了服务调用失败后的降级逻辑(getFallback).
同时我们在Command的构造方法中可以定义当前服务线程池和熔断器的相关参数.
在这里插入图片描述
在使用了Command模式构建了服务对象之后, 服务便拥有了熔断器和线程池的功能.
在这里插入图片描述
隔离:每次调用都只影响自己
熔断:调用同一个服务多个失败,后面再来调用时,就暂时不调用,隔一段时间再进行调用,如果能调用,就恢复。
降级:要给我一个保底处理。 --一点反应都没有,给他报一个错

资源隔离&限流

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
(1)线程池隔离模式:使用一个线程池来存储当前请求,线程池对请求作处理,设置任务返回处理超时时间,堆积的请求先入线程池队列。这种方式要为每个依赖服务申请线程池,有一定的资源消耗,好处是可以应对突发流量(流量洪峰来临时,处理不完可将数据存储到线程池队里慢慢处理)
(2)信号量隔离模式:使用一个原子计数器(或信号量)记录当前有多少个线程在运行,请求来先判断计数器的数值,若超过设置的最大线程个数则丢弃该类型的新请求,若不超过则执行计数操作请求来计数器+1,请求返回计数器-1。这种方式是严格的控制线程且立即返回模式,无法应对突发流量(流量洪峰来临时,处理的线程超过数量,其他的请求会直接返回,不继续去请求依赖的服务)
在这里插入图片描述

服务熔断

正常情况下,断路器处于关闭状态(Closed),
如果调用持续出错或者超时,电路被打开进入熔断状态(Open),后续一段时间内的所有调用都会被拒绝(Fail Fast),
一段时间以后,保护器会尝试进入半熔断状态(Half-Open),允许少量请求进来尝试,
如果调用仍然失败,则回到熔断状态
如果调用成功,则回到电路闭合状态;
在这里插入图片描述
熔断的参数配置

Hystrix提供了如下的几个关键参数,来对一个熔断器进行配置:

circuitBreaker.requestVolumeThreshold //滑动窗口的大小,默认为20
circuitBreaker.sleepWindowInMilliseconds //过多长时间,熔断器再次检测是否开启,默认为5000,即5s钟
circuitBreaker.errorThresholdPercentage //错误率,默认50%

3个参数放在一起,所表达的意思就是:
每当20个请求中,有50%失败时,熔断器就会打开,此时再调用此服务,将会直接返回失败,不再调远程服务。直到5s钟之后,重新检测该触发条件,判断是否把熔断器关闭,或者继续打开。

服务降级

有了熔断,就得有降级。所谓降级,就是当某个服务熔断之后,服务器将不再被调用,此时客户端可以自己准备一个本地的fallback回调,返回一个缺省值。
这样做,虽然服务水平下降,但好歹可用,比直接挂掉要强,当然这也要看适合的业务场景。
注意:
1 熔断是在服务提供方做
2 调用时不能使用feign调用(有自己熔断机制),要用ribbon调用

Zuul路由网关

Zuul 是netflix开源的一个API Gateway 服务器, 本质上是一个web servlet应用。
Zuul 在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架。Zuul 相当于是设备和 Netflix 流应用的 Web 网站后端所有请求的前门,也要注册入Eureka.
在这里插入图片描述官网资料
https://github.com/Netflix/zuul

基本配置

pom

<!--springboot支持-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
</dependency>

	<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
		</dependency>

yml

  server:
  port: 4399
spring:
  application:
    name: ZUUL-GATEWAY
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka #集群环境配置需要改一下
  instance:
    instance-id: gateway-9527.com
    prefer-ip-address: false

修改入口类
在这里插入图片描述

路由访问映射规则

  1. 安全加固:不用服务名,映射路径
    2) 忽略原来服务名访问:原来模式不可以访问
    3) 加上统一前缀
zuul:
  routes:
    myUser.serviceId: user-provider # 服务名
    myUser.path: /myUser/** # 把myUser打头的所有请求都转发给user-provider
  ignored-services: "*" #所有服务都不允许以服务名来访问
  prefix: "/services" #加一个统一前缀

过滤器

Zuul作为网关的其中一个重要功能,就是实现请求的鉴权。而这个动作我们往往是通过Zuul提供的过滤器来实现的。

ZuulFilter

ZuulFilter是过滤器的顶级父类。其中定义的4个最重要的方法:

  • shouldFilter:返回一个Boolean值,判断该过滤器是否需要执行。返回true执行,返回false不执行。
  • run:过滤器的具体业务逻辑。
  • filterType:返回字符串,代表过滤器的类型。包含以下4种:
    • pre:请求在被路由之前执行
    • routing:在路由请求时调用
    • post:在routing和errror过滤器之后调用
    • error:处理请求时发生错误调用
  • filterOrder:通过返回的int值来定义过滤器的执行顺序,数字越小优先级越高。

过滤器执行周期

这张是Zuul官网提供的请求生命周期图,清晰的表现了一个请求在各个过滤器的执行顺序。
在这里插入图片描述

  • 正常流程:
    • 请求到达首先会经过pre类型过滤器,而后到达routing类型,进行路由,请求就到达真正的服务提供者,执行请求,返回结果后,会到达post过滤器。而后返回响应。
  • 异常流程:
    • 整个过程中,pre或者routing过滤器出现异常,都会直接进入error过滤器,再error处理完毕后,会将请求交给POST过滤器,最后返回给用户。
    • 如果是error过滤器自己出现异常,最终也会进入POST过滤器,而后返回。
    • 如果是POST过滤器出现异常,会跳转到error过滤器,但是与pre和routing不同的时,请求不会再到达POST过滤器了。

负载均衡与熔断

Zuul中默认就已经集成了Ribbon负载均衡和Hystix熔断机制。但是所有的超时策略都是走的默认值,比如熔断超时时间只有1S,很容易就触发了。因此建议我们手动进行配置:

zuul:
  retryable: true
ribbon:
  ConnectTimeout: 250 # 连接超时时间(ms)
  ReadTimeout: 2000 # 通信超时时间(ms)
  OkToRetryOnAllOperations: true # 是否对所有操作重试
  MaxAutoRetriesNextServer: 2 # 同一服务不同实例的重试次数
  MaxAutoRetries: 1 # 同一实例的重试次数
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMillisecond: 3000 # 熔断超时时长:3000ms

SpringCloud Config分布式配置中心

微服务架构中,每个项目都有一个yml配置,管理起来麻烦,因为没有统一的地方管理,改了一点儿配置都需要改jar包。要使用spring cloud config来统一管理。

在分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理,实时更新,所以需要分布式配置中心组件。在Spring Cloud中,有分布式配置中心组件spring cloud config ,它支持配置服务放在配置服务的内存中(即本地),也支持放在远程Git仓库中。在spring cloud config 组件中,分两个角色,一是config server,二是config client。

操作

服务端配置

1.github创建配置文件
在这里插入图片描述
2.创建springboot项目并且导入jar

<dependencies>
    <!--springboot支持-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>

    <!--eureka客户端-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <!--配置中心支持-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-config-server</artifactId>
    </dependency>
</dependencies>

3.Yml

server:
  port: 1299
eureka:
  client:
    service-url:
      defaultZone: http://eureka-7001.com:7001/eureka,http://eureka-7002.com:7002/eureka # 集群

  instance:
    prefer-ip-address: true
spring:
  application:
    name: spring-cloud-config-server
  cloud:
    config:
      server:
        git:
          uri: https://github.com/xxx/microservice-config.git
          username: xxx
          password: xxx

4).启动类

@SpringBootApplication
@EnableEurekaClient //加入注册中心
@EnableConfigServer //启用配置服务端
public class ConfigServerApplication_1299 {
 public static void main(String[] args) {
     SpringApplication.run(ConfigServerApplication_1299.class);
 }
}

客户端配置

  1. 新建config_client_3355 springboot项目,为了读取github的配置文件
  2. 导入jar
<dependencies>
    <!--springboot支持-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
<!--eureka客户端-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

    <!--configclient端-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>
</dependencies>
  1. 准备yml
    全局bootstrap.yml
spring:
Application
Name 
  cloud:
    config:
      name: application-user #github上面名称
      profile: test #环境
      label: master #分支
      uri: http://127.0.0.1:1299 #配置服务器
eureka:
  client:
    service-url:
     defaultZone: http://eureka-7001.com:7001/eureka,http://eureka-7002.com:7002/eureka # 集群

  instance:
    prefer-ip-address: true #显示客户端真实ip
  1. 入口类
@SpringBootApplication
@EnableEurekaClient
public class ConfigClientApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConfigClientApplication.class,args);
    }
}
发布了14 篇原创文章 · 获赞 5 · 访问量 674

猜你喜欢

转载自blog.csdn.net/weixin_46091684/article/details/104267883
今日推荐