SpringCloud实战:NetflixRibbon的使用

服务间通信:Spring Cloud Netflix Ribbon和 Spring Cloud OpenFeign

一个大型的系统由多个微服务模块组成,我们一般可以通过内部接口调用的形式(服务A提供一个接口,服务B通过HTTP请求调用服务A的接口)实现各模块之间的通信。为了简化开发,SpringCloud集成了Spring Cloud Netflix Ribbon和Spring Cloud OpenFeign,两个组件都支持通过HTTP请求不同的服务。

举个例子,用户模块和评论模块,当查询评论列表时需要返回用户的基本信息(昵称、头像等),直接利用SQL语句关联查询是可以实现该需求的,但是耦合性较强,亦不利于扩展。用户信息应由用户模块提供,这时就需要用户模块提供接口,评论模块调用此接口,从而拿到用户数据。

本文将简要介绍Spring Cloud Netflix Ribbon,借此引出 Sping Cloud OpenFeign,并详细介绍其用法。

Spring Cloud Netflix Ribbon的使用

Spring Cloud Netflix Ribbon(即 Ribbon )是Spring Cloud Netflix的一个子项目,它提供了HTTP客户端和TCP客户端,用于支持各服务间的通信并且拥有负载均衡能力。

SpringCloud实战:NetflixRibbon的使用

 

Ribbon 的一个核心概念是命名的客户端。每一个负载均衡器都是Ribbon组件的一部分,它们在需要的时候一起工作,并且和远程服务器通信。

在 Spring Cloud工程中引用Ribbon非常简单,只需要在pom.xml中添加以下依赖:

org.springframework.cloudspring-cloud-starter-netflix-ribbon

只要添加了上述依赖,该工程就拥有了Ribbon的HTTP远程调用能力。Ribbon通过RestTemplate类调用远程服务器,因此我们还需要注入RestTemplate类,在 webConfig 类中添加以下代码:

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

除了读者已经熟悉的@Bean 注解外,还多了一个@LoadBalanced注解,只有增加该注解,Ribbon才会启用负载均衡。接下来演示通过comment服务远程调用TEST服务。

首先,在comment工程下创建TestServiceRibbon接口和TestServiceImplRibbon类,该类用于远程调用TEST服务的其中一个接口,编写代码如下:

public interface TestServiceRibbon {
String test(;
}
@service
public class TestServicelmplRibbon implements TestServiceRibbon {
@Autowired
private RestTemplate restTemplate;
@Override
public string test() {
return restTemplate.postForEntity("http://TEST/test" ,null,String.class).getBody();
}
}

我们可以看到,代码注入了webConfig 配置的 RestTemplate类,然后通过RestTemplate 的postForEntity方法调用TEST服务的test接口,并通过getBody方法返回结果。

然后,创建控制器类,并编写如下代码:

@RequestMapping( "ribbon")
@RestController
public class TestcontrollerRibbon i
@Autowired
TestServiceRibbon testserviceRibbon;@RequestMapping( "test")
private String test(){
return testServiceRibbon.test();
}
}

提供上述控制器的目的是更方便地测试Ribbon能否成功调用TEST服务及其负载均衡能力,当然也可以直接用单元测试,但是无法看到负载均衡效果。

我们可以分别启动register、config、comment、test 工程,其中 test工程分别以9999和 9998端口启动两次,浏览器多次访问地址localhost:8203/ribbon/test,可以看到分别打印出端口9999和 9998,说明Ribbon负载均衡已生效。

正如上面所说,如果不添加@LoadBalancer 注解,则无法使用负载均衡功能,并且 postForEntity传入的地址无法直接使用服务名TEST,会报如图11-1所示的错误。

SpringCloud实战:NetflixRibbon的使用

 

因为失去了负载均衡能力,RestTemplate不会拉取注册表信息,而是直接调用传人的地址,因而提示TEST是未知主机 ( host)。要解决这个问题,需要将 http:/TEST/test 替换成具体的地址,如http://localhost:9999/test。

接着介绍postForEntity方法,顾名思义,该方法以POST方式请求HTTP地址并返回相应的实体对象。其中第一个参数为请求地址,第二个参数为请求参数,第三个参数为要转成的实体类。RestTemplate对应的方法还有getForEntity,很明显该方法是GET请求。

通过Ribbon的学习,读者可以了解到服务间是如何通信的。但Ribbon也有自身的缺陷,它通过RestTemplate 去调用HTTP接口,看起来就是一个HTTP远程调用,和整个微服务工程没有多大关系,我们完全可以自己通过远程HTTP请求实现。因此,Spring Cloud又集成了OpenFeign,它的使用更加优雅,像是工程自己的方法。

上一篇:微服务服务调用-Ribbon的简单使用


下一篇:负载均衡和ribbon、ribbon快速入门