微服务架构整理-(六springcloud实战之ribbon)

浦江之猿      2022-05-23     693

关键词:

SpringCloud实战之Ribbon

负责均衡介绍

负载均衡分为 硬件负载均衡和软件负载均衡。常用见的如下:
硬件负载均衡: F5 ,深信服, Array 等;
软件负载均衡: Nginx,LVS,HAProxy,Ribbon 等;

它们的原理是维护一个可用的服务列表,通过心跳机制来剔除不可用节点,从而保证可用列表的有效性。当请求经过负载均衡设备(软件)时,设备会按照设定的算法从可用的列表中选择一个服务进行转发。

Ribbon概念

Ribbon是 Netflix 发布的开源项目,主要功能是提供客户端的软件负载均衡算
法, 是 一 个基于 HTTP 和 TCP 的客户端负载均衡工具,这里可以理解成服务消费者端的负载均衡工具。
SpringCloud对Ribbon进行了二次封闭,可以让开发人员通过RestTemplate(在注入时,直接在上方加入注解 @LoadBalanced 即可)的实例调用接口时,可以自动进行服务选择。

其主要特点包括:

  • 负责均衡算法多样,且支持定制化
  • 小巧,使用方便,无需独立部署,直接在代码里使用即可
  • 不同于服务端负载均衡,Ribbon的可用服务列表直接从注册中心中读取

Ribbon中的负载均衡算法

Ribbon中提供了一系列的负载均衡算法,这些算法封装了相应的java类,使用时只需注入到Spring容器中即可。

算法作用
RandomRule随机选择一个 Server
RoundRobinRule轮询选择
RetryRule先按照RoundRobinRule 策略选择,如果选择到的服务不能访问,则在指定时间内进行重试,选择其他可用的服务
BestAvailableRule先过滤掉由于多次访问故障的服务,然后选择一个并发量最小的服务
ResponseTimeWeightedRule/WeightedResponseTimeRule根据响应时间分配一个 Weight(权重),响应时间越长,Weight 越小,被选中的可能性越低
AvailabilityFilteringRule先过滤掉由于多次访问故障的服务,以及并发连接数超过阈值的服务,然后对剩下的服务按照轮询策略进行访问
ZoneAvoidanceRule综合判断服务节点所在区域的性能和服务节点的 可用性,来 决定选择哪个服务

Ribbon使用

因为SpringCloud对Ribbon进行了二次封闭,所以使用起来很方便。这里在上一篇博客的基础上将Ribbon加进来,所以只给出改动的代码。

添加一个服务提供者

之前只有一个服务提供者,为了能够使用负载均衡,至少需要两个服务提供者。所以这里将之前的product_service 复制一份,稍加修改就可以了。涉及以下几个方面:
端口号与服务名
在application.yml中修改端口号,服务名保持不动,服务消费者根据服务名获取服务提供者的集合,然后在集合中选择(由Ribbon完成)一个服务提供者。

server:
  # port: 9001 #端口
  port: 9003 #端口
spring:
  favicon:
    enabled: false
  application:
    name: service-product #服务名称,与之前保持一样

工程添加到父工程里面
在父工程pom.xml中添加新的module

<modules>
        <module>product_service</module>
        <!--添加product_service_2 module -->
        <module>product_service_2</module>
        <module>order_service</module>
        <module>eureka_service</module>
        <module>eureka_service_1</module>
    </modules>

工程id
product_service_2的pom.xml中修改artifactId

<artifactId>product_service_2</artifactId>

添加Ribbon

在消费者服务(service-order)的配置类中通过添加 @LoadBalanced 方式引进Ribbon, 负载均衡算法通过bean的方式注入,如果不注入算法,默认使用轮询算法。

@Configuration
public class Config 
	//引入Ribbon,此标签引入后,当服务启动的时候会自动读取注册中心的服务提供者
    @LoadBalanced
    @Bean
    public RestTemplate getRestTemplate() 
        return new RestTemplate();
    
	//注入负责均衡算法,这里只列了两种,大家可以根据自己的需求自行添加
    @Bean
    public IRule getIRule() 
        // return new RandomRule();
        return new BestAvailableRule();
    

区别服务提供者

因为两个服务提供者返回的内容都一样,所以这里为了区分是由哪个服务者返回的内容,在返回值上稍加修改,真正的生产环境不需要这样。
product_service
在name后面加上1

 @GetMapping(value = "/id")
    public Product findById(@PathVariable Long id) 
        Product product = productService.findById(id);
        product.setName(product.getName() + "1");
        return product;
    

product_service_2
在name后面加上2

 @GetMapping(value = "/id")
    public Product findById(@PathVariable Long id) 
        Product product = productService.findById(id);
        product.setName(product.getName() + "2");
        return product;
    

访问服务提供者

order_service controller中不能再使用服务提供者的实例,需要将其改成服务名,因为这里会有多个实例,每个实例拥有自己的端口,如果用实例的话,这里拼服务的地址的时候,又需要写个算法来判断使用哪个端口,所以直接使用服务名就可以,具体用哪个服务,交给Ribbon来处理。

/**
 * @author :浦江之猿
 * @date :Created in 2022/05/19 21:48
 */
@RestController
@RequestMapping("/order")
public class OrderController 

    @Autowired
    RestTemplate restTemplate;
    @Autowired
    DiscoveryClient discoveryClient;

    @GetMapping(value = "/buy/id")
    public Product findById(@PathVariable Long id) 
        // 获取元数据
        /* List<ServiceInstance> instances = discoveryClient.getInstances("service-product");
        ServiceInstance instance = instances.get(0);
        restTemplate.getForObject("http://"+instance.getHost()+":"+instance.getPort()+"/product/"+id,Product.class); */
        Product product = null;
        //直接将服务名拼接到地址中
        product = restTemplate.getForObject("http://service-product/product/" + id, Product.class);
        return product;
    

运行结果

注册中心
访问http://localhost:9006/,可以看到service-product启了两个

访问订单
看一下使用轮询算法的结果,http://localhost:9002/order/buy/1 返回值会在下面两条中来回切换。

//product_service 返回的结果
"id":1,"name":"apple1","price":8000.00
//product_service_2返回的结果 
"id":1,"name":"apple2","price":8000.00

总结

关于Ribbon的使用基本就介绍完了,因为SpringCloud对其进行了二次封装,所以使用其来非常方便。最后,希望本文能帮助大家,祝大家在IT之路上少走弯路,一路绿灯不堵车,测试一性通过,bug秒解!
源码下载

微服务架构整理-(七springcloud实战之resttemplate)(代码片段)

SpringCloud实战之RestTemplateGET请求getForEntitygetForObjectPOST请求postForEntitypostForObjectpostForLocationPUT请求DELETE请求总结RestTemplate不仅在SpringCloud中会使用,一般在服务之间相互调用的时候会使用此类。上一篇介绍Ribbon的时候通过在此类... 查看详情

微服务架构整理-(十springcloud实战之hystrix[3])(代码片段)

SpringCloud实战之Hystrix[3]-看版监控前言搭建Dashboard服务创建springboot工程添加依赖配置启动类添加配置文件引用Dashboard服务添加Hystrix依赖添加springboot服务监控依赖配置springboot监控接口的访问权限结果总结前言当需要查看服务的状... 查看详情

微服务架构整理-(十springcloud实战之hystrix[3])(代码片段)

SpringCloud实战之Hystrix[3]-看版监控前言搭建Dashboard服务创建springboot工程添加依赖配置启动类添加配置文件引用Dashboard服务添加Hystrix依赖添加springboot服务监控依赖配置springboot监控接口的访问权限结果总结前言当需要查看服务的状... 查看详情

微服务架构整理-(八springcloud实战之hystrix[1])(代码片段)

SpringCloud实战之Hystrix[1]-基本用法前言Hystrix概念Hystrix使用添加依赖配置启动类添加熔断机制服务降级超时异常总结前言我们知道,在微服务架构中,每个服务都是独立运行,服务与服务之间通过注册中心彼此发现和消... 查看详情

微服务架构整理-(八springcloud实战之hystrix[1])(代码片段)

SpringCloud实战之Hystrix[1]-基本用法前言Hystrix概念Hystrix使用添加依赖配置启动类添加熔断机制服务降级超时异常总结前言我们知道,在微服务架构中,每个服务都是独立运行,服务与服务之间通过注册中心彼此发现和消... 查看详情

微服务架构整理-(九springcloud实战之hystrix[2])

SpringCloud实战之Hystrix[2]-自定义异常熔断处理自定义熔断机制测试同步调用异步调用总结上文中,对异常处理是使用注解@HystrixCommand完成的,当然也可以不使用此注解来完成,我们可以自定义一个机制处理超时,... 查看详情

微服务架构整理-(十二springcloud实战之zuul网关)(代码片段)

SpringCloud实战之Zuul网关Zuul概念Zuul构建网关创建SpringBoot工程添加依赖添加注解添加配置文件基础配置注册Eureka添加路由规则Zuul请求过滤定义过虑逻辑请求结果Zuul路由规则总结Zuul概念Zuul是Netflix旗下的又一重要成员,是一个... 查看详情

微服务架构整理-(九springcloud实战之hystrix[2])(代码片段)

SpringCloud实战之Hystrix[2]-自定义异常熔断处理自定义熔断机制测试同步调用异步调用总结上文中,对异常处理是使用注解@HystrixCommand完成的,当然也可以不使用此注解来完成,我们可以自定义一个机制处理超时,... 查看详情

微服务架构整理-(十springcloud实战之hystrix[3])(代码片段)

SpringCloud实战之Hystrix[3]-看版监控前言搭建Dashboard服务创建springboot工程添加依赖配置启动类添加配置文件引用Dashboard服务添加Hystrix依赖添加springboot服务监控依赖配置springboot监控接口的访问权限结果总结前言当需要查看服务的状... 查看详情

微服务架构整理-(十一springcloud实战之openfeign)(代码片段)

SpringCloud实战之OpenFeignOpenFeign介绍实现消费者功能创建SpringBoot工程添加依赖添加注解声明服务在Controller中调用服务添加配置文件结果实现负载均衡功能实现熔断功能配置熔断开关实现回调函数获取异常信息总结OpenFeign介绍OpenFeig... 查看详情

微服务架构整理-(十二springcloud实战之zuul网关)(代码片段)

SpringCloud实战之Zuul网关Zuul概念Zuul构建网关创建SpringBoot工程添加依赖添加注解添加配置文件基础配置注册Eureka添加路由规则Zuul请求过滤定义过虑逻辑请求结果Zuul路由规则总结Zuul概念Zuul是Netflix旗下的又一重要成员,是一个... 查看详情

springcloud实战微服务之——微服务简介以及入门使用(代码片段)

微服务概述微服务是什么?微服务解决了什么问题?微服务有什么特点?单体架构是什么?一个归档包包含了应用所有功能的应用程序,我们通常称之为单体应用。架构单体应用的架构风格,我们称之为单... 查看详情

springcloud微服务安全实战_6-1_微服务之间的通讯安全之概述

   到目前为止已经实现了一个基于微服务的,前后端分离(这里我用的jquery做的,并不是真的前后端分离,因为我不会vue和angular所以没用)的架构。在网关上做了限流、认证、审计、授权等安全机制,在前端应用上... 查看详情

springcloud实战微服务之——微服务简介以及入门使用(代码片段)

微服务概述微服务是什么?微服务解决了什么问题?微服务有什么特点?单体架构是什么?一个归档包包含了应用所有功能的应用程序,我们通常称之为单体应用。架构单体应用的架构风格,我们称之为单... 查看详情

微服务之springcloud实战:springcloudeureka服务治理

服务治理  SpringCloudEureka是SpringCloudNetflix微服务套件的一部分,它基于NetflixEureka做了二次封装,主要完成微服务的服务治理功能,SpringCloud通过为Eureka增加了SpringBoot自动化配置,只需要简单的依赖和配置就可完成Eureka整合搭建... 查看详情

微服务springcloud+docker入门到高级实战

第一章课程介绍和学习路线1、微服务架构SpringCloud课程介绍简介:课程介绍和课程大纲讲解,讲课风格和重点内容理解技巧2、技术选型和学后水平简介:课程所需基础和技术选型讲解,学完课程可以到达怎样的程度,第二章架... 查看详情

微服务springcloud+docker入门到高级实战(目录)

 第一章课程介绍和学习路线1、微服务架构SpringCloud课程介绍 简介:课程介绍和课程大纲讲解,讲课风格和重点内容理解技巧2、技术选型和学后水平 简介:课程所需基础和技术选型讲解,学完课程可以到达怎样的程度,第二... 查看详情

推荐7个牛哄哄springcloud实战项目(代码片段)

把一个大型的单个应用程序和服务拆分为数个甚至数十个的支持微服务,这就是微服务架构的架构概念,通过将功能分解到各个离散的服务中以实现对解决方案的解耦。关于微服务相关的学习资料不多,而GitHub上的开源项目可以... 查看详情