1.Feign概述
1.1.Feign是什么
Feign是一個宣告式的web服務客戶端,使得撰寫Web服務客戶端變得非常容易,只需要創建一個介面,然后在上面添加注解即可,
1.2.Feign能干什么
相比與Ribbon,Ribbon在實作負載均衡呼叫請求時,是利用RestTemplate請求進行封裝處理,形成了一套Restful風格的模板化呼叫方法,但是在實際開發中,由于對服務依賴的呼叫可能不止一處,往往一個介面會被多處呼叫,所以通常都會針對每個微服務自行封裝一些客戶端類來包裝這些依賴服務的呼叫,
Feign在Ribbon的基礎上做了進一步封裝,在Feign的實作下,我們只需創建一個介面并使用注解的方式來配置它(以前是Dao介面上面標注Mapper注解,現在是一個微服務介面上面標注Feign注解即可),即可完成對服務提供方的介面系結,簡化了使用SpringCloud Ribbon時,自動封裝服務呼叫客戶端的開發量,
2.Feign的簡單使用
首先理一下思路:Feign的實作是基于服務提供方的介面來實作呼叫的,那么我們事先就要創建一個宣告式的介面,而這個介面我們一般放在pojo公共類的服務方,方便之后在客戶端呼叫服務提供者的介面時,只需要引入pojo微服務的依賴jar包即可;再通過介面注入Bean的方式,使用Feign提供的注解,開啟對服務提供者遠端介面的請求呼叫,無需開發者再自己構造一套復雜的Restful url請求呼叫,
Feign的風格:介面呼叫、依賴注入請求介面;
Ribbon的風格:基于RestTemplate呼叫、還需要自己封裝請求url;
相對來說Feign的實作方式更符合面向介面編程的套路,代碼更加簡化便捷,
2.1.公共類api介面撰寫
(1)在springcloud-api公共pojo服務類下新創建一個服務介面service層,撰寫客戶端呼叫介面:
//value中對應服務提供方的名字(value值表示呼叫服務的名稱) @FeignClient(value = "https://www.cnblogs.com/yif0118/archive/2021/04/03/SPRINGCLOUD-PROVIDER-DEPT") @Component //注入到容器中 public interface DeptClientService { /** * 介面中的三個方法對應服務提供者的三個方法 * 這里面的介面對應服務提供者的controller介面,名稱必須一致,然后介面的Mapping映射url必須一致 * @param dept * @return */ @PostMapping("/dept/add") public boolean addDept(Dept dept); @GetMapping("/dept/queryById/{id}") public Dept queryById(@PathVariable("id") Long id); @GetMapping("/dept/queryAll") public List<Dept> queryAll(); }
2.2.消費方客戶端服務呼叫Feign方式實作
這里基于原來Ribbon實作客戶端呼叫來重寫Feign實作,具體Ribbon實作方式見我上一篇博文:SpringCloud(4)--Ribbon負載均衡,這里不再過多描述,
(1)引入pom.xml依賴:
<!--引入feign:版本和ribbon相同--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> <version>1.4.6.RELEASE</version> </dependency> <!--引入Ribbon相關:ribbon->eureka->config--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> <version>1.4.6.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <!--微服務provider方引入eureka--> <dependency> <groupId>org.springframework.cloud</groupId> <!--沒有帶sever表示就是client客戶端--> <artifactId>spring-cloud-starter-eureka</artifactId> <version>1.4.6.RELEASE</version> </dependency> <dependency> <groupId>com.fengye</groupId> <artifactId>springcloud-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
(2)application.yml配置:
server: port: 81 #spring的配置 spring: application: name: springcloud-consumer-dept #默認注冊進eureka中的實體名稱(顯示大寫) datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: org.gjt.mm.mysql.Driver url: jdbc:mysql://localhost:3306/springcloud_db01?useUnicode=true&characterEncoding=utf-8 username: root password: admin #eureka的配置,確定客戶端服務注冊到eureka服務串列內 eureka: client: register-with-eureka: false #表示是否向Eureka注冊中心注冊自己,false表示不注冊自己 service-url: defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
(3)基于介面撰寫客戶端請求Controller:
@RestController public class DeptConsumerController { @Autowired private DeptClientService deptClientService; //注入api中公共介面,面向介面呼叫服務 @RequestMapping("/consumer/dept/add") public boolean add(Dept dept){ return deptClientService.addDept(dept); } @RequestMapping("/consumer/dept/get/{id}") public Dept get(@PathVariable("id") Long id){ Dept result = deptClientService.queryById(id); System.out.println("客戶端請求:data from port= " + result.getDname()); return result; } @RequestMapping("/consumer/dept/list") public List<Dept> list(){ return deptClientService.queryAll(); } }
(4)啟動類中開啟FeignClients注解支持:
@SpringBootApplication @EnableEurekaClient //標識這是一個eureka的client客戶端 @EnableFeignClients(basePackages = {"com.fengye.springcloud"}) //掃描哪個包下面的Feign注解 public class DeptServiceFeignConsumer { public static void main(String[] args) { SpringApplication.run(DeptServiceFeignConsumer.class, args); } }
2.3.啟動服務測驗
這里就單獨只啟動重寫的Feign客戶端服務呼叫請求即可,
請求介面訪問:默認輪詢輸出dbSource

客戶端請求列印輸出陳述句,可以看到Feign同樣實作了服務提供端的負載均衡,

3.Feign原理簡述
Feign注解實作負載均衡的執行流程簡要說明:
- 啟動時,程式會進行包掃描,掃描所有包下所有@FeignClient注解的類,并將這些類注入到spring的IOC容器中,當定義的Feign中的介面被呼叫時,通過JDK的動態代理來生成RequestTemplate,
- RequestTemplate中包含請求的所有資訊,如請求引數,請求URL等,
- RequestTemplate宣告Request,然后將Request交給client處理,這個client默認是JDK的HTTPUrlConnection,也可以是OKhttp、Apache的HTTPClient等,
- 最后client封裝成LoadBaLanceClient,結合ribbon負載均衡地發起呼叫,
微服務實戰SpringCloud之Feign簡介及使用
Spring Cloud Feign - 內部實作細節
本節涉及實體及相關代碼已上傳至github:
https://github.com/devyf/SpringCloud_Study/tree/main/springcloud_hello
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/272138.html
標籤:其他
上一篇:java例外機制
下一篇:迷宮問題
