Spring Cloud中的服务间通信(RestTemplate和Feign)
目录一、服务间通信简介
一个系统可以由不同的微服务构成,比如一个电商系统可以由订单服务、商品服务、用户服务等共同组成。 这些服务相互独立,但又相互依赖。由于它们相互依赖,所以需要通过通信的方式来进行相互调用。服务间通信方式主要由两种:
- HTTP(SpringCloud)
- RPC(Dubbo)
Spring Cloud中服务间两种restful调用方式:
- RestTemplate
- Feign
二、RestTemplate的使用
假设我们现在在8080端口启动一个test服务。 我们使用“http://localhost:8080/test”可以访问得到一段字符串。 现在我们需要使用RestTemplate调用该服务RestTemplate使用总结了以下三种方式。
第一种方式:
RestTemplate restTemplate = new RestTemplate();
String response = restTemplate.getForObject("http://localhost:8080/test", String.class);
这种方式的弊端很明显,url是写死的。没有用到注册与发现。如果对方使用集群,ip地址动态变化,则这边就相应需要修改。
第二种方式:
@Autowired
private LoadBalancerClient loadBalancerClient;
public String test(){
RestTemplate restTemplate = new RestTemplate();
ServiceInstance serviceInstance = loadBalancerClient.choose("TEST"); //从Eureka服务器中找到该服务的地址等信息。
String response = restTemplate.getForObject("http://"+serviceInstance.getHost()+":"+serviceInstance.getPort()+"/test", String.class);
return response;
}
第二种方式将url的获取转变为从Eureka服务器中提取。前提条件是将“TEST”注册到Eureka中。
LoadBalancerClient是Spring Cloud提供的方法。
第三种方式:
第三种方式首先要定义一个类,目的是将RestTemplate配置到Bean中
//将RestTemplate配置到Bean中,方便调用和生命周期管理。
@Component
public class RestTemplateConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
@Autowired
private RestTemplate restTemplate;
public String test(){
//第三种方式,使用Bean配置的形式
String response = restTemplate.getForObject("http://TEST/msg", String.class);
return response;
}
第三种方式将RestTemplate的生命周期交由Spring管理。
在url中不用填写地址和端口,而是使用服务的名称代替。
三、客户端负载均衡器Ribbon
3.1 Ribbon简介
Ribbon实现软负载均衡,核心有三点:- 服务发现:发现依赖服务的列表,就是根据服务的名字,把该服务的实例信息都找出来。
- 服务选择规则:依据规则策略,从多个服务中,选择一个有效的服务。
- 服务监听: 检测失效的服务
实际对应流程:
- 使用ServerList(服务发现),将服务下的所有实例都拿到。
- 使用ServerListFilter(服务监听),将不能使用的实例给过滤掉
- 使用IRule(服务选择规则),从可用的实例中,选择一个实例。
3.2 更改规则选择器
Ribbon的所有规则选择器必须集成IRule接口,默认采用的选择器为RoundRule,该选择器会轮训选择调用。 如果想要修改选择器,在application.yml中配置即可。配置方式如下:
# 配置负载均衡器的选择规则,IRule接口。 TEST为要请求服务的名字。
TEST:
ribbon:
# 前面的key是固定写法,后面的RandomRule是要使用的规则选择类。该类必须实现IRule接口。
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
上述配置例子是将匹配规则换成了随机的形式。这样对于后台可用的实例,会随机选择一个进行调用。
四 使用Feign进行服务间通信
1. 增加依赖<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
2.在Application启动类上增加注解@EnableFeignClients
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
3.新建一个接口,使用该接口进行访问。
@FeignClient(name="TEST") //name为要访问的服务的名字
public interface TestClient {
@GetMapping("/test") //要访问的url
String test(); //调用这个方法,即可获取到相应服务的内容。返回值为对方返回的类型。方法名可以自定义。
}
4.调用上述接口进行访问
@Autowired
private TestClient testClient;
public String test(){
String response = testClient.test();
return response;
}
使用上述方法,就可以进行服务之间的相互调用了。
同样需要各个服务都注册在Eureka中
Feign的特点:
1.声明式REST客户端(伪RPC)
2.采用了基于接口的注解。