前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring Cloud Alibaba - 08 Ribbon 两种方式实现细粒度自定义配置控制微服务的负载均衡策略

Spring Cloud Alibaba - 08 Ribbon 两种方式实现细粒度自定义配置控制微服务的负载均衡策略

作者头像
小小工匠
发布2022-02-03 16:02:55
4450
发布2022-02-03 16:02:55
举报
文章被收录于专栏:小工匠聊架构小工匠聊架构

文章目录

在这里插入图片描述
在这里插入图片描述

需求

假设我们有个场景:

Order-Center 需要采用随机算法调用产品中心 , 而采用轮询算法调用其他中心微服务

工程

在这里插入图片描述
在这里插入图片描述

java代码实现细粒度配置 (不推荐)

注意事项: PayCenterRibbonConfig,ProductCenterRibbonConfig不能被放在我们主启动类所在包以及子包下,不然就起不到细粒度配置

【支付中心对应的Ribbon访问策略】

代码语言:javascript
复制
package com.globalconfig;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RoundRobinRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author 小工匠
 * @version 1.0
 * @description: TODO
 * @date 2022/2/2 19:42
 * @mark: show me the code , change the world
 */
@Configuration
public class PayCenterRibbonConfig {

    @Bean
    public IRule roundRobinRule() {
        return new RoundRobinRule();
    }
}

【产品中心对应的Ribbon访问策略】

代码语言:javascript
复制
package com.globalconfig;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author 小工匠
 * @version 1.0
 * @description: TODO
 * @date 2022/2/2 19:45
 * @mark: show me the code , change the world
 */
@Configuration
public class ProductCenterRibbonConfig {

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

【带有@LoadBalanced的RestTemplate】

代码语言:javascript
复制
package com.artisan.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;

/**
 * @author 小工匠
 * @version 1.0
 * @description: TODO
 * @date 2022/2/2 15:47
 * @mark: show me the code , change the world
 */
@Configuration
public class WebConfig {


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

}

【为每个服务分配 访问策略 】

代码语言:javascript
复制
package com.artisan.config;

import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.netflix.ribbon.RibbonClients;
import org.springframework.context.annotation.Configuration;

/**
 * @author 小工匠
 * @version 1.0
 * @description: TODO
 * @date 2022/2/2 19:51
 * @mark: show me the code , change the world
 */



@Configuration
@RibbonClients(value = {
        @RibbonClient(name = "artisan-product-center",configuration = com.globalconfig.ProductCenterRibbonConfig.class),
        @RibbonClient(name = "artisan-pay-center",configuration = com.globalconfig.PayCenterRibbonConfig.class)
})
public class CustomRibbonConfig {
}

【Controller 】

代码语言:javascript
复制
import com.artisan.common.entity.OrderInfo;
import com.artisan.common.entity.PayInfo;
import com.artisan.common.entity.ProductInfo;
import com.artisan.common.vo.OrderAndPayVo;
import com.artisan.common.vo.OrderVo;
import com.artisan.mapper.OrderInfoMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

/**
 * @author 小工匠
 * @version 1.0
 * @description: TODO
 * @date 2022/2/2 03:20
 * @mark: show me the code , change the world
 */
@RestController
@Slf4j
public class OrderInfoController {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private OrderInfoMapper orderInfoMapper;


    /**
     * 调用地址, 注册中心 地址
     */
    public static final String PRODUCT_URI = "http://artisan-product-center/selectProductInfoById/";
    public static final String PAY_URI = "http://artisan-pay-center/selectPayInfoByOrderNo/";


    @RequestMapping("/v2/selectOrderInfoById/{orderNo}")
    public Object selectOrderInfoById(@PathVariable("orderNo") String orderNo) {

        OrderInfo orderInfo = orderInfoMapper.selectOrderInfoById(orderNo);
        if (null == orderInfo) {
            return "根据orderNo:" + orderNo + "查询没有该订单";
        }

        // 发起远程Http调用
        ResponseEntity<ProductInfo> responseEntity = restTemplate.getForEntity(PRODUCT_URI + orderInfo.getProductNo(), ProductInfo.class);

        ProductInfo productInfo = responseEntity.getBody();
        if (productInfo == null) {
            return "没有对应的商品";
        }

        OrderVo orderVo = new OrderVo();
        orderVo.setOrderNo(orderInfo.getOrderNo());
        orderVo.setUserName(orderInfo.getUserName());
        orderVo.setProductName(productInfo.getProductName());
        orderVo.setProductNum(orderInfo.getProductCount());
        return orderVo;
    }


    @RequestMapping("/getOrderAndPayInfoByOrderNo/{orderNo}")
    public Object getOrderAndPayInfoByOrderNo(@PathVariable("orderNo") String orderNo) {
        OrderInfo orderInfo = orderInfoMapper.selectOrderInfoById(orderNo);
        if (null == orderInfo) {
            return "根据orderNo:" + orderNo + "查询没有该订单";
        }

        ResponseEntity<PayInfo> responseEntity = restTemplate.getForEntity(PAY_URI + orderInfo.getProductNo(), PayInfo.class);
        PayInfo payInfo = responseEntity.getBody();
        if (payInfo == null) {
            return "没有对应的支付信息";
        }

        OrderAndPayVo orderAndPayVo = new OrderAndPayVo();
        orderAndPayVo.setOrderNo(orderNo);
        orderAndPayVo.setProductNo(orderInfo.getProductNo());
        orderAndPayVo.setProductCount(orderInfo.getProductCount());
        orderAndPayVo.setPayNo(payInfo.getPayNo());
        orderAndPayVo.setPayTime(payInfo.getPayTime());
        orderAndPayVo.setUserName(orderInfo.getUserName());
        return orderAndPayVo;
    }


}
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

可以看到,实现了我们最开始的需求 。

配置实现细粒度配置 (推荐)

接着上面的工程,首先屏蔽掉 CustomRibbonConfig

在这里插入图片描述
在这里插入图片描述

然后再 artisan-cloud-customcfg-ribbon-order 子模块的配置文件 application.yml

增加

代码语言:javascript
复制
#自定义Ribbon的细粒度配置
artisan-pay-center:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule

artisan-product-center:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

然后启动多个Pay和Product服务进行测试

结果如下:

访问4次

在这里插入图片描述
在这里插入图片描述

访问 10次

在这里插入图片描述
在这里插入图片描述

源码

https://github.com/yangshangwei/SpringCloudAlibabMaster

本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-02-02 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 需求
  • 工程
  • java代码实现细粒度配置 (不推荐)
  • 配置实现细粒度配置 (推荐)
  • 源码
相关产品与服务
微服务引擎 TSE
微服务引擎(Tencent Cloud Service Engine)提供开箱即用的云上全场景微服务解决方案。支持开源增强的云原生注册配置中心(Zookeeper、Nacos 和 Apollo),北极星网格(腾讯自研并开源的 PolarisMesh)、云原生 API 网关(Kong)以及微服务应用托管的弹性微服务平台。微服务引擎完全兼容开源版本的使用方式,在功能、可用性和可运维性等多个方面进行增强。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com