这次使用的项目基础是 之前学习eureka的项目
具体的博客地址 在这里 : Eureka服务注册中心的使用
1.简单介绍rribbon
不过现在ribbon进入维护, 基本上并不准备更新了
2.负载均衡的几种形式
2.1 进程内LB(本地负载均衡)
2.2集中式LB(服务器负载均衡)
2.3区别
而 ribbon就是负载均衡+restTempalte
3.服务调用架构
4.使用ribbon
在eureka zookeeper consul中 都集成了 ribbon 所以在搭建项目的时候 不需要 再引入ribbon的依赖
其实在eureka博客的项目中,订单服务调用支付服务 实现的负载均衡 是 ribbon 实现的负载均衡,且是ribbon自带的几种负载均衡算法中的默认算法——轮询算法
4.1ribbon的自带算法
IRule接口,Riboon使用该接口,根据特定算法从所有服务中,选择一个服务,
Rule接口有7个实现类,每个实现类代表一个负载均衡算法
4.2设置ribbon的随机算法
首先 声明下 我们使用的是 上次eureka博客写的订单服务和支付服务
注意!!
所以 我们不能跟 服务的主启动类在一个包下
4.2.1 创建自定义负载均衡类
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author Xkuna
* @date 2020/8/5 12:29.
*/
@Configuration
public class MySelfRule {
@Bean
public IRule myRule() {
return new RandomRule() ;
}
}
4.2.2修改主启动类
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;
import top.xkuna.myrule.MySelfRule;
/**
* @author Xkuna
* @date 2020/7/22 12:34.
*/
@SpringBootApplication
@EnableEurekaClient
//自定义rebbion的算法 必须声明 实现该算法的服务名称 和 算法类
@RibbonClient(name = "CLOUD-PAYMENT-SERVICE", configuration = MySelfRule.class)
public class OrderMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderMain80.class,args) ;
}
}
此时依次启动 eureka服务中心 支付服务 订单服务 即可
5.手写ribbon的轮询算法 实现支付服务的 负载均衡
5.1 创建自己的轮询算法接口 和 实现类
package top.xkuna.springcloud.lb;
import org.springframework.cloud.client.ServiceInstance;
import java.util.List;
/**
* @author Xkuna
* @date 2020/8/5 13:52.
*/
public interface LoadBalanced {
ServiceInstance instance(List<ServiceInstance> serviceInstances) ;
}
package top.xkuna.springcloud.lb;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author Xkuna
* @date 2020/8/5 13:54.
*/
@Component
public class MyLB implements LoadBalanced{
private AtomicInteger atomicInteger = new AtomicInteger(0) ;
public final int getAndIncrement() {
int current ;
int next ;
do {
current = atomicInteger.get() ;
next = current >= 2147483647 ? 0 : current + 1 ;
}while (!this.atomicInteger.compareAndSet(current, next)) ;
System.out.println("***********访问次数, next: " + next);
return next ;
}
@Override
public ServiceInstance instance(List<ServiceInstance> serviceInstances) {
int index = getAndIncrement() % serviceInstances.size() ;
return serviceInstances.get(index);
}
}
5.2 修改订单服务 controller
package top.xkuna.springcloud.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import top.xkuna.springcloud.lb.LoadBalanced;
import javax.annotation.Resource;
import java.net.URI;
import java.util.List;
/**
* @author Xkuna
* @date 2020/7/22 12:37.
*/
@RestController
@Slf4j
public class OrderController {
public static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE" ;
@Resource
private RestTemplate restTemplate ;
@Resource
private LoadBalanced loadBalanced ;
@Resource
private DiscoveryClient discoveryClient ;
@GetMapping("port")
public String getPort(){
List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
ServiceInstance instance = loadBalanced.instance(instances);
URI uri = instance.getUri();
return restTemplate.getForObject(uri + "/port", String.class) ;
}
}
将restTempalte配置类的loadBalanced注解去掉
5.3 修改订单服务 主启动类
将我们自定义算法注解注释
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;
import top.xkuna.myrule.MySelfRule;
/**
* @author Xkuna
* @date 2020/7/22 12:34.
*/
@SpringBootApplication
@EnableEurekaClient
//@RibbonClient(name = "CLOUD-PAYMENT-SERVICE", configuration = MySelfRule.class)
public class OrderMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderMain80.class,args) ;
}
}
5.4 修改端口为8001 的支付服务的controller
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
/**
* @author Xkuna
* @date 2020/7/22 11:10.
*/
@RestController
@Slf4j
public class PaymentControler {
@Value("${server.port}")
private String serverPort ;
@GetMapping("/port")
public String getPort(){
return this.serverPort ;
}
}
5.5修改端口为8002 的支付服务的controller
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
/**
* @author Xkuna
* @date 2020/7/22 11:10.
*/
@RestController
@Slf4j
public class PaymentControler {
@Resource
@Value("${server.port}")
private String serverPort ;
@GetMapping("/port")
public String getPort(){
return this.serverPort ;
}
}
此时依次启动 eureka服务中心 支付服务 订单服务
用 订单服务调用 支付服务 即可实现 轮询算法的负载均衡