Spring Cloud 系列(二) Ribbon

1 篇文章 0 订阅
1 篇文章 0 订阅

目录

 

一、 介绍

二、 Ribbon使用一 准备工作

三、 使用方式一 -- 同Eureka一起使用

四、 使用方式二 -- 不依赖Eureka单独使用

五、 Ribbon文件配置

六、 负载均衡策略


一、 介绍

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

二、 Ribbon使用一 准备工作

首先启动一个Eureka Server, 并注册两个服务提供者,服务名称为“service-producer”

三、 使用方式一 -- 同Eureka一起使用

  1. pom中加入Eureka Client 依赖
    <?xml version="1.0" encoding="UTF-8"?>
    <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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    	<modelVersion>4.0.0</modelVersion>
    	<parent>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-parent</artifactId>
    		<version>2.2.6.RELEASE</version>
    		<relativePath/> <!-- lookup parent from repository -->
    	</parent>
    	<groupId>com.springcloud.stu</groupId>
    	<artifactId>eureka-client-consumer-ribbon</artifactId>
    	<version>0.0.1-SNAPSHOT</version>
    	<name>eureka-client-consumer-ribbon</name>
    	<description>eureka-client-consumer-ribbon</description>
    
    	<properties>
    		<java.version>1.8</java.version>
    		<spring-cloud.version>Hoxton.SR4</spring-cloud.version>
    	</properties>
    
    	<dependencies>
    		<dependency>
    			<groupId>org.springframework.cloud</groupId>
    			<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    		</dependency>
    
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-devtools</artifactId>
    			<scope>runtime</scope>
    			<optional>true</optional>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-test</artifactId>
    			<scope>test</scope>
    			<exclusions>
    				<exclusion>
    					<groupId>org.junit.vintage</groupId>
    					<artifactId>junit-vintage-engine</artifactId>
    				</exclusion>
    			</exclusions>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-web</artifactId>
    		</dependency>
    		<dependency>
    			<groupId>org.projectlombok</groupId>
    			<artifactId>lombok</artifactId>
    		</dependency>
    	</dependencies>
    
    	<dependencyManagement>
    		<dependencies>
    			<dependency>
    				<groupId>org.springframework.cloud</groupId>
    				<artifactId>spring-cloud-dependencies</artifactId>
    				<version>${spring-cloud.version}</version>
    				<type>pom</type>
    				<scope>import</scope>
    			</dependency>
    		</dependencies>
    	</dependencyManagement>
    
    	<build>
    		<plugins>
    			<plugin>
    				<groupId>org.springframework.boot</groupId>
    				<artifactId>spring-boot-maven-plugin</artifactId>
    			</plugin>
    		</plugins>
    	</build>
    
    </project>
    

     

  2. Spring boot的启动类上添加@EnableEurekaClient注解来启用Eureka客户端。RestTemplate Bean上 添加@LoadBalanced注解
    @SpringBootApplication
    @EnableEurekaClient
    public class RibbonClientApplication {
    	@Bean
    	@LoadBalanced
    	public RestTemplate getTestTemplate() {
    		return new RestTemplate();
    	}
    
    	public static void main(String[] args) {
    		SpringApplication.run(RibbonClientApplication.class, args);
    	}
    
    }

     

  3. 调用服务提供者提供的服务
    @RestController
    @RequestMapping("/ribbon")
    public class RibbonControoler {
    	@Autowired
    	private RestTemplate restTemplate;
    
        @Autowired
    	private LoadBalancerClient loadBalancerClient;
    	
    	@GetMapping("/get")
    	public String get(String name) {
            //查看负载均衡器选择了哪个服务实例
            ServiceInstance instance = loadBalancerClient.choose("srvice-producer");
    		log.info("uri={}, instanceId={}, matadata={}", instance.getUri(), instance.getInstanceId(), instance.getMetadata());
    		
    		return "producer return:"+restTemplate.getForObject("http://srvice-producer/producer/get?name="+name, String.class);
    	}
    	
    
    }

    这里调用的地址使用的是http://srvice-producer,即注册到Eureka Server上的服务名称。

四、 使用方式二 -- 不依赖Eureka单独使用

  1. pom中引入spring-cloud-starter-netflix-ribbon依赖
    <?xml version="1.0" encoding="UTF-8"?>
    <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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    	<modelVersion>4.0.0</modelVersion>
    	<parent>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-parent</artifactId>
    		<version>2.2.6.RELEASE</version>
    		<relativePath/> <!-- lookup parent from repository -->
    	</parent>
    	<groupId>com.springcloud.stu</groupId>
    	<artifactId>ribbon-client-without-eureka</artifactId>
    	<version>0.0.1-SNAPSHOT</version>
    	<name>ribbon-client-without-eureka</name>
    	<description>ribbon-client-without-eureka</description>
    
    	<properties>
    		<java.version>1.8</java.version>
    		<spring-cloud.version>Hoxton.SR3</spring-cloud.version>
    	</properties>
    
    	<dependencies>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter</artifactId>
    		</dependency>
    
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-test</artifactId>
    			<scope>test</scope>
    			<exclusions>
    				<exclusion>
    					<groupId>org.junit.vintage</groupId>
    					<artifactId>junit-vintage-engine</artifactId>
    				</exclusion>
    			</exclusions>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.cloud</groupId>
    			<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-web</artifactId>
    		</dependency>
    		<dependency>
    			<groupId>org.projectlombok</groupId>
    			<artifactId>lombok</artifactId>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-devtools</artifactId>
    		</dependency>
    	</dependencies>
    
    	<dependencyManagement>
    		<dependencies>
    			<dependency>
    				<groupId>org.springframework.cloud</groupId>
    				<artifactId>spring-cloud-dependencies</artifactId>
    				<version>${spring-cloud.version}</version>
    				<type>pom</type>
    				<scope>import</scope>
    			</dependency>
    		</dependencies>
    	</dependencyManagement>
    	<build>
    		<plugins>
    			<plugin>
    				<groupId>org.springframework.boot</groupId>
    				<artifactId>spring-boot-maven-plugin</artifactId>
    			</plugin>
    		</plugins>
    	</build>
    
    </project>
    
  2. 启动类

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

     

  3. 配置application.yml

    server:
      port: 8901
    spring:
      application:
        name: ribbon-without-eureka
    service-producer:
      ribbon:
        listOfServers: localhost:8631,localhost:8632

    重点是如下配置,来代替Eureka上注册的服务列表 

     service-producer:
      ribbon:
        listOfServers: localhost:8631,localhost:8632

  4. 调用类和使用Eureka时相同

    @RestController
    @RequestMapping("/ribbon")
    public class RibbonControoler {
    	@Autowired
    	private RestTemplate restTemplate;
    
        @Autowired
    	private LoadBalancerClient loadBalancerClient;
    	
    	@GetMapping("/get")
    	public String get(String name) {
            //查看负载均衡器选择了哪个服务实例
            ServiceInstance instance = loadBalancerClient.choose("srvice-producer");
    		log.info("uri={}, instanceId={}, matadata={}", instance.getUri(), instance.getInstanceId(), instance.getMetadata());
    		
    		return "producer return:"+restTemplate.getForObject("http://srvice-producer/producer/get?name="+name, String.class);
    	}
    	
    
    }

五、 Ribbon文件配置

              在application.yml中进行配置

ribbon:
  eager-load:
    enabled: true #是否开启预加载, 默认不预加载
    clients: #开启预加载的服务列表
    - eureka-client-producer2
    - eureka-client-producer3
eureka-client-producer:
  ribbon:
    #负载均衡策略
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
    #同一实例最大重试次数,不包括首次调用
    MaxAutoRetries: 1
    # 切换实例重试的次数,不包括首次所选的server.即第一个server不成功,则切换为另一个server,仍不成功(此处也会对切换后的server重试MaxAutoRetries次),再切换下一个,切换次数有此参数设置。
    MaxAutoRetriesNextServer: 1
    #无论是请求超时或者socket read timeout都进行重试
    OkToRetryOnAllOperations: true
    #服务列表刷新间隔时间
    ServerListRefreshInterval: 2000
    #Apache HttpClient连接超时时间
    ConnectTimeout: 2000
    #Apache HttpClient读取超时时间
    ReadTimeout: 30

重要:Ribbon的超时时长=(ConnectTimeout+ReadTimeout)*(MaxAutoRetries+1)*(MaxAutoRetriesNextServer+1)

 

六、 负载均衡策略

所有负载均衡策略都实现IRule接口

public interface IRule{
    /*
     * choose one alive server from lb.allServers or
     * lb.upServers according to key
     * 
     * @return choosen Server object. NULL is returned if none
     *  server is available 
     */

    public Server choose(Object key);
    
    public void setLoadBalancer(ILoadBalancer lb);
    
    public ILoadBalancer getLoadBalancer();    
}

继承关系

策略说明(源自 https://www.cnblogs.com/idoljames/p/11698923.html

策略类  命名描述
RandomRule随机策略随机选择server
RoundRobinRule轮询策略按照顺序选择server(ribbon默认策略)
RetryRule重试策略在一个配置时间段内,当选择server不成功,则一直尝试选择一个可用的server
BestAvailableRule最低并发策略逐个考察server,如果server断路器打开,则忽略,再选择其中并发链接最低的server
AvailabilityFilteringRule可用过滤策略过滤掉一直失败并被标记为circuit tripped的server,过滤掉那些高并发链接的server(active connections超过配置的阈值)
ResponseTimeWeightedRule响应时间加权重策略根据server的响应时间分配权重,响应时间越长,权重越低,被选择到的概率也就越低。响应时间越短,权重越高,被选中的概率越高,这个策略很贴切,综合了各种因素,比如:网络,磁盘,io等,都直接影响响应时间
ZoneAvoidanceRule区域权重策略综合判断server所在区域的性能,和server的可用性,轮询选择server并且判断一个AWS Zone的运行性能是否可用,剔除不可用的Zone中的所有server
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Cloud Gateway可以与Ribbon组件整合,以实现负载均衡的功能。下面是一个示例,演示了如何使用Spring Cloud Gateway整合Ribbon: 1. 首先,确保你已经在项目的pom.xml文件中添加了Spring Cloud Gateway和Ribbon的依赖。 2. 创建一个Spring Boot应用程序,并在启动类上添加`@EnableEurekaClient`注解,以便将应用程序注册到Eureka Server。 3. 在应用程序的配置文件中,配置Eureka Server的地址和端口号。 4. 创建一个`@Configuration`类,用于配置Spring Cloud Gateway和Ribbon。 ```java @Configuration public class GatewayConfig { @Autowired private DiscoveryClient discoveryClient; @Bean public RouteLocator customRouteLocator(RouteLocatorBuilder builder) { return builder.routes() .route("service-route", r -> r.path("/api/**") .filters(f -> f.stripPrefix(1)) .uri("lb://service")) .build(); } @Bean public LoadBalancerClient loadBalancerClient() { return new RibbonLoadBalancerClient(discoveryClient); } } ``` 在上面的配置中,我们创建了一个`RouteLocator` bean,用于定义路由规则。在这个例子中,我们将所有以`/api/`开头的请求转发到名为`service`的微服务上。同时,我们还创建了一个`LoadBalancerClient` bean,用于实现负载均衡。 5. 创建一个Controller类,用于处理请求并返回响应。 ```java @RestController public class GatewayController { @GetMapping("/api/hello") public String hello() { return "Hello from service!"; } } ``` 在上面的例子中,我们创建了一个`/api/hello`的GET请求处理方法,返回一个简单的字符串。 6. 启动应用程序,并访问`http://localhost:8080/api/hello`,你将会看到从`service`微服务返回的响应。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值