一起来学Spring Cloud(F版) | 第二篇:Ribbon软负载

栏目: Java · 发布时间: 6年前

内容简介:交互图

Spring Cloud 为开发者提供了在分布式系统中的一些常用的组件(例如配置管理,服务发现,断路器,智能路由,微代理,控制总线,一次性令牌,全局锁定,决策竞选,分布式会话集群状态)。使用Spring Cloud开发人员可以快速地完成实现这些模式的服务和应用程序。它们在任何分布式环境中都能很好地工作

Ribbon

RibbonNetflix 开源的基于 HTTPTCP 的客户端负载均衡器框架,目前也已被 Spring Cloud 团队集成在 spring-cloud-netflix 子项目下,主要用于客户端软负载功能,内部已实现了 随机轮训权重减压(选取压力最小的) 等常见的负载算法,同时也提供了 ILoadBalanceIRule 两个接口方便我们自己编写适合自己的负载算法

  • 负载均衡
  • 容错
  • 多协议(HTTP,TCP,UDP)支持异步和反应模型
  • 缓存和批处理

交互图

一起来学Spring Cloud(F版) | 第二篇:Ribbon软负载

Try

要尝试 Spring Cloud Ribbon 首要的就是准备一个服务注册中心,还不太清楚的可以在回头看看上一章 认识Eureka ,这里就不做过多赘述了,准备 eureka-server(回顾上一章)product-serverorder-server 三个项目,后面的两个可以理解为上一章的 eureka-client

Eureka Server

详情参考上一章,或从文末的 GITHUB 链接获取对应篇幅的完整代码

Product Server

一个普通的 Eureka Client 即可,详情参考上一章,或从文末的 GITHUB 链接获取对应篇幅的完整代码

Order Server

一个普通的 Eureka Client

依赖

细心的小伙伴会发现,这和一个普通的 Eureka Client 也没啥区别啊,没任何额外依赖的,那是因为在 spring-cloud-starter-netflix-eureka-client 中已经帮我们依赖过 spring-cloud-starter-netflix-ribbon 了。假如使用 consulzookeeperetcd 等容器为服务发现为者时,就必须依赖 spring-cloud-starter-netflix-ribbon

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
</dependencies>

配置文件

src/main/resources 目录下创建一个 bootstrap.yml 的文件,写上 eureka 相关配置信息

server:
  port: 7072
spring:
  application:
    name: order-server
eureka:
  instance:
    prefer-ip-address: true
    instance-id: ${spring.cloud.client.ip-address}:${spring.application.instance_id:${server.port}}
  client:
    service-url:
      defaultZone: http://localhost:7071/eureka/

主函数

各位小伙伴对 Spring Boot 中的 RestTemplate 应该都不陌生,它是由 Spring Boot 提供而不是 Spring Cloud ,无负载功能,为了方便开发者, Spring Cloud 团队提供了一个 @LoadBalanced 注解(默认采用轮训算法)

package com.battcn;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
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 Levin
 */
@EnableDiscoveryClient
@SpringBootApplication
public class OrderApplication {

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

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

控制器

客户端( order-server:7702 )从 Eureka Server 同步了 product-server:7703product-server:7704 这个时候它是如何知晓注册表中的信息呢?上一章中遗留了一个知识点就是 DiscoveryClient ,通过它就可以获得注册表中客户端的信息了,下列代码块演示了 DiscoveryClient 的简单用法,更多 API 可以自行尝试

package com.battcn.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;

/**
 * @author Levin
 * @since 2018/9/28 0028
 */
@RestController
@RequestMapping("/orders")
public class OrderController {

    private final RestTemplate restTemplate;
    private final DiscoveryClient discoveryClient;

    @Autowired
    public OrderController(RestTemplate restTemplate, DiscoveryClient discoveryClient) {
        this.restTemplate = restTemplate;
        this.discoveryClient = discoveryClient;
    }

    @GetMapping
    public String query() {
        final List<String> services = discoveryClient.getServices();
        for (String service : services) {
            List<ServiceInstance> list = discoveryClient.getInstances(service);
            for (ServiceInstance instance : list) {
                System.out.println(instance.getUri() + "/" + service + " - " + instance.getServiceId());
            }
        }
        return restTemplate.getForObject("http://PRODUCT-SERVER/products", String.class);
    }
}

Why

有的小伙伴对上面的内容会存在一些疑问,为什么没有写 IP:PORT 了,而是写了一串字符,它是怎么做到的?

用通俗的概念来说,它就是编码与解码操作,还记得 Eureka Server UI 中 Application 吗? 
编码:根据 spring.application.name 设置 serviceId 
Server ID:PRODUCT-SERVER
Client A :http://localhost:7073/products
Client B :http://localhost:7074/products

解码:通过 serviceId 找到对应的客户端,
然后根据客户端配置的负载算法从对应集合中
找出符合当前算法条件的结果,最后拼接出相应的 http 地址即可

解码前:http://PRODUCT-SERVER/products 
那么将 http://PRODUCT-SERVER 替换成 instance.getUri() 内容是不是就出来了
http://localhost:7073/products 和 http://localhost:7074/products

一起来学Spring Cloud(F版) | 第二篇:Ribbon软负载

自定义 IRule

假如我们不想使用轮训了,换换口味改成随机算法,又或者想自己写一套适合自己的负载算法,可以用下面这种方式

package com.battcn.config;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author Levin
 * @since 2018/9/28 0028
 */
@Configuration
public class RibbonRuleConfiguration {

    @Bean
    public IRule ribbonRule() {
        return new RandomRule();
    }
}

@RibbonClient(name = "ribbonRule",configuration = RibbonRuleConfiguration.class)
public class OrderController {

}

总结

目前很多大佬都写过关于 Spring Cloud 的教程了,如有雷同,请多多包涵,本教程基于最新的 spring-cloud:Finchley.SR1 编写…


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Out of their Minds

Out of their Minds

Dennis Shasha、Cathy Lazere / Springer / 1998-07-02 / USD 16.00

This best-selling book is now available in an inexpensive softcover format. Imagine living during the Renaissance and being able to interview that eras greatest scientists about their inspirations, di......一起来看看 《Out of their Minds》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

在线进制转换器
在线进制转换器

各进制数互转换器

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具