目录
OpenFeign介绍
OpenFeign最佳实践
我再来遇到个问题,我创建的com.xx.xxx包,放到一起了,不是那种一个在一个下面的那种
Nacos,只要看见这种什么网络报错啥的,java.net.SocketException: Network is unreachable
虽然RestTemple对于HTTP封装后,已经比直接使用HTTPClient简单多,但还是存在问题
1.需要拼接URL,灵活度高,但是封装囊肿,URL复杂时,容易出错
2.代码可读性差,风格不统一。
微服务之间通信方式:RPC和HTTP
RestTemplate
OpenFeign
RPC:是一种远程过程调用,是一种通过网络从远程计算机上请求服务,而不需要了解底层网络通信细节,RPC可以使用多种网络协议进行通信,如HTTP,TCP,UDP等,并且在TCP/IP网络四层模型中跨越了传输层和应用层,总之,RPC可以像调用本地方法一样调用远程方法
OpenFeign介绍
OpenFeign是一个声明式的Web Service客户端,他让微服务之间调用变得更加简单,类似Controller调用Service,只需要创建一个接口,添加注解即可使用OpenFeign
Netflix Feign是OpenFeign的祖先,或者说OpenFeign是Netflix的升级版,网络大多使用的Feign都是OpenFeign
Spring Cloud Feign是Spring对Feign的封装,将Feign项目集成到SpringCloud生态环境中
Spring Cloud Feign也有两个starter
spring-cloud-starter-feign
spring-cloud-starter-openfeign(用)
1.引入依赖
2.通过开启,开启Feign的功能
3.编写客户端
4.修改远程调用
5.测试
OpenFeign的参数传递
1.传递单个参数
2.传递多个参数
3.传递对象
4.传递JSON
客户端调用服务端
订单系统调用商品系统
2.传递多个参数
服务端需要提供相应的接口
1.传递单个参数
2.传递多个参数
3.传递对象
4.传递JSON
package com.bite.order.controller; import com.bite.order.Service.ProductService; import com.bite.order.model.ProductInfo; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; //根据商品ID,获取商品信息 @RequestMapping("/product") @RestController @Slf4j public class ProductController { @Autowired private ProductService productService; //只是一个声明,接口和实现之间的关系绑定,哪个服务,url @RequestMapping("/{productId}") public ProductInfo getProductById(@PathVariable("productId") Integer productId){ log.info("接收到参数:productId"+productId); return productService.selectProductById(productId); } @RequestMapping("/p1") public String p1(Integer id){ return "product-service 接收到参数,id:"+id; } @RequestMapping("/p2") public String p2(Integer id,String name){ return "product-service接收到参数,id:"+id+",name:"+name; } @RequestMapping("/p3") public String p3(ProductInfo productInfo){ return "product-service 接收到参数:productInfo"+productInfo.toString(); } @RequestMapping("/p4") public String p4(@RequestBody ProductInfo productInfo){ return "profuct-service 接收到参数: productInfo"+productInfo.toString(); } }
package com.bite.order.api; import com.bite.order.model.ProductInfo; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.SpringQueryMap; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; //假如后面加上path,那么说明下面的所有前面都有一个product @FeignClient(value = "product-service",path ="/product") public interface ProductApi { @RequestMapping("/{productId}") ProductInfo getProductInfo(@PathVariable("productId") Integer productId); //Feign的客户端 @RequestMapping("/p1") //这个Param不可以省略. String p1(@RequestParam("id")Integer id); @RequestMapping("/p2") //做了一个参数的绑定 public String p2(@RequestParam("id") Integer id, @RequestParam("name") String name); @RequestMapping("/p3") public String p3(@SpringQueryMap ProductInfo productInfo); //SpringQueryMap需要把对象绑定给Feign @RequestMapping("/p4") public String p4(@RequestBody ProductInfo productInfo); }
package com.bite.order;
import com.bite.order.api.ProductApi;
import com.bite.order.model.ProductInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/feign")
public class FeignController {
@Autowired
private ProductApi productApi;
//通过远程调用,o1访问商品服务p1方法
@RequestMapping("/o1")
public String o1(Integer id){
return productApi.p1(id);
}
@RequestMapping("/o2")
public String o2(Integer id,String name){
return productApi.p2(id,name);
}
@RequestMapping("/o3")
public String o3(){
ProductInfo productInfo=new ProductInfo();
productInfo.setId(23);
productInfo.setProductName("乔丹");
return productApi.p3(productInfo);
}
@RequestMapping("/o4")
public String o4(){
ProductInfo productInfo=new ProductInfo();
productInfo.setId(24);
productInfo.setProductName("科比");
return productApi.p4(productInfo);
}
}
OpenFeign最佳实践
我们的一些业务代码不方便给使用者展示,以外一些代码冗余,客户端代码和服务提供者代码十分相似,有没有一种办法可以把公共的代码提出来呢?
点击install把当前工程打成jar包,放到Maven本地仓库。
但是我发现会一个没有主类的错误
我再来遇到个问题,我创建的com.xx.xxx包,放到一起了,不是那种一个在一个下面的那种
这种情况是因为idea选择了空文件夹,会自动折叠。点击项目的设置
把我光标指的地方取消勾即可
OpenFeign的最佳实验
1.继承的方式,把公共的放到一个接口里面,
Nacos,只要看见这种什么网络报错啥的,java.net.SocketException: Network is unreachable
不是端口没开,就是 protocol/ 没删除,它是你运行一会他会再次生成,所以,一旦出现问题,就去把这个鬼东西删除,浪费我两小时,真恶心。
2.抽取的方式
企业开发中,更多是把Feigm接口抽取成为一个独立的模块(做法和继承类似,但是理念不同)
1.抽取方式,完成抽取,
2.打包install,
3.启动服务端。
4.服务调用方,引入抽取过来的模块
(抽取的模块通常由服务提供方来写),抽取的时候提供的API可以只写其中四五个,因为这样整个这个对外提供的服务通常由服务提供方,然后调用方来引入
服务部署
1.确认配置
2.打包,上传包
3.启动服务
4.测试
我们那个抽取的模块,无法进行打包,因为打包都是从Maven下载的,
方法
1.:上传到Maven中央仓库(麻烦)
2.搭建Maven私服(企业)
3.从本地读取jar包(推荐,个人学习)