SpringCloud Ribbon

SpringCloud Ribbon

欢迎关注微信公众号: 程序员小圈圈
原文首发于: www.zhangruibin.com
本文出自于: RebornChang的博客
转载请标明出处^_^

公众号发送:sp4,即可获取截至本节的代码哦~

Ribbon是什么

Spring Cloud Ribbon 是基于 Netflix 公司发布的开源项目 Ribbon 进行封装的一套客户端负载均衡器 。

github地址:https://github.com/Netflix/ribbon

Ribbon 从 Eureka Server 获取服务列表,Ribbon根据负载均衡算法直接请求到具体的微服务,中间省去了负载均
衡服务。
下图是Ribbon负载均衡的流程图简图:

在消费者微服务中使用 Ribbon 实现负载均衡,Ribbon 先从EurekaServer中获取服务列表,然后再根据负载均衡的算法(默认轮训算法)去调用微服务。

Ribbon怎么用

由于依赖了spring-cloud-starter-netflix-eureka-client,会自动添加spring-cloud-starter-netflix-ribbon依赖。

然后我们就可以来在旧的项目上进行改造了。

改造项目

先回顾一下我们的基础项目:
1.项目01,父级项目;
2.项目02,子级公共项目;
3.项目03,子级项目product 8001;
4.项目04,子级项目consumer8002;
5.项目05,子级项目eureka server9000;
6.项目06,子级项目eureka server9002.

首先:
改造服务消费者8002项目
1.修改ConfigBean.java
在ConfigBean.java 中加入注解@LoadBalanced:

package com.zhrb.springcloud.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

/**
 * @ClassName ConfigBean
 * @Description TODO
  * @Author zhrb
 * @Date 2019/9/4 11:56
 * @Version
  */ 
  @Configuration
   public class ConfigBean {
    // 向容器中添加 RestTemplate 组件,直接通过此组件可调用 REST 接口
 ///@LoadBalanced表示这个RestTemplate开启负载均衡,在调用服务提供者的接口时, //可使用 服务名称 替代真实IP地址。服务名称 就是服务提供者在application.yml中 //配置的spring.application.name属性的值  @LoadBalanced
 @Bean  public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
}

2.修改ProductConsumerController
PS:之前手误写成了ProductControllerConsumer,现在改回来
将静态变量: REST_URL_PREFIX 的值修改为:http://springcloud-product

修改后的文件内容如下:

package com.zhrb.springcloud.controller;

import com.zhrb.springcloud.entity.Product;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import java.util.List;

/**
 * @ClassName ProductControllerConsumer
 * @Description TODO
  * @Author zhrb
 * @Date 2019/9/4 11:57
 * @Version
  */ @RestController @RequestMapping(value = "/consumer/product")
public class ProductConsumerController {

    //private static final String REST_URL_PREFIX = "http://127.0.0.1:8001";
 //修改为注册中心的地址springcloud-product //private static final String REST_URL_PREFIX = "http://127.0.0.1:9000";  private static final String REST_URL_PREFIX = "http://springcloud-product";
    @Autowired
  private RestTemplate restTemplate;

    @PostMapping(value = "/add")
    public boolean add(Product product) {
        return restTemplate.postForObject(REST_URL_PREFIX + "/product/add",
                product, Boolean.class);
    }

    @GetMapping(value = "/{id}")
    public Product get(@PathVariable("id") Long id) {
        return restTemplate.getForObject(REST_URL_PREFIX + "/product/" + id,
                Product.class);
    }

    @GetMapping(value = "/list")
    public List<Product> list() {
        return restTemplate.getForObject(REST_URL_PREFIX + "/product/list",
                List.class);
    }
}

@LoadBalanced表示这个RestTemplate开启负载均衡,在调用服务提供者的接口时,可使用 服务名称替代真实IP地址。服务名称 就是服务提供者在application.yml中配置的spring.application.name属性的值 。

然后:
修改8001项目中的ProductController.java
修改list()方法,目的是能在前台看出来消费者消费的是哪个服务提供者,修改后ProductController代码如下:

package com.zhrb.springcloud.controller;

import com.zhrb.springcloud.entity.Product;
import com.zhrb.springcloud.service.ProductService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Collection;
import java.util.List;

/**
 * @ClassName ProductController
 * @Description TODO
  * @Author zhrb
 * @Date 2019/9/3 15:18
 * @Version
  */ @RestController @RequestMapping("/product")
@MapperScan("com.zhrb.springcloud.mapper")
@Api(value = "/product",description = "商品管理 程序员小圈圈",position = 1)
public class ProductController {

    @Autowired
  private ProductService productService;

    @ApiOperation(value="product,返回boolean", notes="新增商品")
    @PostMapping(value = "/add")
    public boolean add(@RequestBody Product product) {
        return productService.add(product);
    }

    @ApiOperation(value="id,返回boolean", notes="新增商品")
    @GetMapping(value = "/{id}")
    public Product get(@PathVariable("id") Long id) {
        return productService.get(id);
    }

    @ApiOperation(value="product,返回boolean", notes="新增商品")
    @GetMapping(value = "/list")
    public List<Product> list() {
        List<Product> productList = productService.list();
        for (Product p :productList){
            p.setProductName(p.getProductName()+"本条数据来自8001");
        }
        return productList;
    }
}

最后:

在这些的基础上,我们直接复制项目04,增加一个服务提供者。

像之前复制9000项目那样,复制项目并修改文件。
新项目命名为springclouddemo-03-provider-product-8011,修改apllication.yml文件的端口声明为8011,不修改spring name(重点)。

复制完项目之后,将ProductController中的list()方法的‘来自8001’改为‘来自8011’。

此时系统架构简图应该如下图所示:

[外链图片转存失败(img-9PHlVsfL-1568015278972)(https://www.zhangruibin.com/upload/2019/09/uof1hu4teci8go6vkeqp4da6sc.png)]
这样理论上来讲,消费者从开启了LoadBalanced ribbon 去均衡的访问8001,以及8011项目。

那么事实是不是这样呢?我们试下就知道了:

启动项目验证

项目启动顺序为:
9000->9002->8001->8011->8002.

启动后访问其中一个Eureka Server的地址:http://localhost:9002
可以看到,两个服务提供者和一个服务消费者都已经注册了进来:

然后我们访问服务消费者去消费服务:
http://localhost:8002/consumer/product/list
第一次访问:
[外链图片转存失败(img-9p1HqiGo-1568015278976)(https://www.zhangruibin.com/upload/2019/09/sqb6ci0k1cggjovtvcu6pq8l6c.png)]
第二次访问:
[外链图片转存失败(img-Jj92U6yl-1568015278979)(https://www.zhangruibin.com/upload/2019/09/02vrj6fvqggeipdb2u876b5r86.png)]
从上面两张图我们可以看出来,两次访问的是不同的服务提供者,LoadBalance成功。

最后我们总结一下,用户点击下按钮后后台的操作是怎样一个步骤:
0.几个项目启动,8001,8011,8002分别向9000,9002项目注册;
1.用户发起请求,请求路由到消费者8002,;
2.8002发起请求去请访问项目名为springcloud-product的服务提供者;
3.ribbon根据负载均衡,获取可以实现访问的可提供访问的服务列表,然后根据负载均衡算法,将8002发起的消费请求转发到8011或者8001项目进行访问;
4.服务方返回数据给8002,8002展示给用户。
至此,关于ribbon的基本应用及效果已经展示完毕,值得一提的是,还有一个组件和Ribbon效果类似,那就是Feign。
下节我将开一个小节,将Ribbon换成Feign,并对两者进行一个简单的对比。

感兴趣的小伙伴可以关注下公众号的推送或者博主的技术博客哦。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值