前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >《SpringCloud篇:002Ribbon服务之间的负载均衡》

《SpringCloud篇:002Ribbon服务之间的负载均衡》

作者头像
发布2020-11-13 14:37:32
2620
发布2020-11-13 14:37:32
举报
文章被收录于专栏:后端JavaEE后端JavaEE

一、概述

Ribbon是为了实现服务与服务之间调用的负载均衡,是客户端负载均衡,并且默认采用轮询的策略。(类似于Nginx,但是Ribbon是用于服务端的,Nginx是客户端的)

找官方文档

在这里插入图片描述
在这里插入图片描述

根据文档配置pom依赖

在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>

启动类上加LoadBalance注解

代码语言:javascript
复制
package com.qf.springcloud.consumer;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableFeignClients
@EnableCircuitBreaker
@EnableHystrixDashboard
@ServletComponentScan(basePackages = "com.qf.springcloud.consumer")
public class ConsumerStarterApp {

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


    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }


//    @Bean
//    public IRule randomRule(){
//        return new RandomRule();
//    }
}

修改controller,改成直接访问就可以

代码语言:javascript
复制
package com.qf.springcloud.consumer.controller;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.qf.springcloud.consumer.client.ProviderClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;

@RestController
public class ConsumerController {

    /*@Autowired
    private EurekaClient eurekaClient;*/

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private ProviderClient providerClient;

    @GetMapping("/consumer/test")
    public String test() throws InterruptedException {
        /*//1. 通过Eureka获取PROVIDER服务的ip和port
        InstanceInfo provider = eurekaClient.getNextServerFromEureka("PROVIDER", false);
        String ip = provider.getIPAddr();
        int port = provider.getPort();

        //2. 通过RestTemplate调用provider的/provider/test
        String result = restTemplate.getForObject("http://" + ip + ":" + port + "/provider/test", String.class);*/

        /*
        //1. 访问目标服务
        String result = restTemplate.getForObject("http://PROVIDER/provider/test", String.class);
        */
        Thread.sleep(2000);
        System.out.println("test:" + Thread.currentThread().getName());
        String result = providerClient.test();
        //3. 返回结果
        return result;
    }


    @GetMapping("/param/test/{type}")
    /*
    @HystrixCommand(fallbackMethod = "paramTestFallback",commandProperties = {
            @HystrixProperty(name = "circuitBreaker.enabled",value = "true"),
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "20"),
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "30000"),
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "10")

    })
    */
    public Map paramTest(@PathVariable Integer type) throws InterruptedException {
        System.out.println("paramTest:" + Thread.currentThread().getName());
        if (type == 1){
            // path
            return providerClient.path(123);
        }else if (type == 2){
            int i = 1 / 0;
            // param
            return providerClient.param("张老三",233);
        }else{
            // body
            Map map = new HashMap();
            map.put("abcdefg","hijklmn");
            return providerClient.body(map);
        }
    }


    public Map paramTestFallback(Integer type){
        System.out.println("paramTestFallback:" + Thread.currentThread().getName());
        Map map = new HashMap();
        map.put("msg","我的Consumer自己出现了问题");
        return map;
    }
}

为了掩饰负载均衡,所以我们创建多个provider,复制原来的provider,在application.yml中修改它的端口号

代码语言:javascript
复制
spring:
  application:
    # 指定服务名称
    name: provider



eureka:
  client:
    service-url:
      # 指定注册到的eureka的地址信息
      defaultZone: http://admin:admin@localhost:8761/eureka/,http://admin:admin@localhost:8762/eureka/



server:
  port: 8081

在controller也修改一下它的内容让它们有所区分

代码语言:javascript
复制
package com.qf.springcloud.provider.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ProviderController {

    @Value("${server.port}")
    private String port;

    @GetMapping("/provider/test")
    public String test(){
        return "Hello Eureka!!!" + port;
    }

}

重启consumer,实现负载均衡(默认轮询)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

使用注解或者yml来修改复杂均衡策略 修改consumer中的启动类,注解中的(随机效果)

代码语言:javascript
复制
package com.qf.springcloud.consumer;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableFeignClients
@EnableCircuitBreaker
@EnableHystrixDashboard
@ServletComponentScan(basePackages = "com.qf.springcloud.consumer")
public class ConsumerStarterApp {

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


    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }


//    @Bean
//    public IRule randomRule(){
//        return new RandomRule();
//    }
}

使用yml配置响应时间权重的负载均衡

代码语言:javascript
复制
PROVIDER:
 ribbon:
   NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightResponseTimeRule

重启,先以轮训开始,然后根据响应时间分配权重

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-11-11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、概述
相关产品与服务
负载均衡
负载均衡(Cloud Load Balancer,CLB)提供安全快捷的流量分发服务,访问流量经由 CLB 可以自动分配到云中的多台后端服务器上,扩展系统的服务能力并消除单点故障。负载均衡支持亿级连接和千万级并发,可轻松应对大流量访问,满足业务需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档