SpringCloud之实现服务器端的负载均衡Ribbon(二)

一 Ribbon简介

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

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

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

接到上篇 http://www.cnblogs.com/grasp/p/9258811.html

继续在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

原文地址:https://www.cnblogs.com/grasp/p/9296530.html

时间: 2024-10-22 03:54:27

SpringCloud之实现服务器端的负载均衡Ribbon(二)的相关文章

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

什么是负载均衡器? 假设有一个分布式系统,该系统由在不同计算机上运行的许多服务组成.但是,当用户数量很大时,通常会为服务创建多个副本.每个副本都在另一台计算机上运行.此时,出现 "Load Balancer(负载均衡器)".它有助于在服务器之间平均分配传入流量. 服务器端负载均衡器 传统上,Load Balancers(例如Nginx.F5)是放置在服务器端的组件.当请求来自 客户端 时,它们将转到负载均衡器,负载均衡器将为请求指定 服务器.负载均衡器使用的最简单的算法是随机指定.在这

2.【Spring Cloud Alibaba】实现负载均衡-Ribbon

负载均衡的两种方式 如何实现负载均衡 目前已经实现让A总能找到B,如何实现负载均衡 负载均衡的两种方式 服务器端负载均衡 客户端负载均衡 使用Ribbo实现负载均衡 Ribbon是什么 ==Netflix开源的客户端侧负载均衡器== 引入Ribbon后的架构演进 整合Ribbon实现负载均衡 // 在spring容器中,创建一个对象,类型RestTemplate:名称/ID是:restTemplate // <bean id="restTemplate" class="

003客户端负载均衡Ribbon &amp; 短路器Hystrix

1.POM配置 和普通Spring Boot工程相比,仅仅添加了Eureka.Ribbon.Hystrix.Spring Boot Starter Actuator依赖和Spring Cloud依赖管理 <dependencies> <!--添加Eureka Server依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-

负载均衡Ribbon

1.1         消费者 1.1.1      创建Maven工程 1.1.2      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

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

对于任何一个高可用高负载的系统来说,负载均衡是一个必不可少的名称.在大型分布式计算体系中,某个服务在单例的情况下,很难应对各种突发情况.因此,负载均衡是为了让系统在性能出现瓶颈或者其中一些出现状态下可以进行分发业务量的解决方案.在SpringCloud 体系当中,加入了Netflix公司的很多优秀产品,其中一个就是针对于服务端进行负载均衡的Ribbon. 本系列博文目录 [微服务]之三:轻松搞定SpringCloud微服务目录 本系列为连载文章,阅读本文之前强烈建议您先阅读前面几篇. 相关简介

SpringCloud开发学习总结(四)—— 客户端负载均衡Ribbon

通过上一章<SpringCloud开发学习总结(三)-- 服务治理Eureka>,我们已经搭建起微服务架构中的核心组件--服务注册中心(包括单点模式和高可用模式).同时还注册了一个服务,命名为hello-service.现在我们已经有了服务注册中心和服务提供者,下面就来尝试构建一个服务消费者,它主要完成两个目标,发现服务以及消费服务.其中,服务发现的任务由Eureka的客户端完成,而服务消费的任务由Ribbon完成.Ribbon是一个基于HTTP和TCP的客户端负载均衡器,它可以在通过客户端中

Spring-cloud微服务实战【五】:负载均衡ribbon

在实战三中,我们曾说到,我们需要一种机制,可以在访问服务的时候不需要关心IP,并且还能提供类似Nginx的负载均衡的功能,其实在上一篇文章中我们已经使用过spring-cloud的负载均衡功能了,还记得我们在配置restTemplate的时候加的注解吗? @LoadBalanced就是告诉restTemplate,需要使用负载均衡,并且,在eureka-client消费者消费服务的时候,只能通过@LoadBalanced才能使用eureka-server中的服务application-name来

干货分享微服务spring-cloud(4.负载均衡ribbon与熔断器hystrix)

Ribbon是一个基于http和tcp的客户端负载均衡工具 Hystrix具备服务降级.服务熔断.线程和信号隔离.请求缓存.请求合并以及服务监控 为了方便消费者负载均衡效果,复制demo-springcloud-client1并重名为demo-springcloud-client2,修改配置文件和启动类,服务提供者1和2服务名均为spring.application.name=demo-springcloud-client 修改YhqContoller实现,为了方便负载均衡观察效果,demo-s

SpringCloud(2) 客户端的负载均衡Ribbon

和Nginx不同,Ribbon是客户端的负载均衡,Nginx是服务端的负载均衡 创建ribbon的demo项目 首先加入ribbon依赖 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> <version>1.4.0.RELEASE</version>&