新闻资讯

新闻资讯 通知公告

SpringCloud系列-Ribbon客户端侧负载均衡

编辑:016     时间:2020-02-15

     Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具。它基于Netfilx Ribbon实现。通过SpringCloud的封装,可以让我们轻松地将面向服务的REST模版请求自动转换成客户端负载均衡的服务调用。         它有助于控制HTTP和TCP客户端的行为。为Ribbon配置服务提供者地址列表后,Ribbon就可以基于某种负载均衡算法,自动地帮助服务消费者去请求。Ribbon默认为我们提供了很多的负载均衡的算法,例如轮询、随机等。        在SpringCloud中,当Ribbon与Eureka配合使用时,Ribbon可以自动从Eureka Server获取服务提供者地址列表,并基于负载均衡算法,请求其中一个服务提供者示例。


项目实例:

  1. 新建一个Springboot项目,并添加Ribbon的依赖:
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency> 复制代码
  1. 为RestTemplate添加@LoadBalanced注解
@SpringBootApplication
@EnableDiscoveryClient
public class ConsumerRibbon {

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

    public static void main(String[] args) {
        SpringApplication.run(ConsumerRibbon.class, args);
    }

} 复制代码
  1. 新建一个测试Controller:
@RestController
public class TestController {

    @Autowired
    RestTemplate restTemplate;

    @GetMapping("ribbon-consumer")
    public String testRibbon(){ return restTemplate.getForEntity("http://springboot-eureka:8081/hello",
                String.class).getBody();
    }
} 复制代码
  1. 启动eureka-server项目(此项目在上一篇文章中创建的)
  2. 启动ConsumerRibbon项目
  3. 启动Springboot-Eureka项目
  4. 访问http://localhost:xxxx
  5. 访问http://localhost:8081/hello,返回结果如下:
{
	hello world!
} 复制代码

       通过动手实践,我们可以发现通过Sprig Cloud Ribbon的封装,我们在框架中使用客户端负载均衡非常简单,只需要以下两步:

  • 服务提供者只需要启动多个服务实例并注册到一个注册中心或是多个相关联的服务注册中心
  • 服务消费者直接通过调用被@LoadBalanced注解修饰过的RestTemplate来实现面向服务接口的调用

RestTemplate详解:

  • GET请求: 在RestTemplate中,对GET请求可以通过如下两个方法进行调用实现。 第一种:getForEntity函数。该方法返回的是ResponseEntity,该对象是Spring对HTTP请求响应的封装,其中主要存储了HTTP的几个重要元素。主要有请求状态的请求码(404,500,200等)以及Body。` (主要函数方法:)
//返回值类型
	public ResponseEntity(HttpStatus status) {
		this(null, null, status);
	}
	public ResponseEntity(@Nullable T body, HttpStatus status) {
		this(body, null, status);
	}
	public ResponseEntity(MultiValueMap<String, String> headers, HttpStatus status) {
		this(null, headers, status);
	}
	public ResponseEntity(@Nullable T body, @Nullable MultiValueMap<String, String> headers, HttpStatus status) {
		super(body, headers);
		Assert.notNull(status, "HttpStatus must not be null");
		this.status = status;
	} 复制代码

第二种:getForObject函数。该方法可以理解为getForEntity函数进一步的封装,它通过HttpMessageConverterExtractor对HTTP的请求响应体Body 内容进行对象转换,实现请求直接返回包装好的对象内容。也提供了三种方法:

两种用法示例:
@Autowired
    RestTemplate restTemplate;

    @GetMapping("ribbon-consumer")
    public String testRibbon(){
        ResponseEntity<String> forEntity = restTemplate.getForEntity("http://springboot-eureka:8081/hello",
                String.class);
        User forObject = restTemplate.getForObject("", User.class); return restTemplate.getForEntity("http://springboot-eureka:8081/hello",
                String.class).getBody();
    } 
  • POST请求: 在 Res七Templ琴e 中, 对 POST 请求时可以通过如下三个方法进行调用实现。 第一种: postForEntity 函数。 该方法同 GET 请求中的 ge七ForEntity 类似, 会在调用后返回 ResponseEn巨ty对象, 其中 T 为请求响应的 body类型。 第二种: postForObjec七函数。 该方法也跟getForObject的类型类似, 它的作用是简化postForEntity的后续处理。 通过直接将请求响应的body内容包装成对象来返回使用。 第三种:postForLocation函数,该方法实现了POST请求提交资源,并返回新资源的URI。示例:
@PostMapping("post")
    public void testRibbonPost(){
        ResponseEntity<String> url = restTemplate.postForEntity("url", User.class, String.class);
        URI url1 = restTemplate.postForLocation("url", User.class, String.class);
        String url2 = restTemplate.postForObject("url", User.class, String.class);
    } 复制代码
  • PUT请求: 在RestTemplate当中。put请求可以直接使用put方法进行调用。同时put函数也有三种重载方法:在这里插入图片描述示例:
@PutMapping("put")
    public void testRibbonPut(){
        restTemplate.put("url",User.class);
    } 复制代码
  • DELETE请求: 在RestTemplate中,delete请求也可以直接调用delete函数。在这里插入图片描述示例:
@DeleteMapping("delete")
    public void testRibbonDelete(){
       restTemplate.delete("url");
    } 复制代码

Ribbon配置自定义:         很多场景下,可能根据需要自定义Ribbon的配置,例如修改Ribbon的负载均衡规则等。Spring Cloud Edgware允许使用java代码或属性自定义Ribbon的配置,两种方式是等价的。         在SpringCloud中,Ribbon的默认配置如下(格式是BeanType beanName: ClassName)

  • IClientConfig ribbonClientConfig: DefaultClientConfigImpl
  • IRule ribbonRule: ZoneAvoidanceRule
  • IPing ribbonPing: DummyPing
  • ServerList ribbonServerList: ConfigurationBaseServerList
  • ServerListFilter ribbonServerListFilter: ZonePreferenceServerListFilter
  • ILoadBalancer ribbonLoadBalancer: ZoneAwareLoadBalancer
  • ServerListUpdate ribbonServerListUpdate: PolongServerListuUpdat1.新建一个项目,test-ribbon 2.创建Ribbon的配置类:
/**
 * 该类为Ribbon配置类
 * 注意:该类不应该在主应用程序上下文的@ComponentScan所扫描的包中
 */
@Configuration
public class RibbonConfiguration {

    @Bean
    public IRule ribbonRule(){
        //负载均衡规则,改为随机 return new RandomRule();
    }
} 复制代码

3.创建空类,并在其上添加@Configuration注解和@RibbonClinet注解

/**
 * 使用RibbonClient,为特定那么的Ribbon Client自定义配置
 * 使用@RibbonClient的configuration属性,指定ribbon的配置类
 * 
 */
@Configuration
@RibbonClient(name = "test-ribbon", configuration = RibbonConfiguration.class)
public class TestConfiguration {
} 复制代码

4.启动测试

使用属性自定义Ribbon配置:

Ribbon支持使用属性自定义的方式来进行配置。 支持的属性如下,配置的前缀是.ribbon.。其中,是RibbonClient的名称,如果省略,则表示是全局配置。

  • NFLoadBalancerClassName:配置ILoadBalancer的实现类
  • NFLoadBalancerRuleClassName:配置IRule的实现类。
  • NFLoadBalancerPingClassName:配置IPing的实现类。
  • NIWSServerListClassName:配置ServerList的实现类。
  • NIWSServerListFilterClassName:配置serverListFilter的实现类 示例: 饥饿加载: SpringCloud会为每个名称的RibbonClient维护一个子应用程序上下文,这个上下文默认加载是懒加载的。指定名称的RibbonClient第一次请求时,对应的上下文才会被加载,因此,首次请求往往会比较慢。从SpringCloudDalston开始,我们可配置饥饿加载。例如:
ribbon:
 eager-load:
  enabled: true clients: client1, client2 复制代码

这样对于名为client1、client2的RibbonClient,将在启动时就加载相对应的子应用程序上下文,从而提高首次请求的访问速度。

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。

回复列表

相关推荐