Ribbon负载均衡

Ribbon负载均衡

1.概述:

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

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

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

2、Ribbon初步配置

修改consumer-80的配置

  • pom文件,增加Ribbon的相关依赖
<!--Ribbon相关引用,与eureka有关-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>
  • 修改application.yml ,追加Eureka的注册服务地址
eureka:
  client:
    service-url:
      defaultZone: eureka7001.com:7001/eureka,http://eureka7004.com:7004/eureka,http://eureka7003.com:7003/eureka
    register-with-eureka: false
  • 主启动类中增加注解@EnableEurekaClient
package com.blj.springcloud;

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

@SpringBootApplication
@EnableEurekaClient
public class DeptConsumer80_App {
    public static void main(String[] args) {
        SpringApplication.run(DeptConsumer80_App.class,args);
    }
}
  • ConfigBean配置中增加@LoadBalance注解,开启客户端负载均衡
package com.blj.springcloud.config;


import org.springframework.beans.factory.annotation.Autowired;
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 ConfigBean {

    @Bean
    @LoadBalanced//ribbon实现的一套 ==客户端、负载均衡的工具
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}
  • 修改客户端访问类80的controller,将地址改为微服务名称STUDY-SPRINGCLOUD-DEPT
package com.blj.springcloud.controller;

import com.blj.springcloud.entities.Dept;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import java.util.List;

@RestController
@RequestMapping(value = "consumer")
public class DeptController_Consumer {

    //public static final  String REST_URL_PREFFIX="http://localhost:8001";
    public static final  String REST_URL_PREFFIX="http://STUDY-SPRINGCLOUD-DEPT";

    //使用restTemplate访问restful接口非常简单粗暴
    //(url,requestMap,responseBean.class)这三个参数分别代表
    //REST请求地址,请求参数,HTTP响应被转换的对象类型
    @Autowired
    private RestTemplate restTemplate;

    @PostMapping(value = "/dept/add")
    public boolean add(@RequestBody Dept dept){
        return  restTemplate.postForObject(REST_URL_PREFFIX+"/dept/add",dept,Boolean.class);
    }

    @GetMapping(value ="/dept/get/{deptno}")
    public Dept get(@PathVariable("deptno") Long deptno){
        return  restTemplate.getForObject(REST_URL_PREFFIX+"/dept/get/"+deptno,Dept.class);
    }

    @GetMapping(value ="/dept/list")
    public List<Dept> list(){
        return  restTemplate.getForObject(REST_URL_PREFFIX+"/dept/list",List.class);
    }

    @RequestMapping(value = "/dept/discovery",method = RequestMethod.GET)
    public Object discovery(){
        return  restTemplate.getForObject(
                REST_URL_PREFFIX+"/dept/discovery",
                Object.class);
    }


}
  • 启动
    先启动Eureka集群,然后启动8001服务注册进eureka,再启动80客户端
    在这里插入图片描述
  • 新建8004、8003服务提供者
    复制8001的配置和类

yml配置中的实例名称application name不能改,下面以8083为例

#配置服务器信息
server:
  port: 8003
#数据库信息配置
spring:
  application:
    name: study-springcloud-dept  #微服务名称
  datasource:
    url: jdbc:mysql://localhost:3306/clouddb03?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: root1234
    driver-class-name: com.mysql.jdbc.Driver #mysql驱动包
    type: com.alibaba.druid.pool.DruidDataSource #当前数据源操作类型

    #druid连接池配置
    initialSize: 5  #初始化连接数
    minIdle: 5      #数据库连接池最小连接维持数
    maxActive: 20   #数据库最大活动连接数
    maxWait: 60000
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT 1 FROM DUAL
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    poolPreparedStatements: true
    # 配置监控统计拦截的filters,去掉监控界面sql无法统计,‘wall’用于防火墙
    filters: stat,wall,log4j
    maxPoolPreparedStatementPerConnectionSize: 20
    userGlobalDataSourceStat: true
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500

#Mybatis配置
mybatis:
  #type-aliases-package: com.blj.springcloud.entities        #所有Entities实体类别名所在包
  mapper-locations: classpath:mybatis/mapper/**/*.xml        #mapper映射文件

  configuration:
    map-underscore-to-camel-case: true #开启驼峰命名
    cache-enabled: true #开启二级缓存
  type-aliases-package: com.blj.springcloud.entities        #所有Entities实体类别名所在包

#客户端注册进eureka服务列表
eureka:
  client:
    service-url:
      #defaultZone: http://localhost:7001/eureka
      defaultZone: http://localhost:7001/eureka,http://localhost:7004/eureka,http://localhost:7003/eureka

  instance:
    instance-id:  cloud-dept8003 #自定义服务名称信息
    prefer-ip-address: true   #访问路径可以显示ip地址
info:
  app.name: study-springcloud-micoservices
  company.name: www.blj.com
  build.artifactId: ${project.artifactId}
  build.version: ${project.version}
  • 总结

Ribbon其实就是一个软负载均衡的客户端组件,他和其他所有需要请求的客户端结合使用,和Eureka结合只是其中的一个实例。默认采用轮询算法。

Ribbon核心组件IRule

IRule:根据特定算法中从服务列表中选取一个要访问的服务

Ribbon采用的负载均衡算法:

  • com.netflix.loadbalancer.RoundRobinRule 轮询:默认

  • com.netflix.loadbalancer.RandomRule 随机

  • com.netflix.loadbalancer.AvailabilityFilteringRule 会先过滤掉由于多次访问故
    障而处于断路器跳闸状态的服务、还有并发的连接数量超过阈值的服务,然后对剩余 的服务列表按照轮询策略进行访问

  • com.netflix.loadbalancer.WeightedResponseTimeRule 根据平均响应时间计算所有服务的权重,响应时间越快的服务权重越大,选中的概率越高。刚启动时如果统计信息不足,则上有RoundRobinRule策略,等统计信息足够,会切换到WeightedResponseTimeRule

  • com.netflix.loadbalancer.RetryRule 先按RoundRobinRule轮询算法获取服务,如果失败则在指定时间内进行重试

  • com.netflix.loadbalancer.BestAvailableRule 会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务

  • com.netflix.loadbalancer.ZoneAvoidanceRule 默认规则,复合判断Server所在区域的性能和Server的可用性选择服务

配置负载均衡算法

1、使用Ribbon内置的7种负载均衡的算法:在ConfigBean中显示声明算法,增加bean

@Bean
public IRule myRule(){
    return new RandomRule(); //用我们选择的随机算法
}

2.使用自定义的负载均衡算法

  • 1、主启动类上添加注解@RibbonClient
package com.blj.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;

@SpringBootApplication
@EnableEurekaClient
//在启动该微服务式是能去加载我们定义的Ribbon配置类
@RibbonClient(name="STUDY-SPRINGCLOUD-DEPT",configuration = MySelfRule.class)
public class DeptConsumer80_App {
    public static void main(String[] args) {
        SpringApplication.run(DeptConsumer80_App.class,args);
    }
}
  • 2、编写自定义Ribbon配置类

注意:Ribbon官方文档明确指出:自定义配置类不能放在@ComponentScan所扫描的当前包以及子包下,否则我们自定义的这个配置类就会被所有的Ribbon客户端锁共享,达不到特殊定制化的目的。

所以,我们新建package com.blj.myrule,编写MySelfRule.java

package com.blj.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 MySelfRule {

    //这里面编写自定义的负载均衡算法,
    // 这里就简单直接还是用Ribbon内置的算法作为演示

    @Bean
    public IRule getMySelfRule(){
        return new RandomRule();//随机算法
    }

}
  • 3、自定义规则深度解析
package com.blj.myrule;

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.Server;

public class MyRandomRule extends AbstractLoadBalancerRule {

    //实现代码
    @Override
    public Server choose(Object o) {
        //实现代码
        return null;
    }

    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值