springcloud攻坚 ribbon

ribbon是一个负载均衡工具,在springcloud的很多组件的中都将它融合进去了,所以有时候会出现很多让人蛋疼的版本冲突问题,笔者在学习的过程中就遇到了一些问题,其中最难受的就是yml文件中无法配置ribbon的连接超时时间,也翻看了一些源码,发现是底层有个配置类写死了,但又没有什么好的解决方案,如果您有幸略过此篇文章并有遇到过类似的问题,非常希望您提点下我_
好(o)/~ 先记录下怎么搭建的吧
ribbon一般用于消费者的负载均衡,这里就略过服务提供者的那部分了

一、引入pom依赖

eureka整合了ribbon,所以只要引入eureka的依赖即可

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

二、主启动类记得打开@EnableEurekaClient注解哦

package com.atguigu.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})
@EnableEurekaClient
public class OrderMain80 {

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

其实到这里ribbon已经开始了负载均衡,但是默认的负载算法是轮询,是不是完全无感知,说白了@EnableEurekaClient已经开启了ribbon 哈哈

三、修改默认的负载均衡策略

新建一个配置类,这个类一定不能在主启动类同级别或主启动类级别的包下面(官网有明确要求)

package com.atguigu.ribbon;

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.WeightedResponseTimeRule;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;

@Configurable
public class RibbonConfiguration {

        @Bean
        public IRule ribbonRule(IClientConfig clientConfig) {
        		// 注册别的默认负载均衡方法
                return new WeightedResponseTimeRule(); 
        }

}

同时在主启动类级别的包下添加另外一个配置类,给RestTemplate添加负载均衡功能

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class ApplicationContentConfig {

    @Bean
    @LoadBalanced //开启ribbon自带负载均衡
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}

这样就妥了

四、自己写负载均衡策略

这里给个案例
在这里插入图片描述
接口 不多说

package com.atguigu.springcloud.lb;

import org.springframework.cloud.client.ServiceInstance;

import java.util.List;

public interface LoderBalancer {
    ServiceInstance instances(List<ServiceInstance> instances);
}

AtomicInteger 原子类存储请求个数
自己写逻辑获取要调用的服下标

package com.atguigu.springcloud.lb;

import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

@Component
public class MYLB implements LoderBalancer {
    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));
        return next;
    }
    @Override
    public ServiceInstance instances(List<ServiceInstance> instances) {
        int index = getAndIncrement()%instances.size();
        return instances.get(index);
    }
}

获取所有的服务
调用上述方法获取下标,调用对用的服务

package com.atguigu.springcloud.controller;

import com.atguigu.springcloud.entities.CommenResult;
import com.atguigu.springcloud.entities.Payment;
import com.atguigu.springcloud.lb.LoderBalancer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.net.URI;
import java.util.List;

@RestController
@Slf4j
public class OrderController {

    @Autowired
    RestTemplate restTemplate;
    @Autowired
    LoderBalancer loderBalancer;
    @Autowired
    DiscoveryClient discoveryClient;

    // private String url = "http://CLOUD-PAYMEN-SERVICE/";

    @GetMapping(value = "consumer/payment/lb")
    public CommenResult<Payment> getPaymentLB(@PathVariable("id") long id){
        List<ServiceInstance> instances = discoveryClient.getInstances("服务提供者名称");
        if (null == instances || instances.size()<=0){
            return null;
        }
        ServiceInstance serviceInstance = loderBalancer.instances(instances);
        URI uri = serviceInstance.getUri();
        return restTemplate.getForObject(uri+"payment/get/"+id,CommenResult.class);
    }


}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值