springcloud篇】四. Ribbon负载均衡和Feign负载均衡


中国加油,武汉加油!

篇幅较长,请配合目录观看

项目准备

  1. 本案例基于springcloud篇】三. Eureka入门
  2. 7001,8181,8282,8383改配置
    eureka.client.service-url.defaultZone=http://eureka.7001.com:7001/eureka
  3. 本章重点不在eureka
  4. 主Ribbon 次Feign

1. Ribbon

SpringCloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。

简单的说,Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。Ribbon客户端组件提供一系列完善的配置项如连接超时重试等。简单的说,就是在配置文件中列出LoadBalanCer(简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器。我们也很容易使用Ribbon实现自定义的负载均衡算法。

1.1 LB(负载均衡)

LB,即负载均衡( LoadBalanced ),在微服务或分布式集群中经常用的一种应用。
负载均衡简单的说就是将用户的请求平摊的分配到多个服务上,从而达到系统的HA。
常见的负载均衡有软件nginx , LVS,硬件F5等。
相应的在中间件,例如:dubbo和 SpringCloud中均给我们提供了负载均衡,SpringCloud的负载均衡算法可以自定义。

1.2 相关链接

  1. 官方资料:https://github.com/Netflix/ribbon/wiki

1.3 Ribbon核心组件IRule(面试题)

策略名称策略对应的类名实现原理
轮询策略(默认)RoundRobinRule轮询策略表示每次都顺序取下一个 provider,比如一共有 5 个provider,第 1 次取第 1 个,第 2次取第 2 个,第 3 次取第 3 个,以此类推
权重轮询策略WeightedResponseTimeRule1.根据每个 provider 的响应时间分配一个权重,响应时间越长,权重越小,被选中的可能性越低。2.原理:一开始为轮询策略,并开启一个计时器,每 30 秒收集一次每个 provider 的平均响应时间,当信息足够时,每个 provider附上一个权重,并按权重随机选择provider,高权越重的 provider会被高概率选中。
随机策略RandomRule从 provider 列表中随机选择一个provider
最少并发数策略BestAvailableRule选择正在请求中的并发数最小的 provider,除非这个provider 在熔断中。
在“选定的负载均衡策略”基础上进行重试机制RetryRule1.“选定的负载均衡策略”这个策略是轮询策略RoundRobinRule 2.该重试策略先设定一个阈值时间段,如果在这个阈值时间段内当选择 provider 不成功,则一直尝试采用“选定的负载均衡策略:轮询策略”最后选择一个可用的provider
可用性敏感策略AvailabilityFilteringRule过滤性能差的 provider,有 2种:第一种:过滤掉在 eureka 中处于一直连接失败 provider 第二种:过滤掉高并发的 provider
区域敏感性策略ZoneAvoidanceRule1.以一个区域为单位考察可用性,对于不可用的区域整个丢弃,从剩下区域中选可用的provider2.如果这个 ip 区域内有一个或多个实例不可达或响应变慢,都会降低该 ip 区域内其他 ip 被选中的权重。

2. 新建springcloud-producer-8383项目(Module-Maven)

2.1 复制pom依赖

2.2 复制java代码

2.3 复制application.properties并修改

server.port=8383
eureka.client.service-url.defaultZone=http://eureka.7001.com:7001/eureka
eureka.instance.instance-id=springcloud-producer-8383
eureka.instance.lease-expiration-duration-in-seconds=90
eureka.instance.lease-renewal-interval-in-seconds=30

在这里插入图片描述

2.4 启动7001和8181,8282,8383

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

2.5 springcloud-consumer开启负载均衡

package com.wpj.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
/**
 * 远程调用的工具类  OkHttp客户端
 */
@Configuration
public class RestTemplateConfig {

    // 这次我们使用了OkHttp客户端,只需要注入工厂即可
    @Bean
    @LoadBalanced   // 开启负载均衡
    public RestTemplate restTemplate(){
        return new RestTemplate(new OkHttp3ClientHttpRequestFactory());
    }
}

2.6 springcloud-consumer修改controller

package com.wpj.controller;

import com.wpj.bean.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.List;

@RestController
@Scope("prototype")
public class UserController {
    @Resource
    private RestTemplate restTemplate;
    
    private static final String url="http://springcloud-producer";
    
    @RequestMapping("/list")
    public List<User> list(){
        return this.restTemplate.getForObject(url+"/list",List.class);
    }
}

2.7 重启程序入口并访问http://127.0.0.1:8282/list

在springcloud-producer和springcloud-producer-8383的Controller输出一段话

2.7.1 通过下面的工具类测试

在这里插入图片描述

3. 修改负载均衡算法

3.1 springcloud-consumer配置application.properties

# {服务名称}.ribbon.NFLoadBalancerRuleClassName
# 配置Ribbon的负载均衡的算法,默认轮询,修改为随机
SPRINGCLOUD-PRODUCER.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule

3.2 编写Test

package com.wpj.test;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;

@RunWith(SpringRunner.class)
@SpringBootTest
public class TestRibbon {

    @Resource
    RibbonLoadBalancerClient client;

    @Test
    public void test1(){
        for (int i = 1; i <=10 ; i++) {
            ServiceInstance instance = client.choose("SPRINGCLOUD-PRODUCER");
            String ip = instance.getHost();
            int port = instance.getPort();
            System.out.println(ip+":"+port);
        }
    }
}

3.3 启动程序类并运行test测试

在这里插入图片描述

4. 修改负载均衡算法第二种方式

4.1 注释掉第一种方式的配置

4.2 修改程序入口

package com.wpj;

import com.netflix.loadbalancer.RandomRule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
@EnableEurekaClient
public class ConsumerApplication {

    /**
     * 显示实例化 负载均衡的策略对象,那么默认的轮询策略就会失效
     * @return
     */
    @Bean
    public RandomRule createRule(){
        return new RandomRule();
    }

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

4.3 运行test测试

在这里插入图片描述

5. Ribbon重置机制

5.1 springcloud-consumer导入依赖

<!-- Ribbon重试机制-->
<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
</dependency>

5.2 application.properties配置

# 配置重试机制
# 开启Spring Cloud的重试功能
spring.cloud.loadbalancer.retry.enabled=true
# Ribbon的连接超时时间
SPRINGCLOUD-PRODUCER.ribbon.ConnectTimeout=250
# Ribbon的数据读取超时时间
SPRINGCLOUD-PRODUCER.ribbon.ReadTimeout=1000
# 是否对所有操作都进行重试
SPRINGCLOUD-PRODUCER.ribbon.OkToRetryOnAllOperations=true
# 切换实例的重试次数
SPRINGCLOUD-PRODUCER.ribbon.MaxAutoRetriesNextServer=1
# 对当前实例的重试次数
SPRINGCLOUD-PRODUCER.ribbon.MaxAutoRetries=1

6. Feign负载均衡

Feign是一个声明式WebService客户端。使用Feign能让编写Web Service客户端更加简单, 它的使用方法是定义一个接口,然后在上面添加注解,同时也支持JAX-RS标准的注解。Feign也支持可拔插式的编码器和解码器。Spring Cloud对Feign进行了封装,使其支持了Spring MVC标准注解和HttpMessageConverters。Feign可以与Eureka和Ribbon组合使用以支持负载均衡。
封装了一个注解,简化Ribbon的调用代码,让代码更加清晰,方便开发~~

6.1 相关链接

  1. 官网 http://projects.spring.io/spring-cloud/spring-cloud.html#spring-cloud-feign

6.2 springcloud-consumer导包

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

6.3 编写UserClient

package com.wpj.api;

import com.wpj.bean.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.List;

@FeignClient("springcloud-producer")
public interface UserClient {
    @RequestMapping("/list")
    public List<User> list();
}

6.4 修改Controller

package com.wpj.controller;

import com.wpj.api.UserClient;
import com.wpj.bean.User;
import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;

@RestController
@Scope("prototype")
public class UserController {

    @Resource
    private UserClient userClient;

    @RequestMapping("/list")
    public List<User> list(){
        return userClient.list();
    }

}

6.5 程序入口添加注解

package com.wpj;

import com.netflix.loadbalancer.RandomRule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class ConsumerApplication {

    /**
     * 显示实例化 负载均衡的策略对象,那么默认的轮询策略就会失效
     * @return
     */
    @Bean
    public RandomRule createRule(){
        return new RandomRule();
    }

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

6.6 访问接口

在这里插入图片描述

7 Feign集成带参方法

/**
 * 根据ID查询
 * @param id
 * @return
 */
@RequestMapping("/getById")
public User getById(@RequestParam Integer id);

/**
 * 模拟传递对象参数
 * @param user
 * @return
 */
@RequestMapping("/updateUser")
public int updateUser(@RequestBody User user);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值