SpringCloud之Ribbon负载均衡器

了解Ribbon

    什么是负载均衡?负载均衡(LoadBanlance)就是将用户请求平均分摊到多个服务上,从而达到系统的高可用。
    服务端负载均衡:利用代理服务器(nginx),先发送请求,然后通过负载均衡算法,在多个服务器之间选择一个进行访问;即在服务器端进行负载均衡算法分配。
    客户端负载均衡:客户端会有一个服务器地址列表,在发送请求前通过负载均衡算法选择一个服务器,然后进行访问,即在客户端就进行负载均衡算法分配。
    SpringCloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。(Eureka中已经集成了Ribbon,所以不需要引入新包)

项目搭建

注:在springcloud-eureka-application基础上做修改,我们提供两个生产者provider01与provider02

1、修改配置

在之前项目基础上,provider再复制一份新的出来,做个集群,保证端口不冲突,配置注意如下;
集群中的provider要保证:spring.application.name=provider相同,eureka.instance.instance-id不同,否则集群不成功。
例如:

spring.application.name均为provider

spring:
  application:
    name: provider     

instance-id分别为provider01与provider02

eureka:
  instance:
  instance-id: provider01
eureka:
  instance:
  instance-id: provider02

2、修改consumer中的RestTemplate,加上@LoadBalanced注解
在这里插入图片描述
3、修改consumer中的调用方式
在这里插入图片描述
修改完成之后启动Eureka Server、Provider01、Provider02与Consumer,查看Eureka界面,如下所示:
在这里插入图片描述
调用consumer中的接口:http://localhost:8083/list
查看两个provider中的调用情况,会发现两个服务被轮询访问。(Ribbon默认采用的就是轮询算法)

完整代码如下:

https://gitee.com/superbutton/spring-cloud-study/tree/develop/springcloud-ribbon-application

    那么为什么根据服务名就可以选择定位到服务的相关信息,可以追踪到源码的LoadBalancerInterceptor,看到相关的处理思路
在这里插入图片描述
这里rule可以查看到具体的负载均衡策略
在这里插入图片描述
默认采用轮询算法
在这里插入图片描述
在这里插入图片描述

修改负载均衡策略的两种方式

1、修改配置文件application.yml
修改格式:服务名.Ribbon. NFLoadBalancerRuleClassName=****(策略的全类名)

provider:   #配置负载均衡策略的服务名
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule   #随机

2、修改代码
创建配置类,注意,该类不能放在ComponentScan的同包或子包下,这里我创建com.zh.rule.myrule包,之前的代码都在com.zh.cloud包下:

package com.zh.rule.myrule;

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 MyRule {

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

在主类中添加注解@RibbonClient(name = “provider”,configuration = MyRule.class)
解释:name是服务提供者的服务名,configuration 配置的负载均衡的配置

package com.zh.cloud;

import com.zh.rule.myrule.MyRule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;

@SpringBootApplication
@EnableDiscoveryClient // 开启EurekaClient功能
@RibbonClient(name = "provider",configuration = MyRule.class)
public class ConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }
}

注:如果有多个需要配置,如下所示:

@RibbonClients(@RibbonClient(name = "provider",configuration = MyRule.class),@RibbonClient(name = "provider2",configuration = MyRule2.class))

这种也适合自定义负载均衡策略。

有兴趣的话可以看看这种配置方法,感觉太麻烦。

常见的负载均衡策略

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

重试策略

    思考一个问题,两个provider,突然一个挂了,但是之前说过的eureka的自我保护策略,服务并没有被及时剔除,那么consumer访问时势必会出现问题。所以这里有一个重试机制。SpringCloud整合了Spring Retry增强了restTemplate的重试能力,当第一次访问服务失败之后,会再次重试另一个服务。
实现方式如下(调用端修改):
添加Spring-retry依赖

<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
</dependency>

修改配置文件:

spring:
  cloud:
    loadbalancer:
      retry:
        enabled: true # 开启Spring Cloud的重试功能
provider:   #调用服务的服务名
  ribbon:
    ConnectTimeout: 250 # Ribbon的连接超时时间.超时后开始重试
    ReadTimeout: 1000 # Ribbon的数据读取超时时间
    OkToRetryOnAllOperations: true # 是否对所有操作都进行重试
    MaxAutoRetriesNextServer: 1 # 切换实例的重试次数
MaxAutoRetries: 1 # 对当前实例的重试次数

    测试中随意kill一台provider,查看是否会出现调用异常。可以看到内部已经有了重试机制,不会再出现异常了。
完整代码:

https://gitee.com/superbutton/spring-cloud-study/tree/develop/springcloud-ribbon-retry

了解Feign

    一个可以简化ribbon调用,方便开发的组件:Feign。
    Feign是一个声明式WebService客户端,它让微服务之间的调用变得更简单了。(Feign已经封装了Ribbon,让ribbon的调用方式更简单,若要配置负载均衡策略之类的,还是按照之前的配置就行。)
项目构建(consumer改造)
导入依赖:

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

主类上加使能注解:@EnableFeignClients
在这里插入图片描述
新建UserClientInter

package com.zh.cloud.api;

import com.zh.cloud.model.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.List;

@FeignClient(value = "provider")   //调用的服务名
public interface UserClientInter {
    /**
     * 暴露接口
     * @return
     */
    @GetMapping("/v1/user/list")   //此处的调用路径必须与服务提供者的路径相同
    public List<User> queryUser();     //接口声明与服务提供者保持一致
}

controller调用

package com.zh.cloud.controller;

import com.zh.cloud.api.UserClientInter;
import com.zh.cloud.model.User;
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.GetMapping;
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 UserClientInter userClientInter;

    @GetMapping("/list")
    public List<User> getUsers() {
        return userClientInter.queryUser();
    }
}

启动进行访问:http://localhost:8082/list
完整代码如下:

https://gitee.com/superbutton/spring-cloud-study/tree/develop/springcloud-feign-application
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值