1. 程式人生 > >Spring Cloud學習系列第二章:使用Feign呼叫服務

Spring Cloud學習系列第二章:使用Feign呼叫服務

一、Feign簡介

  Feign是一個宣告式的Web服務客戶端。這使得Web服務客戶端的寫入更加方便 要使用Feign建立一個介面並對其進行註釋。它具有可插入註釋支援,包括Feign註釋和JAX-RS註釋。Feign還支援可插拔編碼器和解碼器。Spring Cloud增加了對Spring MVC註釋的支援,並使用Spring Web中預設使用的HttpMessageConvertersSpring Cloud整合Ribbon和Eureka以在使用Feign時提供負載均衡的http客戶端。

  上面這段話是官方文件,說的有些囉嗦,簡單來說,就是Feign幫我們準備了一套呼叫Spring Cloud註冊服務中心裡面的服務,不用再去使用Apache httpclient之類的http客戶端工具了,還提供了很多功能,編解碼、負載均衡等。

二、建立Feign專案

我們的目的是使用上一章釋出的服務,而且是到Eureka Server中去訪問服務,所以我們的Feign專案就是比Eureka Server專案多一個Feign的依賴,內容如下。

<?xml version="1.0" encoding="UTF-8"?>
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.nan</groupId>
	<artifactId>feigndemo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>feigndemo</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.6.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
		<spring-cloud.version>Dalston.SR2</spring-cloud.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-feign</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka</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>${spring-cloud.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>


</project>

  專案啟動入口要啟用Feign client,內容如下。

package com.nan.feigndemo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class FeigndemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(FeigndemoApplication.class, args);
    }

}

  接下來就要宣告Feign客戶端了,目的就是指向我們釋出的服務,首先看內容。

package com.nan.feigndemo.client;

import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@FeignClient("HelloService")
public interface HelloServiceClient {

    @RequestMapping("/hello")
    String hello(@RequestParam("name") String name);

}

  很明顯,這是一個interface,是一個宣告式使用方式。重要的註解,FeignClient,"HelloService"屬性就是我們釋出的服務的spring.application.name。下面的介面方法就和我們釋出的Rest介面一致了,另外RequestMapping不要用在interface上,不然會被spring mvc容器掃描到。

  然後編寫我們自己的專案業務,呼叫這個客戶端,內容如下。

package com.nan.feigndemo.controller;

import com.nan.feigndemo.client.HelloServiceClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class FeignDemoController {

    @Autowired
    private HelloServiceClient helloServiceClient;

    @RequestMapping("/feigndemo")
    public String feignDemo(@RequestParam("name") String name) {
        return helloServiceClient.hello(name);
    }

}

  簡單的controller,就不多廢話了。重要的是下面的專案配置。

server:
  port: 8080
spring:
  application:
    name: FeignDemo
eureka:
  client:
    serviceUrl:
      defaultZone: http://node01:8081/eureka/,http://node02:8082/eureka/

 server.port和application.name是我們專案自己的,eureka.client.serviceUrl就是我們的Eureka Server叢集模式的地址,然後啟動專案,記得Eureka server和HelloService也要啟動。然後瀏覽器訪問我們的feigndemo專案,瀏覽器輸入http://localhost:8080/feigndemo?name=秦始皇,瀏覽器會出現 Hello 秦始皇, this client port is 9091,再重新整理頁面,會出現 Hello 秦始皇, this client port is 9092。OK,服務呼叫,負載均衡都已實現,真是太佩服他們了,一步一步簡化我們的開發。

  以上就是筆者目前所學,還是很初級的內容,如果有什麼錯誤和遺漏,還請見諒並指正,不勝感激。