Ribbon-3使用配置文件自定义Ribbon Client

我们讨论一下怎么使用配置文件,这是从SpringCloud Netflix1.0开始的,

6.4 Customizing the Ribbon Client by Setting Properties

https://cloud.spring.io/spring-cloud-netflix/multi/multi_spring-cloud-ribbon.html

Starting with version 1.2.0, Spring Cloud Netflix now supports customizing Ribbon clients by 

setting properties to be compatible with the Ribbon documentation.

This lets you change behavior at start up time in different environments.

The following list shows the supported properties>:

<clientName>.ribbon.NFLoadBalancerClassName: Should implement ILoadBalancer

<clientName>.ribbon.NFLoadBalancerRuleClassName: Should implement IRule

<clientName>.ribbon.NFLoadBalancerPingClassName: Should implement IPing

<clientName>.ribbon.NIWSServerListClassName: Should implement ServerList

<clientName>.ribbon.NIWSServerListFilterClassName: Should implement ServerListFilter

clientName是我要请求的serviceId,这边有一个注意点

Classes defined in these properties have precedence over beans defined by using 

@RibbonClient(configuration=MyRibbonConfig.class) and the defaults provided by Spring Cloud Netflix.

这个配置文件里面定义的类,用JAVA代码的优先级要高,同时高于Spring Cloud Netflix的默认配置,也就是优先级

配置文件NO.1,java代码No2,默认的配置No3,这边给了一个demo,如果你想配置IRULE的话

To set the IRule for a service name called users, you could set the following properties:

负载均衡的规则的话,你可以这么玩

users:
  ribbon:
    NIWSServerListClassName: com.netflix.loadbalancer.ConfigurationBasedServerList
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule

非常简单,

/**
 * A loadbalacing strategy that randomly distributes traffic amongst existing
 * servers.
 * 
 * @author stonse
 * 
 */
public class RandomRule extends AbstractLoadBalancerRule {

根据响应时间加权,这个是加权,不是优先级,

/** 
 * Rule that use the average/percentile response times
 * to assign dynamic "weights" per Server which is then used in 
 * the "Weighted Round Robin" fashion. 
 * <p>
 * The basic idea for weighted round robin has been obtained from JCS
 * The implementation for choosing the endpoint from the list of endpoints
 * is as follows:Let's assume 4 endpoints:A(wt=10), B(wt=30), C(wt=40), 
 * D(wt=20). 
 * <p>
 * Using the Random API, generate a random number between 1 and10+30+40+20.
 * Let's assume that the above list is randomized. Based on the weights, we
 * have intervals as follows:
 * <p>
 * 1-----10 (A's weight)
 * <br>
 * 11----40 (A's weight + B's weight)
 * <br>
 * 41----80 (A's weight + B's weight + C's weight)
 * <br>
 * 81----100(A's weight + B's weight + C's weight + C's weight)
 * <p>
 * Here's the psuedo code for deciding where to send the request:
 * <p>
 * if (random_number between 1 &amp; 10) {send request to A;}
 * <br>
 * else if (random_number between 11 &amp; 40) {send request to B;}
 * <br>
 * else if (random_number between 41 &amp; 80) {send request to C;}
 * <br>
 * else if (random_number between 81 &amp; 100) {send request to D;}
 * <p>
 * When there is not enough statistics gathered for the servers, this rule
 * will fall back to use {@link RoundRobinRule}. 
 * @author stonse
 */
public class WeightedResponseTimeRule extends RoundRobinRule {

其实Ribbon支持各种各样的rule,重试的Rule,

 * @deprecated Use {@link WeightedResponseTimeRule}
 * 
 * @see WeightedResponseTimeRule
 * 
 */
public class ResponseTimeWeightedRule extends RoundRobinRule {

这两个其实是一样的,只不过之前的名称取得不好,现在改名了,see WeightedResponseTimeRule,我们可以看一下

IRURE的实现类,响应时间加权的rule,RoundRobinRule,是继承了RoundRobinRule,还有重试的Rule,RandomRule,

最高可用性的Rule,BestAvaliableRule,

/**
 * A rule that skips servers with "tripped" circuit breaker and picks the
 * server with lowest concurrent requests.
 * <p>
 * This rule should typically work with {@link ServerListSubsetFilter} which puts a limit on the 
 * servers that is visible to the rule. This ensure that it only needs to find the minimal 
 * concurrent requests among a small number of servers. Also, each client will get a random list of 
 * servers which avoids the problem that one server with the lowest concurrent requests is 
 * chosen by a large number of clients and immediately gets overwhelmed.
 * 
 * @author awang
 *
 */
public class BestAvailableRule extends ClientConfigEnabledRoundRobinRule {

我很难做到一个节点比另一个节点响应时间长,所以我还是使用RandomRule,

microservice-simple-provider-user.ribbon.NFLoadBalancerRuleClassName=
com.netflix.loadbalancer.RandomRule

随机的规则去负载均衡

localhost:8010/movie/1

localhost:8010/test
<?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 
http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.learn</groupId>
	<artifactId>microservice-consumer-movie-ribbon-properties-customizing</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>microservice-simple-consumer-movie</name>
	<description>Demo project for Spring Boot</description>

  <parent>
    <groupId>cn.learn</groupId>
    <artifactId>microcloud02</artifactId>
    <version>0.0.1</version>
  </parent>
  
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<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>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-redis</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka</artifactId>
		</dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
	</dependencies>

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


</project>
#debug=true
server.port=8010

eureka.client.serviceUrl.defaultZone=http://admin:1234@10.40.8.152:8761/eureka

spring.application.name=microservice-consumer-movie-ribbon
eureka.instance.prefer-ip-address=true
eureka.instance.instance-id=${spring.application.name}:${spring.cloud.client.ipAddress}:${spring.application.instance_id:${server.port}}
eureka.client.healthcheck.enabled=true
spring.redis.host=10.40.8.152
spring.redis.password=1234
spring.redis.port=6379

microservice-simple-provider-user.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule

package com.learn.cloud.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.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import com.learn.cloud.entity.User;

@RestController
public class MovieController {
  @Autowired
  private RestTemplate restTemplate;
  
  @Autowired
  private LoadBalancerClient loadBalancerClient;

  @GetMapping("/movie/{id}")
  public User findById(@PathVariable Long id) {
    // http://localhost:7900/simple/
    // VIP virtual IP
    // HAProxy Heartbeat
	 ServiceInstance serviceInstance = this.loadBalancerClient.choose("microservice-simple-provider-user");
	 System.out.println("==============" + ":" + serviceInstance.getServiceId() + ":" + serviceInstance.getHost() + ":" + serviceInstance.getPort());
	 return this.restTemplate.getForObject("http://microservice-simple-provider-user/simple/" + id, User.class);
  }
  
  @GetMapping("/test")
  public String test() {
//    ServiceInstance serviceInstance = this.loadBalancerClient.choose("microservice-simple-provider-user");
//    System.out.println("111" + ":" + serviceInstance.getServiceId() + ":" + serviceInstance.getHost() + ":" + serviceInstance.getPort());

    ServiceInstance serviceInstance2 = this.loadBalancerClient.choose("microservice-simple-provider-user2");
    System.out.println("222" + ":" + serviceInstance2.getServiceId() + ":" + serviceInstance2.getHost() + ":" + serviceInstance2.getPort());

    return "1";
  }
  
}
package com.learn.cloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableEurekaClient
public class ConsumerMovieRibbonApplication {

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

  public static void main(String[] args) {
    SpringApplication.run(ConsumerMovieRibbonApplication.class, args);
  }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值