简介

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进行测试。

SpringCloud学习笔记(2):使用Ribbon负载均衡的更多相关文章

  1. go微服务框架kratos学习笔记七(kratos warden 负载均衡 balancer)

    目录 go微服务框架kratos学习笔记七(kratos warden 负载均衡 balancer) demo demo server demo client 池 dao service p2c ro ...

  2. springcloud(十四)、ribbon负载均衡策略应用案例

    一.eureka-server服务中心项目不再创建 二.eureka-common-empdept公共组件项目不再掩饰 三.创建eureka-client-provider-empdept-one提供 ...

  3. 【官方文档】Nginx负载均衡学习笔记(二)负载均衡基本概念介绍

    简介 负载均衡(Server Load Balancer)是将访问流量根据转发策略分发到后端多台 ECS 的流量分发控制服务.负载均衡可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应 ...

  4. SpringCloud学习笔记《---03 Ribbon Rule---》核心篇

  5. SpringCloud学习笔记(五):Ribbon负载均衡

    简介 Spring Cloud Ribbon是基于Netflix Ribbon实现的一套 客户端 负载均衡的工具 .(重点:客户端) 简单的说,Ribbon是Netflix发布的开源项目,主要功能是提 ...

  6. SpringCloud学习(4)——Ribbon负载均衡

    Ribbon概述 SpringCloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡工具. 简单的说, Ribbon是Netflix发布的开源项目, 主要功能是提供客户端软 ...

  7. SpringCloud的入门学习之概念理解、Ribbon负载均衡入门

    1.Ribbon负载均衡,Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端.负载均衡的工具. 答:简单的说,Ribbon是Netflix发布的开源项目,主要功能 ...

  8. spring cloud学习笔记二 ribbon负载均衡

    Ribbon是Netflix发布的负载均衡器,它有助于控制HTTP和TCP的客户端的行为.为Ribbon配置服务提供者地址后,Ribbon就可基于某种负载均衡算法,自动地帮助服务消费者去请求.Ribb ...

  9. 最适合新手入门的SpringCloud教程 6—Ribbon负载均衡「F版本」

    SpringCloud版本:Finchley.SR2 SpringBoot版本:2.0.3.RELEASE 源码地址:https://gitee.com/bingqilinpeishenme/Java ...

随机推荐

  1. Unity经典游戏教程之:冒险岛

    版权声明: 本文原创发布于博客园"优梦创客"的博客空间(网址:http://www.cnblogs.com/raymondking123/)以及微信公众号"优梦创客&qu ...

  2. Java实现调用Bartender控制条码打印机

    官方提供的主要是C#支持. 基于java调用bartender二次开发官方给了一份1998年的J#代码,,,完全用不了,,,百度谷歌搜索万能的网友的答案,发现也没有可参考的.. 最后想到了之前用到了一 ...

  3. 章节十五、7- 配置文件-Console Logging

    一.创建xml文件 1.创建xml文件 在项目中我们需要专门建一个文件夹来放xml文件或者是其它文件. 2.然后对文件夹进行命名 3.选择new  其它 4.选择XML File 5.给xml文件命名 ...

  4. 99% 的人都不知道的 Kubernetes 网络疑难杂症排查方法

    原文链接:Kubernetes 网络疑难杂症排查分享 大家好,我是 roc,来自腾讯云容器服务 (TKE) 团队,经常帮助用户解决各种 K8S 的疑难杂症,积累了比较丰富的经验,本文分享几个比较复杂的 ...

  5. Linux安装nfs共享文件

    简介nfs nfs网络文件系统常用于共享音视频,图片等静态资源.将需要共享的资源放到NFS里的共享目录,通过服务器挂载实现访问. 服务端安装: yum install -y nfs-utils rpc ...

  6. 循环while和for

    1.循环语句的基本操作 #while循环使用,其中break是用来结束当前循环的 count = 0 while True: print(count) count += 1 if count == 3 ...

  7. c语言实现基本的数据结构(一) 线性表

    #include <stdio.h> #include <tchar.h> #include <stdlib.h> #define LIST_INIT_SIZE 1 ...

  8. R 实用命令 2

    1. how to temporarily unload the packages in R > library(Daim) 载入程辑包:‘Daim’ The following objects ...

  9. Python中的for else 和while else的用法

    for else 在for 循环中,如果没有从任何一个break中退出,则会执行和for对应的else,只要从break中退出了,则else部分不执行. while else while 后面的els ...

  10. 如何使用WorkManager执行后台任务(下)

    0x00 WorkManager的高级用法 在上一文中已经了解到 WorkManager的基本用法之后,今天来看看它的一些高级用法: 链式任务调用 唯一任务序列 传递参数和获取返回值 0x01 链式任 ...