文章目录

  • 一、 Ribbon简介
  • 二、 使用Ribbon开发微服务
    • 1 创建springcloud工程 和 commons子模块
    • 2 开发服务提供者 - ribbonappservice
    • 3 开发服务消费者 - ribbonappclient
  • 三、 集中式与进程内负载均衡区别
  • 四、 Ribbon常见的负载均衡策略
    • 1 Ribbon中的常用负载均衡简介
    • 2 配置负载均衡策略
  • 五、 Ribbon的点对点直连

一、 Ribbon简介

Ribbon 是一个基于Http和TCP的客服端负载均衡工具,它是基于Netflix Ribbon实现的。它不像spring cloud服务注册中心、配置中心、API网关那样独立部署,但是它几乎存在于每个spring cloud 微服务中。包括feign提供的声明式服务调用也是基于该Ribbon实现的。ribbon默认提供很多种负载均衡算法,例如 轮询、随机 等等。甚至包含自定义的负载均衡算法。Ribbon可以用于解决并提供微服务的负载均衡的问题。

二、 使用Ribbon开发微服务

在Spring Cloud中,使用Ribbon技术开发Eureka Client组件还是非常方便的。我们在开发过程中,不需要像Dubbo那样关注服务的角色。无论是Provider还是Consumer都是一个微服务客户端,只是在编码层面上,服务消费者代码的开发相对比较麻烦。我们通过简单案例测试一下Spring Cloud中的微服务开发过程。
因为现在的Eureka Server部署在Linux中,并已为Linux定义了新的主机域名,需要先修改开发测试环境中的hosts文件。windows中的hosts文件位于:C:\windows\system32\dirvers\etc\hosts。新增内容如下:(IP根据具体情况配置)

192.168.14.128 eureka1
192.168.14.129 eureka2

1 创建springcloud工程 和 commons子模块

1.1 POM依赖

<?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"><modelVersion>4.0.0</modelVersion><packaging>pom</packaging><modules><module>commons</module><module>ribbonappservice</module><module>ribbonappclient</module></modules><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.2.RELEASE</version></parent><groupId>com.bjsxt</groupId><artifactId>springcloud</artifactId><version>1.0-SNAPSHOT</version><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>Hoxton.SR1</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>
</project>

1.2 commons 的pom.xml

<?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>springcloud</artifactId><groupId>com.bjsxt</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>commons</artifactId>
</project>

1.3 commons子模块中user类 (包含set,get等方法)

2 开发服务提供者 - ribbonappservice

2.1 POM依赖

<?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>springcloud</artifactId><groupId>com.bjsxt</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><!-- 服务提供方项目, 使用Ribbon技术开发 --><artifactId>ribbonappservice</artifactId><dependencies><!-- spring cloud是通过http协议对外发布一个基于REST规则的微服务通过SpringMVC技术中的Controller对外提供微服务的。--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Eureka客户端依赖,spring cloud中,服务的提供者和消费者都是Eureka客户端。必须依赖此资源 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><dependency><groupId>com.bjsxt</groupId><artifactId>commons</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies></project>

2.2 服务提供者代码

package com.bjsxt.userservice.controller;import com.bjsxt.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;import java.util.HashMap;
import java.util.Map;/*** 提供服务的控制器*/
@Controller
public class UserController {@RequestMapping("/user/save")@ResponseBodypublic Map<String, Object> save(User user){System.out.println("新增用户数据: " + user);Map<String, Object> result = new HashMap<>();result.put("code", "200"); // 返回的状态码result.put("message", "新增用户成功"); // 返回的处理结果消息。return result;}
}

2.3 配置文件application.yml

server:port: 8082spring:application:name: ribbon-app-serviceeureka: # Eureka客户端,启动的时候,如果未配置Eureka服务端地址列表,则在localhost:8761注册client:service-url:  # 配置Eureka服务端地址,注册中心地址,多个地址使用逗号 ',' 分隔。defaultZone: http://localhost:8761/eureka/

2.4 启动类

package com.bjsxt.userservice;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;/*** 服务提供方启动类* 在Spring Cloud低版本中,如果开发的代码是Eureka Client(服务提供者和消费者),* 那么启动类上需要增加注解* @EnableEurekaClient - 当前应用是一个Eureka客户端* @EnableDiscoveryClient - 当前应用需要启动发现机制,就是找到Eureka服务端,并注册发现服务。*/
@SpringBootApplication
public class RibbonAppServiceApp {public static void main(String[] args) {SpringApplication.run(RibbonAppServiceApp.class, args);}
}

2.5 检查Eureka Server中的服务注册情况(Eureka Server项目使用SpringCloud Netflix Eureka文章中的

3 开发服务消费者 - ribbonappclient

3.1 POM依赖

<?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>springcloud</artifactId><groupId>com.bjsxt</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>ribbonappclient</artifactId><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><dependency><groupId>com.bjsxt</groupId><artifactId>commons</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies></project>

3.2 控制器

package com.bjsxt.userclient.controller;import com.bjsxt.entity.User;
import com.bjsxt.userclient.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;import java.util.Map;/*** 服务消费端*/
@Controller
public class UserController {@Autowiredprivate UserService userService;@RequestMapping("/user/save")@ResponseBodypublic Map<String, Object> save(User user){// 调用本地服务代码,本地服务代码远程调用application service服务提供方。Map<String, Object> result = this.userService.save(user);System.out.println("远程调用返回的结果:" + result);return result;}}

3.3 服务接口

package com.bjsxt.userclient.service;import com.bjsxt.entity.User;import java.util.Map;public interface UserService {Map<String, Object> save(User user);
}

3.4 服务实现

package com.bjsxt.userclient.service.impl;import com.bjsxt.entity.User;
import com.bjsxt.userclient.service.UserService;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;import java.util.Map;@Service
public class UserServiceImpl implements UserService {/*** 是Ribbon技术中的负载均衡客户端对象。其中封装了从Eureka Server上发现的所有的服务地址列表* 包括服务的名称,IP,端口等。*/@Autowiredprivate LoadBalancerClient loadBalancerClient;/*** 远程方法调用。访问application service,访问的地址是:http://localhost:8080/user/save* @param user* @return*/@Overridepublic Map<String, Object> save(User user) {// 根据服务的名称,获取服务实例。服务名称就是配置文件yml中的spring.application.name// 服务实例包括,这个名称的所有服务地址和端口。ServiceInstance instance = this.loadBalancerClient.choose("ribbon-app-service");// 访问地址拼接StringBuilder builder = new StringBuilder("");builder.append("http://").append(instance.getHost()).append(":").append(instance.getPort()).append("/user/save").append("?username=").append(user.getUsername()).append("&password=").append(user.getPassword()).append("&remark=").append(user.getRemark());System.out.println("本地访问地址:" + builder.toString());// 创建一个Rest访问客户端模板对象。RestTemplate template = new RestTemplate();// 约束响应结果类型ParameterizedTypeReference<Map<String, Object>> responseType =new ParameterizedTypeReference<Map<String, Object>>() {};// 远程访问application service。ResponseEntity<Map<String, Object>> response =template.exchange(builder.toString(), HttpMethod.GET,null, responseType);Map<String, Object> result = response.getBody();return result;}
}

3.5 配置文件application.yml

server:port: 8081spring:application:name: ribbon-app-clienteureka:client:service-url:defaultZone: http://localhost:8761/eureka/

3.6 启动类

package com.bjsxt.userclient;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class RibbonAppClientApp {public static void main(String[] args) {SpringApplication.run(RibbonAppClientApp.class, args);}
}

三、 集中式与进程内负载均衡区别

业界主流的负载均衡解决方案有:集中式负载均衡和进程内负载均衡。

1 集中式负载均衡
即在客户端和服务端之间使用独立的负载均衡设施(可以是硬件,如F5, 也可以是软件,如nginx), 由该设施负责把访问请求通过某种策略转发至服务端。
2 进程内负载均衡
将负载均衡逻辑集成到客户端组件中,客户端组件从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的服务端发起请求。Ribbon就是一个进程内的负载均衡实现。

四、 Ribbon常见的负载均衡策略

Ribbon就属于进程内负载均衡,它只是一个类库,集成于Eureka Client进程,Eureka Client进程通过访问注册中心Eureka Server发现服务列表,发现的服务列表信息是由ribbon来管理的。当访问Application Service的时候,Application Client会通过ribbon来找到合适的Application Service地址信息,并发起远程调用请求。

1 Ribbon中的常用负载均衡简介

1 轮询策略(默认) RoundRobinRule

轮询策略表示每次都顺序取下一个provider,比如一共有5个provider,第1次取第1个,第2次取第2个,第3次取第3个,以此类推

2 权重轮询策略(常用) WeightedResponseTimeRule

1.根据每个provider的响应时间分配一个权重,响应时间越长,权重越小,被选中的可能性越低。
2.原理:一开始为轮询策略,并开启一个计时器,每30秒收集一次每个provider的平均响应时间,当信息足够时,给每个provider附上一个权重,并按权重随机选择provider,高权越重的provider会被高概率选中。

3 随机策略(不推荐) RandomRule

从provider列表中随机选择一个provider

4 最少并发数策略(应用在硬件软件环境一致的情况下) BestAvailableRule

选择正在请求中的并发数最小的provider,除非这个provider在熔断中。

5 在“选定的负载均衡策略”基础上进行重试机制 RetryRule

1.“选定的负载均衡策略”这个策略是轮询策略RoundRobinRule
2.该重试策略先设定一个阈值时间段,如果在这个阈值时间段内当选择provider不成功,则一直尝试采用“选定的负载均衡策略:轮询策略”最后选择一个可用的provider

6 可用性敏感策略(一般在同区域内服务集群环境中使用) AvailabilityFilteringRule

过滤性能差的provider,有2种:
第一种:过滤掉在eureka中处于一直连接失败provider
第二种:过滤掉高并发的provider

7 区域敏感性策略(应用在大型的,物理隔离分布式环境中) ZoneAvoidanceRule

1.以一个区域为单位考察可用性,对于不可用的区域整个丢弃,从剩下区域中选可用的provider
2.如果这个ip区域内有一个或多个实例不可达或响应变慢,都会降低该ip区域内其他ip被选中的权重。

2 配置负载均衡策略

可以通过修改 ribbonappclient 应用的全局配置文件来改变当前环境中使用的Ribbon负载均衡策略。

server:port: 8081spring:application:name: ribbon-app-clienteureka:client:service-url:defaultZone: http://localhost:8761/eureka/ribbon-app-service: # 远程访问这个命名的服务ribbon: # 底层Ribbon配置NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 就是具体的负载均衡策略类型全名

五、 Ribbon的点对点直连

Ribbon也可以脱离Eureka Server注册中心,通过配置的方式指定要调用的远程服务信息,实现Ribbon点对点直连。修改的配置内容如下:

server:port: 8081spring:application:name: ribbon-app-client#eureka:
#  client:
#    service-url:
#      defaultZone: http://localhost:8761/eureka/ribbon-app-service: # 远程访问这个命名的服务ribbon: # 底层Ribbon配置NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 就是具体的负载均衡策略类型全名listOfServers: localhost:8080  # 多个地址用逗号分隔。ribbon: # 关闭Ribbon自动访问Eureka服务端。eureka:enabled: false

SpringCloud Netflix Ribbon相关推荐

  1. 从零开始搭建spring-cloud(2) ----ribbon

    撸了今年阿里.头条和美团的面试,我有一个重要发现.......>>> 在微服务架构中,业务都会被拆分成一个独立的服务,服务与服务的通讯是基于http restful的.Spring ...

  2. 第六章 SpringCloud之Ribbon负载均衡

    ###################使用默认的负载均衡(轮询)############################# 1.pom.xml <?xml version="1.0&q ...

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

    现在所有的服务已经通过了 Eureka 进行了注册,那么使用 Eureka 注册的目的是希望所有的服务都统一归属到 Eureka 之中进 行处理,但是现在的问题,所有的微服务汇集到了 Eureka 之 ...

  4. SpringCloud的Ribbon负载均衡

    Spring Cloud Ribbon相关学习: 简介 Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具. 简单的说,Ribbon是Netflix ...

  5. SpringCloud[04]Ribbon负载均衡服务调用

    文章目录 Ribbon负载均衡服务调用 1. 概述 1. Ribbon是什么 2. Ribbon能做什么 2. Ribbon负载均衡演示 1. 架构说明 2. Ribbon的POM依赖 3. Rest ...

  6. SpringCloud NetFlix学习笔记(一)

    前言: 学习B站UP主狂神说视频笔记整理视频链接 微服务 服务演进 三层架构+MVC >> SSM >> SpringBoot 它们都属于all in one 单体架构 单体架 ...

  7. SpringCloud/Eureka/Ribbon:No instances available for springcloud-provider-dept

    服务注册方: <!--eureka server--> <dependency><groupId>org.springframework.cloud</gro ...

  8. SpringCloud之Ribbon简单入门

    提出疑问 ① 如何在配置Eureka Client注册中心时不去硬编码Eureka Server的地址? ② 在微服务不同模块间进行通信时,如何不去硬编码服务提供者的地址? ③ 当部署多个相同微服务时 ...

  9. SpringCloud(7)Ribbon 与负载均衡

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

最新文章

  1. 【SQL提数】case..when..then..end的使用
  2. spark Docker镜像构建及push脚本
  3. python 保存本地乱码_请教大神,如何解决保存后的文件的乱码问题
  4. 免费计算机维修基础教程,《计算机组装与维修基础教程》第1课:计算机基础知识.ppt...
  5. android beta项目官方页面,安卓7.0开发者预览版如何安装?Android Beta项目正式上线...
  6. 建立远程桌面连接计算机无密码,win7远程桌面空密码的步骤_win7系统如何设置让远程桌面登录无需密码-win7之家...
  7. 诗和远方:无题(五十一)
  8. iOS用户体验之-modal上下文
  9. 2018.09.18 循环终止
  10. 【Java开发】之配置文件的读取
  11. origin9.0中文版
  12. 学生抗疫HTML网页设计作品 学生疫情网页模板 大学生抗疫感动专题网页设计作业 HTML学生抗疫网站作业设计
  13. 如何从数据库中选出最热的十个检索词
  14. 多益网络社招iq_多益网络2018秋招iq测试题(二)
  15. java 数组的扩容,缩容,插入元素,查找元素 详解(通俗易懂)
  16. 【oracle】oracle筛选后导出表,载入对象选择,保存对象选择,save object selection的使用,过滤clob导出,利用osf文件
  17. 有没有免费的 BI 软件
  18. win10系统无法加载操作系统且自动恢复失败的解决方案
  19. c语言数组子集,C语言实现数组所有子集
  20. 服务安全:如何保证服务器不断电数据不丢失?

热门文章

  1. ltv价值 应用_用户终生价值Ltv是什么,在游戏设计中如何考虑?
  2. 二叉搜索树(创建,插入,删除):基础篇,适合新手观看。
  3. Python--第4次平时作业
  4. wordList04
  5. 操作系统内存管理--简单、页式、段式、段页式
  6. 牛客小白月赛11:Rinne Loves Data Structure
  7. LOJ6053简单的函数(min_25筛)
  8. Codeforces Round #727 (Div. 2) E. Game with Cards dp + 思维
  9. CF641D. Little Artem and Random Variable
  10. Most Powerful