spring cloud ribbon的使用

     上节我们学会了如何搭建一个eureka server服务,本节我们使用ribbon来实现服务间的调用。

前置条件:

    1、创建几个工程

        eureka-server
            |- 服务注册中心
        product-provider-8777
        product-provider-8778
        product-provider-8779
        product-provider-8780
            |- 服务提供者,提供商品查询服务,请求url为: http://host:port/product/selectOne/{productId},返回服务的端口、服务名和商品信息
            |- 上面四个product-provider-%d的工程代码都是一样的
            |- 8777 和 8778 一组,spring.application.name = product-provider-01
            |- 8779 和 8780 一组,spring.application.name = product-provider-02
        order-consumer
            |- 服务消费者,调用product-provider-%d服务,来完成商品信息的获取
            |- 访问url : http://host:port/orders/create/{providerId}/{productId}
                ** providerId 用来替换上面%d的值
                ** productId 商品编号,可以使用p0001、p0002、p0003

 

需求:

    |- 在consumer工程中使用ribbon来完成provider工程的调用
    |- 调用 product-provider-01 时修改默认的负载均衡策略(轮询)采用自定义的随机策略

    |- ribbon客户端立即初始化,服务端配置

ribbon:
  eager-load:
    enabled: true
    clients: product-provider-8780  # 需要立即初始化的服务名

   

实现步骤:

    1、eureka-server和product-provider功能没有什么特殊的地方,需要将8777和8778工程的spring.application.name的值改成product-provider-01另外2个修改成product-provider-02
    2、consumer工程
        |- 配置RestTemplate,需要加上@LoadBalanced注解,使之具有客户端负载均衡的能力(ribbon)
        |- 由于product-provider-01的负载均衡策略需要改变,因此需要配置RibbonClient
            ** 注意在RibbonClient中指定的配置文件不可在spring boot的主上下文中被扫描到,否则会是一个全局的配置,对所有的RibbonClient都会生效,如果需要对单独的RibbonClient
                     生效,则需要定义一个配置文件 RibbonProductProvider01Conf 这个可以在spring boot的主上下文中,里面的RibbonClient指定的配置文件 RibbonProductProvider01Configuration
                     必须要在spring boot的主上下文之外。

 

代码结构:

 

 实现:

一、注册中心和服务提供者

    这部分的代码都是普通的代码,没有什么需要注意的

 

二、服务消费者

1、定义RestTemplate

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

   注意: @LoadBalanced注解 加上即可


2、修改product-provider-01的负载均衡策略
    2.1、RibbonProductProvider01Configuration文件的编写

/**
 * 注意: 此类不可被spring 的主上下文扫描到,否则就是全局配置,对所有的ribbon客户端都会起作用
 * <p>
 * 对 spring.application.name = product-provider-01 进行单独配置
 * 修改对product-provider-01的负载均衡策略为随机访问,不在是默认的轮训访问
 *
 * @author huan.fu
 * @date 2018/5/29 - 11:40
 */
@Configuration
public class RibbonProductProvider01Configuration {

	/**
	 * 设置负载均衡策略为 随机,默认是轮训
	 *
	 * @return
	 */
	@Bean
	public IRule ribbonRule() {
		return new RandomRule();
	}

}

    可以进行配置的选项,以及默认值
    IClientConfig  DefaultClientConfigImpl
    IRule  ZoneAvoidanceRule
    IPing  DummyPing
    ServerList<Server>  ConfigurationBasedServerList
    ServerListFilter<Server>  ZonePreferenceServerListFilter
    ILoadBalancer  ZoneAwareLoadBalancer
    ServerListUpdater  PollingServerListUpdater


    2.2、 RibbonProductProvider01Conf配置文件的编写

/**
 * 对 spring.application.name = product-provider-01 进行单独配置
 * 修改对product-provider-01的负载均衡策略为随机访问,不在是默认的轮训访问
 *
 * @author huan.fu
 * @date 2018/5/29 - 11:40
 */
@RibbonClient(name = "product-provider-01", configuration = RibbonProductProvider01Configuration.class)
@Component
public class RibbonProductProvider01Conf {

}

 
    注意:@RibbonClient中的name的是服务提供者的spring.application.name的值,configuration指向上面编写的配置文件

3、编写控制层进行调用

/**
 * 订单控制器
 *
 * @author huan.fu
 * @date 2018/5/28 - 16:52
 */
@RestController
@RequestMapping("orders")
public class OrdersController {

	@Autowired
	private RestTemplate restTemplate;

	/**
	 * 创建订单
	 *
	 * @param productId
	 * @return
	 */
	@GetMapping("create/{providerId}/{productId}")
	public Map<String, Object> createOrders(@PathVariable String providerId, @PathVariable String productId) {
		return restTemplate.getForObject("http://product-provider-" + providerId + "/product/selectOne/" + productId, Map.class);
	}

}

 

测试:

    1、注册中心截图

 

   2、运行结果


 

完整代码

      https://gitee.com/huan1993/spring-cloud-parent/tree/master/ribbon

posted @ 2018-05-29 20:13  huan1993  阅读(25)  评论(0编辑  收藏  举报