SpringCloud实战2-Ribbon客户端负载均衡

前面我们已经完成了注册中心和服务提供者两个基础组件。接着介绍使用Spring Cloud Ribbon在客户端负载均衡的调用服务。

ribbon 是一个客户端负载均衡器,可以简单的理解成类似于 nginx的负载均衡模块的功能。

主流的LB(负载均衡)方案可分成两类:

一种是集中式LB, 即在服务的消费方和提供方之间使用独立的LB设施(可以是硬件,如F5, 也可以是软件,如nginx), 由该设施负责把访问请求通过某种策略转发至服务的提供方;

另一种是进程内LB,将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的服务器。Ribbon就属于后者,它只是一个类库,集成于消费方进程,消费方通过它来获取到服务提供方的地址。

Ribbon的架构图:如下:
在这里插入图片描述

1.首先我们先在原来的基础上新建一个Ribbon模块,如下图:
在这里插入图片描述
现在我们单独使用ribbon,在Ribbon模块下添加依赖,如下图所示:

<dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>

修改application.yml文件,如下所示:

server:
  port: 8082
spring:
  application:
    name: Ribbon-Consumer
#providers这个是自己命名的,是服务提供者名,ribbon,listOfServer这两个是规定的
providers:
  ribbon:
    listOfServers: localhost:8080,localhost:8081

在Ribbon模块下新建一个测试类如下代码:

@RestController
public class ConsumerController {

  //注入负载均衡客户端
   @Autowired
    private LoadBalancerClient loadBalancerClient;

    @RequestMapping("/consumer")
    public String helloConsumer() throws ExecutionException, InterruptedException {
     //这里是根据配置文件的那个providers属性取的
        ServiceInstance serviceInstance = loadBalancerClient.choose("providers");
      //负载均衡算法默认是轮询,轮询取得服务
        URI uri = URI.create(String.format("http://%s:%s", serviceInstance.getHost(), serviceInstance.getPort()));
        return uri.toString();
  }

运行结果如下:

会轮询的获取到两个服务的URL 访问第一次,浏览器出现http://localhost:8080 访问第二次就会出现http://localhost:8081
在这里给普及一下有哪些负载均衡算法:

  1. 简单轮询负载均衡(RoundRobin)
    以轮询的方式依次将请求调度不同的服务器,即每次调度执行i = (i + 1) mod n,并选出第i台服务器。

  2. 随机负载均衡 (Random)
    随机选择状态为UP的Server

  3. 加权响应时间负载均衡 (WeightedResponseTime)
    根据相应时间分配一个weight,相应时间越长,weight越小,被选中的可能性越低。

  4. 区域感知轮询负载均衡(ZoneAvoidanceRule)
    复合判断server所在区域的性能和server的可用性选择server

如果想配置其他轮询算法在yml配置文件中配置,如下配置一个随机算法所示:

server:
  port: 8082
spring:
  application:
    name: Ribbon-Consumer
#providers这个是自己命名的,ribbon,listOfServer这两个是规定的
providers:
  ribbon:
    listOfServers: localhost:8080,localhost:8081

##如果不想选用默认的轮询的负载均衡算法,在这里做如下配置
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

接着在启动类动一下手脚让我们配置的随机算法的负载均衡生效,只需要实现一个实现了IRule接口的Bean即可,如下:


@SpringBootApplication
public class RibbonApplication {

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

    @Bean
    public IRule ribbonRule(){
        return new RandomRule();
    }
}

因此重新启动Ribbon启动类,得到的结果是随机的

那么问题来了,服务的地址是写死在配置文件中,如果某个服务挂了,那么还会把请求转发到挂掉的服务中,因此,解决的办法是,跟Eureka对接,结合一起用。就可以依靠Eureka动态的获取一个可用的服务列表,隔一段时间我就更新一次,

或者Eureka设置一个监听端口,某一个服务挂了,Eureka通知我,我会知道,变更服务列表,这样不久形成一个闭环了吗?这样就不存在高可用性问题了。跟Eureka配合一起用同时解决了的Ribbon的单点故障问题。

第一步,毫无疑问就是修改Ribbon模块的pom.xml文件,加入如下依赖:

<dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>

第二步,修改yml配置文件如下:

server:
  port: 8082
spring:
  application:
    name: Ribbon-Consumer

eureka:
#客户端
  client:
#注册中心地址
    service-url:
      defaultZone: http://localhost:6010/eureka/

这样就可以跟Eureka结合,这样Ribbon就可以通过Eureka动态的获取服务列表

接着在启动类加上服务发现注解,如下:

@EnableDiscoveryClient

启动类接着声明一个负载均衡的请求器@LoadBalanced,还有请求发起的工具RestTemplate

如下代码:

@SpringBootApplication
@EnableDiscoveryClient
public class RibbonApplication {

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


    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

}

接着我们在上一节文章中的两个DEMO1,DEMO2模块添加一下测试代码:如下:

demo1:

@RestController
public class HelloController {

    @RequestMapping("/hello")
    public String hello(){
        return "hello1";
    }

}

demo2代码如下:

@RestController
public class HelloController {

    @RequestMapping("/hello")
    public String hello(){
        return "hello2";
    }

}

接着我们用RestTemplate进行面向服务调用,不再面向IP调用。

如下代码:

@RestController
public class ConsumerController {



    @Autowired
    private  RestTemplate restTemplate;

    @RequestMapping("/consumer")
    public String helloConsumer() throws ExecutionException, InterruptedException {

        return restTemplate.getForEntity("http://HELLO-SERVICE/hello",String.class).getBody();

}

接着我们继续在已经运行的Ribbon模块上,在浏览器输入localhost:8082,运行结果如下:

hello1或者hello2,

可以看到hello1 ,hello2轮询方式出现,因为默认就是轮询方式

Feign的使用

首先新建demo1和demo2对应的feign模块
在这里插入图片描述
demo-feign的pom文件依赖:

    <artifactId>demo-feign</artifactId>
    <packaging>pom</packaging>
    <modules>
        <module>demo-feign-demo1</module>
        <module>demo-feign-demo2</module>
    </modules>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
        </dependency>
    </dependencies>

在demo-feign-demo1中新建demo-application-demo1中hello接口对应的feign客户端
在这里插入图片描述
demo-feign-demo2也同上

然后修改demo-application-demo1的pom依赖:
在这里插入图片描述
添加feign-demo2的依赖

接着在demo1的HelloController注入demo2的feign客户端
在这里插入图片描述
最后在demo1的启动类上添加如下注解:

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients(basePackages = "com.wlj.feign.*")
public class Demo1Application {

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

重启application-demo1,查看接口调用结果:
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值