远程调用-OpenFeign(一)

目录

1.RestTemplate存在问题

2.OpenFeign介绍

一、主要特点

二、应用场景

3.OpenFeign快速上手

3.1引入依赖

3.2添加注解

3.3编写OpenFeign的客户端 

3.4远程调用

​编辑3.5测试

4.OpenFeign参数传递

4.1传递单个参数

4.2传递多个参数

4.3传递对象 

4.4传递JSON


1.RestTemplate存在问题

观察原本远程调用的代码

 public OrderInfo selectOrderById(Integer orderId) {
     OrderInfo orderInfo = orderMapper.selectOrderById(orderId);
     String url = "http://product-service/product/"+ orderInfo.getProductId();
     ProductInfo productInfo = restTemplate.getForObject(url, 
ProductInfo.class);
     orderInfo.setProductInfo(productInfo);
     return orderInfo;
 }

虽说RestTemplate对HTTP进行封装后,比直接使用HTTPClient方便很多,但还是存在一些问题:

  1. 需要拼接URL,灵活性高,但是封装臃肿,URL复杂时,容易出错
  2. 代码可读性差,风格不统一

微服务之间的通信方式,通常有两种:RPC和HTTP

在SpringCloud中,默认是使用HTTP来进行微服务的通信,最常用的实现形式有两种:RestTemplate和OpenFeign 

RPC(Remote Procedure Call)远程过程调用,是一种通过网络从远程计算机上请求服务,而不需要了解底层网络通信细节。RPC可以使用多种网络协议进行通信,如HTTP、TCP、UDP等,并且在TCP/IP网络四层模型中跨越了传输层和应用层。简言之RPC就是像调用本地方法一样调用远程方法

常见的RPC框架有:
Dubbo: https://cn.dubbo.apache.org/zh-cn/

Thrift :Apache Thrift - Home

gRPC:gRPC                    

2.OpenFeign介绍

OpenFeign是一种声明式的REST客户端,它是Netflix开源的一款基于Java的HTTP客户端库,后成为Spring Cloud的二级子项目。OpenFeign通过声明式的方式定义REST API接口,并自动生成实现该接口的客户端代码,从而极大地简化了HTTP请求和响应的处理过程,特别是在微服务架构中,它极大地简化了服务之间的调用。以下是对OpenFeign的详细介绍:

一、主要特点

  1. 声明式API:通过注解方式声明API接口,如使用@GetMapping、@PostMapping等Spring MVC注解,让代码更加简洁和易于维护。
  2. 自动封装HTTP请求:OpenFeign自动封装HTTP请求,包括HTTP方法、请求URL、请求参数、请求头等,开发者无需手动编写HTTP请求代码。
  3. 支持多种编解码器:支持JSON、XML、Form等多种数据格式的编解码,开发者可以根据需要选择合适的编解码器。
  4. 请求拦截器和响应拦截器:开发者可以通过实现请求拦截器和响应拦截器来对HTTP请求和响应进行处理,如添加认证信息、重试机制等。
  5. 负载均衡:支持通过Ribbon进行负载均衡,可以实现多个服务提供方的负载均衡。
  6. 熔断器支持:集成了Hystrix熔断器,可以在服务调用失败或超时时进行降级处理,保证服务的可靠性和可用性。
  7. 灵活的配置方式:支持多种配置方式,包括通过注解、属性文件、Java配置等方式进行配置,可以灵活地适应不同的需求。

二、应用场景

OpenFeign在微服务架构中有着广泛的应用场景,主要包括:

  1. 服务间调用:在微服务架构中,服务间的调用是常见的需求,OpenFeign提供了一种简单、高效的方式来实现服务间的远程调用。
  2. 客户端负载均衡:通过整合Ribbon,OpenFeign可以实现客户端的负载均衡,提高系统的可用性和响应速度。
  3. 服务降级:集成Hystrix熔断器,可以在服务调用失败或超时时进行降级处理,避免级联故障的发生。

3.OpenFeign快速上手

3.1引入依赖

 <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-openfeign</artifactId>
 </dependency>

3.2添加注解

在order-service的启动类添加注解 @EnableFeignclients,开启OpenFeign的功能

 @EnableFeignClients
 @SpringBootApplication
 public class OrderServiceApplication {
     public static void main(String[] args) {
         SpringApplication.run(OrderServiceApplication.class, args);
     }
 }

3.3编写OpenFeign的客户端 

基于SpringMVC的注解来声明远程调用的信息
 import com.bite.order.model.ProductInfo;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;

 @FeignClient(value = "product-service", path = "/product")
 public interface ProductApi {
     @RequestMapping("/{productId}")
     ProductInfo getProductById(@PathVariable("productId") Integer productId);
 }

@FeignClient注解作用在接口上,参数说明:

  • name/value:指定FeignClient的名称,也就是微服务的名称,用于服务发现,Feign底层会使用 SpringCloud LoadBalance进行负载均衡.也可以使用url属性指定一个具体的url
  • path:定义当前FeignClient的统一前缀.

3.4远程调用

修改远程调用的方法

 @Autowired
 private ProductApi productApi;
 /**
  * Feign实现远程调⽤
  * @param orderId
  */
 public OrderInfo selectOrderById(Integer orderId) {
     OrderInfo orderInfo = orderMapper.selectOrderById(orderId);
     ProductInfo productInfo = productApi.getProductById(orderInfo.getProductId());
     orderInfo.setProductInfo(productInfo);
     return orderInfo;
 }

代码对比:


3.5测试

启动服务, 访问接口, 测试远程调用: http://127.0.0.1:8080/order/1
可以看出来, 使⽤Feign也可以实现远程调用.
Feign简化了与HTTP服务交互的过程, 把REST客⼾端的定义转换为Java接口, 并通过注解的方式来声明请求参数,请求方式等信息, 使远程调用更加方便

4.OpenFeign参数传递

通过观察,我们可以发现,Feign的客户端和服务提供者的接口声明非常相似

上面例子中,演示了Feign从URL中获取参数,接下来演示下Feign参数传递的其他方式

4.1传递单个参数

服务提供方product-service

 @RequestMapping("/product")
 @RestController
 public class ProductController {
     @RequestMapping("/p1")
     public String p1(Integer id){
         return "p1接收到参数:"+id;
     }
 }

Feign客户端:

 @FeignClient(value = "product-service", path = "/product")
 public interface ProductApi {

     @RequestMapping("/p1")
     String p1(@RequestParam("id") Integer id);
 }

注意: @RequestParam 做参数绑定, 不能省略

服务消费方order-service
 @RequestMapping("/feign")
 @RestController
 public class TestFeignController {
     @Autowired
     private ProductApi productApi;

     @RequestMapping("/o1")
     public String o1(Integer id){
         return productApi.p1(id);
     }
 }

 测试远程调用:http://127.0.0.1:8080/feign/o1?id=5

4.2传递多个参数

使用多个@RequestParam进行参数绑定即可

服务提供方product-service:

 @RequestMapping("/p2")
 public String p2(Integer id,String name){
     return "p2接收到参数,id:"+id +",name:"+name;
 }

Feign客户端:

 @RequestMapping("/p2")
 String p2(@RequestParam("id")Integer id,@RequestParam("name")String name);

服务消费方order-service:

 @RequestMapping("/o2")
 public String o2(@RequestParam("id")Integer id,@RequestParam("name")String name){
     return productApi.p2(id,name);
 }

4.3传递对象 

服务提供方product-service:

 @RequestMapping("/p3")
 public String p3(ProductInfo productInfo){
     return "接收到对象, productInfo:"+productInfo;
 }

Feign客户端:

 @RequestMapping("/p3")
 String p3(@SpringQueryMap ProductInfo productInfo);

服务消费方order-service:

 @RequestMapping("/o3")
 public String o3(ProductInfo productInfo){
     return productApi.p3(productInfo);
 }

测试远程调用:http://127.0.0.1:8080/feign/o3?id=5&productName=zhangsan

4.4传递JSON

服务提供方product-service:

 @RequestMapping("/p4")
 public String p4(@RequestBody ProductInfo productInfo){
     return "接收到对象, productInfo:"+productInfo;
 }

Feign客户端:

 @RequestMapping("/p4")
 String p4(@RequestBody ProductInfo productInfo);

服务消费方order-service:

 @RequestMapping("/o4")
 public String o4(@RequestBody ProductInfo productInfo){
     System.out.println(productInfo.toString());
     return productApi.p4(productInfo);
 }

测试远程调用:http://127.0.0.1:8080/feign/o4

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值