基于Spring cloud Ribbon和Eureka实现客户端负载均衡

前言

本案例将基于Spring cloud Ribbon和Eureka实现客户端负载均衡,其中Ribbon用于实现客户端负载均衡,Eureka主要是用于服务注册及发现;java

传统的服务端负载均衡

常见的服务端负载均衡有基于nginx实现的,Nginx收到请求后,经过轮询,IP哈希等算法来决定转发该请求到哪一个服务来处理,这种方式缺点仍是比较多的;nginx

客户端负载均衡

在微服务架构中,会有不少服务,每一个服务有可能会有多个实例,为了治理这些服务,咱们能够经过eureka、consoul、 zookeeper来实现,解决完服务管理后,可是还有问题,若是当某个服务但愿调用其它服务,一般会经过eureka去查询服务列表,而后eureka返回该服务的全部实例,and 而后调用方应该用哪一个服务呢?算法

这时候,就须要客户端负载均衡来处理这个问题了,客户端负载均衡是和应用程序绑定在一块儿的,咱们不须要单独部署一个额外的服务,本文将使用Spring cloud Ribbon,能够帮助客户端去决定选择哪一个服务实例来调用,并能够设定负载均衡算法;spring

Netflix ribbon介绍

一个客户端的负载均衡实现,Netflix ribbon提供了如下功能:后端

一、负载均衡缓存

二、故障容错springboot

三、支持多种协议(HTTP, TCP, UDP)架构

四、缓存app

在maven项目中,可使用如下方式引入:负载均衡

<dependency>
    <groupId>com.netflix.ribbon</groupId>
    <artifactId>ribbon</artifactId>
    <version>2.2.2</version>
</dependency>

Netflix ribbon例子

一种快速建立工程的方法是去https://start.spring.io/网站,添加对应的依赖,而后直接下载引入到IDE便可;

一、建立Eureka服务管理工程

很简单,主要是要在Spring boot工程里加上@EnableEurekaServer注解,并添加如下application.properties中的配置;

RibbonEurekaServerApplication
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
 
@SpringBootApplication
@EnableEurekaServer
public class RibbonEurekaServerApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(RibbonEurekaServerApplication.class, args);
    }
}

application.properties

spring.application.name= ${springboot.app.name:eureka-serviceregistry}
server.port = ${server-port:8761}
eureka.instance.hostname= ${springboot.app.name:eureka-serviceregistry}
eureka.client.registerWithEureka= false
eureka.client.fetchRegistry= false
eureka.client.serviceUrl.defaultZone: http://${registry.host:localhost}:${server.port}/eureka/

而后启动,界面以下:

二、建立服务端工程

首先,建一个controller

@RestController
public class MyRestController {

    @Autowired
    Environment environment;

    @GetMapping("/")
    public String health() {
        return "I am Ok";
    }

    @GetMapping("/backend")
    public String backend() {
        System.out.println("Inside MyRestController::backend...");

        String serverPort = environment.getProperty("local.server.port");

        System.out.println("Port : " + serverPort);

        return "Hello form Backend!!! " + " Host : localhost " + " :: Port : " + serverPort;
    }
}

而后新建启动类,并加上@EnableDiscoveryClient注解

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

最后,加上配置文件application.properties

spring.application.name=server
server.port = 9090
 
eureka.client.serviceUrl.defaultZone= http://${registry.host:localhost}:${registry.port:8761}/eureka/
eureka.client.healthcheck.enabled= true
eureka.instance.leaseRenewalIntervalInSeconds= 1
eureka.instance.leaseExpirationDurationInSeconds= 2

三、建立客户端工程

注意客户端工程须要添加spring-cloud-starter-netflix-ribbon依赖;

首先,咱们新建启动类,并加上@RibbonClient@EnableDiscoveryClient注解

@EnableDiscoveryClient
@SpringBootApplication
@RibbonClient(name = "server", configuration = RibbonConfiguration.class)
public class RibbonClientApplication {

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

注意这里的RibbonConfiguration,是咱们的自定义配置类,这里面的方法能够本身根据状况重写,本例子只是一个简单的测试,用的是Ribbon提供的默认方式,代码以下:

public class RibbonConfiguration {

    @Autowired
    IClientConfig config;

    @Bean
    public IPing ribbonPing(IClientConfig config) {
        return new PingUrl();
    }

    @Bean
    public IRule ribbonRule(IClientConfig config) {
        return new AvailabilityFilteringRule();
    }
}

最后,添加application.properties配置文件,以下:

spring.application.name=client
server.port=8888

eureka.client.serviceUrl.defaultZone= http://${registry.host:localhost}:${registry.port:8761}/eureka/
eureka.client.healthcheck.enabled= true
eureka.instance.leaseRenewalIntervalInSeconds= 1
eureka.instance.leaseExpirationDurationInSeconds= 2


server.ribbon.eureka.enabled=true
#server.ribbon.listOfServers=localhost:9090,localhost:9091,localhost:9092
server.ribbon.ServerListRefreshInterval=1000
#logging.level.root=TRACE

例子测试验证

首先,打包,而后启动全部的以上服务,使用java -jar -Dserver.port=XXXX YYYYY.jar命令启动便可;

启动后,能够在eureka中看到咱们启动的服务:

因为咱们要演示客户端负载均衡功能,因此再启动几个服务端服务,端口为9091 and 9092,启动后以下:

OK,准备工做搞好了,能够开测了,点击http://localhost:8888/client/frontend几回,结果以下,,

一、Server Response :: Hello form Backend!!! Host : localhost :: Port : 9090

二、Server Response :: Hello form Backend!!! Host : localhost :: Port : 9092

三、Server Response :: Hello form Backend!!! Host : localhost :: Port : 9091

而后能够再启动或删除几个后端服务,如启动一个9093端口,在测试一下,9093端口对应的服务也能够访问到,效果一样OK。。。

那么,若是只想写死,从几个服务中选择,而不是自动变更呢,能够在客户端用如下配置,那么就会一直从这三个服务中选取了。

server.ribbon.listOfServers=localhost:9090,localhost:9091,localhost:9092
相关文章
相关标签/搜索