【SpringCloud】Ribbon定制化配置

文章目录

使用Ribbon自带负载均衡算法

添加负载均衡算法Configuration

java 复制代码
//注意package位置假设启动器为@ComponentScan("com.test.springcloud")
package com.test.config
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MySelfRule
{
    @Bean
    public IRule myRule()
    {
        return new RandomRule();//定义为随机
    }
}

注意:

官方文档明确给出了警告

这个自定义配置类不能放在@ComponentScan所扫描的当前包下以及子包下,

否则我们自定义的这个配置类就会被所有的Ribbon客户端所共享,达不到特殊化定制的目的了。

RestTemplate使用上面负载均衡算法

java 复制代码
package com.test.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;

@Configuration
public class ApplicationContextConfig
{
    @Bean
    @LoadBalanced //添加负载均衡配置注解,如果自定义的话不需要使用该注解否则报错
    public RestTemplate getRestTemplate()
    {
        return new RestTemplate();
    }
}

自定义负载均衡算法

负载均衡算法实现

定义负载均衡算法接口

java 复制代码
public interface LoadBalancer
{
    ServiceInstance instances(List<ServiceInstance> serviceInstances);
}

实现负载均衡算法

java 复制代码
@Component
public class MyLB implements LoadBalancer
{
	//通过CAS(乐观锁)的方式进行,本质是通过CompareAndSet,先比较后赋值的方式,只有当前值和期望值相同时才可以进行赋值
    private AtomicInteger atomicInteger = new AtomicInteger(0);

    public final int getAndIncrement()
    {
        int current;
        int next;

        do {
            current = this.atomicInteger.get();
            next = current >= 2147483647 ? 0 : current + 1;
        }while(!this.atomicInteger.compareAndSet(current,next));
        System.out.println("*****第几次访问,次数next: "+next);
        return next;
    }

    //负载均衡算法:rest接口第几次请求数 % 服务器集群总数量 = 实际调用服务器位置下标  ,每次服务重启动后rest接口计数从1开始。
    @Override
    public ServiceInstance instances(List<ServiceInstance> serviceInstances)
    {
        int index = getAndIncrement() % serviceInstances.size();

        return serviceInstances.get(index);
    }
}

以上实现负载均衡算法的instance可自定义

RestTemplate

java 复制代码
package com.test.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;

@Configuration
public class ApplicationContextConfig
{
    @Bean
    //@LoadBalanced //去掉这个注解
    public RestTemplate getRestTemplate()
    {
        return new RestTemplate();
    }
}

在Controller中使用该负载均衡算法

java 复制代码
public class Controller{
	@GetMapping(value = "/consumer/payment/lb")
    public String getPaymentLB()
    {
        List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
        if(instances == null || instances.size() <= 0)
        {
            return null;
        }
        // 在下面有解释ServiceInstance
        ServiceInstance serviceInstance = loadBalancer.instances(instances);
        URI uri = serviceInstance.getUri();
        return restTemplate.getForObject(uri+"/payment/lb",String.class);

    }

}

ServiceIInstance解释

ServiceInstance 是 Spring Cloud 提供的一个接口,用于表示服务的实例信息。它提供了获取服务实例的相关信息和元数据的方法。

ServiceInstance 接口定义了以下常用方法:

  • String getServiceId(): 获取服务名称(serviceId)。
  • String getHost(): 获取服务实例的主机名。
  • int getPort(): 获取服务实例的端口号。
  • boolean isSecure(): 返回服务实例是否使用安全协议(如 HTTPS)进行通信。
  • URI getUri(): 获取服务实例的完整 URI。
  • Map<String, String> getMetadata(): 返回服务实例的元数据,这些元数据可以由服务提供方自定义。
  • 通过使用 DiscoveryClient(服务发现客户端)获取到的服务实例列表,可以进一步使用 ServiceInstance 接口来获取每个服务实例的具体信息。
    示例:
java 复制代码
@Autowired
private DiscoveryClient discoveryClient;

public void getServiceInstances(String serviceName) {
    List<ServiceInstance> instances = discoveryClient.getInstances(serviceName);
    for (ServiceInstance instance : instances) {
        String serviceId = instance.getServiceId();
        String host = instance.getHost();
        int port = instance.getPort();
        boolean isSecure = instance.isSecure();
        URI uri = instance.getUri();
        Map<String, String> metadata = instance.getMetadata();
        
        // 打印服务实例信息
        System.out.println("Service ID: " + serviceId);
        System.out.println("Host: " + host);
        System.out.println("Port: " + port);
        System.out.println("Is Secure: " + isSecure);
        System.out.println("URI: " + uri);
        System.out.println("Metadata: " + metadata);
    }
}
相关推荐
成富3 小时前
文本转SQL(Text-to-SQL),场景介绍与 Spring AI 实现
数据库·人工智能·sql·spring·oracle
鹿屿二向箔5 小时前
基于SSM(Spring + Spring MVC + MyBatis)框架的汽车租赁共享平台系统
spring·mvc·mybatis
豪宇刘5 小时前
SpringBoot+Shiro权限管理
java·spring boot·spring
想进大厂的小王5 小时前
项目架构介绍以及Spring cloud、redis、mq 等组件的基本认识
redis·分布式·后端·spring cloud·微服务·架构
customer085 小时前
【开源免费】基于SpringBoot+Vue.JS医院管理系统(JAVA毕业设计)
java·vue.js·spring boot·后端·spring cloud·开源·intellij-idea
一只爱打拳的程序猿6 小时前
【Spring】更加简单的将对象存入Spring中并使用
java·后端·spring
杨荧6 小时前
【JAVA毕业设计】基于Vue和SpringBoot的服装商城系统学科竞赛管理系统
java·开发语言·vue.js·spring boot·spring cloud·java-ee·kafka
ajsbxi9 小时前
苍穹外卖学习记录
java·笔记·后端·学习·nginx·spring·servlet
鹿屿二向箔9 小时前
基于SSM(Spring + Spring MVC + MyBatis)框架的咖啡馆管理系统
spring·mvc·mybatis