springcloud-Ribbon 客户端负载均衡

  • Ribbon 基础
  • Ribbon 引入项目改造

一般来说,提到负载均衡,大家一般很容易想到浏览器 -> NGINX -> 反向代理多个 Tomcat 这样的架构图——业界管这种负载均衡模式叫”服务器端负载均衡”,因为此种模式下,负载均衡算法是 NGINX 提供的,而 NGINX 部署在服务器端。

Ribbon 则是一个客户端侧负载均衡组件——通俗地说,就是集成在客户端(服务消费者一侧),并提供负载均衡算法的一个组件。

Ribbon 是 Netflix 发布的负载均衡器,它可以帮我们控制 HTTP 和 TCP 客户端的行为。只需为 Ribbon 配置服务提供者地址列表,Ribbon 就可基于负载均衡算法计算出要请求的目标服务地址。

Ribbon 默认为我们提供了很多的负载均衡算法,例如轮询、随机、响应时间加权等——当然,为 Ribbon 自定义负载均衡算法也非常容易,只需实现IRule 接口即可。

TIPS Ribbon 的仓库地址(Github): https://github.com/Netflix/ribbon

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

图片描述

创建ribon服务,microservice-consumer-movie-ribbon

pom.xml 

 Maven 引入依赖:由于 spring-cloud-starter-netflix-eureka-client 已经包含 spring-cloud-starter-netfilx-ribbon,故而无需额外添加依赖

<?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.lzj1234</groupId>
    <artifactId>microservice-consumer-movie-ribbon</artifactId>
    <version>1.0-SNAPSHOT</version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.7.RELEASE</version>
        <relativePath/>
    </parent>

    <properties>
        <java.version>1.8</java.version>
<!--        <maven.compiler.source>8</maven.compiler.source>-->
<!--        <maven.compiler.target>8</maven.compiler.target>-->
    </properties>
    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <!--            <version>2.4.2</version>-->
        </dependency>

        <!-- 引入H2数据库,一种内嵌的数据库,语法类似MySQL -->
        <!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.4.200</version>
            <!--            <scope>test</scope>-->
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.18</version>
            <scope>provided</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <!--            <version>2.4.2</version>-->
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-clean-plugin -->
        <dependency>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-clean-plugin</artifactId>
            <version>2.5</version>
        </dependency>
        <!-- 新增依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>

    <!-- 引入spring cloud的依赖,不能少,主要用来管理Spring Cloud生态各组件的版本 -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.SR2</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>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.5.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

  

org.springframework.boot:spring-boot-maven-plugin:2.0.7.RELEASE:repackage failed: Unable to find mai

<plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>

  

这是因为springboot默认没有启动类,需要手动添加启动类:springboot

创建启动类,App.java

package com.lzj1234;

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;

@SpringBootApplication
@EnableDiscoveryClient
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class,args);
}

@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
// 只需在 RestTemplate 上添加 LoadBalanced 注解,即可让 RestTemplate 整合 Ribbon
}

  

再次执行mvn install 命令,安装依赖包,就不会出错了

MovieController

package com.lzj1234;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
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;
import org.springframework.web.client.RestTemplate;

@RequestMapping("/movies")
@RestController
public class MovieController {

    @Autowired
    RestTemplate restTemplate;

    @GetMapping("/users/{id}")
    public User findById(@PathVariable Long id){
        // 这里用到了RestTemplate的占位符能力  microservice-provider-user
        User user=this.restTemplate.getForObject("http://microservice-provider-user/users/{id}",User.class,id);
        return user;
    }
}

配置文件

server:
  port: 8010
spring:
  application:
    name: microservice-consumer-movie-ribbon
logging:
  level:
    root: INFO
    # 配置日志级别,让hibernate打印出执行的SQL参数
    org.hibernate: INFO
    org.hibernate.type.descriptor.sql.BasicBinder: TRACE
    org.hibernate.type.descriptor.sql.BasicExtractor: TRACE

# 新增配置
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8080/eureka/
  instance:
    prefer-ip-address: true

  

mvn spring-boot:run 

在项目中引用 Ribbon 来实现了客户端的负载均衡。Ribbon 是一个客户端侧负载均衡组件——通俗地说,就是集成在客户端(服务消费者一侧),并提供负载均衡算法的一个组件。

菜鸟的自白
原文地址:https://www.cnblogs.com/lzjloveit/p/14417318.html