SpringCloud系列-利用Feign實現宣告式服務呼叫
上一篇文章《手把手帶你利用Ribbon實現客戶端的負載均衡》介紹了消費者通過Ribbon呼叫服務實現負載均衡的過程,裡面所需要的引數需要在請求的URL中進行拼接,但是引數太多會導致拼接字串的效率低下,本文將介紹一種更好的方案,利用Feign實現宣告式服務呼叫。
本文目錄
一、Feign簡介二、搭建註冊中心三、服務提供者四、Feign服務消費者五、服務呼叫實戰
一、Feign簡介
Feign是一個宣告式的Web Service客戶端,它的目的就是讓Web Service呼叫更加簡單。
Feign提供了HTTP請求的模板,通過編寫簡單的介面和插入註解,就可以定義好HTTP請求的引數、格式、地址等資訊,而Feign則會完全代理HTTP請求,我們只需要像呼叫方法一樣呼叫它就可以完成服務請求及相關處理。
總起來說,Feign具有如下特性:
- 可插拔的註解支援,包括Feign註解和JAX-RS註解;
- 支援可插拔的HTTP編碼器和解碼器;
- 支援Hystrix和它的Fallback;
- 支援Ribbon的負載均衡;
- 支援HTTP請求和響應的壓縮。
二、搭建註冊中心
首先新建一個SpringBoot專案,命名spring-cloud-eureka,然後按照下面步驟編寫程式碼即可。
- pom.xml程式碼
新增eureka-server的依賴,程式碼如下:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.RELEASE</version><!-- eureka版本 -->
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
- 啟動類程式碼
啟動類添加註解@EnableEurekaServer即可,程式碼如下:
@EnableEurekaServer
@SpringBootApplication
public class SpringCloudEurekaApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudEurekaApplication.class, args);
}
}
- 配置檔案
使用yml的配置檔案,application.yml配置如下:
server:
port: 9001 #服務埠
eureka:
instance:
hostname: localhost
client:
register-with-eureka: false #是否將eureka自身作為應用註冊到eureka註冊中心
fetch-registry: false #為true時,可以啟動,但報異常:Cannot execute request on any known server
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
配置項說明:
1. server.port=9001表示設定該服務註冊中心的埠號
2. eureka.instance.hostname=localhost表示設定該服務註冊中心的hostname
3. eureka.client.register-with-eureka=false,由於我們目前建立的應用是一個服務註冊中心,而不是普通的應用。預設情況下,這個應用會向註冊中心(也是它自己)註冊它自己,設定為false表示禁止這種預設行為
4. eureka.client.fetch-registry=false,表示不去檢索其他的服務,因為服務註冊中心本身的職責就是維護服務例項,它也不需要去檢索其他服務
- 執行截圖
開啟瀏覽器訪問http://localhost:9001/,可以看到註冊中心以及啟動,執行截圖如下:
註冊中心執行截圖
三、服務提供者
服務註冊中心有了之後,我們可以向這個服務註冊中心註冊一個服務提供者,新建一個SpringBoot專案,命名spring-cloud-user-service,提供使用者查詢服務,然後按照下面步驟編寫程式碼即可。
- pom.xml程式碼
新增eureka-client的依賴,程式碼如下:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.60</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.RELEASE</version><!-- eureka版本 -->
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
- 啟動類程式碼
啟動類添加註解@EnableEurekaClient即可,程式碼如下:
@EnableEurekaClient
@SpringBootApplication
public class UserServiceDemoApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceDemoApplication.class, args);
}
}
新增一個提供使用者服務的UserController,程式碼如下:
/**
* 使用者服務
*/
@Slf4j
@RestController
@RequestMapping("/provider")
public class UserController {
static Map<Integer, User> userMap = new HashMap<>();
static {
//模擬資料庫
User user1 = new User(1, "張三", "123456");
userMap.put(1, user1);
User user2 = new User(2, "李四", "123123");
userMap.put(2, user2);
}
/**
* 根據id 查詢
*/
@RequestMapping("/getUser")
public String getUser(Integer id) {
log.info("呼叫getUser介面,id={}",id);
User user = userMap.get(id);
return JSON.toJSONString(user);
}
- 配置檔案
使用yml的配置檔案,application.yml配置如下:
server:
port: 8100 #服務埠
eureka:
client:
serviceUrl:
defaultZone: http://localhost:9001/eureka/
spring:
application:
name: user-service
四、Feign服務消費者
首先新建一個SpringBoot專案,命名spring-cloud-consumer-fegin,然後按照下面步驟編寫程式碼即可。
- pom.xml程式碼
新增eureka-client的依賴,程式碼如下:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<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>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.RELEASE</version><!-- eureka版本 -->
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
- 啟動類程式碼
新增@EnableFeignClients註解,就代表啟啟用feign客戶端。
啟動類添加註解@EnableEurekaClient,也註冊到註冊中心,程式碼如下:
@EnableEurekaClient
@EnableFeignClients
@SpringBootApplication
public class SpringCloudConsumerFeginApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudConsumerFeginApplication.class, args);
}
}
- 使用註解@FeignClient 定義feign客戶端
下面將定義了一個feign客戶端,將遠端服務http://user-service//provider/getUser對映為一個本地Java方法呼叫。
IFeginService介面程式碼如下:
//表示"user-service"的服務 提供
@FeignClient(value = "user-service")
public interface IFeginService {
@RequestMapping(value = "/provider/getUser")
public String getUser(@RequestParam("id") Integer id);
}
註解說明:
@FeignClient
屬性名 | 預設值 | 作用 |
---|---|---|
value | 空字串 | 呼叫服務名稱,和name屬性相同 |
name | 空字串 | 呼叫服務名稱,和value屬性相同 |
url | 空字串 | 全路徑地址或hostname,http或https可選 |
path | 空字串 | 自動給所有方法的requestMapping前加上字首,類似與controller類上的requestMapping |
- 新增一個Controller
新增一個Controller,使用註解@Autowired使用上面所定義feign的客戶端,用於呼叫服務提供者。
@RestController
@RequestMapping("/consumer")
public class FeginController {
@Autowired
private IFeginService feginService;
@GetMapping("/getUser")
public String getUser(Integer id) {
return feginService.getUser(id);
}
}
- 配置檔案
使用yml的配置檔案,application.yml配置如下:
server:
port: 8083 #服務埠
eureka:
client:
serviceUrl:
defaultZone: http://localhost:9001/eureka/
spring:
application:
name: fegin-consumer
五、服務呼叫實戰
- 啟動服務中心並註冊服務
程式碼編寫之後,按順序啟動spring-cloud-eureka、spring-cloud-user-service和spring-cloud-consumer-fegin,先訪問註冊中心http://localhost:9001/,出現下圖說明註冊中心和兩個服務已經註冊成功。
註冊中心執行截圖
啟動spring-cloud-user-service時候啟動兩個服務8100,啟動命令如下:
java -jar spring-cloud-user-service-0.0.1-SNAPSHOT.jar --server.port=8100
- 服務呼叫
開啟瀏覽器訪問http://localhost:8083/consumer/getUser?id=1,訪問成功後截圖如下:
請求成功截圖
到此SpringCloud整合Feign呼叫服務的過程已經全部實現,有問題歡迎留言溝通哦!
完整原始碼地址: https://github.com/suisui2019/springboot-study
推薦閱讀
1.手把手帶你利用Ribbon實現客戶端的負載均》
2.SpringCloud搭建註冊中心與服務註冊
3.SpringCloud實現服務間呼叫(RestTemplate方式)
4.別在 Java 程式碼裡亂打日誌了,這才是正確的打日誌姿勢!
5.編碼神器Lombok,學會後開發效率至少提高一倍!
Java碎碎念公眾號限時領取免費Java相關資料,涵蓋了Java、Redis、MongoDB、MySQL、Zookeeper、Spring Cloud、Dubbo/Kafka、Hadoop、Hbase、Flink等高併發分散式、大資料、機器學習等技術。
關注下方公眾號即可免費領取: