文章目录
需求工程java代码实现细粒度配置 (不推荐)配置实现细粒度配置 (推荐)源码需求
假设我们有个场景:
Order-Center 需要采用随机算法调用产品中心 , 而采用轮询算法调用其他中心微服务
工程
java代码实现细粒度配置 (不推荐)
注意事项: PayCenterRibbonConfig,ProductCenterRibbonConfig不能被放在我们主启动类所在包以及子包下,不然就起不到细粒度配置
【支付中心对应的Ribbon访问策略】
package com.globalconfig;import flix.loadbalancer.IRule;import flix.loadbalancer.RoundRobinRule;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;/*** @author 小工匠* @version 1.0* @description: TODO* @date /2/2 19:42* @mark: show me the code , change the world*/@Configurationpublic class PayCenterRibbonConfig {@Beanpublic IRule roundRobinRule() {return new RoundRobinRule();}}
【产品中心对应的Ribbon访问策略】
package com.globalconfig;import flix.loadbalancer.IRule;import flix.loadbalancer.RandomRule;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;/*** @author 小工匠* @version 1.0* @description: TODO* @date /2/2 19:45* @mark: show me the code , change the world*/@Configurationpublic class ProductCenterRibbonConfig {@Beanpublic IRule randomRule() {return new RandomRule();}}
【带有@LoadBalanced的RestTemplate】
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 /2/2 15:47* @mark: show me the code , change the world*/@Configurationpublic class WebConfig {@Bean@LoadBalancedpublic RestTemplate restTemplate() {return new RestTemplate();}}
【为每个服务分配 访问策略 】
package com.artisan.config;import org.flix.ribbon.RibbonClient;import org.flix.ribbon.RibbonClients;import org.springframework.context.annotation.Configuration;/*** @author 小工匠* @version 1.0* @description: TODO* @date /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 】
import mon.entity.OrderInfo;import mon.entity.PayInfo;import mon.entity.ProductInfo;import mon.vo.OrderAndPayVo;import mon.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 /2/2 03:20* @mark: show me the code , change the world*/@RestController@Slf4jpublic class OrderInfoController {@Autowiredprivate RestTemplate restTemplate;@Autowiredprivate 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
增加
#自定义Ribbon的细粒度配置artisan-pay-center:ribbon:NFLoadBalancerRuleClassName: flix.loadbalancer.RoundRobinRuleartisan-product-center:ribbon:NFLoadBalancerRuleClassName: flix.loadbalancer.RandomRule
然后启动多个Pay和Product服务进行测试
结果如下:
访问4次
访问 10次
源码
/yangshangwei/SpringCloudAlibabMaster