美文网首页
ribbon的使用

ribbon的使用

作者: 一个神奇的女码农 | 来源:发表于2019-11-18 10:46 被阅读0次

    简介

    spring cloud ribbon 是一个基于http和TCP客户度负载均衡工具,它基于Netflix Ribbon实现。通过Spring Cloud的封装,可以让我们轻松地将面向服务的REST模版请求自动转换成客户端负载均衡的服务调用。

    负载均衡

    负载均衡有两种,一般是服务器负载均衡,分为硬件负载均衡和软件负载均衡.
    硬件负载均衡是用于服务器节点之间的负载均衡设备
    软件负载均衡是通过在服务器上安装一些负载均衡的软件,来完成一些请求分发的工作,例如我们现在用的Nginx


    负载均衡架构图.png

    搭建ribbon工程

    创建一个spring boot的工程,然后勾选上


    ribbon创建.png

    添加配置文件

    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:8080/eureka
    server:
      port: 8764
    spring:
      application:
        name: service-ribbon
    

    在启动类上添加

    @EnableEurekaClient
    @EnableDiscoveryClient
    

    我们需要使用对象RestTemplate。该对象会使用Ribbon的自动化配置,同时通过配置@LoadBalanced开启客户端负载均衡。

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

    测试

    编写一个测试类,注入template

    @RestController
    public class RibbonController {
        @Autowired
        RestTemplate restTemplate;
    
        @RequestMapping("/helloRibbon")
        public String helloRibbon(){
            //访问hello-service服务的hello接口
            ResponseEntity<String> forEntity = restTemplate.getForEntity("http://service-user/test", String.class);
            System.out.println(forEntity);
            return forEntity.getBody();
        }
    }
    

    启动两个producer
    可以在注册中心看到

    注册中心.png
    多次访问http://localhost:8764/helloRibbon
    查看控制台就可以看到两个user分别被访问了

    请求方式

    GET 请求

        在RestTemplate中,对GET请求可以通过如下两个方法进行调用实现。
    
        第一种:getForEntity函数。该方法返回的是ResponseEntity,该对象是Spring对HTTP请求响应的封装,其中主要存储了HTTP的几个重要元素,比如HTTP请求状态码的枚举对象HttpStatus(也就是我们常说的404、500这些错误码)、在它的父类HttpEntity中还存储着HTTP请求的头信息对象HttpHeaders以及泛型类型的请求体对象。比如下面的例子,就是访问USER-SERVER服务端/user请求,同时最后一个参数didi会替换url中的{1}占位符,而返回的ResponseEntity对象的body内容类型会根据第二个参数转换为String类型。
    
    image
        若我们希望返回body是一个User对象类型,也可以这样实现:
    
    image
        上面的例子是比较常用的方法,getForEntity函数实际上提供了以下三种不同的重载实现。
    

    ▪️getForEntity(String url, Class responseType,Object... urlVariables);

        该方法提供了三个参数,其中url为请求的地址,responseType为请求响应体body的包装类型,urlVariables为url中的参数绑定。GET请求的参数绑定通过使用url中拼接的方式,比如http://USER-SERVICE/user?name=didi,我们可以像这样自己将参数拼接到 url中,但更好的方法是在url中使用占位符并配合urlVariables参数实现GET请求的参数绑定,比如url定义为:getForEntity("http://USER-SERVICE/user?name={1}", String.class, "didi"),其中第三个参数didi会替换掉url中的{1}站位符。这里需要注意的是,由于urlVariables参数是一个数组,所以它的顺序会对应url中占位符定义的数字顺序。
    

    ▪️getForEntity(String url, Class responseType, Map urlVariables);

        该方法提供的参数重,只有urlVariables的参数类型与上面的方法不同。这里使用了Map类型,所以使用该方法进行参数绑定时需要再占位符中指定Map中的参数的key值,比如url定义为http://USER-SERVICE/user?name={name},在Map类型的urlVariables中,我们就需要put一个key为name的参数来绑定url中{name}占位符的值,比如:
    
    image

    ▪️getForEntity(URI url, Class responseType)

        该方法使用uri对象来代替之前url和urlVariables参数来指定访问地址和参数绑定。URI是JDK java.net包下单一个类,它表示一个统一资源标识符(Uniform Resource Identifier)引用,比如下面的例子:
    
    image
        更多关于如何定义一个URI的方法可以参见JDK文档,这里不做详细说明。
    
        第二种:getForObject函数。该方法可以理解为对getForEntity的进一步封装,它通过HttpMessageConverterExtractor对HTTP的请求响应体body内容进行对象转换,实现请求直接返回包装好的对象内容。比如:
    

    RestTemplate restTemplate = new RestTemplate();

    String result = restTemplate.getForObject(uri, String.class);

        当body是一个User对象时,可以直接这样实现:
    

    RestTemplate restTemplate = new RestTemplate();

    User result = restTemplate.getForObject(uri, User.class);

        当不需要关注请求响应除body外的其他内容时,该函数就非常好用,可以少一个从Response中获取body的步骤。它与getForEntity函数类似,也提供了三种不同的重载实现。
    

    ▪️getForObject(String url, Class responseType, Object ... urlVariables)

    ▪️getForObject(String url, Class responseType, Map urlVariables)

    ▪️getForObject(URI url, Class responseType)

    POST 请求

        在RestTemplate中,对POST请求时可以通过如下三个方法调用实现。
    

    ▪️第一种:postForEntity函数。

        该方法同GET请求中的getForEntity类似,会在调用后返回ResponseEntity对象,其中T为请求响应的body类型。比如下面这个例子,使用postForEntity提交POST请求到USER-SERVICE服务的/user接口,提交的body内容为user对象,请求响应返回的body类型为String。
    
    image

    postForEntity函数也实现了三种不同的重载方法。

    image

    ▪️postForEntity(String url, Object request, Class responseType, Object... uriVariables)

    ▪️postForEntity(String url, Object request, Class responseType, Map uriVariables)

    ▪️postForEntity(URI url, Object request, Class responseType)

        这些函数中的参数用法大部分与getForEntity一致,比如,第一个重载函数和第二个重载函数中的uriVariables参数都用来对url中的参数进行绑定使用;responseType参数是对请求响应的body内容的类型定义。这里需要注意的是新增加的request参数,该参数可以是一个普通对象,也可以是一个HttpEntity对象。如果是普通对象,而非HttpEntity对象的时候,RestTemplate会将请求对象转换为一个HttpEntity对象来处理;其中Object就是request的类型,request内容会呗视作完整的body来处理;而如果request是一个HttpEntity对象,那么就会被当作一个完成的HTTP请求对象来处理,这个request中不仅包含了body的内容,也包含了header的内容。
    

    ▪️第二种:postForObject函数。

        该方法也跟getForObject的类型类似,它的作用就是简化postForEntity的后续处理。通过直接将请求响应的body内容包装成对象来返回使用,比如下面的例子:
    
    image

    postForObject函数也实现了三种不同的重载方法:

    image

    ▪️postForObject(String url, Object request, Class responseType, Object... uriVariables)

    ▪️postForObject(String url, Object request, Class responseType, Map uriVariables)

    ▪️postForObject(URI url, Object request, Class responseType)

        这三个函数除了返回的对象类型不同,函数的传入参数均与postForEntity一致,因此可参考之前postForEntity的说明。
    

    ▪️第三种:postForLocation函数。

        该方法实现了以POST请求提交资源,并返回新的资源的URI,比如下面的例子:
    
    image
        postForLocation函数也实现了三种不同的重载方法:
    
    image

    ▪️postForLocation(String url, Object request, Object... uriVariables)

    ▪️postForLocation(String url, Object request, Map uriVariables)

    ▪️postForLocation(URI url, Object request)

    由于postForLocation函数会返回新资源的URI,该URI就相当于指定了返回类型,所以此方法实现的POST请求不需要像postForEntity和postForObject那样指定responseType。其他的参数用法相同。

    参考文章:https://www.jianshu.com/p/1bd66db5dc46

    相关文章

      网友评论

          本文标题:ribbon的使用

          本文链接:https://www.haomeiwen.com/subject/gnqsictx.html