springcloud 组件之 ribbon 实战使用(三)

Ribbon 是springcloud 主要组件之一,起到服务调用和负载均衡的作用,其底层封装在 eureka 的客户端和feign组件中,今天只讲使用,后续会讲源码和原理。

1、jar 包的引入:其jar包 包含于 eureka 客户端包里:在上几篇的基础上 这里就 不需要重复引入了。

 2、引入RestTemplate配置类 里面注入RestTemplate的方法上面添加注解@LoadBalanced ,@Bean

    @Bean
    @LoadBalanced  //起到负载均衡作用
    RestTemplate restTemplate() {
        return new RestTemplate();
    }

   //负载均衡的配置 
   @Bean
    public IRule ribbonRule() {
        return new RandomRule();
    }

  //启动方法
  public static void main(String[] args) {
        SpringApplication.run(TestLoadBalanceMain.class,args);
    }

3、客户端 Controller  方法创建

public static String SERVIER_NAME = "micro-order-no";

@Autowired
private RestTemplate restTemplate;

@RequestMapping("/queryU")
public List<ConsultContent> queryU(HttpServletRequest request) {
    log.info(Thread.currentThread().getName() + "========queryContents=========");
    //该方法通过负载算法。选择一个服务调用。
    List<ConsultContent> results = restTemplate.getForObject("http://"
            + SERVIER_NAME + "/user/queryContent", List.class);
    return results;
}

4、服务提供方 Controller  方法创建

 @RequestMapping("/queryContent")
    public List<ConsultContent> queryContent(HttpServletRequest request) {
        logger.info(""+this.hashCode());
        ConsultContent c = new ConsultContent();
        c.setContent("sdsdsdsdsdsdd");
        List<ConsultContent> list = new ArrayList<>();
        list.add(c);
        return list;
    }

5、三个微服务启动后调用结果

6、客户端  controller 可以起多个服务,调用时根据负载算法选择其中一个服务调用。小伙伴可以自己测试一下。

7、Ribbon 的Api 有多种类型 比如  get ,post 等等,我在这贴出来大家可以认真看看:

Get 请求 :关注请求的一些信息
getForEntity:此方法有三种重载形式,分别为: 
getForEntity(String url, Class<T> responseType) 
getForEntity(String url, Class<T> responseType, Object... uriVariables) 
getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables) 
getForEntity(URI url, Class<T> responseType) 
注意:此方法返回的是一个包装对象 ResponseEntity<T>其中 T 为 responseType 传入类型, 
想拿到返回类型需要使用这个包装类对象的 getBody()方法 
getForObject:此方法也有三种重载形式,这点与 getForEntity 方法相同: 
getForObject(String url, Class<T> responseType) 
getForObject(String url, Class<T> responseType, Object... uriVariables) 
getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables) 
getForObject(URI url, Class<T> responseType) 
注意:此方法返回的对象类型为 responseType 传入类型 
Post 请求 :主要关注请求结果信息
post 请求和 get 请求都有*ForEntity 和*ForObject 方法,其中参数列表有些不同,除了这两个 
方法外,还有一个 postForLocation 方法,其中 postForLocation 以 post 请求提交资源,并返 
回新资源的 URI 
postForEntity:此方法有三种重载形式,分别为:postForEntity(String url, Object request, Class<T> responseType, Object... uriVariables) 
postForEntity(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables) 
postForEntity(URI url, Object request, Class<T> responseType) 
注意:此方法返回的是一个包装对象 ResponseEntity<T>其中 T 为 responseType 传入类型, 
想拿到返回类型需要使用这个包装类对象的 getBody()方法 
postForObject:此方法也有三种重载形式,这点与 postForEntity 方法相同: 
postForObject(String url, Object request, Class<T> responseType, Object... uriVariables) 
postForObject(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables) 
postForObject(URI url, Object request, Class<T> responseType) 
注意:此方法返回的对象类型为 responseType 传入类型 
postForLocation:此方法中同样有三种重载形式,分别为: 
postForLocation(String url, Object request, Object... uriVariables) 
postForLocation(String url, Object request, Map<String, ?> uriVariables) 
postForLocation(URI url, Object request) 
注意:此方法返回的是新资源的 URI,相比 getForEntity、getForObject、postForEntity、 
postForObject 方法不同的是这个方法中无需指定返回类型,因为返回类型就是 URI,通过 
Object... uriVariables、Map<String, ?> uriVariables 进行传参依旧需要占位符,参看 postForEntity 
部分代码

 8、ribbon 负载均衡算法:ribbon中具体实现负载均衡的策略是通过IRule这个接口来实现的,接口实现结构图

默认的负载均衡策略是:ZoneAvoidanceRule:区域权衡策略。然后我们可以通过配置来使用其他的负载均衡策略。

9、代码中配置ribbon 属性:


import com.netflix.client.config.CommonClientConfigKey;
import com.netflix.client.config.DefaultClientConfigImpl;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.*;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/*
  这是在代码中配置ribbon,也可以在bootstrap配置文件中配置,二选一
* 注意:这个类最好不要出现在启动类的@ComponentScan扫描范围
* 如果出现在@ComponentScan扫描访问,那么这个配置类就是每个服务共用的配置了
* */
@Configuration
public class RibbonLoadBalanceMicroOrderConfig {

    //如果指定调用某个服务,可以加上服务名;配置文件中配置也是类似这样
    @RibbonClientName
    private String name = "micro-order";

    @Bean
    @ConditionalOnClass
    public IClientConfig defaultClientConfigImpl() {
        DefaultClientConfigImpl config = new DefaultClientConfigImpl();
        config.loadProperties(name);
        config.set(CommonClientConfigKey.MaxAutoRetries,2);
        config.set(CommonClientConfigKey.MaxAutoRetriesNextServer,2);
        config.set(CommonClientConfigKey.ConnectTimeout,2000);
        config.set(CommonClientConfigKey.ReadTimeout,4000);
        config.set(CommonClientConfigKey.OkToRetryOnAllOperations,true);
        return config;
    }
    /*
    * 判断服务是否存活
    * 不建议使用
    * */
    @Bean
    public IPing iPing() {
        //这个实现类会去调用服务来判断服务是否存活
        return new PingUrl();
    }

    @Bean
    public IRule ribbonRule() {
        //线性轮训
        new RoundRobinRule();
        //可以重试的轮训
        new RetryRule();
        //根据运行情况来计算权重
        new WeightedResponseTimeRule();
        //过滤掉故障实例,选择请求数最小的实例
        new BestAvailableRule();
        return new RandomRule();
    }
}

10、Ribbon 选择性配置文件中配置:

ribbon.client.name=micro-order
#点对点直连测试配置
# 关闭ribbon访问注册中心Eureka Server发现服务,但是服务依旧会注册。
#true使用eureka false不使用:服务类表是否从eureka 中来
ribbon.eureka.enabled=true
spring.cloud.loadbalancer.retry.enabled=true
#指定调用的节点,和 ribbon.eureka.enabled=true  二选一配置;这种方式不建议使用,灵活性不好。
#micro-order.ribbon.listOfServers=localhost:8001
#单位ms ,请求连接超时时间
ribbon.ConnectTimeout=1000
#单位ms ,请求处理的超时时间
ribbon.ReadTimeout=3000
#接口幂等性思想,是否重试所有的接口
ribbon.OkToRetryOnAllOperations=false
#切换实例的重试次数
ribbon.MaxAutoRetriesNextServer=2
#对当前实例的重试次数 当Eureka中可以找到服务,但是服务连不上时将会重试
ribbon.MaxAutoRetries=2
#负载均衡的算法配置
ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
#验证服务是否存活的配置
ribbon.NFLoadBalancerPingClassName=com.netflix.loadbalancer.PingUrl

11、其实Ribbon 也可以自己脱离springCloud单独使用:

 依赖jar

/*
    * ribbon作为调用客户端,可以单独使用
    * */
    @Test
    public void test1() {
        try {
            ConfigurationManager.getConfigInstance().setProperty("myClients.ribbon.listOfServers","localhost:8001,localhost:8002");
            RestClient client = (RestClient)ClientFactory.getNamedClient("myClients");
            HttpRequest request = HttpRequest.newBuilder().uri(new URI("/user/queryContent")).build();

            for (int i = 0; i < 10; i++) {
                HttpResponse httpResponse = client.executeWithLoadBalancer(request);
                String entity = httpResponse.getEntity(String.class);
                System.out.println(entity);
            }
        } catch (URISyntaxException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

这样也可以调用,小伙伴可以亲自测试一下,有不懂的地方及时留言!下一篇我们讲解Hystrix 的实战使用,敬请期待!!!

猜你喜欢

转载自blog.csdn.net/nandao158/article/details/108072358