前一篇文章介绍了Spring Cloud Eureka的简单实践,本篇文章介绍Ribbon的实践。

What is Ribbon

Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,这里的客户端是站在服务器的角度来看的,它基于Netflix Ribbon实现。
通过Spring Cloud的封装,可以轻松的将面向服务的Rest模板请求自动转化成客户端负载均衡的服务调用。当然这属于软件的负载均衡。

例子

下面通过一个简单例子来用用Ribbon,基于上篇文章代码来进行。

  1. 首先,新建一个项目service-consumer,作为暴露对外的url调用,该项目pom文件如下:
<dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-ribbon</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
    </dependencies>
  1. 写一个main类
@SpringBootApplication
@EnableEurekaClient
public class RibbonConsumerApplication {
    public static void main(String[] args){
        SpringApplication.run(RibbonConsumerApplication.class,args);
    }
}
  1. 配置一个RestTemplate的bean:
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
  1. 定一个公开的controller,用于从另一个服务端获取数据:
    @Autowired
    private RestTemplate restTemplate;

    @GetMapping(value = "/ribbon/{name}")
    public String findInfoById(@PathVariable String name){
        //注意以下命名是以eureka的服务名称来获取的
        ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://hello-service/user?name={1}",String.class,name+":test anla");
        String body = responseEntity.getBody();
        return body;
    }
  1. 此时,hello-service,就做为服务提供者,实际中可能有多个hello-service实例,它们在eureka注册的名称需要一致,端口不同,在
    hello-service中可以定义众多restful方法供调用:
    @RequestMapping(value = "/user",method = RequestMethod.GET)
    public String index(@RequestParam String name){
        ServiceInstance config = client.getLocalServiceInstance();
        String serviceId = config.getServiceId();
        String result = "hello: I am "+serviceId+", hello-service"+name+"my port is"+config.getPort();
        logger.info(result);
        return result;
    }
  1. 分别启动eureka-server,hello-service,service-consumer,然后改变hello-service的server.port,换一个端口再进行注册,此时eureka中实例如下:
    这里写图片描述

此时在浏览器中输入:http://localhost:8081/ribbon/123
回车两次,可以分别看到不同端口输出(默认是轮询方法负载均衡)
这里写图片描述

这里写图片描述

一个简单例子就完成了,可以去我git上直接clone代码,check out到v2分支:
https://github.com/anLA7856/hello-springcloud.git

小窥

在上述示例代码中,我使用了RestTemplate来进行对服务端的restful调用,当然,在Restful API规范中,对应有不同的操作,而在
RestTemplate中也有对应:

  • GET
    • public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables)
    • public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables)
    • public <T> ResponseEntity<T> getForEntity(URI url, Class<T> responseType)
    • public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables)
    • public <T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables)
  • POST
    • public <T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType, Object... uriVariables)
    • public <T> T postForObject(String url, Object request, Class<T> responseType, Object... uriVariables)
  • PUT
    • public void put(String url, Object request, Object... uriVariables)
  • DELTE
    • public void delete(String url, Object... uriVariables)

上述中列举了四种请求的对应的方法,其中重载则并未列出了。

负载均衡策略

对于Ribbon,负载均衡策略主要有以下几种:

  • RandomRule:随机
  • RoundRobinRule:线性轮询一次选择每个服务器实例
  • RetryRule:具备重试机制的实例选择功能
  • WeightedResponseTimeRule:对RoundRobinRule的扩展,增加了对实例运行情况来计算权重,并根据权重来挑选实例
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐