前言:
Spring Cloud系列教程的所有博客均在下方的目錄鏈接中,方便大家查找和閱讀。建議按照順序學習,對於項目搭建有疑問的可以着重看目錄裏的第二篇博客。
Spring cloud學習專欄目錄
一、簡介
Feign是Netflix開發的聲明式的Http客戶端,使用時只需要創建一個接口,並在接口上添加註解就可以。Feign支持自帶的註解和JAX-RS註解等。Spring cloud對Feign進行了增強,Feign支持了Spring MVC的註解,並且整合了Ribbon和Eureka,從而讓Feign的使用更加方便。
二、對服務消費者添加Feign支持
問題回顧:
之前我們在服務消費者(車牌微服務)中是使用 RestTemplate調用REST服務,並且在啓動類中添加了RestTemplate的實例。通過使用feign我們就不需要使用RestTemplate了。
2.1 pom文件添加依賴
找到服務消費者的父工程的pom文件,添加feign的依賴。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
</parent>
<groupId>com.springcloud</groupId>
<artifactId>microservice-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>microservice-provide-user</module>
<module>microservice-consumer-ticket</module>
</modules>
<dependencyManagement>
<dependencies>
<!-- 導入Spring Cloud的依賴管理 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- web支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--springboot 整合eureka客戶端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--整合hystrix-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<!-- 健康監控 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- hystrix儀表盤 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<!--整合fegnin客戶端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 資源文件拷貝插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<!-- springboot插件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.2 創建接口UserFeignClient
在服務消費者中新創建一個包,這裏我起名爲com.spring.ticketservice.feign
新建一個接口名爲UserFeignClient,添加註解@FeignClient(value = " ") 其中value的值爲用戶微服務的application.name。接口的請求地址、返回值、參數等均參照UserController中定義的接口進行編寫。
package com.spring.ticketservice.feign;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.spring.ticketservice.pojo.User;
@FeignClient(value = "microservice-provide-user")
public interface UserFeignClient {
@RequestMapping(value = "/queryUserInfo/{id}", method = RequestMethod.GET)
public User queryUserInfo(@PathVariable("id") Long id);
}
2.3 修改服務消費者的service方法
刪除RestTemplate的注入,注入剛編寫好的UserFeignClient。
刪除原先調用用戶微服務接口的代碼,改爲調用UserFeignClient中的方法。
package com.spring.ticketservice.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.spring.ticketservice.feign.UserFeignClient;
import com.spring.ticketservice.pojo.User;
@Service
public class TicketService {
// @Autowired
// private RestTemplate restTemplate;
@Autowired
private UserFeignClient userFeignClient;
@Autowired
private LoadBalancerClient loadBalancerClient;
/*
* 查詢車票信息時查詢用戶的信息(這裏爲了簡化操作就不對車票信息進行查詢,直接去調用查詢用戶信息的接口)
*/
@HystrixCommand(fallbackMethod = "queryTicketInfoFallbackMethod")
public User queryTicketInfo(Long id) {
String serviceId = "microservice-provide-user";
ServiceInstance serviceInstance = this.loadBalancerClient.choose(serviceId);
//打印出請求了哪個端口的用戶微服務
System.out.println("請求了" + serviceInstance.getPort());
//向用戶微服務中的接口發送請求的地址
// String url = "http://microservice-provide-user/getUserInfo/"+ id;
// return restTemplate.getForObject(url, User.class);
return userFeignClient.queryUserInfo(id);
}
/*
* 處理請求失敗的方法
*/
public User queryTicketInfoFallbackMethod(Long id) {
User user = new User(0l,"出錯了");
return user;
}
}
2.4 修改服務消費者的啓動類
添加註解@EnableFeignClients,並且刪除先前RestTemplate對象的添加。
2.5 啓動服務進行測試
啓動Eureka微服務、用戶微服務、車票微服務。
訪問車票微服務中的接口,可以看到請求成功。
2.6 注意事項
2.6.1 註解的使用
編寫UserFeignClient時我們使用了註解@RequestMapping(value = “/queryUserInfo/{id}”, method = RequestMethod.GET),我們知道@GetMapping(value = “/queryUserInfo/{id}”)是一個組合註解,也就是說,這兩個其實是一樣的但是這裏不能使用@GetMapping這種組合註解否則啓動會報錯。
2.6.2 多參數構造及複雜參數構造
當你的傳參爲如下所示的對象User時,你需要使用post方法,如果你使用了get方法會報錯。因爲這種情況下他會默認以post方法進行提交,而你規定的時get方法所有就會有衝突。
如果你想使用get方法,那麼就把User對象中的參數一個一個寫出來加上@RequestParam註解就可以了
三、設置統一的Hystrix fallback接口
問題回顧:
之前我們寫fallback方法時是放在服務消費者(車票微服務)中的service類中。
但這樣太雜亂不利用統一的管理,現在我們要把fallback方法單獨拿出來放在一個類中。
3.1 修改服務消費者(車票微服務)的service方法
刪除@hystrix註解以及之前編寫的fallback方法
3.2 創建一個類TicketServiceFallback來管理fallback方法
新建一個包com.spring.ticketservice.fallback然後創建TicketServiceFallback類讓他實現UserFeignClient接口,添加@Component註解並實現其中的方法。其實也就是把之前刪掉的fallback方法移到了這裏。
package com.spring.ticketservice.fallback;
import com.spring.ticketservice.feign.UserFeignClient;
import com.spring.ticketservice.pojo.User;
@Component
public class TicketServiceFallback implements UserFeignClient{
@Override
public User queryUserInfo(Long id) {
User user = new User(0l,"出錯了");
return user;
}
}
3.3 修改UserFeignClient
3.4 修改配置文件
修改車票微服務的配置文件,開啓斷路器
# 配置api端口號
server.port=8082
# tomcat
server.tomcat.uri-encoding=UTF-8
# 服務名稱,也就是在eureka
spring.application.name=microservice-consumer-ticket
# 是否啓動註冊,這是一個客戶端需要註冊
eureka.client.register-with-eureka=true
# 是否檢索服務
eureka.client.fetch-registry=true
# 服務註冊中心的地址
eureka.client.service-url.default-zone=http://localhost:8761/eureka
#eureka.client.service-url.default-zone=http://admin:123456@localhost:8761/eureka
#開放所有的節點
management.endpoints.web.exposure.include=*
#顯示詳細的健康信息
management.endpoint.health.show-details=always
#開啓hystrix斷路器
feign.hystrix.enabled=true
3.5 啓動服務開始測試
啓動eureka微服務、用戶微服務、車票微服務。
首先訪問 http://localhost:8082/getTicketInfo/1 可以看到現在接口是正常的。
———————————————————————————————————
然後我們將用戶微服務停掉,再次訪問可以看到fallback方法是生效的