重新定义cloud 第5章 spring cloud ribbon

  • ribbon是 netFlix 公司开发的

  • 负载均衡 组件

  • pivotal 将 其 整合 进入 Spring Cloud 生态

  • 丰富的负载均衡策略

  • 重试机制

  • 支持多协议的异步 与 相应模型

  • 容错

  • 缓存

  • 批处理

spring cloud ribbon 概述

  • 负载均衡 load balance

  • 利用特定方式 将流量 分摊到 多个操作单元上 的一种手段

  • 如:nginx 和 lvs

  • 软负载 nginx

  • 硬负载 f5

  • 集中式 负载均衡:因特网与服务提供者。也称:服务端负载均衡。Nginx ,F5

  • 进程内负载均衡:一个实例库 选取 一个实例 进行 流量导入。

    • 实例库 一般在 eureka consul zookeeper etcd 注册中心的
    • 负载均衡器 就是类似 Ribbon的IPC (inter-process communication进程间 通信)
    • 进程内负载均衡:也叫做 客户端负载均衡
  • Feign与zuul中 已经默认继承了 Ribbon

  • 客户端负载均衡,赋予了 应用一些 支配 HTTP 与 TCP 行为的能力

  • 客户端负载均衡(后端负载均衡),也是 进程内 负载均衡

入门案例

父类

	<modules>
		<module>ch5-1-eureka-server</module>
		<module>ch5-1-ribbon-loadbalancer</module>
		<module>ch5-1-client-a</module>
	</modules>

	<!--  利用传递依赖,公共部分  --> 
	<dependencies>
        
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>
		<!-- springboot web -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
        
	</dependencies>



一个logback.xml备份

<?xml version="1.0" encoding="UTF-8"?>

<!-- Logback configuration. See http://logback.qos.ch/manual/index.html -->
<configuration scan="true" scanPeriod="10 seconds">
	<!--<include resource="org/springframework/boot/logging/logback/base.xml" 
		/> -->

	<!--定义日志文件的存储地址和前缀名 -->
	<property name="LOG_HOME" value="logs" />
	<property name="LOG_PREFIX" value="client-a" />

	<!-- 一般信息按照每天生成日志文件 -->
	<appender name="INFO_FILE"
		class="ch.qos.logback.core.rolling.RollingFileAppender">
		<File>${LOG_HOME}/${LOG_PREFIX}-info.log</File>
		<rollingPolicy
			class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
			<!-- 每天一归档 -->
			<fileNamePattern>${LOG_HOME}/${LOG_PREFIX}-info-%d{yyyyMMdd}.log.%i
			</fileNamePattern>
			<!-- 单个日志文件最多500MB, 30天的日志周期,最大不能超过20GB -->
			<maxFileSize>100MB</maxFileSize>
			<maxHistory>30</maxHistory>
			<totalSizeCap>20GB</totalSizeCap>
		</rollingPolicy>
		<encoder>
			<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
			<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}
				-%msg%n</Pattern>
		</encoder>
	</appender>

	<!--错误信息按照每天生成日志文件 -->
	<appender name="ERROR_FILE"
		class="ch.qos.logback.core.rolling.RollingFileAppender">
		<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
			<level>ERROR</level>
		</filter>
		<File>${LOG_HOME}/${LOG_PREFIX}-error.log</File>
		<rollingPolicy
			class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
			<!-- 每天一归档 -->
			<fileNamePattern>${LOG_HOME}/${LOG_PREFIX}-error-%d{yyyyMMdd}.log.%i
			</fileNamePattern>
			<!-- 单个日志文件最多500MB, 30天的日志周期,最大不能超过20GB -->
			<maxFileSize>100MB</maxFileSize>
			<maxHistory>30</maxHistory>
			<totalSizeCap>20GB</totalSizeCap>
		</rollingPolicy>
		<encoder>
			<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
			<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}
				-%msg%n</Pattern>
		</encoder>
	</appender>

	<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
		<encoder>
			<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} -
				%msg%n</pattern>
		</encoder>
	</appender>

	<!-- 日志输出级别 这样设置不打印日志 -->
	<root level="INFO">
		<appender-ref ref="STDOUT" />
		<appender-ref ref="INFO_FILE" />
		<appender-ref ref="ERROR_FILE" />
	</root>

</configuration>

eureka server

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

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {}

server:
  port: 8888
eureka:
  instance:
    hostname: localhost
  client:
    registerWithEureka: false
    fetchRegistry: false
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

client-a

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


server:
  port: 7070
spring:
  application:
    name: client-a
eureka:
  client:
    serviceUrl:
      defaultZone: http://${eureka.host:127.0.0.1}:${eureka.port:8888}/eureka/
  instance:
    prefer-ip-address: true

@SpringBootApplication
@EnableDiscoveryClient
public class ClientAApplication {}

@RestController
public class TestController {

	@GetMapping("/add")
	public String add(Integer a, Integer b, HttpServletRequest request){
		return " From Port: "+ request.getServerPort() + ", Result: " + (a + b);
	}
}

ribbon-loadbalancer

	<dependencies>
        
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
		</dependency>
        
	</dependencies>
配置负载均衡
@SpringBootApplication
@EnableDiscoveryClient
public class RibbonLoadbalancerApplication {

    public static void main(String[] args) {
        SpringApplication.run(RibbonLoadbalancerApplication.class, args);
    }
    
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}


spring:
  application:
    name: ribbon-loadbalancer
server:
  port: 7777
eureka:
  client:
    serviceUrl:
      defaultZone: http://${eureka.host:127.0.0.1}:${eureka.port:8888}/eureka/
  instance:
    prefer-ip-address: true
使用负载均衡
@RestController
public class TestController {
	
    @Autowired
    private RestTemplate restTemplate;

	@GetMapping("/add")
	public String add(Integer a, Integer b) {
		String result = restTemplate
				.getForObject("http://CLIENT-A/add?a=" + a + "&b=" + b, String.class);
		System.out.println(result);
		return result;
	}
}

测试

  • client-a 启动7070 和 7075端口

  • 访问:http://localhost:7777/add?a=100&b=300

    From Port: 7070, Result: 400
    From Port: 7075, Result: 400
    

Ribbon 实战

  • nginx 负载均衡策略
    • 轮询
    • 权重
    • ip_hash
  • Ribbon负载均衡策略
    • Random Rule 随机
    • RoundRobinRule 轮询 ,按顺序。(默认策略)
    • RetryRule 重试
    • Beat Available Rule 最低并发策略
    • Availability Filtering Rule 可用过滤策略
    • Response Time Weighted Rule 相应时间 加权策略。相应时间越长,权重越低
    • Zone Avoidance Rule 区域权衡策略。所在区域的性能 和 Server的 可用性轮询

全局策略的设置

@Configuration
public class TestConfiguration {
	
	@Bean
	public IRule ribbonRule() {
		return new RandomRule();
	}
}

基于注解的策略设置

  • 对:单个源 服务 生效的

  • 针对一个源服务设置 其 特有的策略

  • 使用 @RibbonClient 注解

@Configuration
@AvoidScan //空的声明
public class TestConfiguration {
	
	@Autowired
    IClientConfig config;//针对客户端的配置管理器

	@Bean
	public IRule ribbonRule(IClientConfig config) {
		return new RandomRule();
	}
}

public @interface AvoidScan {
}

@SpringBootApplication
@EnableDiscoveryClient

//对 client-a 服务 使用的策略 是TestConfiguration
@RibbonClient(name = "client-a", configuration = TestConfiguration.class)

/*
@RibbonClients(value = {
		@RibbonClient(name = "client-a", configuration = TestConfiguration.class),
		@RibbonClient(name = "client-b", configuration = TestConfiguration.class)
})
*/

//不去扫描 AvoidScan 注解标记的 类
@ComponentScan(
    excludeFilters = 
    {@ComponentScan.Filter(type = FilterType.ANNOTATION, value = {AvoidScan.class})}
              )

public class RibbonLoadbalancerApplication {

    public static void main(String[] args) {
        SpringApplication.run(RibbonLoadbalancerApplication.class, args);
    }
    
    
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

基于配置文件的策略设置

  • 基本语法是 . ribbon.*

  • 推荐使用

    client-a:
      ribbon:
        ConnectTimeout: 3000
        ReadTimeout: 60000
        MaxAutoRetries: 1 #对第一次请求的服务的重试次数
        MaxAutoRetriesNextServer: 1 #要重试的下一个服务的最大数量(不包括第一个服务)
        OkToRetryOnAllOperations: true
        NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #随机策略
    

ribbon 的重试 与 超时

  • F 版本重试 默认是开启的
client-a:
  ribbon:
    ConnectTimeout: 3000
    ReadTimeout: 60000
    MaxAutoRetries: 1 #对第一次请求的服务的重试次数
    MaxAutoRetriesNextServer: 1 #要重试的下一个服务的最大数量(不包括第一个服务)
    OkToRetryOnAllOperations: true

Ribbon的 饥饿加在

  • Ribbon 并不是 在启动 时 就加在上下文,而是 实际请求的 时候才会创建

  • 因此 第一次调用 显得颇为 乏力

  • 指定 Ribbon 具体的客户端的名称 来 开户 饥饿 加在

    #启动的时候,便加载 所有配置项 的应用程序上下文
    ribbon:
      eager-load:
        enabled: true
        clients: client-a, client-b, client-c
    

Ribbon 脱离 Eureka 的使用

  • 默认: ribbon客户端 从 Eureka 注册中心读取 服务注册信息列表
  • 如果 eureka 是 公共注册中心(http://eureka.springcloud.cn),容易产生 服务侵入 问题
  • 应该:ribbon 客户端 自行 指定源服务
ribbon:
  eureka:
    enable: false
client:
  ribbon:
    listOfServers: http://localhost:7070,http://localhost:7071

Spring Cloud Ribbon 进阶

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }


@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Qualifier
public @interface LoadBalanced {
}



@Configuration
@ConditionalOnClass({RestTemplate.class}) //必须有 RestTemplate 才会加在
@ConditionalOnBean({LoadBalancerClient.class})
@EnableConfigurationProperties({LoadBalancerRetryProperties.class})
public class LoadBalancerAutoConfiguration {
    @LoadBalanced
    @Autowired(
        required = false
    )
    private List<RestTemplate> restTemplates = Collections.emptyList();
    @Autowired(
        required = false
    )
    private List<LoadBalancerRequestTransformer> transformers = Collections.emptyList();

    public LoadBalancerAutoConfiguration() {
    }
  • Ribbon 内部提供了 7种 可选的 负载均衡 策略
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值