简介

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. maysql的自增字段

    因为mysql中的自增字段与oracle数据库是不一样的,所以在这里唠嗑一下mysql的自增字段 1.添加自增字段 1.1 在创建表时添加 create table emp( empno ) auto ...

  2. 逆向破解之160个CrackMe —— 002-003

    CrackMe —— 002 160 CrackMe 是比较适合新手学习逆向破解的CrackMe的一个集合一共160个待逆向破解的程序 CrackMe:它们都是一些公开给别人尝试破解的小程序,制作 c ...

  3. Spring系列(一):Spring核心概念

    一.Spring概念 Spring是一种多层的J2EE应用程序框架,其核心就是管理资源组件以及依赖关系,Spring框架为现代基于java的企业应用程序提供了一个全面的编程和配置模型. 二.Sprin ...

  4. Java 8 Stream实践

    [**前面的话**]Java中的Stream于1.8版本析出,平时项目中也有用到,今天就系统的来实践一下.下面借用重庆力帆队伍中我个人比较喜欢的球员来操作一波,队员的年龄为了便于展示某些api做了调整 ...

  5. HTML发展历程

    HTML是超文本标记语言的缩写,不同于C或JAVA等编程语言,HTML由标签组成.通过标签可以在网页中插入文字.图片.链接.音频.视频等元素,进而描述网页.和Windows一样,随着技术的发展,HTM ...

  6. DT-06 For Homekit

    一. 配置DT-06上网 连接此热点,会自动弹出wifi配置页面. 输入选中的路由密码,点 Join加入,如果路由没有出现在列表中,点 Other手工输入(仅支持2.4g路由配置) 二.配置dt-06 ...

  7. (二十五)c#Winform自定义控件-有确定取消的窗体(一)

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...

  8. ES解决bootstrap checks failed, memory locking requested for elasticsearch process but memory is not locked问题

    问题描述: ERROR: [1] bootstrap checks failed[1]: memory locking requested for elasticsearch process but ...

  9. Selenium webdriver工作原理

    webdriver是以server-client 经典模式设计的 server端可以是任何浏览器作为remote server,职责就是处理client的请求并作出相应操作,response的具体内容 ...

  10. shiro@RequiresPermission的设置

    public class MyShiroRealm extends AuthorizingRealm { //slf4j记录日志,可以不使用 private Logger logger = Logge ...