序言
Spring Cloud Netflix的微服務都是以HTTP接口的形式暴露的,是以可以用Apache的HttpClient或Spring的RestTemplate去調用
而Feign是一個使用起來更加友善的HTTP用戶端,它用起來就好像調用本地方法一樣,完全感覺不到是調用的遠端方法
Feign是一個聲明式的Web Service用戶端,它的目的就是讓Web Service調用更加簡單。Feign提供了HTTP請求的模闆,通過編寫簡單的接口和插入注解,就可以定義好HTTP請求的參數、格式、位址等資訊。
Feign會完全代理HTTP請求,我們隻需要像調用方法一樣調用它就可以完成服務請求及相關處理。
Feign整合了Ribbon和Hystrix(關于Hystrix我們後面再講),可以讓我們不再需要顯式地使用這兩個元件。
總起來說,Feign具有如下特性:
- 可插拔的注解支援,包括Feign注解和JAX-RS注解;
- 支援可插拔的HTTP編碼器和解碼器;
- 支援Hystrix和它的Fallback;
- 支援Ribbon的負載均衡;
- 支援HTTP請求和響應的壓縮。
https://github.com/Netflix/feign
微服務提供方注冊服務到Eureka執行個體代碼
pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
資源配置檔案
## server
server.port=8082
##eureka
eureka.client.serviceUrl.defaultZone=http://localhost:8081/eureka/
eureka.instance.instance-id=${spring.application.name}:${server.port}
# 設定微服務調用位址為IP優先(預設為false)
eureka.instance.prefer-ip-address=true
# 心跳時間,即服務續約間隔時間(預設為30s)
eureka.instance.lease-renewal-interval-in-seconds=30
# 發呆時間,即服務續約到期時間(預設為90s)
eureka.instance.lease-expiration-duration-in-seconds=9
起始檔案
@EnableEurekaClient
public class StartMain {
public static void main(String[] args) {
SpringApplication.run(StartMain.class, args);
}
}
接口controller,可以沒有facade層的接口,這裡是為拉給java其他用戶端調用設計的。
//controller層
@RestController
@RequestMapping(value = "/Promotion",method = RequestMethod.GET)
public class PromotionController implements PromotionFacade {
@Override
@RequestMapping(value = "/delete")
public String releasePromotion(@RequestParam int orderID){
return orderID+"-- hello!";
}
}
//facade層
public interface PromotionFacade {
/**
* 釋放門店優惠券
*/
String releasePromotion(@RequestParam int orderID);
}
好啦,這個啟動起來之後,就注冊到啦eureka中啦,等待被調用吧。
Feign調用簡單示例
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
## server
server.port=8083
##eureka
eureka.instance.instance-id=${spring.application.name}:${server.port}
eureka.client.serviceUrl.defaultZone=http://localhost:8081/eureka/
#租期更新時間間隔(3)
eureka.instance.leaseRenewalIntervalInSeconds=30
#租期到期時間(預設90秒)
eureka.instance.leaseExpirationDurationInSeconds=90
@SpringBootApplication
@EnableFeignClients(basePackages = { "trade.order.remote" })
@EnableEurekaClient
public class StartMain {
public static void main(String[] args) {
SpringApplication.run(StartMain.class, args);
}
}
調用類
//remote層
@FeignClient(name = "trade-promotion")
public interface PromotionClient {
@RequestMapping(value = "/Promotion/delete",method = RequestMethod.GET)
String releasePromotion(@RequestParam int orderID) ;
}
//controller 層
@RestController
@RequestMapping(value = "/promotion", method = RequestMethod.GET)
public class PromotionController {
@Autowired
PromotionClient promotionClient;
@RequestMapping(value = "/delete")
public String delete(@RequestParam int orderID) {
return promotionClient.releasePromotion(orderID);
}
}
note:
1.上述調用隻又remote就可以啦。
2.注意路由位址大小寫規範,不要以為自己很牛逼,一會大一會小,要我說,你很挫,一直小就可以啦。。
Feign 工作原理
- 在開發微服務應用時,我們會在主程式入口添加 @EnableFeignClients 注解開啟對 Feign Client 掃描加載處理。根據 Feign Client 的開發規範,定義接口并加 @FeignClients 注解。
- 當程式啟動時,會進行包掃描,掃描所有 @FeignClients 的注解的類,并将這些資訊注入 Spring IOC 容器中。當定義的 Feign 接口中的方法被調用時,通過JDK的代理的方式,來生成具體的 RequestTemplate。當生成代理時,Feign 會為每個接口方法建立一個 RequetTemplate 對象,該對象封裝了 HTTP 請求需要的全部資訊,如請求參數名、請求方法等資訊都是在這個過程中确定的。
- 然後由 RequestTemplate 生成 Request,然後把 Request 交給 Client 去處理,這裡指的 Client 可以是 JDK 原生的 URLConnection、Apache 的 Http Client 也可以是 Okhttp。最後 Client 被封裝到 LoadBalanceclient 類,這個類結合 Ribbon 負載均衡發起服務之間的調用。
@FeignClient 注解
- name:指定 Feign Client 的名稱,如果項目使用了 Eureka,name 屬性會作為微服務的名稱,用于服務發現。
- url:url 一般用于調試,可以手動指定 @FeignClient 調用的位址。
- decode404:當發生404錯誤時,如果該字段為 true,會調用 decoder 進行解碼,否則抛出 FeignException。
- configuration:Feign 配置類,可以自定義 Feign 的 Encoder、Decoder、LogLevel、Contract。
- fallback:定義容錯的處理類,當調用遠端接口失敗或逾時時,會調用對應接口的容錯邏輯,fallback 指定的類必須實作 @FeignClient 标記的接口。
- fallbackFactory:工廠類,用于生成 fallback 類示例,通過這個屬性我們可以實作每個接口通用的容錯邏輯,減少重複的代碼。
- path:定義目前 FeignClient 的統一字首。
Feign參數綁定
@PathVariable
/**
* 在服務提供者我們有一個方法是用直接寫在連結,SpringMVC中用的@PathVariable
* 這裡邊和SpringMVC中有些有一點點出入,SpringMVC中隻有一個參數而且參數名的話是不用額外指定參數名的,而feign中必須指定
*/
@RequestMapping(value = "/greet/{dd}",method = RequestMethod.GET)
String greetFeign(@PathVariable("dd") String dd);
@RequestParam
/**
* 這裡說下@RequestParam 注解和SpringMVC中差别也是不大,我認為差別在于Feign中的是參數進入URL或請求體中,
* 而SpringMVC中是參數從請求體中到方法中
* @param ids id串,比如“1,2,3”
* @return
*/
@RequestMapping(value = "/users",method = RequestMethod.GET)
public List<User> getUsersByIds(@RequestParam("ids") List<Long> ids);
@RequestHeader
/**
* 這裡是将參數添加到Headers中
* @param name 參數
*/
@RequestMapping(value = "/headers")
String getParamByHeaders(@RequestHeader("name") String name);
@RequestBody
/**
* 調用服務提供者的post方法,接收回來再被服務提供者丢回來
* @param user User對象
*/
@RequestMapping(value = "/user", method = RequestMethod.POST)
User getUserByRequestBody(@RequestBody User user);
Feign壓縮與日志
1.請求壓縮(Feign request/response compression)
##這兩行即可開啟壓縮
feign.compression.request.enabled=true
feign.compression.response.enabled=true
## 配置壓縮具體資訊
feign.compression.request.enabled=true
feign.compression.request.mime-types=text/xml,application/xml,application/json
feign.compression.request.min-request-size=2048
2. Feign日志(Feign logging)
Feign對日志的處理非常靈活,可為每個Feign用戶端指定日志記錄政策,每個Feign用戶端都會建立一個logger。預設情況下,logger的名稱是Feigh接口的完整類名。需要注意的是,Feign的日志列印隻會對Debug級别做出響應。
我們可以為每個Feign用戶端配置各種的Logger.Level對象,告訴Feign記錄哪些日志。Logger.Level的值有以下選擇。
- NONE,無記錄(DEFAULT)。
- BASIC,隻記錄請求方法和URL以及響應狀态代碼和執行時間。
- HEADERS,記錄基本資訊以及請求和響應标頭。
- FULL,記錄請求和響應的頭檔案,正文和中繼資料。
開啟記錄
logging.level.com.cnblogs.hellxz.client.EurekaServiceFeign: DEBUG
總結
多看文檔吧