一、什么是    ribbon?

        就是负载均衡!
nginx也是负载均衡 1.1 !!!!ribbon和nginx的区别是什么?
/* nginx:
正向代理(和客户端连在一起)
反向代理(和服务器端连在一起),nginx的负载均衡其实使用的就是反向代理 ribbon:
负载均衡是和客户端连在一起的,也就是说ribbon是客户端层面的负载均衡
负载均衡放在客户端的好处是什么?
可以让客户端非常直观的看到所有服务器的负载情况,
那么客户端一般情况下会选择负载比较少的服务器进行连接(选择游戏大区)
*/

二、consumer 开启负载均衡的配置

1.2 ribbon默认自带的有eureka的jar包,也就是如果需要使用ribbon的时候就必须要配置eureka,

            也就是说需要把自己托管给eureka,ribbon是客户端层面的负载均衡,那么ribbon是配置在consumer中还是provider中?
必须要配置在consumer上 /*
将 20190927-springcloud-consumer-6081 项目的jar包放在父级目录上,做jar包管理。
我的放在 新建项目 20190927-springcloud-consumer-ribbon-6082 做负载均衡。和另一项目一样,需要创建启动类,和配置文件。 */ 1.3 添加jar包
添加eureka的client端,ribbon的jar包
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>

  20190927-springcloud-consumer-management  父级jar包展示。

<?xml version="1.0" encoding="UTF-8"?>
<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">
<parent>
<artifactId>20190927-springcloud-parent</artifactId>
<groupId>com.aaa</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion> <artifactId>20190927-springcloud-consumer-management</artifactId> <packaging>pom</packaging> <modules>
<module>20190927-springcloud-consumer-6081</module>
<module>20190927-springcloud-consumer-ribbon-6082</module>
</modules> <!--
消费者 依赖于 model 和页面交互
在20190927-springcloud-consumer-management项目下,建立多个子级项目,可以将这里的jar包直接放在
父级的项目的xml文件中。 我的放在这里 没有生效,还是在子级项目上添加的jar 包依赖。
--> <dependencies>
<dependency>
<groupId>com.aaa</groupId>
<artifactId>20190927-springcloud-model</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency> <!--
微服务,将 spring-boot-starter-web添加进来 需要修改默认的端口号。
-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies> </project>
 20190927-springcloud-consumer-ribbon-6082 jar包依赖, 的配置文件,开启轮循,controller层。
<?xml version="1.0" encoding="UTF-8"?>
<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">
<parent>
<artifactId>20190927-springcloud-consumer-management</artifactId>
<groupId>com.aaa</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion> <groupId>com.aaa</groupId>
<artifactId>20190927-springcloud-consumer-ribbon-6082</artifactId> <!--
添加jar包
添加eureka的client端,ribbon的jar包
--> <dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency> <dependency>
<groupId>com.aaa</groupId>
<artifactId>20190927-springcloud-model</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency> <!--
微服务,将 spring-boot-starter-web添加进来 需要修改默认的端口号。
-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies> </project>



1.配置文件
server.port=6082
server.servlet.context-path=/

#三、 设置eureka 不要将自己注册到注册中心里面。
eureka.client.register-with-eureka=false

# ribbon 负载均衡的配置,需要将自己分别在三个 eureka上去注册。
eureka.client.service-url.defaultZone=http://eureka01:7081/eureka,http://eureka02:7082/eureka,http://eureka03:7083/eureka
2.开启轮循
package com.aaa.zxf.config;

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 ConfigRest { @Bean
@LoadBalanced //开启负载均衡 轮循的模式
public RestTemplate getRestTemplate(){
return new RestTemplate();
} }


3.controller层
package com.aaa.zxf.controller;

import com.aaa.zxf.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate; import java.util.List; @RestController
public class UserController { // private static final String URL = "http://USER-PROVIDER"; private static final String URL ="http://USER-PROVIDER"; @Autowired
private RestTemplate restTemplate; @RequestMapping("/userAll")
public List<User> selectAllUser(){
return restTemplate.getForObject(URL+"/userAll",List.class);
} }

三、provider 负载均衡的配置。


1.4 真正的负载均衡
需要创建provider-8082和8083项目 1.5 进行配置
8081,8082,8083三个项目中的所有的controller都必须要一致(@RequestMapping("/userAll"))

8081,8082,8083项目的application.properties配置文件必须要更改

【eureka的实例id:因为eureka的实例id是不能重复的,所以必须更改】
eureka.instance.instance-id=user-provider-8082

spring.application.name不能改变,也就是说8081,8082,8083三个项目的application.name都必须要一样 1.6 启动顺序
首先启动三台eureka(7081,7082,7083)
再启动三台provider(8081,8082,8083)
最后启动consumer(6082)

provider的配置文件,修改id  其他的都一样。从8081复制即可。

#四
#在eureka中配置实例, 就是eureka的status下显示的名字
# 不可以重复!!! 等同于mysql中表的id。
eureka.instance.instance-id=user-provider-8082

#四
#在eureka中配置实例, 就是eureka的status下显示的名字
# 不可以重复!!! 等同于mysql中表的id。
eureka.instance.instance-id=user-provider-8083
 

四、负载均衡的源码分析?
1.7 ribbon的负载均衡算法
如果不指定ribbon的算法,则ribbon使用的是轮询!!!
如何指定ribbon的算法? 1.8 负载均衡源码解析
IRule:接口
ILoadBalancer:接口
AbstractLoadBalancer(抽象类) --> 实现了ILoadBalancer接口
AbstractLoadBalancerRule(抽象类) --> 实现了IRule接口
有一个属性:ILoadBalance-->getter/setter方法
RandomRule(最终所实现随机算法的地方)--->继承了AbstractLoadBalancerRule
-->实现了IRule接口
RoundRobbinRule--->继承了AbstractLoadBalancerRule
-->实现了IRule接口 IRule:
public Server choose(Object key):选择出一个服务-->提供给consumer使用
public void setLoadBalancer(ILoadBalancer lb):ILoadBalancer-->实现类(AbstractLoadBalancer)
public ILoadBalancer getLoadBalancer()
ILoadBalancer:
!!其实就是和每一个服务打交道!!
getServer(Object key):所有的获取服务都必须要通过key来进行获取 虽然已经实现了ribbon算法自定义配置,但是ribbon框架是不知道的,但是自己已经实现了负载均衡算法,需要告诉ribbon,只需要在主启动类上添加注解@RibbonClient(name,configuration)
name:通过eureka的Application的值来映射到真正的provider(8081,8082,8083)
name = "USER-PROVIDER"
configuration:指向的是自己自定义的算法配置类 @Configuration
public class RibbonRuleMine { @Bean
public IRule randoms() {
return new RandomRule();
} }


算法?
package com.aaa.lee.springcloud.config;

import com.netflix.loadbalancer.ILoadBalancer;

import java.util.concurrent.ThreadLocalRandom;

public class Test {

    // 随机算法
public Server choose(ILoadBalancer lb, Object key) {
// 如果负载均衡器为null的时候,直接返回(其实就是标识了该consumer开启了负载均衡@LoadBalance)
if (lb == null) {
return null;
}
// 创建Server对象,没有初始化
Server server = null; // 循环进入条件是server为null-->也就是说第一次一定会进入循环
while (server == null) {
// Thread.interrupted():标识线程所处于的状态,如果线程的状态为存在,返回值就是true,如果不存在返回值就是false
// 什么时候线程会断开??-->网络故障,网络延迟,各种阻塞
if (Thread.interrupted()) {
return null;
}
// getReachableServers():获取当前正在存活的服务(一共有20个服务,其中有4个宕机,存活的服务就是16个)
// getAllServers():获取所有的服务个数(包含宕机的)
List<Server> upList = lb.getReachableServers();
List<Server> allList = lb.getAllServers(); // allList.size() == 0 说明没有服务,直接return null
int serverCount = allList.size();
if (serverCount == 0) {
return null;
} // serverCount:就是所有服务的个数(包含宕机的服务)
// 假设:30台
int index = chooseRandomInt(serverCount);
// upList:存活的服务
server = upList.get(index); if (server == null) { /**
* Thread.yield():线程谦让
* 什么叫多线程之间的谦让呢?
* 当并发出现的时候,线程和线程是互不相让的(线程阻塞),其中一个线程就会出现问题,就会处于等待状态(线程阻塞会更严重)
* 当调用yield()方法的时候,出现问题的线程就开始谦让,这个线程会再次被唤醒处于就绪状态,需要重新抢夺客户端所发送过来的并发
*/
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 int chooseRandomInt(int serverCount) {
// Math.random.nextInt(999):随机获取到从1到999的随机数
// ThreadLocalRandom.current().nextInt(30):就是获取的是随机数(从1到30进行随机数)
//
/*
* Random和ThreadLocalRandom都是随机数,那么为什么使用ThreadLocalRandom不使用Random?
* !!Random就是线程安全的!!
* ThreadLocalRandom:是jdk7的新特性!!
* 虽然random是线程安全的,但是在多线程的情况,Random效率就会非常低
* random在处理多线程的情况下是线程安全的,会受到线程保护,就会降低效率(队列)
* Random所随机出来的数字是可以预测的(Random有规律)
*
* TreadLocalRandom官方给出的解释,当项目期望在多线程中运行的时候,如果使用到了随机数,可以直接使用该类,因为该
* 类就是针对于并发所开发的,和Random相比TreadLocalRandom可以减少线程之间的竞争,性能可以达到最优!
*
*
*/
return ThreadLocalRandom.current().nextInt(serverCount);
} }

五、图解





springcloud 负载均衡之 ribbon。的更多相关文章

  1. SpringCloud系列之客户端负载均衡Netflix Ribbon

    1. 什么是负载均衡? 负载均衡是一种基础的网络服务,它的核心原理是按照指定的负载均衡算法,将请求分配到后端服务集群上,从而为系统提供并行处理和高可用的能力.提到负载均衡,你可能想到nginx.对于负 ...

  2. SpringCloud 客户端负载均衡:Ribbon

    目录 Ribbon 介绍 开启客户端负载均衡,简化 RestTemplate 调用 负载均衡策略 Ribbon 介绍 Ribbon 是 Netflix 提供的一个基于 Http 和 TCP 的客户端负 ...

  3. Spring Cloud之负载均衡组件Ribbon原理分析

    目录 前言 一个问题引发的思考 Ribbon的简单使用 Ribbon 原理分析 @LoadBalanced 注解 @Qualifier注解 LoadBalancerAutoConfiguration ...

  4. Spring Cloud官方文档中文版-客户端负载均衡:Ribbon

    官方文档地址为:http://cloud.spring.io/spring-cloud-static/Dalston.SR2/#_spring_cloud_netflix 文中例子我做了一些测试在:h ...

  5. 【Spring Cloud】客户端负载均衡组件——Ribbon(三)

    一.负载均衡 负载均衡技术是提高系统可用性.缓解网络压力和处理能力扩容的重要手段之一. 负载均衡可以分为服务器负载均衡和客户端负载均衡,服务器负载均衡由服务器实现,客户端只需正常访问:客户端负载均衡技 ...

  6. 负载均衡框架 ribbon 二

    Ribbon 负载均衡机制 官方文档地址:https://github.com/Netflix/ribbon/wiki/Working-with-load-balancers 1. Ribbon 内置 ...

  7. SpringCloud系列五:Ribbon 负载均衡(Ribbon 基本使用、Ribbon 负载均衡、自定义 Ribbon 配置、禁用 Eureka 实现 Ribbon 调用)

    1.概念:Ribbon 负载均衡 2.具体内容 现在所有的服务已经通过了 Eureka 进行了注册,那么使用 Eureka 注册的目的是希望所有的服务都统一归属到 Eureka 之中进 行处理,但是现 ...

  8. SpringCloud全家桶学习之客户端负载均衡及自定义负载均衡算法----Ribbon(三)

    一.Ribbon是什么? Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端  负载均衡的工具(这里区别于nginx的负载均衡).简单来说,Ribbon是Netf ...

  9. springCloud负载均衡Ribbon和Feign的区别

    1.什么是负载均衡: 负载均衡(Load Balance)是分布式系统架构设计中必须考虑的因素之一,它通常是指,将请求/数据[均匀]分摊到多个操作单元上执行,负载均衡的关键在于[均匀]. 2.常见的负 ...

随机推荐

  1. Travelling(hdu3001)

    Travelling Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  2. 小小明系列故事——游戏的烦恼(hdu 4517)

    小小明系列故事--游戏的烦恼 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)To ...

  3. 【Java例题】3.4求a+aa+aaa+aaaa+... ...+aa...a(n个

    4. package chapter3; import java.util.*; public class demo4 { public static void main(String[] args) ...

  4. element message多次点击出现多个提示框,如何显示一个或者在同一位置显示

    /* message在同一位置弹出 */ /* reset elementUI message */ .el-message { top: 20px !important; } .el-message ...

  5. MySQL数据库报错 > 1366 - Incorrect string value: ‘\xE6\xB1\x9F\xE6\x96\x87‘ for column ‘Teacher‘ at row 1

    数据库报错这个多半是数据库在创建的时候没有选择字符编码,导致输入中文的时候出现报错. > 1366 - Incorrect string value: '\xE6\xB1\x9F\xE6\x96 ...

  6. Spring企业级程序设计 • 【第1章 Spring之旅】

    全部章节   >>>> 本章目录 1.1 Spring框架基础 1.1.1 Spring特点及体系结构 1.1.1 Spring的体系结构 1.1.2  使用Eclipse搭建 ...

  7. 在pycharm中创建py文件——创建你的第一个项目

    开启编程第一步   创建一个项目 创建项目了xdm,敲黑板了哈 首先打开你的pycharm,点击New Project新建项目 就会进入到配置你这个项目所要用到的环境,这里我们用python列举 在L ...

  8. 你在寻找Vue3移动端项目框架嘛?请看这里

    现在web开发变得更加美妙高效,在于开发工具设计得更好了,丰富性与易用性,都有所提高.丰富性带来了一个幸福的烦恼,就是针对实际应用场景,如何选择工具 ? 1. Vue Cli和Vite之间的选择 Vi ...

  9. gRPC创建Java RPC服务

    1.说明 本文介绍使用gRPC创建Java版本的RPC服务, 包括通过.proto文件生成Java代码的方法, 以及服务端和客户端代码使用示例. 2.创建生成代码工程 创建Maven工程,grpc-c ...

  10. 来自MyBatis不一样收获结果的探索之旅-v3.5.9

    概述 定义 MyBatis官网 https://mybatis.org/mybatis-3/ 最新版本为3.5.9 MyBatis是一个的ORM框架,支持自定义SQL.存储过程和高级映射.MyBati ...