Ribbon核心组件IRule
修改 3-cloud-consumer-order80
新建 Ribbon 规则类
注意该包不能被扫描到
代码语言:javascript复制package com.ray.myrule;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Description: Ribbon 规则类
* @Author Administrator
* @Date 2020/10/11 14:20
* @Version 1.0
*/
@Configuration
public class MySelfRule {
@Bean
public IRule myRule() {
return new RandomRule(); // 定义为随机
}
}
config
代码语言:javascript复制package com.ray.springcloud.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
* @Description: 相当于封装了 HttpClient
* @Author Ray
* @Date 2020/10/07 11:40
* @Version 1.0
*/
@Configuration
public class RestTemplateConfig {
@Bean
@LoadBalanced // 赋予负载均衡能力
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}
改 main
代码语言:javascript复制package com.ray.springcloud;
import com.ray.myrule.MySelfRule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
/**
* @Description:
* @Author Ray
* @Date 2020/10/07 11:41
* @Version 1.0
*/
@SpringBootApplication
@EnableEurekaClient // 客户端
@RibbonClient(name = "CLOUD-PAYMENT-SERVICE", configuration = MySelfRule.class) // 负载规则替换,默认轮询
public class OrderMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderMain80.class, args);
}
}
测试
http://localhost/consumer/payment/get/130
随机使用 8001 或 8002 端口
Ribbon负载均衡算法
改造 8001 和 8002
controller
代码语言:javascript复制@GetMapping("/lb")
public String getPaymentLB() {
return port;
}
改造 80
config
代码语言:javascript复制package com.ray.springcloud.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
* @Description: 相当于封装了 HttpClient
* @Author Ray
* @Date 2020/10/07 11:40
* @Version 1.0
*/
@Configuration
public class RestTemplateConfig {
@Bean
//@LoadBalanced // 赋予负载均衡能力
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}
interface
代码语言:javascript复制package com.ray.springcloud.lb;
import org.springframework.cloud.client.ServiceInstance;
import java.util.List;
/**
* @Description: 自己实现轮询算法 - 接口
* @Author Administrator
* @Date 2020/10/11 14:57
* @Version 1.0
*/
public interface LoadBalancer {
/**
* 得到目前注册中心可以使用的集群机器,放到集合里面
*/
ServiceInstance instances(List<ServiceInstance> serviceInstances);
}
service
代码语言:javascript复制package com.ray.springcloud.lb;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @Description: 自己实现轮询算法 - 实现
* @Author Administrator
* @Date 2020/10/11 15:14
* @Version 1.0
*/
@Slf4j
@Component
public class MyLB implements LoadBalancer {
// 默认从0开始
private AtomicInteger atomicInteger = new AtomicInteger(0);
/**
* 获取当前的次数
*/
public final int getAndIncrement() {
int current;
int next;
do {
// 得到当前的值
current = this.atomicInteger.get();
// 考虑防止越界,实际肯定不会这么大
next = current >= Integer.MAX_VALUE ? 0 : current 1;
// 如果值不相同,不停自旋,直到相同 compareAndSet
log.info("<<<<< 自旋中 current: [{}] -- next: [{}]", current, next);
} while (!this.atomicInteger.compareAndSet(current, next));
log.info(">>>>> 访问次数 next: [{}]", next);
return next;
}
/**
* 第几次请求数
*/
@Override
public ServiceInstance instances(List<ServiceInstance> serviceInstances) {
int index = getAndIncrement() % serviceInstances.size();
return serviceInstances.get(index);
}
}
测试
http://localhost/consumer/payment/lb
结果:依次输出 8001 和 8002
结论:自定义算法实现Ribbon负载均衡默认轮询