zoukankan      html  css  js  c++  java
  • 基于Spring cloud Ribbon和Eureka实现客户端负载均衡

    前言

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

    传统的服务端负载均衡

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

    客户端负载均衡

    在微服务架构中,会有很多服务,每个服务有可能会有多个实例,为了治理这些服务,我们可以通过eureka、consoul、 zookeeper来实现,解决完服务管理后,但是还有问题,如果当某个服务希望调用其它服务,通常会通过eureka去查询服务列表,然后eureka返回该服务的所有实例,and 然后调用方应该用哪个服务呢?

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

    Netflix ribbon介绍

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

    1、负载均衡

    2、故障容错

    3、支持多种协议(HTTP, TCP, UDP)

    4、缓存

    在maven项目中,可以使用以下方式引入:

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

    Netflix ribbon例子

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

    1、创建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/

    然后启动,界面如下:

    2、创建服务端工程

    首先,建一个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

    3、创建客户端工程

    注意客户端工程需要添加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几次,结果如下,,

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

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

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

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

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

    server.ribbon.listOfServers=localhost:9090,localhost:9091,localhost:9092
  • 相关阅读:
    FTP服务
    Samba文件共享服务设置
    Samba
    编译安装-httpd-2.2.15.tar.gz
    分析排查系统故障
    进程--计划任务
    磁盘配额
    LVM卷
    Linux磁盘分区
    用户组权限
  • 原文地址:https://www.cnblogs.com/chenpi/p/10514093.html
Copyright © 2011-2022 走看看