0.简介

spring cloud 实现负载均衡的方式有很多,本文主要讲解Netflex旗下的ribbon

ribbon是Neflix旗下的一个开源项目,主要的功能是实现负载均衡。

ribbon的负载均衡和我们常用的负载均衡的主要区别是,ribbon是本地负载均衡,消费者的请求会在客户端被决定好发送到哪台服务提供者进行处理,而nginx是服务器负载均衡,所有的客户端请求都会交由nginx进行处理。

在spring-cloud3.0以前,是集成了ribbon的,在以后的版本中并没有集成ribbon,需要手动引入的。

在此之前,我们先画个图,整理一下前面搭建的生成者和消费者的关系

1.创建新生产者

我们参考前面文章,创建新的生产者,命名为sCloudProvider2,

POM文件:

<?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>s-cloud</artifactId>
        <groupId>site.longkui</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>s-cloud-provider2</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--eureka 客户端-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <version>3.1.8-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>

配置文件:

server:
  port: 9002 #服务的端口
#spring相关配置
spring:
  application:
    name: service-provider1  #服务的名称
#eureka配置
eureka:
  client:
    service-url:
      # 填写注册中心服务器地址
      defaultZone: http://localhost:7001/eureka
    # 是否需要将自己注册到注册中心
    register-with-eureka: true
    # 是否需要搜索服务信息
    fetch-registry: true
  instance:
    # 使用ip地址注册到注册中心
    prefer-ip-address: true
    # 注册中心列表中显示的状态参数
    instance-id: ${spring.cloud.client.ip-address}:${server.port}

这里注意,应用的名称是 service-provider1,也就是不论多少个生产者,只要应用名称是同一个,eureka就认为是同一个,这样内部的负载均衡算法才会在多个生产者中来回选择。

启动类参考修改如下:

package site.longkui.scloudprovider2;

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

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

controller类修改如下,注意,这里的显示内容和第一个生产者不一样,是为了区分不同的生产者。

package site.longkui.scloudprovider2.controller;

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

@RestController
@RequestMapping("/user")
public class UserController {

    @GetMapping("/getUser")
    public String getUser() {
        return "I`m provider 222 ,return user";
    }
}
2.修改消费者配置,实现负载均衡

我们首先修改消费者的RestTemplage,增加@LoadBalanced注解,这个注解可以实现负载均衡。

package site.longkui.consumer1.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;

@Configuration
public class ApplicationConfig {
    /**
     * 注册RestTemplate对象到Spring容器
     */
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
}

然后修改controller,把原来的服务地址改为消费者地址,

由原来的 http://127.0.0.1:9001/user/getUser改为http://service-provider1/user/getUser

格式参考: http://{服务提供者应用名名称}/{具体的controller}

package site.longkui.consumer1.controller;

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

@RestController
@RequestMapping("/consumer1")
public class userConsumerController {
    @Autowired
    private RestTemplate restTemplate; // 提供多种便捷访问远程http服务的方法,简单的restful服务模板
    /**
     * 消费者接口
     */
    @GetMapping("/getUser")
    public  String getUser(){
        //指出服务地址
        String url="http://service-provider1/user/getUser";
        //返回值类型和我们的业务返回值一致
        return restTemplate.getForObject(url, String.class);
    }
}

然后重启项目,访问消费者的地址,效果如下:

可以看到,我们访问消费者的地址不变,而返回的消息不断的在两个生产者之间变换,实现了负载均衡。