首页
学习
活动
专区
圈层
工具
发布

SpringCloud详细教程 | 第二篇: 客户端负载平衡器Ribbon(Greenwich版本)

前面说过在微服务架构中, 各个服务之间通常是基于HTTP的Restful API进行通信, Spring Cloud有两种服务调用方式,一种是Ribbon+RestTemplate,另一种是Feign,本文先将讲解前者

一. Ribbon简介

可以参考官方文档: http://cloud.spring.io/spring-cloud-netflix/single/spring-cloud-netflix.html#spring-cloud-ribbon

  • Ribbon是一个客户端负载均衡器,它可以很好地控制HTTP和TCP客户端的行为

Spring Cloud Netflix默认情况下为Ribbon(BeanType beanName:ClassName)提供以下bean:

  • IClientConfig ribbonClientConfig:DefaultClientConfigImpl
  • IRule ribbonRule:ZoneAvoidanceRule
  • IPing ribbonPing:NoOpPing
  • ServerList ribbonServerList:ConfigurationBasedServerList
  • ServerListFilter ribbonServerListFilter:ZonePreferenceServerListFilter
  • ILoadBalancer ribbonLoadBalancer:ZoneAwareLoadBalancer
  • ServerListUpdater ribbonServerListUpdater:PollingServerListUpdater
  1. IClientConfig:Ribbon的客户端配置,主要的作用就是装载配置信息,用于初始化客户端和负载均衡器。默认的实现方式是DefaultClientConfigImpl
  2. IRule:默认采用ZoneAvoidanceRule实现,该策略能够在多区域环境下选出最佳区域的实例。
  3. IPing:默认采用DummyPing实现,该检查策略是一个特殊的实现,实际上并不会检查实例是否可用,而是始终返回true,默认认为所有实例都可用。
  4. ServerList: 服务实例清单的维护机制,默认采用ConfigurationBasedServerList实现。
  5. ServerlistFilter: 服务实例清单过滤机制,默认采用ZonePreferenceServerListFilter,该策略能够优先过滤出于请求方处于同区域的服务实例。
  6. ILoadBalancer:负载均衡器,默认采用ZoneAwareLoadBalancer,它具备区域感知的能力

Ribbon可以在通过客户端中配置的ribbonServerList服务端列表去轮询访问以达到均衡负载的作用 当Ribbon与Eureka联合使用时,ribbonServerList会被DiscoveryEnabledNIWSServerList重写,扩展成从Eureka注册中心中获取服 务端列表。同时它也会用NIWSDiscoveryPing来取代IPing,它将职责委托给Eureka来确定服务端是否已经启动

二. Ribbon实战

既然是负载均衡对吧 得有两个服务消费者 我们使用Idea启动多个实例即可 再启动之前设置下 我的idea版本2018.3的 选择右上角勾线即可

启动eureka-client, 端口为8762 , 然后将eureka-client的配置文件的端口改为8764,再启动, 打开浏览器: 输入 http://localhost:8761/ 这时你会发现: eureka-client在eureka-server注册了2个实例

192.168.1.103:eureka-client:8764 192.168.1.103:eureka-client:8762

端口号分别是: 8762 8764

开始创建ribbon-server服务 创建时勾选ribbon依赖

改造后的pom.xml文件 也就是继承父pom文件 和 父pom添加ribbon-server模块

代码语言:javascript
复制
<?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>    <parent>        <groupId>com.li</groupId>        <artifactId>SpringCloudLearn</artifactId>        <version>1.0-SNAPSHOT</version>        <relativePath>../</relativePath>    </parent>    <artifactId>ribbon-server</artifactId>    <version>0.0.1-SNAPSHOT</version>    <name>ribbon-server</name>    <description>Demo project for Spring Boot</description>    <properties>        <java.version>1.8</java.version>        <spring-cloud.version>Greenwich.SR1</spring-cloud.version>    </properties>    <dependencies>        <!--eureka客户端-->        <dependency>            <groupId>org.springframework.cloud</groupId>            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>        </dependency>        <!--ribbon-->        <dependency>            <groupId>org.springframework.cloud</groupId>            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>        </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>

配置文件

代码语言:javascript
复制
# 端口号server.port=8765# 需要指明spring.application.name 这个很重要# 这在以后的服务与服务之间相互调用一般都是根据这个namespring.application.name=ribbon-server#服务注册中心实例的主机名eureka.instance.hostname=localhost#服务注册中心端口号eureka.port=8761#在此指定服务注册中心地址eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${eureka.port}/eureka/

在程序入口处,通过@EnableDiscoveryClient向服务中心注册

并且向程序注入一个Bean: RestTemplate

并通过@LoadBalanced注解表明这个RestRemplate开启负载均衡的功能

并定义接口/hello 进行调用使用

代码语言:javascript
复制
package com.li.ribbonserver;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.loadbalancer.LoadBalanced;import org.springframework.cloud.netflix.eureka.EnableEurekaClient;import org.springframework.context.annotation.Bean;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.client.RestTemplate;@RestController@EnableEurekaClient@SpringBootApplicationpublic class RibbonServerApplication {    public static void main(String[] args) {        SpringApplication.run(RibbonServerApplication.class, args);    }    @Bean    @LoadBalanced // 开启负载均衡    RestTemplate restTemplate() {        return new RestTemplate();    }    @RequestMapping("/hello")    public String hello(String name) {        // 地址直接写服务名称即可        return this.restTemplate().getForObject("http://eureka-client/hello?name" + name, String.class);    }}

可能大家发现我之前是通过ip地址和端口号进行调用, 现在不再手动获取ip和端口,而是直接通过服务名称调用现在改为服务名进行调用了, 因为通过Ribbon和Eureka结合使用时从Eureka注册中心中获取服务端列表从而获取到服务名所对应的ip以及端口号

启动项目,打开浏览器访问: localhost:8765/hello?name=lhd 看下效果

第一次访问:

第二次访问:

通过控制台可以看到 自动获取Eurka服务中心的eurrka-client服务名对应的ip以及端口号

这样就实现了Ribbon客户端对服务调用的负载均衡

源码下载: https://github.com/LiHaodong888/SpringCloudLearn

下一篇
举报
领券