Spring Cloud Fegin:服务调用
# 6.Spring Cloud Fegin:服务调用
在前几章我们介绍了Spring Cloud中的一些核心组件,包括Eureka、Ribbon等,它们为构建微服务架构提供了强大的支持。在微服务架构中,服务之间的通信是非常常见的需求,而如何简化和优化这种通信过程是我们关注的焦点之一。
在本章中,我们将介绍Spring Cloud中另一个重要的组件——Feign。Feign是Spring Cloud提供的一个声明式HTTP客户端,通过注解方式定义接口,使得开发者可以像调用本地方法一样调用远程服务。通过使用Feign,我们可以将服务间通信的过程进一步简化,使得代码更加清晰、可维护性更高。
# 1.Feign简化微服务调用
在使用Ribbon和RestTemplate时,我们通常会针对每个微服务自行封装一些客户端类来包装对依赖服务的调用。这样做是因为一个接口可能会被多处调用,为了提高代码的复用性和可维护性,我们需要将对服务的调用逻辑封装到一个独立的类中。然而,这种方式还是需要开发人员手动定义和实现这些客户端类,增加了开发的复杂度。
而Feign则在此基础上做了进一步的封装。它通过使用接口和注解的方式来定义和配置对服务提供方的接口,从而简化了对依赖服务的调用。在使用Feign时,我们只需要创建一个接口并使用注解的方式来配置它,就可以完成对服务提供方的接口绑定。这种方式类似于以前在DAO接口上标注Mapper注解的做法,但是使用Feign更加简洁和方便。它避免了手动编写大量的客户端类的工作,极大地简化了使用Ribbon时自动封装服务调用客户端的开发量。
# 2.Feign集成Ribbon
Feign不仅简化了代码,还集成了Ribbon负载均衡,利用Ribbon维护了生产者的服务列表信息,并且通过轮询实现了客户端的负载均衡。而与Ribbon不同的是,通过feign只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用,feign还集成了Hystrix。
# 3. Feign vs. OpenFeign
在微服务中,我们经常需要通过HTTP请求来调用其他服务。Feign是一个声明式的HTTP客户端,可以帮助我们更轻松地实现这一目标。但是,随着微服务架构的发展,Feign的功能有些许不足。这时,OpenFeign应运而生,它是对Feign的增强和扩展。
Feign是Netflix开发的一个项目,它可以通过简单的接口和注解来定义服务调用。例如,我们可以通过以下方式定义一个Feign客户端:
@FeignClient(name = "example", url = "http://localhost:8080")
public interface ExampleFeignClient {
@RequestMapping(value = "/example", method = RequestMethod.GET)
String getExample();
}
2
3
4
5
6
OpenFeign在Feign的基础上进行了扩展,提供了更多功能和灵活性。最主要的区别在于,OpenFeign支持使用更多的Spring MVC注解来定义接口,使得接口定义更加灵活和易懂。例如,我们可以这样定义一个使用了Spring MVC注解的OpenFeign客户端:
@FeignClient(name = "example")
public interface ExampleFeignClient {
@GetMapping("/example")
String getExample();
@PostMapping("/example")
String postExample(@RequestBody String body);
}
2
3
4
5
6
7
8
9
总的来说,OpenFeign是Feign的一个增强版本,提供了更多功能和灵活性,适用于更多复杂的场景。这里我们使用OpenFeign版本。
# 4.代码实现
# 4.1 添加依赖
在消费者cloud-service2
的pom.xml中添加Feign的依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2
3
4
# 4.2 启用Feign
在主应用类上添加@EnableFeignClients
注解:
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class CloudService2Application {
public static void main(String[] args) {
SpringApplication.run(CloudService2Application.class, args);
}
}
2
3
4
5
6
7
8
9
10
# 4.3 定义Feign客户端接口
通常,我们会在项目中创建一个专门的包来存放Feign客户端接口。典型的包名可以是com.example.project.client
或com.example.project.service.client
。接口名则一般采用<服务名>Client
的形式,如CloudService1Client
。
使用@FeignClient
注解定义一个接口,通过接口调用远程服务:
package cn.ywenrou.cloudservice2.service.client;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
@FeignClient(name = "cloud-service1")
public interface CloudService1Client {
@GetMapping("/service1/hello")
String hello();
}
2
3
4
5
6
7
8
9
10
# 4.4 使用Feign客户端
在需要调用服务的地方,注入Feign客户端并调用方法,替代之前使用硬编码主机名和端口号的方式而且参数复杂时URL难以维护,代码可读性差,而且编程体验也不好;
@RestController
class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private CloudService1Client service1Client;
@RequestMapping(value="/service2/hello")
public String helloController() {
//return restTemplate.getForObject("http://cloud-service1/service1/hello", String.class);
return service1Client.hello();
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 4.5 查看效果
多尝试几次,可以看到自带负载均衡
# 6.总结
本章介绍了Spring Cloud中的Feign组件,它通过声明式的方式简化了微服务之间的调用。通过定义接口并使用注解配置,Feign能够自动将接口绑定到服务提供方,极大地简化了服务调用的流程。
在使用Feign时,我们可能会遇到某些服务不稳定或出现异常的情况(网络延迟、服务超负载、服务故障等)。接下来的章节将介绍如何通过集成Hystrix来解决这些问题,实现服务的降级处理。Hystrix是一个能够帮助我们提高系统稳定性的组件,它可以在服务不可用时提供备用方案,保证系统在异常情况下依然能够正常运行。