达内广州C++学院|c++培训|广州达内科技C++/C#培训|.NET培训|IT培训|达内广州岗顶中心 达内广州C++学院|c++培训|广州达内科技C++/C#培训|.NET培训|IT培训|达内广州岗顶中心
java程序员
 当前位置:主页 > 高端课程 > java程序员 >

SpringCloud学习笔记(2):使用Ribbon负载均衡

时间:2019-09-11  来源:未知  作者:广州达内培训

简介

Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡工具,在注册中心对Ribbon客户端进行注册后,Ribbon可以基于某种负载均衡算法,如轮询(默认)、随机、加权轮询、加权随机等自动帮助服务消费者调用接口。

项目介绍

  1. sc-parent,父模块(请参照SpringCloud学习笔记(1):Eureka注册中心)
  2. sc-eureka,注册中心(请参照SpringCloud学习笔记(1):Eureka注册中心)
  3. sc-provider-random,随机端口的提供者
  4. sc-consumer,使用Ribbon负载均衡的消费者

随机端口的提供者

1.在父模块下创建子模块项目sc-provider-random,pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.cf</groupId>
    <artifactId>sc-parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <artifactId>sc-provider-random</artifactId>
  
  <dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
  </dependencies>
</project>

2.创建启动类provider.ProviderApplication:

package provider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ProviderApplication {

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

3.创建Controller:provider.controller.BookController

package provider.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/book")
@RestController
public class BookController {
    
    @GetMapping("/list")
    public String getBookList(){
        System.out.println("------------我被访问了-----------");
        return "[\"Java入门到放弃\",\"C++入门到放弃\",\"Python入门到放弃\",\"C入门到放弃\"]";
    }
}

4.创建application.yml:

server:
  port: 0 #默认8080,配置随机端口需要设置为0

spring:
  application:
    name: sc-provider-random
eureka:
  client:
    serviceUrl: 
      defaultZone: http://localhost:8080/eureka/
  instance:
    instance-id: ${spring.application.name}:${random.value} #实例名随机生成

5.依次启动注册中心sc-eureka以及两个提供者sc-provider-random,提供者sc-provider-random每次启动端口都不一样,可以看到sc-provider-random的两个实例都在注册中心注册:

使用Ribbon负载均衡的消费者

1.在父模块下创建子模块项目sc-consumer,pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.cf</groupId>
    <artifactId>sc-parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <artifactId>sc-consumer</artifactId>
  
  <dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    
    <!-- spring-cloud-starter-netflix-eureka-client依赖中已经包含ribbon -->
    <!-- <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
    </dependency> -->
  </dependencies>
</project>

2.创建启动类consumer.ConsumerApplication:

package consumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
public class ConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }
    
    //为RestTemplate整合Ribbon,使其具备负载均衡的能力
    @LoadBalanced
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

3.创建调用提供者服务的Controller:consumer.controller.ConsumerController

package consumer.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class ConsumerController {
    @Autowired
    private RestTemplate restTemplate;
    
    @GetMapping("/getBookList")
    public String getBookList(){
        //sc-provider-random 为提供者服务名
        return restTemplate.getForObject("http://sc-provider-random/book/list", String.class);
    }
}

注意:在使用Ribbon负载均衡时,服务名称不能有下划线,否则会出现valid hostname异常

4.创建application.yml:

server:
  port: 8083

spring:
  application:
    name: sc-consumer
    
eureka:
  client:
    registerWithEureka: false
    serviceUrl:
      defaultZone: http://localhost:8080/eureka/    

5.依次启动注册中心sc-eureka、两个提供者sc-provider-random、消费者sc-consumer,并访问http://localhost:8083/getBookList:

多次访问后,通过控制台的日志打印可以发现消费者时通过轮询的方式访问两个提供者实例。

更改负载均衡策略

Ribbon默认使用RoundRobinRule(轮询)来做为负载均衡策略,我们可以实现IRule接口或者使用Ribbon提供的现成的负载均衡策略来替换默认的轮询策略。如下,使用随机访问的策略来替代默认的轮询,在消费者启动类中添加:

    @Bean
    public IRule randomRule(){
        return new RandomRule();//使用随机访问的策略来替代默认的轮询
    }

自定义负载均衡策略

一个自定义负载均衡策略小例子,依旧是轮询访问策略,只是每个服务实例访问5次后才会访问下一个服务实例。

1.创建类consumer.rule.MyRule:

package consumer.rule;

import java.util.List;

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

public class MyRule extends AbstractLoadBalancerRule {
    private int currIndex = 0;//当前服务实例索引
    
    private int currCount = 0;//当前服务实例被访问次数
    
    private static final int MAX_COUNT = 5;//每个服务实例最大访问次数为5

    public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null) {
            return null;
        }
        Server server = null;

        while (server == null) {
            if (Thread.interrupted()) {
                return null;
            }
            List<Server> upList = lb.getReachableServers();
            List<Server> allList = lb.getAllServers();

            int serverCount = allList.size();
            if (serverCount == 0) {
                /*
                 * No servers. End regardless of pass, because subsequent passes
                 * only get more restrictive.
                 */
                return null;
            }

            int index = chooseRandomInt(upList.size());
            server = upList.get(index);

            if (server == null) {
                /*
                 * The only time this should happen is if the server list were
                 * somehow trimmed. This is a transient condition. Retry after
                 * yielding.
                 */
                Thread.yield();
                continue;
            }

            if (server.isAlive()) {
                return (server);
            }

            // Shouldn't actually happen.. but must be transient or a bug.
            server = null;
            Thread.yield();
        }

        return server;

    }

    protected synchronized int chooseRandomInt(int serverCount) {
        currCount++;
        if(currCount > MAX_COUNT){
            currIndex++;
            if(currIndex >= serverCount){
                currIndex = 0;
            }
            currCount = 1;
        }
        return currIndex;
    }

    @Override
    public Server choose(Object key) {
        return choose(getLoadBalancer(), key);
    }

    @Override
    public void initWithNiwsConfig(IClientConfig clientConfig) {
        // TODO Auto-generated method stub
        
    }
}

2.修改配置:

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

依次启动注册中心sc-eureka、两个提供者sc-provider-random、消费者sc-consumer,并访问http://localhost:8083/getBookList进行测试。




上一篇:java http/https后台上传服务器视频到接口
下一篇:没有了

友情链接:
  • 全球最大晶圆代工半导体制造厂,台积电斥资订购艾斯摩尔机器设备
  • 英特尔依然是那个英特尔,且看英特尔的城防体系
  • 支持双 DRAM 内存接口,慧荣企业级 SSD 主控方案披露
  • 在全球被反垄断罚款,冤!高通到底哪里得罪了欧盟?
  • 强强联合!万业、微电子所和芯鑫共同打造全新半导体设备
  • 复旦大学校长称:对于集成电路产业发展,大学应该主动担当
  • 技术再升级!无锡中科芯攻克晶圆级再布线及晶圆级凸点制备关键技
  • 聚力!万业企业设立集成电路装备集团,提供自主可控设备
  • 德州仪器C2000微控制器增强连通性和控制性
  • 英特尔打出降价策略,以免被竞争对手 AMD 打败?
  • 贸易摩擦的闹剧没有赢家,苹果有勇气离开中国吗?
  • 图像信号与视觉处理器的发展趋势
  • 真干快消品定位方案班(第二期)火热开班
  • Java集合 ArrayList原理及使用
  • TDD(测试驱动开发)死了吗?
  • JAVA基础之XML相关
  • javaweb项目搭建ehcache缓存系统
  • 每日一码——字符串统计
  • 一篇文章帮你彻底搞清楚“I/O多路复用”和“异步I/O”的前世今生
  • 九:模板方法模式
  • 十二:命令模式(人员解耦和)
  • Java 转PPT为图片、PDF、SVG、XPS、ODP以及PPT和PPTX互转
  • SpringCloud学习(SPRINGCLOUD微服务实战)一
  • 记一次微信网页授权后获取用户信息并重定向
  • 速途新营销五点实战洞察解码“品效合一”
  • 十一:外观模式详解(Service,action与dao)
  • 手把手教你学会 基于JWT的单点登录
  • mysql锁机制总结,以及优化建议
  • 解决多个版本jar包冲突【jar内包名重命名】
  • 中国首张5G终端电信设备进网许可证 华为Mate 20 X 5G版入网
  • RPC之Thrift
  • 高级Java工程师必备 ----
  • 天猫618期间实物支付GMV增长38.5%
  • 换季了,老板你的库存处理好了吗?
  • 从“618”大数据看中国消费新活力
  • 小米生态链:贵在格局感与收放度
  • CODING 2.0 企业级持续交付解决方案
  • 老铁奇趴“新京济” 快手*京东618战报出炉
  • 中小企业新媒体运营基本技能
  • 上汽大通房车再度携手LINE FRIENDS 魔都巡游顺利开启
  • 华为高端手机国内市场份额超苹果夺得榜首
  • 中国智能制造分析报告
  • iPlus艾加营销助力腾讯广告牵手吴晓波 推进商业IP变现
  • 2019世界新能源汽车大会7月1日将在海南举行
  • 区域酒企如何转型突围
  • 时时彩论坛
  • 五星体育斯诺克
  • 北单比分直播
  • 河北11选5走势图
  • 福建体彩36选7开奖结果
  • 九龙图库下载