【云原生&微服务一】SpringCloud之Ribbon实现负载均衡详细案例(集成Eureka、Ribbon)

简介: 【云原生&微服务一】SpringCloud之Ribbon实现负载均衡详细案例(集成Eureka、Ribbon)

一、负载均衡概述

在分布式 或 微服务架构中,服务的提供者往往有多个实例 会注册到服务注册中心中,服务消费者需要使用服务时,需要决定使用哪个服务提供者,这正是负载均衡的体现。
负载均衡也可以理解为:将用户的请求平摊分配到每个服务器上,尽可能的压榨每台服务器的带宽、性能。

负载均衡的方式有两种:

  • 服务端负载均衡

    像以前的老架构,通过nginx对请求做负载均衡,然后下发到指定的tomcat。
  • 客户端负载均衡

    client获取到所有的service实例,然后做负载均衡规则。例如:Ribbon、Feign

本文我们针对SpringCloud如何集成Ribbon实现负载均衡做一个讨论。

注:(版本信息)--

二、Ribbon实现负载均衡

整体项目目录包括三个Module,分别为:eureka-server、ribbon-feign-sample、ribbon-feign-sample-consumer。
在这里插入图片描述
其中eureka-server作为服务注册中心、ribbon-feign-sample作为服务提供者、ribbon-feign-sample-consumer作为服务消费者。

Ribbon 与 RestTemplate 配合使用,实现了微服务之间的调用。

0、最上层父项目spring-cloud-center的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>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.7.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <packaging>pom</packaging>

    <!--子模块-->
    <modules>
        <module>ribbon-feign-sample</module>
        <module>ribbon-feign-sample-consumer</module>
        <module>eureka-server</module>
    </modules>

    <artifactId>spring-cloud-center</artifactId>
    <groupId>com.saint</groupId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-cloud-center</name>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.3.7.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--整合spring cloud-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR8</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--整合spring cloud alibaba-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.2.5.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <!-- java编译插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

关于Spring-cloud和SpringBoot的版本对应关系,参考博文:SpringBoot、SpringCloud、SpringCloudAlibaba的版本对应关系

1、搭建服务注册中心eureka-server

eureka-server整体代码结构目录如下:
在这里插入图片描述
其整体很简单、仅仅包含一个pom.xml文件、一个配置文件、一个启动类。

1、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>spring-cloud-center</artifactId>
        <groupId>com.saint</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>eureka-server</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <description>eureka-server</description>

    <dependencies>

        <!--集成Eureka-server-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
    </dependencies>

</project>

2、修改配置文件application.yml

server:
  port: 10010
spring:
  application:
    name: eureka-server
eureka:
  client:
    # 把自身注册到Eureka-server中
    register-with-eureka: true
    # 服务注册中心不需要去检索其他服务
    fetch-registry: false
    # 指定服务注册中心的位置
    service-url:
      defaultZone: http://localhost:10010/eureka
  instance:
    hostname: localhost

3、修改启动类

package com.saint;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

/**
 * @author Saint
 */
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

这里和普通的启动有一个区别:需要加上 @EnableEurekaServer 注解开启Eureka-Server。

4、启动eureka-server

启动成功后,控制台输出如下:
在这里插入图片描述
进入到eureka-server 的dashboard,可以看到eureka-server已经上线:
在这里插入图片描述

2、搭建服务提供者ribbon-feign-sample

ribbon-feign-sample整体代码结构目录如下:
在这里插入图片描述
其中包含一个pom.xml文件、一个配置文件、一个启动类、一个Controller。

1、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>spring-cloud-center</artifactId>
        <groupId>com.saint</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>ribbon-feign-sample</artifactId>
    <groupId>com.saint</groupId>
    <version>0.0.1-SNAPSHOT</version>
    <description>ribbon test service provider</description>

    <dependencies>

        <!--集成eureka-client-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
    </dependencies>

</project>

2、修改配置文件application.yml

server:
  port: 8081
spring:
  application:
    name: greeting-service
eureka:
  client:
    # 将当前服务注册到服务注册中心
    service-url:
      defaultZone: http://localhost:10010/eureka

3、修改启动类

package com.saint;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

/**
 * Saint
 */
@SpringBootApplication
@EnableEurekaClient
public class RibbonFeignSampleApplication {
    public static void main(String[] args) {
        SpringApplication.run(RibbonFeignSampleApplication.class, args);
    }
}

这里和普通的启动有一个区别:需要加上 @EnableEurekaClient 注解开启eureka-client。

4、编写GreetingController

package com.saint.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author Saint
 */
@RestController
@RequestMapping("/greeting")
public class GreetingController {

    @GetMapping("/sayHello/{name}")
    public String sayHello(@PathVariable("name") String name) {
        System.out.println("接收到了请求调用 + " + name);
        return "Hello, " + name;
    }
}

5、启动GREETING-SERVICE服务实例1(8081端口)

服务启动成功后,控制台输出如下:
在这里插入图片描述
再看eureka-server dashboard中多了一个 GREETING-SERVICE 服务,并且其有一个实例 192.168.3.32:greeting-service:8081
在这里插入图片描述

6、启动GREETING-SERVICE服务实例2(8082端口)

1> 修改RibbonFeignSampleApplication的配置:
在这里插入图片描述

2> 复制出一个RibbonFeignSampleApplication配置:
在这里插入图片描述
3> 修改第二启动类配置名为:RibbonFeignSampleApplication-8082,启动端口为8082
在这里插入图片描述
4> 运行RibbonFeignSampleApplication-8082
在这里插入图片描述
5> 启动之后,看eureka-server dashboard中GREETING-SERVICE 服务多了一个实例 192.168.3.32:greeting-service:8082
在这里插入图片描述

3、搭建服务消费者ribbon-feign-sample-consumer

ribbon-feign-sample-consumer整体代码结构目录如下:
在这里插入图片描述
其包含一个pom.xml文件、一个application配置文件、一个启动类、一个Http负载均衡配置类、一个Controller。

1、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>spring-cloud-center</artifactId>
        <groupId>com.saint</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>ribbon-feign-sample-consumer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <description>ribbon test service provider</description>

    <dependencies>

        <!--集成ribbon-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>
        
        <!--集成eureka-client-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

2、修改配置文件application.yml

server:
  port: 9090
spring:
  application:
    name: consumer-service
eureka:
  client:
    # 将当前服务注册到服务注册中心
    service-url:
      defaultZone: http://localhost:10010/eureka

注:服务端口为9090,后面我们进行接口调用的时候会用到。

3、修改启动类

package com.saint;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

/**
 * Saint
 */
@SpringBootApplication
@EnableEurekaClient
public class RibbonFeignSampleConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(RibbonFeignSampleConsumerApplication.class, args);
    }
}

4、修改HTTP负载均衡配置类--HttpConfig

package com.saint.config;

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;

/**
 * Http配置类
 *
 * @author Saint
 */
@Configuration
public class HttpConfig {

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

HttpConfig类的作用:对RestTemple的调用使用Ribbon做负载均衡,将RestTemplate注入到Spring IOC容器中。

5、编写ConsumerController

package com.saint.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

/**
 * @author Saint
 */
@RestController
public class ConsumerController {
    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping("/say/{name}")
    public String getHello(@PathVariable("name") String name) {
        String res = restTemplate.getForObject("http://GREETING-SERVICE/greeting/sayHello/" + name, String.class);
        return res;
    }
}

ConsumerController中通过RestTemplate调用http://GREETING-SERVICE/greeting/sayHello/{name}

6、启动ribbon-feign-sample-consumer

启动成功后,看eureka-server dashboard中多了一个 CONSUMER-SERVICE 服务,并且其有一个实例 192.168.3.32:consumer-service:9090
在这里插入图片描述

4、使用浏览器进行调用服务消费者

上述步骤中,我们已经依次启动了eureka-server、ribbon-feign-sample-8081、ribbon-feign-sample-8082、ribbon-feign-sample-consumer;三个服务、四个实例。

此处我们针对服务消费者ribbon-feign-sample-consumer做四次接口调用,分别为:

  1. http://localhost:9090/say/saint
  2. http://localhost:9090/say/saint2
  3. http://localhost:9090/say/saint3
  4. http://localhost:9090/say/saint4

在这里插入图片描述
然后我们去看ribbon-feign-sample-8081、ribbon-feign-sample-8082的控制台输出:

1> ribbon-feign-sample-8081控制台输出:
在这里插入图片描述
2> ribbon-feign-sample-8082控制台输出:
在这里插入图片描述

3> 结果说明:
我们可以发现,四个请求,ribbon-feign-sample-8081和ribbon-feign-sample-8082各分担了两个请求。其中ribbon-feign-sample-8081服务实例承担了请求:http://localhost:9090/say/saint2、http://localhost:9090/say/saint4,而ribbon-feign-sample-8082服务实例承担了请求:http://localhost:9090/say/saint、http://localhost:9090/say/saint3。

从现象上来看,已经Ribbon实现了负载均衡,并且默认是按照轮询的方式。

下文我们接着讨论 Ribbon是如何实现负载均衡(源码分析)?

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
相关文章
|
5月前
|
数据可视化 Java BI
将 Spring 微服务与 BI 工具集成:最佳实践
本文探讨了 Spring 微服务与商业智能(BI)工具集成的潜力与实践。随着微服务架构和数据分析需求的增长,Spring Boot 和 Spring Cloud 提供了构建可扩展、弹性服务的框架,而 BI 工具则增强了数据可视化与实时分析能力。文章介绍了 Spring 微服务的核心概念、BI 工具在企业中的作用,并深入分析了两者集成带来的优势,如实时数据处理、个性化报告、数据聚合与安全保障。同时,文中还总结了集成过程中的最佳实践,包括事件驱动架构、集中配置管理、数据安全控制、模块化设计与持续优化策略,旨在帮助企业构建高效、智能的数据驱动系统。
301 1
将 Spring 微服务与 BI 工具集成:最佳实践
|
8月前
|
缓存 负载均衡 监控
微服务架构下的电商API接口设计:策略、方法与实战案例
本文探讨了微服务架构下的电商API接口设计,旨在打造高效、灵活与可扩展的电商系统。通过服务拆分(如商品、订单、支付等模块)和标准化设计(RESTful或GraphQL风格),确保接口一致性与易用性。同时,采用缓存策略、负载均衡及限流技术优化性能,并借助Prometheus等工具实现监控与日志管理。微服务架构的优势在于支持敏捷开发、高并发处理和独立部署,满足电商业务快速迭代需求。未来,电商API设计将向智能化与安全化方向发展。
492 102
|
11月前
|
安全 Java Apache
微服务——SpringBoot使用归纳——Spring Boot中集成 Shiro——Shiro 身份和权限认证
本文介绍了 Apache Shiro 的身份认证与权限认证机制。在身份认证部分,分析了 Shiro 的认证流程,包括应用程序调用 `Subject.login(token)` 方法、SecurityManager 接管认证以及通过 Realm 进行具体的安全验证。权限认证部分阐述了权限(permission)、角色(role)和用户(user)三者的关系,其中用户可拥有多个角色,角色则对应不同的权限组合,例如普通用户仅能查看或添加信息,而管理员可执行所有操作。
554 0
|
11月前
|
安全 Java 数据安全/隐私保护
微服务——SpringBoot使用归纳——Spring Boot中集成 Shiro——Shiro 三大核心组件
本课程介绍如何在Spring Boot中集成Shiro框架,主要讲解Shiro的认证与授权功能。Shiro是一个简单易用的Java安全框架,用于认证、授权、加密和会话管理等。其核心组件包括Subject(认证主体)、SecurityManager(安全管理员)和Realm(域)。Subject负责身份认证,包含Principals(身份)和Credentials(凭证);SecurityManager是架构核心,协调内部组件运作;Realm则是连接Shiro与应用数据的桥梁,用于访问用户账户及权限信息。通过学习,您将掌握Shiro的基本原理及其在项目中的应用。
399 0
|
11月前
|
前端开发 Java 数据库
微服务——SpringBoot使用归纳——Spring Boot集成Thymeleaf模板引擎——Thymeleaf 介绍
本课介绍Spring Boot集成Thymeleaf模板引擎。Thymeleaf是一款现代服务器端Java模板引擎,支持Web和独立环境,可实现自然模板开发,便于团队协作。与传统JSP不同,Thymeleaf模板可以直接在浏览器中打开,方便前端人员查看静态原型。通过在HTML标签中添加扩展属性(如`th:text`),Thymeleaf能够在服务运行时动态替换内容,展示数据库中的数据,同时兼容静态页面展示,为开发带来灵活性和便利性。
467 0
|
11月前
|
NoSQL Java 关系型数据库
微服务——SpringBoot使用归纳——Spring Boot 中集成Redis——Redis 介绍
本文介绍在 Spring Boot 中集成 Redis 的方法。Redis 是一种支持多种数据结构的非关系型数据库(NoSQL),具备高并发、高性能和灵活扩展的特点,适用于缓存、实时数据分析等场景。其数据以键值对形式存储,支持字符串、哈希、列表、集合等类型。通过将 Redis 与 Mysql 集群结合使用,可实现数据同步,提升系统稳定性。例如,在网站架构中优先从 Redis 获取数据,故障时回退至 Mysql,确保服务不中断。
404 0
微服务——SpringBoot使用归纳——Spring Boot 中集成Redis——Redis 介绍
|
11月前
|
XML Java 数据库连接
微服务——SpringBoot使用归纳——Spring Boot集成MyBatis——基于 xml 的整合
本教程介绍了基于XML的MyBatis整合方式。首先在`application.yml`中配置XML路径,如`classpath:mapper/*.xml`,然后创建`UserMapper.xml`文件定义SQL映射,包括`resultMap`和查询语句。通过设置`namespace`关联Mapper接口,实现如`getUserByName`的方法。Controller层调用Service完成测试,访问`/getUserByName/{name}`即可返回用户信息。为简化Mapper扫描,推荐在Spring Boot启动类用`@MapperScan`注解指定包路径避免逐个添加`@Mapper`
593 0
|
9月前
|
Java 数据库连接 微服务
若依微服务的Mybatis-plus集成过程:一份详细的入门教程。
以上就是Spring Boot项目中集成MyBatis Plus的详细步骤。集成成功后,你就可以使用Mybatis-plus提供的强大功能,让你的增删改查操作更为简单。以上步骤简单易懂,非常适合初学者使用。希望对您有所帮助。
910 20
|
10月前
|
Cloud Native Serverless 流计算
云原生时代的应用架构演进:从微服务到 Serverless 的阿里云实践
云原生技术正重塑企业数字化转型路径。阿里云作为亚太领先云服务商,提供完整云原生产品矩阵:容器服务ACK优化启动速度与镜像分发效率;MSE微服务引擎保障高可用性;ASM服务网格降低资源消耗;函数计算FC突破冷启动瓶颈;SAE重新定义PaaS边界;PolarDB数据库实现存储计算分离;DataWorks简化数据湖构建;Flink实时计算助力风控系统。这些技术已在多行业落地,推动效率提升与商业模式创新,助力企业在数字化浪潮中占据先机。
519 12
|
11月前
|
消息中间件 存储 Java
微服务——SpringBoot使用归纳——Spring Boot中集成ActiveMQ——ActiveMQ安装
本教程介绍ActiveMQ的安装与基本使用。首先从官网下载apache-activemq-5.15.3版本,解压后即可完成安装,非常便捷。启动时进入解压目录下的bin文件夹,根据系统选择win32或win64,运行activemq.bat启动服务。通过浏览器访问`http://127.0.0.1:8161/admin/`可进入管理界面,默认用户名密码为admin/admin。ActiveMQ支持两种消息模式:点对点(Queue)和发布/订阅(Topic)。前者确保每条消息仅被一个消费者消费,后者允许多个消费者同时接收相同消息。
392 0
微服务——SpringBoot使用归纳——Spring Boot中集成ActiveMQ——ActiveMQ安装