0
点赞
收藏
分享

微信扫一扫

spring cloud 之 ribbon介绍

ribbon是负责负载均衡的,属于进程内负载均衡。请求发送到ribbon然后由ribbon发送到各个服务.

服务端负载均衡:Nginx与F5集中式负载均衡指位于因特网与服务提供者之间,并负责把网络请求发到各个提供单位.

spring cloud 之 ribbon介绍_spring


 进程内负载均衡是指从一个实例库选取一个实例进行流量导入,在微服务的范畴内,实例库一般是存储在Eureka、Consul、Zookeeper、etcd这样的注册中心,而此时的负载均衡器就是类似Ribbon的IPC(Inter-Process Communication,进程间通信)组件,因此,进程内负载均衡也叫作客户端负载均衡

spring cloud 之 ribbon介绍_.net_02



Ribbon负载均衡策略

spring cloud 之 ribbon介绍_spring_03


spring cloud 之 ribbon介绍_负载均衡_04




 可以在java配置文件中配置自己需要的负载均衡策略如:

spring cloud 之 ribbon介绍_.net_05



也可以在yml文件中配置负载均衡的实现类:(注意:yml的配置高于java配置文件,若同时配置了Java和yml则会选择yml的配置)

spring cloud 之 ribbon介绍_负载均衡_06



bootstrap.yml中配置ribbon的其他配置:

spring cloud 之 ribbon介绍_负载均衡_07



 ribbon默认是懒加载,所以第一次请求会慢很多(它需要从注册中心拿取服务实例列表,在进行自身策略的调整),为了避免这个问题使懒加载变为饿加载让其在项目启动时就加载,我们采用如下配置:

spring cloud 之 ribbon介绍_负载均衡_08



 ribbon1.2.0之后的版本支持了yml配置ribbon的行为,也就是说通过配置文件能决定让ribbon使用哪些实现类来完成负载均衡:

ribbon各个功能的接口:这些接口在用到的时候可查有哪些实现类,若有兴趣也可自己实现具体实现类来配置。

spring cloud 之 ribbon介绍_负载均衡_09



 自定义配置实现类的列表:

spring cloud 之 ribbon介绍_.net_10

 配置具体功能的实现类如:

spring cloud 之 ribbon介绍_spring_11



 由于ribbon因为是以eureka client的身份去连接eureka server,从而拿到各个服务实例的列表去做负载均衡,所以当eureka server是一个社区型的公共注册中心时,可能下面的实例有的是你不需要的。这时候就没必要从eureka server来拿服务实例了,可自行配置需要的服务实例如下配置:

1.先关掉从eureka那服务实例列表的开关:

spring cloud 之 ribbon介绍_.net_12



 2.在配置需要做负载均衡的实例:

spring cloud 之 ribbon介绍_spring_13



 代码:

启动类:负载均衡依靠@LoadBalanced注解修饰过的RestTemplate来实现。具体原理可通过源码@loadBalanced注解内部注释或网上介绍查看。


package cn.springcloud.book;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.netflix.ribbon.RibbonClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
import org.springframework.web.client.RestTemplate;

import cn.springcloud.book.config.AvoidScan;
import cn.springcloud.book.config.TestConfiguration;

@SpringBootApplication
@EnableDiscoveryClient
@RibbonClient(name = "client-a", configuration = TestConfiguration.class)
//@RibbonClients(value = {
// @RibbonClient(name = "client-a", configuration = TestConfiguration.class),
// @RibbonClient(name = "client-b", configuration = TestConfiguration.class)
//})
@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();
}
}


自定义注解:该注解是个空注解,主要是为了让启动类中的扫描注解过滤掉改拥有该注解的类。


package cn.springcloud.book.config;

public @interface AvoidScan {

}


配置类:


package cn.springcloud.book.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;

@Configuration
@AvoidScan
public class TestConfiguration {

@Autowired
IClientConfig config;

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


controller类:该类是接收外部请求,拿到请求后先确定是哪个服务,之后在负载均衡到该服务下的某个服务实例上。


package cn.springcloud.book.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class TestController {

@Autowired
private RestTemplate restTemplate;

@Autowired
private LoadBalancerClient lbClient;

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

@GetMapping("/add1")
public void add1(Integer a, Integer b) {
ServiceInstance instance = this.lbClient.choose("client-a");
System.out.println(instance.getHost()+":"+instance.getPort());
}

@GetMapping("/add2")
public void add2(Integer a, Integer b) {
ServiceInstance instance = this.lbClient.choose("client-b");
System.out.println(instance.getHost()+":"+instance.getPort());
}
}





 bootstrap.yml


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
#client-a:
# ribbon:
# ConnectTimeout: 3000
# ReadTimeout: 60000
# MaxAutoRetries: 1 #对第一次请求的服务的重试次数
# MaxAutoRetriesNextServer: 1 #要重试的下一个服务的最大数量(不包括第一个服务)
# OkToRetryOnAllOperations: true
# NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule#
#ribbon:
# eager-load:
# enabled: true
# clients: client-a, client-b, client-c


pom.xml


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.springcloud.book</groupId> 父类为spring boot 2.0.0
<artifactId>ch5-2</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>ch5-2-ribbon-loadbalancer</artifactId>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>

<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>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>


举报

相关推荐

0 条评论