SpringCloud之Ribbon负载均衡

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: SpringCloud之Ribbon负载均衡

Spring Cloud Ribbon是基FNetflix Ribbon实现的一套客户端  负载均衡的工具。


简单的说,Ribbon是Netflx发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。Ribbon客户端组件提供一系列完善的配置项如连接超时, 重试等。简单的说,就是在配置文件中列出Load Balancer (简称LB)后面所有的机器, Ribbon会自动的帮助你基 于某种规则(如简单轮询,随机连接等)去连接这些机器。我们也很容易使用Ribbon实现自定义的负载均衡算法。


Ribbon在工作时分成两步

第一步先选择EurekaServer ,它优先选择在同一个区域内负载较少的server


第二步再根据用户指定的策略,在从server取到的服务注册列表中选择一个地址。其中Ribbon提供了多种策略:比如轮询、随机和根据响应时间加权。


ribbon是一个负载均衡客户端,可以很好的控制htt和tcp的一些行为。Feign默认集成了ribbon。7种方式。

2018122916283038.png

架构:搭建两个eureka服务端(7001,7003),还有两个服务提供者(8001,8002),一个服务消费者(80)

20181229143839388.png

首先微服务7001与7003进行Eureka集群搭建。配置文件是通过两个Eureka Server互相注册,配置的时候要表示自己就是注册中心,不注册自己。在启动类加上@EnableEurekaServer表示该服务是服务端启动类,接受其它微服务注册进来。


C:\Windows\System32\drivers\etc\hosts目录下配置域名

#127.0.0.1       activate.navicat.com
127.0.0.1       localhost
127.0.0.1       eureka7001
127.0.0.1       eureka7003
127.0.0.1       eureka7005
127.0.0.1       myzuul.com

7001yml配置

server: 
  port: 7001
eureka:
  instance:
    hostname: eureka7001 #eureka服务端的实例名称
    #hostname: localhost
    prefer-ip-address: true     #访问路径可以显示IP地址
  client: 
    register-with-eureka: false     #false表示不向注册中心注册自己。
    fetch-registry: false     #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
    service-url: 
      #defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/       #设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址
      defaultZone: http://eureka7003:7003/eureka/  #将自己注册到其它的eureka服务器

7003yml配置

server: 
  port: 7003
eureka:
  instance:
    hostname: eureka7003 #eureka服务端的实例名称
    prefer-ip-address: true     #访问路径可以显示IP地址
    #hostname: localhost
  client: 
    register-with-eureka: false     #false表示不向注册中心注册自己。
    fetch-registry: false     #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
    service-url: 
      #defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/       #设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址(单机)。
      defaultZone: http://eureka7001:7001/eureka/   #将自己注册到其它的eureka服务器

把8001与8002注册进eureka服务注册中心,8001与8002可以拥有自己独立的数据库本案例是连接了两个数据库,配置时需要注意的地方

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>microservicecloud</artifactId>
        <groupId>com.smxy.lq</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>microservicecloud-provider-dept-8001</artifactId>
    <dependencies>
        <!-- 引入自己定义的api通用包,可以使用Dept部门Entity -->
        <dependency>
            <groupId>com.smxy.lq</groupId>
            <artifactId>microservicecloud-api</artifactId>
            <version>${project.version}</version>
        </dependency>
         <!--actuator监控信息完善-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!-- 将微服务provider侧注册进eureka -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</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-test</artifactId>
        </dependency>
        <!-- 修改后立即生效,热部署 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>springloaded</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
    </dependencies>
</project>

yum配置,把8001注册进两个Eureka服务中心,8002同理,需要注意的是


1.eureka.client.serviceUrl.defaultZone 中defaultZone不等于default-zone使用default-zone eureka客户端会识别不了。


2.使用IP进行配置eurake 但是没有eureka.instance.prefer-ip-address=true时,集群erueka注册信息混乱。


3.两个服务的spring.application.name需要一致

server:
  port: 8001
mybatis:
  config-location: classpath:mybatis/mybatis.cfg.xml        # mybatis配置文件所在路径
  type-aliases-package: com.smxy.lq.entities    # 所有Entity别名类所在包
  mapper-locations:
  - classpath:mybatis/mapper/**/*.xml                       # mapper映射文件
spring:
   application:
    name: microservicecloud-dept
   datasource:
    type: com.alibaba.druid.pool.DruidDataSource            # 当前数据源操作类型
    driver-class-name: org.gjt.mm.mysql.Driver              # mysql驱动包
    url: jdbc:mysql://localhost:3306/cloudDB01              # 数据库名称
    username: root
    password: 671354
    dbcp2:
      min-idle: 5                                           # 数据库连接池的最小维持连接数
      initial-size: 5                                       # 初始化连接数
      max-total: 5                                          # 最大连接数
      max-wait-millis: 200                                  # 等待连接获取的最大超时时间
eureka:
  client: #客户端注册进eureka服务列表内
    service-url:
       #defaultZone: http://localhost:7001/eureka
       defaultZone: http://eureka7001:7001/eureka/,http://eureka7003:7003/eureka/
  instance:
    instance-id: microservicecloud-dept8001  #服务名称
    prefer-ip-address: true     #访问路径可以显示IP地址
info:
  app.name: microservicecloud
  company.name: www.baidu.com
  build.artifactId: $project.artifactId$
  build.version: $project.version$

在启动类上面添加@EnableEurekaClient即可,本服务启动后会自动注入进eureka服务中

/**
 * @author BushRo
 * @Description: TOTO
 * @date 2018-12-29
 */
@SpringBootApplication
@EnableEurekaClient//本服务启动后会自动注入进eureka服务中
public class DeptProvider8002_App {
    public static void main(String[] args) {
        SpringApplication.run(DeptProvider8002_App.class, args);
    }
}

新建一个80端口的服务消费者,利用Ribbon轮训访问两个服务提供者,实现负载均衡的效果

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>microservicecloud</artifactId>
        <groupId>com.smxy.lq</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>microservicecloud-consumer-dept-80</artifactId>
    <description>部门微服务消费者</description>
    <dependencies>
        <dependency><!-- 自己定义的api -->
            <groupId>com.smxy.lq</groupId>
            <artifactId>microservicecloud-api</artifactId>
            <version>${project.version}</version>
        </dependency>
        <!-- Ribbon相关 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-ribbon</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- 修改后立即生效,热部署 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>springloaded</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
    </dependencies>
</project>

yml配置

server:
  port: 80
eureka:
  client:
    register-with-eureka: false
    service-url:
      defaultZone: http://eureka7001:7001/eureka/,http://eureka7003:7003/eureka/

启动类

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

springboot微服务之间的调用可以使用RestTemplate


RestTemplate提供了多种便捷访问远程Http服务的方法,

是一种简单便捷的访问restful服务模板类,是Spring提供的用于访问Rest服务的客戸端模板工具集。在使用负载均衡的时候只要添加上@LoadBalanced注解就好了。默认是轮询的方式调用。

1.首先把这个类加载到spring容器中

/**
 * @author BushRo
 * @Description: TOTO
 * @date 2018-12-25
 */
@Configuration
public class ConfigBean {
    @Bean
    @LoadBalanced//Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端       负载均衡的工具。
    public RestTemplate getRestTemplate()
    {
        return new RestTemplate();
    }
}

2.在Controller中调用,使用 使用restTemplate访问restful接口非常的简单粗暴无脑。 (url, requestMap,ResponseBean.class)这三个参数分别代表 REST请求地址、请求参数、HTTP响应转换被转换成的对象类型。

    private static final String REST_URL_PREFIX = "http://MICROSERVICECLOUD-DEPT";
    @Autowired
    private RestTemplate restTemplate;
    @RequestMapping(value = "/consumer/dept/test")
    public String test() {
        return restTemplate.getForObject(REST_URL_PREFIX + "/dept/test", String.class);
    }

远程调用的地址前缀为8001与8002配置的spring.application.name中的名称大写,所以前面配置yml是名称需要一致

20181229154151297.png

8001与8002服务提供方需要提供的接口

    @RequestMapping(value = "/dept/test")
    public String test() {
        return "8001";
    }
    @RequestMapping(value = "/dept/test")
    public String test() {
        return "8002";
    }

依次启动7001,7003,8001,8002,80访问80的接口出现如下结果,出现不同的结果说明负载均衡配置成功。

20181229154738865.png

20181229154756758.png

自定义负载均衡的方式

@Configuration
public class ConfigBean {
    @Bean
    @LoadBalanced//Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端       负载均衡的工具。
    public RestTemplate getRestTemplate()
    {
        return new RestTemplate();
    }
    @Bean
    public IRule myRule(){
        return new RandomRule();
    }
}


相关实践学习
部署高可用架构
本场景主要介绍如何使用云服务器ECS、负载均衡SLB、云数据库RDS和数据传输服务产品来部署多可用区高可用架构。
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
1月前
|
负载均衡 算法
ribbon的7种负载均衡算法和替换方法
ribbon的7种负载均衡算法和替换方法
34 0
ribbon的7种负载均衡算法和替换方法
|
17天前
|
负载均衡 网络协议 Java
构建高效可扩展的微服务架构:利用Spring Cloud实现服务发现与负载均衡
本文将探讨如何利用Spring Cloud技术实现微服务架构中的服务发现与负载均衡,通过注册中心来管理服务的注册与发现,并通过负载均衡策略实现请求的分发,从而构建高效可扩展的微服务系统。
|
1月前
|
负载均衡 算法 Java
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(四)Ribbon的使用
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(四)Ribbon的使用
23 0
|
1月前
|
SpringCloudAlibaba 负载均衡 Java
【二】SpringCloud Alibaba之Nacos整合篇(配置负载均衡)
【二】SpringCloud Alibaba之Nacos整合篇(配置负载均衡)
237 0
|
1月前
|
负载均衡
【二十】搭建SpringCloud项目四(Ribbon)
【二十】搭建SpringCloud项目四(Ribbon)
19 0
|
1月前
|
存储 负载均衡 Java
【Spring底层原理高级进阶】微服务 Spring Cloud 的注册发现机制:Eureka 的架构设计、服务注册与发现的实现原理,深入掌握 Ribbon 和 Feign 的用法 ️
【Spring底层原理高级进阶】微服务 Spring Cloud 的注册发现机制:Eureka 的架构设计、服务注册与发现的实现原理,深入掌握 Ribbon 和 Feign 的用法 ️
|
1月前
|
负载均衡 算法 Java
SpringCloud负载均衡源码解析 | 带你从表层一步步剖析Ribbon组件如何实现负载均衡功能
SpringCloud负载均衡源码解析 | 带你从表层一步步剖析Ribbon组件如何实现负载均衡功能
|
1月前
|
负载均衡 程序员 微服务
【微服务】2、一篇文章详解 Ribbon 负载均衡
【微服务】2、一篇文章详解 Ribbon 负载均衡
37 0
|
10天前
|
负载均衡 算法 应用服务中间件
面试题:Nginx有哪些负载均衡算法?Nginx位于七层网络结构中的哪一层?
字节跳动面试题:Nginx有哪些负载均衡算法?Nginx位于七层网络结构中的哪一层?
28 0
|
3月前
|
负载均衡 应用服务中间件 nginx
百度搜索:蓝易云【Nginx和tomcat实现负载均衡教程】
至此,你已经成功地使用Nginx和Tomcat实现了负载均衡。Nginx将根据配置的负载均衡策略将客户端请求分发到多个Tomcat服务器上,以提高系统的性能和可用性。请注意,在实际生产环境中,还需要进行其他配置和优化,如健康检查、会话保持等,以满足具体的需求。
34 0