一 Ribbon简介

Ribbon是Netflix发布的负载均衡器,它有助于控制HTTP和TCP的客户端的行为。为Ribbon配置服务提供者地址后,Ribbon就可基于某种负载均衡算法,自动地帮助服务消费者去请求。Ribbon默认为我们提供了很多负载均衡算法,例如轮询、随机等。当然,我们也可为Ribbon实现自定义的负载均衡算法。

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

下图展示了Ribbon与Eureka配合使用时的架构

搭建负载均衡Ribbon (ribbon-consumer)

接到上篇 “SpringCloud之服务注册与发现Eureka(一)

继续在springcloud工程中添加模块ribbon-consumer,也是通过start.spring.io提供的模板创建

新的目录

生成的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.xuan</groupId>
<artifactId>ribbon-consumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging> <name>ribbon-consumer</name>
<description>Demo project for Spring Boot</description> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
</properties> <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>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies> <dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build> </project>

修改启动文件RibbonConsumerApplication.java,注意增加RestTemplate 的bean注解。

package com.xuan.ribbonconsumer;

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.web.client.RestTemplate; @EnableDiscoveryClient
@SpringBootApplication
public class RibbonConsumerApplication {
@Bean
@LoadBalanced
RestTemplate restTemplate () {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(RibbonConsumerApplication.class, args);
}
}

增加测试的消费接口ConsumerController.java

package com.xuan.ribbonconsumer;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate; @RestController
public class ConsumerController {
@Autowired
RestTemplate restTemplate; @RequestMapping(value = "/ribbon-consumer", method = RequestMethod.GET)
public String helloConsumer() {
return restTemplate.getForEntity("http://eureka-client/hello",
String.class).getBody();
}
}

注意要去实现提供者的“hello”接口,在后面在描述具体实现过程。

修改配置文件”application.properties“,让消费者注册中心注册,并且通过注册中心找到服务提供者。

spring.application.name=ribbon-consumer
server.port=9000
eureka.client.serviceUrl.defaultZone=http://localhost:8080/eureka/

为了观察是否进行了负载均衡,在eureka-client模块,增加一个服务提供者接口HelloController.java实现hello接口。

package com.xuan.eurekaclient;

import com.netflix.appinfo.InstanceInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController
public class HelloController {
private static final Logger logger = LoggerFactory.getLogger(HelloController.class); @Autowired
private DiscoveryClient client; @Value("${server.port}")
String port; @RequestMapping(value = "hello", method = RequestMethod.GET)
public String index() {
    StringBuffer uriList = new StringBuffer("Hello World " + port + " 端口为您服务!<br>");

    return uriList.toString();
    }
}

如果需要打印服务端的详细明细可以修改为:

package com.xuan.eurekaclient;

import com.netflix.appinfo.InstanceInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController
public class HelloController {
private static final Logger logger = LoggerFactory.getLogger(HelloController.class); @Autowired
private DiscoveryClient discoveryClient; @Value("${server.port}")
String port; @RequestMapping(value = "hello", method = RequestMethod.GET)
public String index() {
StringBuffer uriList = new StringBuffer("Hello World " + port + " 端口为您服务!<br>"); List<ServiceInstance> list = discoveryClient.getInstances("eureka-client");
uriList.append("<br>discoveryClient.getServices().size() = " + discoveryClient.getServices().size());
for( String s : discoveryClient.getServices()){
List<ServiceInstance> serviceInstances = discoveryClient.getInstances(s);
for(ServiceInstance si : serviceInstances){
uriList.append("<br>services:" + s + ":getHost()=" + si.getHost());
uriList.append("<br>services:" + s + ":getPort()=" + si.getPort());
uriList.append("<br>services:" + s + ":getServiceId()=" + si.getServiceId());
uriList.append("<br>services:" + s + ":getUri()=" + si.getUri());
}
} return uriList.toString();
}
}

在eureka-client模块再增加两个配置文件,使用不同的端口,从而在一天电脑可以启动多个服务提供者,方便测试

增加”application-peer1.properties“文件

spring.application.name=eureka-client
server.port=8091
eureka.client.serviceUrl.defaultZone=http://localhost:8080/eureka/

增加”application-peer1.properties“文件

spring.application.name=eureka-client
server.port=8092
eureka.client.serviceUrl.defaultZone=http://localhost:8080/eureka/

添加完成后eureka-client模块的目录结构为:

设置IDEA编辑器的Edit Configurations,增加两个启动配置,修改过完后的列表和注意的地方:

配置和环境都设置完成后:就可以分别启动模块了:

1.EurekaServerApplication

2.EurekaClientApplication,EurekaClientApplication1,EurekaClientApplication2

启动后打开http://localhost:8080/显示如图:

最后启动RibbonConsumerApplication模块在打开http://localhost:8080/显示如下

消费者RibbonConsumer也注册成功了。

访问消费者提供的接口http://localhost:9000/ribbon-consumer,查看是否进行了负载均衡,刷新一次,端口就变化了一次,说明访问的是不同的服务提供者

源码下载地址:https://gitee.com/xuantest/SpringCloud-Ribbon

SpringCloud之实现客户端的负载均衡Ribbon(二)的更多相关文章

  1. SpringCloud系列七:使用Ribbon实现客户端侧负载均衡

    1. 回顾 在前面,已经实现了微服务的注册与发现.启动各个微服务时,Eureka Client会把自己的网络信息注册到Eureka Server上. 但是,在生成环境中,各个微服务都会部署多个实例,因 ...

  2. 【微服务】之四:轻松搞定SpringCloud微服务-负载均衡Ribbon

    对于任何一个高可用高负载的系统来说,负载均衡是一个必不可少的名称.在大型分布式计算体系中,某个服务在单例的情况下,很难应对各种突发情况.因此,负载均衡是为了让系统在性能出现瓶颈或者其中一些出现状态下可 ...

  3. SpringCloud学习系列之二 ----- 服务消费者(Feign)和负载均衡(Ribbon)使用详解

    前言 本篇主要介绍的是SpringCloud中的服务消费者(Feign)和负载均衡(Ribbon)功能的实现以及使用Feign结合Ribbon实现负载均衡. SpringCloud Feign Fei ...

  4. SpringCloud学习笔记:负载均衡Ribbon(3)

    1. RestTemplate简介 RestTemplate是Spring Resource中一个访问第三方RESTful API接口的网络请求框架. RestTemplate是用来消费REST服务的 ...

  5. Spring Cloud 入门教程(五): Ribbon实现客户端的负载均衡

    接上节,假如我们的Hello world服务的访问量剧增,用一个服务已经无法承载, 我们可以把Hello World服务做成一个集群. 很简单,我们只需要复制Hello world服务,同时将原来的端 ...

  6. 客户端负载均衡Ribbon之二:Loadbalance的源码

    Load Balance负载均衡是用于解决一台机器(一个进程)无法解决所有请求而产生的一种算法. 像nginx可以使用负载均衡分配流量,ribbon为客户端提供负载均衡,dubbo服务调用里的负载均衡 ...

  7. 服务注册发现Eureka之三:Spring Cloud Ribbon实现客户端负载均衡(客户端负载均衡Ribbon之三:使用Ribbon实现客户端的均衡负载)

    在使用RestTemplate来消费spring boot的Restful服务示例中,我们提到,调用spring boot服务的时候,需要将服务的URL写死或者是写在配置文件中,但这两种方式,无论哪一 ...

  8. 0403-服务注册与发现-客户端负载均衡-Ribbon的基本使用

    一.概述 问题1.上一篇文章已说明如何注册微服务,但是调用方如何调用,以及如何防止硬编码.即电影微服务调用用户微服务 问题2.用户微服务多个节点,调用服务方如何负载均衡 二.实现负载均衡方式 2.1. ...

  9. 客户端负载均衡Ribbon之源码解析

    什么是负载均衡器? 假设有一个分布式系统,该系统由在不同计算机上运行的许多服务组成.但是,当用户数量很大时,通常会为服务创建多个副本.每个副本都在另一台计算机上运行.此时,出现 "Load ...

随机推荐

  1. Linux批量解压文件

    最近下载了Imagenet2012的数据文件,训练数据下有很多tar文件,这些tar文件都在一个目录内,所以想批量解压到该目录下每个单独的文件夹内 批量解压的步骤是, 1.列出所有的以tar为后缀的文 ...

  2. python性能分析——insert()

    我们在list中插入数据时,经常使用这两个函数: append():在列表的末尾增加一个数据 insert():在某个特定位置前加一个数据 Python内的list实现是通过数组实现的,而不是链表的形 ...

  3. 实验吧—Web——WP之 Forms

    我们先打开解题链接: 做Web题的第一步就是查看网页源代码,当然,有些网页他不会让你点击右键,那么可以在地址栏里的地址前面加上:view-source: 当然也可以打开控制台F12 我们可以看到代码里 ...

  4. 杜教BM【转载】

    https://blog.csdn.net/qq_36876305/article/details/80275708 #include <bits/stdc++.h> using name ...

  5. mysql对后空格不敏感 mysql数据库对空格的查询处理

    mysql对后空格不敏感 https://blog.csdn.net/lzupb/article/details/73530589 结论:查询条件中建议对字符串做trim处理,在数据入库的时候最好也做 ...

  6. 下面的程序段创建了BufferedReader类的对象in,以便读取本机c盘my文件夹下的文件1.txt。File构造函数中正确的路径和文件名的表示是( )。

    下面的程序段创建了BufferedReader类的对象in,以便读取本机c盘my文件夹下的文件1.txt.File构造函数中正确的路径和文件名的表示是(    ). ./表示当前项目的路径../表示当 ...

  7. 【HAOI2012】外星人

    又犯sb错了QAQ 原题: 艾莉欧在她的被子上发现了一个数字 ,她觉得只要找出最小的x使得,.根据这个 她就能找到曾经绑架她的外星人的线索了.当然,她是不会去算,请你帮助她算出最小的x. test&l ...

  8. 【shell编程】之基础知识了解shell

    一.什么是shell Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁.Shell 既是一种命令语言,又是一种程序设计语言. Shell 是指一种应用程序,这个应用程序提供了 ...

  9. 【mybatis源码学习】调试mybatis的第一个程序

    [一].基础知识准备 mybatis-config.xml配置文件的结构 MyBatis配置文件中大标签configuration下子标签包括: configuration |--- properti ...

  10. day12Flume、azkaban、sqoop

    1.PS:Hive中好少有update这个方法,因为他主要是用来批量数据的处理分析. 2.PS:软连接和硬连接的区别 软连接就是我们普通和Windows系统一样的快捷方式,她也是一个文件 硬连接就是他 ...