目录
负载均衡 Nginx ,Ribbon, Feign 这三者之间的区别?
Ribbon概述
Ribbon是什么?
Ribbon能干什么?
1.LB负载均衡
1.1 集中式LB(偏硬件)
1.2 进程式LB(偏软件)
Ribbon官网
https://github.com/Netflix/ribbon/wiki/Getting-Started
Ribbon配置初步(重点)
-
Ribbon是客户端的负载均衡,修改服务消费者的pom.xml文件
-
修改服务消费者的application.yml文件,追加Eureka的服务注册地址
-
在服务消费者的主配置类ConfigBean中注入的 RestTemplate 类上添加 @LoadBalanced 注解
-
在服务消费者上的主启动类上添加 @EnableEurekaClient 注解
-
修改服务消费者的Controller类,实现通过负载均衡和Eureka结合去访问服务提供者。
当不使用Eureka的时候,你也可以直接访问服务提供者,前提你自己要知道服务的访问地址,端口号等信息。
当使用Eureka的时候,你可以通过Eureka去获取服务的信息,然后根据信息去访问相应的服务。
Ribbon是客户端的负载均衡,当某一个服务是一个集群的时候(注册到Eureka的服务名字都一样),对服务的选择需要负载均衡,
springCloud_Eureka 与 Ribbon的结合,可以简化服务访问的的过程,简化获取服务信息的过程(不用再使用DiscoveryClient获取信息
了)。
- 完成,启动顺序。先启动Eureka服务,然后启动服务提供者,再启动服务消费者。—ok完成。
结论:Ribbon和Eureka整合后服务消费者可以直接调用服务而不用再关心地址和端口号
Ribbon负载均衡
多集群,多为微服务架构。
构建步骤
- 分别建立三个服务提供者,这三个服务注册到Eureka的服务名字都要一样。三个服务的pom.xml文件如下:
- 启动顺序:先启动Eureka服务,在启动三个服务提供者,最后启动服务消费者。
- 服务消费者进行访问
- 结果如下图,每次访问的服务消费者不一样,采用轮询算法。
总结: Ribbon其实就是一个软负载均衡的客户端组件 ,他可以和其他所需请求的客户端结合使用,和eureka结合只是其中的一 个实例。
Ribbon核心组件IRule(负责选择什么样的负载均衡算法)
IRule:根据特定算法中从服务列表中选取一个要访问的服务。
默认使用的是轮询算法,如果修改别的算法,修改服务消费者的配置类ConfigBean,代码如下:
Ribbon源码解析
查看官网
Ribbon自定义负载均衡算法(默认有的算法:轮询,随机,根据响应时间加权)
链接地址
自定义Ribbon负载均衡算法的注意事项:
注意:官方文档中有指出,自定义的类不能放在@ComponentScan或SpringBootApplication所扫描的当前包以及子包下,否则自定义的这个配置类将会被所有的Ribbon客户端所共享。
实现步骤
1、在启动器的上一级创建一个包存放自定义算法的文件
2、找到一个自带的负载均衡算法,以随机算法为例,将RandomRule的代码拿出来,修改一下新的文件名。自定义算法必须继承于AbstractLoadBalancerRule类
package com.demo.myrule;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
public class RandomRule_Test extends AbstractLoadBalancerRule {
public RandomRule_Test() {
}
private int total=0; //当前调用次数
private int currentIndex=0; //当前被引用的服务
public Server choose(ILoadBalancer lb, Object key) {
if (lb == null) {
return null;
} else {
Server server = null;
while(server == null) {
if (Thread.interrupted()) {
return null;
}
List<Server> upList = lb.getReachableServers();
List<Server> allList = lb.getAllServers();
int serverCount = allList.size();
if (serverCount == 0) {
return null;
}
//自定义的负载均衡算法
if (total<5){
server=upList.get(currentIndex);
total++;
}else{
total=0;
currentIndex++;
if (currentIndex>upList.size()-1){
currentIndex=0;
}
server=upList.get(currentIndex);
}
/*
Ribbon自带的一个获取随机Server的算法
int index = this.chooseRandomInt(serverCount);
server = (Server)upList.get(index);
*/
if (server == null) {
Thread.yield();
} else {
if (server.isAlive()) {
return server;
}
server = null;
Thread.yield();
}
}
return server;
}
}
protected int chooseRandomInt(int serverCount) {
return ThreadLocalRandom.current().nextInt(serverCount);
}
public Server choose(Object key) {
return this.choose(this.getLoadBalancer(), key);
}
public void initWithNiwsConfig(IClientConfig clientConfig) {
}
}
3、将自定义的负载均衡算法注入到Bean中,在自定义算法的文件同级创建一个配置类
package com.demo.myrule;
import com.netflix.loadbalancer.IRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class Rule_Test {
@Bean
public IRule myRule(){
//需要什么算法就new对应的类
return new RandomRule_Test();
}
}
4、在启动类中添加Ribbon注解
package com.demo.springcloud;
import com.demo.myrule.Rule_Test;
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;
@SpringBootApplication
@EnableEurekaClient
//name:针对哪个服务,configuration:使用什么算法类
@RibbonClient(name = "SPRINGCLOUD.PROVIDER-DEPT",configuration = Rule_Test.class)
public class DeptConsumer_80 {
public static void main(String[] args) {
SpringApplication.run(DeptConsumer_80.class,args);
}
}
5、测试,将7001端口的服务注册中心启动,然后启动8001,8002,8003以及80端口的负载均衡微服务,在访问80负载均衡客户端请求时,每次刷新的结果都是按照我们写的这个负载均衡算法去执行,就算达成效果了