简介

Spring Cloud Ribbon是一个基于Http和TCP的客户端负载均衡工具,它是基于Netflix Ribbon实现的。它不像服务注册中心、配置中心、API网关那样独立部署,但是它几乎存在于每个微服务的基础设施中。理解Ribbon对于我们使用Spring Cloud来讲非常的重要,因为负载均衡是对系统的高可用、网络压力的缓解和处理能力扩容的重要手段之一。

在Spring Cloud中,有两种服务调用方式,一种是Ribbon+RestTemplate,另一种是Feign。文本先讲解下基于Ribbon+RestTemplate的用法。

当Ribbon与Eureka配合使用时,Ribbon可自动从Eureka Server获取服务提供者地址列表,并基于负载均衡算法,请求其中一个服务提供者实例。

实现

新建服务spring-cloud-ribbon

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">
<modelVersion>4.0.0</modelVersion> <groupId>com.yan</groupId>
<artifactId>spring-cloud-ribbon</artifactId>
<version>1.0-SNAPSHOT</version> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
<relativePath/>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>RELEASE</version>
</dependency>
</dependencies> </project>

配置

yml

server:
port: 8004
spring:
application:
name: spring-cloud-ribbon
cloud:
config:
discovery:
enabled: true
service-id: spring-cloud-config-server
profiles:
active: dev
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/

启动类

核心是配有注解@LoadBalanced的RestTemplate的Bean配置

package com.yan;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate; @SpringBootApplication
@Configuration
@EnableDiscoveryClient
public class RibbonApplication {
public static void main(String[] args) {
SpringApplication.run(RibbonApplication.class, args);
} @Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}

Controller

package com.yan.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate; import java.util.StringJoiner; @RestController
@RequestMapping("/ribbon")
public class RibbonController {
private final RestTemplate template; @Autowired
public RibbonController(RestTemplate template) {
this.template = template;
} @GetMapping("/get")
public Object get(String svcName, String url, String className) {
Class<?> clazz = getResponseType(className);
String uri = getUrl(svcName, url);
return template.getForObject(uri, clazz);
} @PostMapping("/post")
public Object post(@RequestParam String svcName, @RequestParam String url, @RequestParam String className, @RequestBody HttpEntity<?> httpEntity) throws JsonProcessingException {
Class<?> clazz = getResponseType(className);
String url1 = getUrl(svcName, url);
Object res = template.postForObject(url1, httpEntity, clazz);
String resJson = new ObjectMapper().writeValueAsString(res);
System.out.println(resJson);
return res;
} private Class<?> getResponseType(@RequestParam String className) {
Class<?> clazz;
try {
clazz = Class.forName(className);
} catch (ClassNotFoundException e) {
clazz = String.class;
}
return clazz;
} private String getUrl(String svcName, String url) {
StringJoiner stringJoiner = new StringJoiner("/");
String uri = stringJoiner.add(svcName).add(url).toString().replaceAll("/+", "/");
return "http://" + uri;
} }

测试

假如我有两个名叫svcA的服务,同时注册到同一个Eureka上,只是端口号不同,它们都有一个post接口定义如下:

    @Value("${server.port}")
private int port; @PostMapping("/post/{name}")
public String post(@PathVariable String name, @RequestBody String type) {
return "svcA:" + port + "===>\n" + "name:" + name + "\ntype:" + type;
}

打开Postman:

发送请求:http://localhost:8004/ribbon/post?svcName=SVCA&url=/post/xixi&className=java.lang.String

Header:{'Content-Type': 'application/json'}

Body: {'raw': {

{

"headers": {"Content-Type": ["application/json"]},

"body": "haha"

}

}}

多次点击发送请求,在ribbon服务下看到日志:

"svcA:8081===>\nname:xixi\ntype:haha"
"svcA:8087===>\nname:xixi\ntype:haha"
"svcA:8081===>\nname:xixi\ntype:haha"
"svcA:8087===>\nname:xixi\ntype:haha"
"svcA:8081===>\nname:xixi\ntype:haha"
"svcA:8087===>\nname:xixi\ntype:haha"

两个服务交替接收请求,这说明Ribbon配置生效了。

Spring-Cloud-Ribbon学习笔记(一):入门的更多相关文章

  1. spring cloud(学习笔记)高可用注册中心(Eureka)的实现(二)

    绪论 前几天我用一种方式实现了spring cloud的高可用,达到两个注册中心,详情见spring cloud(学习笔记)高可用注册中心(Eureka)的实现(一),今天我意外发现,注册中心可以无限 ...

  2. Spring Cloud Alibaba学习笔记(1) - 整合Spring Cloud Alibaba

    Spring Cloud Alibaba从孵化器版本毕业:https://github.com/alibaba/spring-cloud-alibaba,记录一下自己学习Spring Cloud Al ...

  3. Spring Cloud Alibaba学习笔记(3) - Ribbon

    1.手写一个客户端负载均衡器 在了解什么是Ribbon之前,首先通过代码的方式手写一个负载均衡器 RestTemplate restTemplate = new RestTemplate(); // ...

  4. spring cloud(学习笔记)高可用注册中心(Eureka)的实现(一)

    最近在学习的时候,发现微服务架构中,假如只有一个注册中心,那这个注册中心挂了可怎么办,这样的系统,既不安全,稳定性也不好,网上和书上找了一会,发现这个spring cloud早就想到了,并帮我们解决了 ...

  5. Spring Cloud Alibaba学习笔记(23) - 调用链监控工具Spring Cloud Sleuth + Zipkin

    随着业务发展,系统拆分导致系统调用链路愈发复杂一个前端请求可能最终需要调用很多次后端服务才能完成,当整个请求陷入性能瓶颈或不可用时,我们是无法得知该请求是由某个或某些后端服务引起的,这时就需要解决如何 ...

  6. Spring Cloud Alibaba学习笔记(20) - Spring Cloud Gateway 内置的全局过滤器

    参考:https://cloud.spring.io/spring-cloud-static/Greenwich.SR2/single/spring-cloud.html#_global_filter ...

  7. Spring Cloud Alibaba学习笔记(15) - 整合Spring Cloud Gateway

    Spring Cloud Gateway 概述 Spring Cloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基于Netty.Reactor以及WEbFlux构建,它 ...

  8. Spring Cloud Alibaba学习笔记(4) - Feign配置与使用

    什么是Feign Feign是一个声明式Web Service客户端. 使用Feign能让编写Web Service客户端更加简单, 它的使用方法是定义一个接口,然后在上面添加注解,同时也支持JAX- ...

  9. Spring Cloud Alibaba学习笔记

    引自B站楠哥:https://space.bilibili.com/434617924 一.创建父工程 创建父工程hello-spring-cloud-alibaba Spring Cloud Ali ...

  10. spring cloud(学习笔记)微服务启动错误(1)

    今天下午在启动spring cloud微服务的时候,报了这个错误: Error starting ApplicationContext. To display the auto-configurati ...

随机推荐

  1. 从零开始搭建一个从Win7环境备份至CentOS7的SVN双机备份环境

    ★几个关键的事项★ 需要关闭防火墙filewalld跟selinux ,在root用户下操作: [root@localhost svnRepos]# systemctl stop firewalld ...

  2. (转)HashMap底层实现原理/HashMap与HashTable区别/HashMap与HashSet区别

    ①HashMap的工作原理 HashMap基于hashing原理,我们通过put()和get()方法储存和获取对象.当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算h ...

  3. JavaScript 对象拷贝研究

    介绍一下JavaScript里面的一些对象拷贝的方法 浅拷贝 深拷贝 利用序列化进行对象拷贝

  4. python正则表达式(四)

    re模块的高级用法 search 需求:匹配出文章阅读的次数 #coding=utf-8 import re ret = re.search(r"\d+", "阅读次数为 ...

  5. EasyAR 开发实例---AR礼物(简单demo)

    一个节日礼物效果 --显示模型 在本次的案例中,我使用的是unity5.6.3版本,EasyAR 为2.0.(用1.0的版本,在渲染那块有问题) [导入SDK]到EasyAR官网(http://www ...

  6. win7的python3.5安装numpy包

    1.你需要先确保已经安装了pip(因为我是我们需要用pip安装numpy包),我在cmd里面输入pip能显示pip的有关信息,所以我已经安装了pip了(其实是python3.x自带了pip) 如果没有 ...

  7. 深度优先搜素之N皇后问题

    #include<stdio.h>#include<malloc.h>#include<math.h>int x,a[101],book[101],count=0; ...

  8. 小甲鱼Python第十六讲课后习题--017函数

    函数的定义用def,函数名后要用冒号 函数的返回:函数中使用return   测试题: 0. 你有听说过DRY吗? DRY是指Don't Repeat Yourself ,特指在程序设计以及计算中避免 ...

  9. hql 语法详解

    HQL查询:Criteria查询对查询条件进行了面向对象封装,符合编程人员的思维方式,不过HQL(Hibernate Query Lanaguage)查询提供了更加丰富的和灵活的查询特性,因此 Hib ...

  10. 5、css补充

    css其余问题补充 本篇导航: 默认的高度和宽度问题 后台管理布局 css响应式布局 一.默认的高度和宽度问题 1.父子都是块级元素 <!DOCTYPE html> <html> ...