目录
前面我们远程调用服务是使用的Ribbon(负载均衡)+RestTemplate(远程调用)时,利用RestTemplate对http请求的封装处理,形成了一套模板化的调用方法。
RestTemplate
RestTemplate
是Spring框架提供的用于访问REST服务的客户端工具。它简化了与RESTful服务进行交互的过程,提供了丰富的方法来发送HTTP请求并处理响应。以下是关于RestTemplate
的一些重要信息:
主要功能和特点:
发送HTTP请求:
RestTemplate
可以发送各种类型的HTTP请求,包括GET、POST、PUT、DELETE等。处理响应: 可以处理从REST服务接收到的响应,包括解析JSON、XML等格式的响应数据。
错误处理: 提供了异常处理机制,可以捕获和处理HTTP请求中可能发生的错误。
请求参数设置: 支持设置请求头、请求参数、请求体等。
拦截器: 可以添加拦截器来对请求和响应进行处理,例如日志记录、认证等。
序列化和反序列化: 支持自定义消息转换器,用于处理请求和响应的数据格式转换。
RESTful风格: 遵循RESTful架构风格,使得与RESTful服务的交互更加简单和直观。
下面是一个简单的示例展示如何使用
RestTemplate
发送GET请求:import org.springframework.web.client.RestTemplate; public class RestTemplateExample { public static void main(String[] args) { RestTemplate restTemplate = new RestTemplate(); // 发送GET请求 String url = "https://api.example.com/data"; String response = restTemplate.(url, String.class); System.out.println("Response: " + response); } }
Feign在此基础上做了进一步封装
Feign
Feign是一个声明式的、模板化的HTTP客户端,它简化了编写Web服务客户端的过程。Feign是Netflix开发的一个基于Netflix Ribbon实现的声明式、模板化的HTTP客户端,它使得编写HTTP客户端变得更加简单和优雅。
主要特点:
声明式API: Feign允许开发人员定义接口并用注解来描述HTTP请求,使得编写HTTP客户端的代码更加清晰和简洁。
集成负载均衡: 基于Ribbon实现了负载均衡功能,可以轻松地在多个服务实例之间进行负载均衡。Feign内置了Ribbon
支持插件扩展: 可以通过编写插件来扩展Feign的功能,实现定制化的需求。
支持多种编码器和解码器: 支持多种数据格式的编解码,如JSON、XML等,可以根据需要自定义编解码器。
集成Hystrix: 可以与Hystrix集成,实现服务的容错和熔断功能。
简化服务调用: 通过定义接口和注解,可以轻松地调用远程服务,避免了手动构建HTTP请求的繁琐过程。
以下是一个简单示例展示如何使用Feign定义接口并调用远程服务
- 定义Feign接口:
@FeignClient(name = "CLOUD-PAYMENT-SERVICE", url = "http://example.com") public interface ExampleFeignClient { @GetMapping("/api/data") String getData(); }
- 调用远程服务:
@RestController public class ExampleController { @Autowired private ExampleFeignClient feignClient; @GetMapping("/getData") public String getData() { return feignClient.getData(); } }
ExampleFeignClient
接口使用@FeignClient
注解定义了远程服务的信息,然后在ExampleController
中注入ExampleFeignClient
接口,并通过调用接口方法来实现远程服务调用。注意事项:
- 需要在Spring Boot应用中添加Feign的依赖。
- 需要在应用配置中启用Feign客户端。
- 可以通过配置文件进行Feign的相关配置,如超时时间、重试机制等。
总的来说,Feign是一个强大且易用的HTTP客户端工具,可以帮助开发人员简化远程服务调用的过程,提高开发效率和代码可维护性。
(以前是Dao接口上面标注Mapper注解,现在是一个微服务接口上标准一个Feign注解即可,类似与Dubbo接口上添加的@Resoure进行远程RPC调用),即可完成对服务提供方的接口绑定,简化了使用Spring Cloud Ribbon时,自动封装服务调用客户端开发量。
OpenFeign
OpenFeign是一个基于Feign的声明式HTTP客户端,用于简化编写HTTP客户端的过程。OpenFeign是Spring Cloud中的一个组件,它提供了对Feign的增强功能,并与Ribbon、Hystrix等组件集成,使得调用远程服务变得更加简单和灵活。
主要特点:
声明式API: OpenFeign允许开发人员定义接口并用注解描述HTTP请求,使得代码更加清晰和简洁。
集成负载均衡: 与Ribbon集成,可以实现负载均衡功能,自动选择合适的服务实例进行调用。
支持断路器: 与Hystrix集成,实现服务的容错和熔断功能,提高系统的稳定性。
支持自定义扩展: 可以通过自定义注解、拦截器等方式扩展OpenFeign的功能,满足特定需求。
支持多种编解码器: 支持多种数据格式的编解码,如JSON、XML等,可以根据需要自定义编解码器。
集成Spring Cloud: 与Spring Cloud无缝集成,可以方便地与Eureka、Zuul等组件配合使用。
以下是一个简单示例展示如何使用OpenFeign定义接口并调用远程服务:代码与Feign一致
- 定义OpenFeign接口:
@FeignClient(name = "example-service", url = "http://example.com") public interface ExampleFeignClient { @GetMapping("/api/data") String getData(); }
- 调用远程服务
@RestController public class ExampleController { @Autowired private ExampleFeignClient feignClient; @GetMapping("/getData") public String getData() { return feignClient.getData(); } }
注意事项:
- 需要在Spring Boot应用中添加OpenFeign的依赖。
- 需要在应用配置中启用OpenFeign客户端。
- 可以通过配置文件进行OpenFeign的相关配置,如超时时间、重试机制等。
Feign与OpenFeign区别
Feign | OpenFeign |
---|---|
Feign是Spring Cloud组件中的一个轻量级RESTful的HTTP服务客户端,Feign内置了Ribbon,用来做客户端负载均衡,去调用服务注册中心的服务。Feign的使用方式是:使用Feign的注解定义接口,调用这个接口,就可以调用服务注册中心的服务 | OpenFeign是Spring Cloud在Feign的基础上支持了SpringMVC的注解,如@RequestMapping等等。OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务。 |
org.springframework.cloud spring-cloud-starter-feign | org.springframework.cloud spring-cloud-starter-openfeign |
- OpenFeign 是对 Feign 的重新实现和扩展,由 Spring Cloud 团队维护,提供了更多功能和扩展性。
- Feign 是 Netflix 开发的声明式 HTTP 客户端工具,使用注解来定义和实现 HTTP 请求。
- OpenFeign 支持 Feign 的所有功能,并增加了对 Spring Cloud 的集成支持。
主要区别:
集成性: OpenFeign 是 Spring Cloud 的一部分,提供了与 Spring Cloud 生态的无缝集成,可以与 Eureka、Ribbon、Hystrix 等组件轻松配合使用。而原始的 Feign 是 Netflix 开发的独立库,需要额外的配置和集成。
功能扩展: OpenFeign 在 Feign 的基础上增加了对 Spring Cloud 的集成支持,包括与 Eureka 的服务发现、Ribbon 的负载均衡、Hystrix 的断路器功能等。这些功能使得在微服务架构中更容易地实现服务间的通信和容错处理。
自定义扩展: OpenFeign 提供了更多的扩展点和自定义能力,可以通过自定义注解、拦截器等方式扩展 OpenFeign 的功能,满足特定的需求。Feign 相对来说扩展性较弱。
版本更新: OpenFeign 在继续 Feign 的基础上进行了持续的更新和改进,修复了一些 Feign 存在的问题,并增加了新的特性和功能,使得 OpenFeign 更适合在现代微服务架构中使用。
相似之处:
声明式 API: OpenFeign 和 Feign 都支持声明式的 API,通过接口和注解的方式描述 HTTP 请求,使得代码更加清晰和简洁。
简化远程调用: 两者都旨在简化远程服务调用的过程,避免手动构建 HTTP 请求,提高开发效率。
负载均衡支持: OpenFeign 和 Feign 都支持负载均衡功能,可以与 Ribbon 集成实现服务的负载均衡。
总的来说,OpenFeign 是对 Feign 的增强和扩展,使得在 Spring Cloud 中使用声明式 HTTP 客户端更加方便和强大。如果你在 Spring Cloud 环境下进行微服务开发,推荐使用 OpenFeign 来简化远程服务调用的流程。
OpenFeign使用
之前的服务间调用,我们使用的是ribbon+RestTemplate
现在改为使用Feign
注意不要引用错了pom
pom
<!-- eureka-client 由于注册服务使用7001eureka -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- OpenFeign 依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
配置文件
server:
port: 80
spring:
application:
name: cloud-order-service
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:7001/eureka/
# defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
主启动类
@SpringBootApplication
@EnableFeignClients
public class OrderFeiginMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderFeiginMain80.class,args);
}
}
fegin调用
需要调用的其他的服务的接口
package com.tudeen.learn.service;
import com.tudeen.learn.entity.CommonResult;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@Component
@FeignClient(name = "CLOUD-PAYMENT-SERVICE")
public interface PaymentFeignService {
@GetMapping(value = "/payment/getPaymentByid/{id}")
CommonResult getPaymentByid(@PathVariable("id") String id);
@GetMapping(value = "/payment/feign/timout")
String paymentFeignTimemout();
}
controller
@RestController
@Slf4j
public class OrderFeignController {
@Resource
private PaymentFeignService paymentFeignService;
@GetMapping(value = "/payment/get/{id}")
public CommonResult<Payment> getPaymentById(@PathVariable("id") String id){
return paymentFeignService.getPaymentByid(id);
}
}
测试
可以远程调用两台支付模块的服务8001、8002 Feign默认使用ribbon实现负载均衡
OpenFeign超时机制
OpenFeign默认等待时间是1秒,超过1秒,直接报错
设置超时时间,修改配置文件:
因为OpenFeign的底层是ribbon进行负载均衡,所以它的超时时间是由ribbon控制
server:
port: 80
spring:
application:
name: cloud-order-service
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:7001/eureka/
# defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
#设置feign客户端超时时间,(OpenFeign默认支持ribbon)
ribbon:
#指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间
ReadTimeout: 5000
#指的是建立连接后从服务器读取到可用资源所用的时间,默认为5秒
ConnectTimeout: 5000
注意:
- 通常情况下,Feign 客户端的超时时间应该在 Feign 的配置中设置,而不是放在 Eureka 的配置中。以下是一个示例,展示如何正确地配置 Feign 客户端的超时时间:
eureka: client: register-with-eureka: true fetch-registry: true service-url: defaultZone: http://localhost:7001/eureka/ # Feign 客户端超时时间配置 feign: client: config: default: connectTimeout: 5000 readTimeout: 5000
- 在集成了 Eureka 注册中心的情况下,你可以在 Eureka 客户端配置的同一配置文件中设置 Feign 客户端的超时时间。虽然在一些情况下将不同服务的配置分开可能更清晰,但是将 Feign 客户端的超时时间配置放在 Eureka 客户端配置的同一文件中也是可行的(因为都默认使用Ribbon进行负载均衡)。
如果同时在 Ribbon 配置中设置了超时时间(
ribbon.ConnectTimeout
和ribbon.ReadTimeout
),则 Ribbon 的超时时间配置可能会覆盖 Feign 客户端的超时时间配置,因为 Feign 在内部集成了 Ribbon,部分配置可能会共享。eureka: client: register-with-eureka: true fetch-registry: true service-url: defaultZone: http://localhost:7001/eureka/ # Feign 客户端超时时间配置 ribbon: ConnectTimeout: 5000 ReadTimeout: 5000
OpenFeign日志
Feign提供了日志打印功能,我们可以通过配置来调整日志级别,从而了解Feign中Http请求的细节。说白了就是对Feign接口的调用情况进行监控和输出
OpenFeign的日志级别有以下:
public static enum Level {
NONE,
BASIC,
HEADERS,
FULL;
private Level() {
}
}
使用OpenFeign的日志,实现在配置类中添加OpenFeign的日志类
FeignLogLevelConfig
类是一个配置类,通过@Bean
注解的方式定义了一个名为feignLoglevelConfig
的 Bean,返回了日志级别Logger.Level.FATAL
。这里将 Feign 客户端的日志级别设置为FATAL
,这意味着只会输出严重错误信息。
@Configuration
public class FeignLogLevelConfig {
@Bean
public Logger.Level feignLoglevelConfig(){
return Logger.Level.FATAL;
}
}
为指定类设置日志级别:
@Component
@FeignClient(name = "CLOUD-PAYMENT-SERVICE",configuration = FeignLogLevelConfig.class)
public interface PaymentFeignService {
}
配置文件中
logging:
# 开启OpenFeign的日志功能,设置日志级别
level:
#feign日志以什么级别监控哪个接口
com.atguigu.springcloud.service.PaymentFeignService: debug
启动服务即可运行
显示任务超时,因为OpenFeign默认等待时间是1秒,超过1秒,直接报错