Spring Cloud Ribbon实现客户端负载均衡的方法

2025-05-29 0 23

简介

Spring Cloud Ribbon实现客户端负载均衡的方法

我们继续以之前博客的代码为基础,增加ribbon组件来提供客户端负载均衡负载均衡是实现高并发、高性能、可伸缩服务的重要组成部分,它可以把请求分散到一个集群中不同的服务器中,以减轻每个服务器的负担。客户端负载均衡是运行在客户端程序中的,如我们的web项目,然后通过获取集群的ip地址列表,随机选择一个server发送请求。相对于服务端负载均衡来说,它不需要消耗服务器的资源。

基础环境

  1. jdk 1.8
  2. maven 3.3.9
  3. intellij 2018.1

git:项目源码

更新配置

我们这次需要在本地启动两个产品服务程序,用来验证负载均衡,所以需要为第二个程序提供不同的端口。spring cloud配置服务中心的配置默认会覆盖本地系统环境变量,而我们需要通过系统环境变量来设置产品服务的端口,所以需要在配置中心git仓库中修改产品服务的配置文件product-service.yml

?

1

2

3

4

5

6

7
server:

port: 8081

spring:

cloud:

config:

allow-override: true

override-system-properties: false

allow-override的默认值即为true,写出它来是想作说明,它的意思是允许远程配置中心的配置项覆盖本地的配置,并不是说允许本地的配置去覆盖远程的配置。当然我们可以把它设置成false,但是为了提供更精确的覆盖规则,这里保留了默认值。

我们添加了override-system-properties=false,即虽然远程配置中心的配置文件可以覆盖本地的配置,但是不要覆盖本地系统变量。修改完成后提交到git仓库。

另外,在productservice项目的productcontroller中添加一些log,用来验证负载均衡是否生效:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15
package cn.zxuqian.controllers;

import org.slf4j.logger;

import org.slf4j.loggerfactory;

import org.springframework.web.bind.annotation.requestmapping;

import org.springframework.web.bind.annotation.restcontroller;

@restcontroller

public class productcontroller {

private static logger log = loggerfactory.getlogger(productcontroller.class);

@requestmapping("/products")

public string productlist() {

log.info("access to /products endpoint");

return "外套,夹克,毛衣,t恤";

}

}

为web配置ribbon

首先在pom.xml中添加ribbon的依赖:

?

1

2

3

4
<dependency>

<groupid>org.springframework.cloud</groupid>

<artifactid>spring-cloud-starter-netflix-ribbon</artifactid>

</dependency>

然后修改application类,添加如下代码:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15
@enablecircuitbreaker

@enablediscoveryclient

@ribbonclient(name = "product-service")

@springbootapplication

public class application {

public static void main(string[] args) {

springapplication.run(application.class, args);

}

@bean

@loadbalanced

public resttemplate rest(resttemplatebuilder builder) {

return builder.build();

}

}

这里用到了@ribbonclient(name = "product-service")注解,用来标记此项目为ribbon负载均衡的客户端,它需要选择产品服务集群中其中的一台来访问所需要的服务,这里的name属性对应于productservice项目中配置的spring.application.name属性。

@loadbalanced注解标明了resttemplate会被配置为自动使用ribbon的loadbalancerclient来选择服务的uri并发送请求。

在我们在productservice类中添加如下代码:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27
@service

public class productservice {

private final resttemplate resttemplate;

@autowired

private discoveryclient discoveryclient;

public productservice(resttemplate resttemplate) {

this.resttemplate = resttemplate;

}

@hystrixcommand(fallbackmethod = "backupproductlist")

public string productlist() {

list<serviceinstance> instances = this.discoveryclient.getinstances("product-service");

if(instances != null && instances.size() > 0) {

return this.resttemplate.getforobject(instances.get(0).geturi() + "/products", string.class);

}

return "";

}

public string backupproductlist() {

return "夹克,毛衣";

}

public string productlistloadbalanced() {

return this.resttemplate.getforobject("http://product-service/products", string.class);

}

}

这里新添加了一个productlistloadbalanced方法,跟之前的productlist方法访问的是同一服务,只不过是用ribbon client去做了负载均衡,这里的uri的host变成了product-service即要访问的服务的名字,跟@ribbonclient中配置的name属性保持一致。最后在我们的productcontroller中添加下面的代码:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16
@restcontroller

public class productcontroller {

@autowired

private productservice productservice;

@requestmapping("/products")

public string productlist() {

return productservice.productlist();

}

@requestmapping("/productslb")

public string productlistloadbalanced() {

return productservice.productlistloadbalanced();

}

}

来创建一个专门处理/productslb请求的方法,调用productservie提供负载均衡的方法。

到这里我们的代码就完成了,代码看似简单,其实是所有的配置都使用了默认值。ribbon提供了编程式和配置式两种方式来配置ribbon client。现简单介绍下,后续深入ribbon时再和大家一起看看如何修改它的配置。ribbon提供如下配置(左边是接口,右边是默认实现):

  1. iclientconfig ribbonclientconfig: defaultclientconfigimpl
  2. irule ribbonrule: zoneavoidancerule
  3. iping ribbonping: dummyping
  4. serverlist<server> ribbonserverlist: configurationbasedserverlist
  5. serverlistfilter<server> ribbonserverlistfilter: zonepreferenceserverlistfilter
  6. iloadbalancer ribbonloadbalancer: zoneawareloadbalancer
  7. serverlistupdater ribbonserverlistupdater: pollingserverlistupdater

因为我们这个项目用了eureka,所以有些配置项和默认实现有所不同,如eureka使用discoveryenabledniwsserverlist取代ribbonserverlist来获取在eureka上注册的服务的列表。下边有一个简单的congiguration类,来自spring官网:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15
public class sayhelloconfiguration {

@autowired

iclientconfig ribbonclientconfig;

@bean

public iping ribbonping(iclientconfig config) {

return new pingurl();

}

@bean

public irule ribbonrule(iclientconfig config) {

return new availabilityfilteringrule();

}

}

ribbon默认不会发送ping检查server的健康状态,默认均正常,然后irune默认实现为zoneavoidancerule用来避免aws ec2问题较多的zone,这在本地测试环境来说是用不到的,然后替换成了availabilityfilteringrule,这个可以开启ribbon自带的断路器功能,来过滤不正常工作的服务器。

测试

首先启动我们的configserver配置中心服务,然后启动registry eureka注册与发现服务,然后启动两个productservice,第一个我们可以正常使用spring-boot:run插件来启动,第二个我们需要给它提供一个新的端口,可以用如下命令启动:

?

1
$ server_port=8082 mvn spring-boot:run

最后启动我们的web客户端项目,访问http://localhost:8080/productslb,然后刷新几次,会看到运行着productservice的两个命令行窗口会随机出现我们的log:

?

1
access to /products endpoint

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持快网idc。

原文链接:https://blog.csdn.net/fengqiuzhihua/article/details/80205923

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 Spring Cloud Ribbon实现客户端负载均衡的方法 https://www.kuaiidc.com/111727.html

相关文章

发表评论
暂无评论