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,然后按照下面步驟編寫代碼即可。

  1. 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>
  1. 啟動類代碼

啟動類添加注解@EnableEurekaServer即可,代碼如下:

@EnableEurekaServer
@SpringBootApplication
public class SpringCloudEurekaApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringCloudEurekaApplication.class, args);
    }
}
  1. 配置文件

使用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,表示不去檢索其他的服務,因為服務注冊中心本身的職責就是維護服務實例,它也不需要去檢索其他服務
  1. 運行截圖

打開瀏覽器訪問http://localhost:9001/,可以看到注冊中心以及啟動,運行截圖如下:


注冊中心運行截圖

三、服務提供者

服務注冊中心有了之后,我們可以向這個服務注冊中心注冊一個服務提供者,新建一個SpringBoot項目,命名spring-cloud-user-service,提供用戶查詢服務,然后按照下面步驟編寫代碼即可。

  1. 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>
  1. 啟動類代碼

啟動類添加注解@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);
    }
  1. 配置文件

使用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,然后按照下面步驟編寫代碼即可。

  1. 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>
  1. 啟動類代碼

添加@EnableFeignClients注解,就代表啟啟用feign客戶端。

啟動類添加注解@EnableEurekaClient,也注冊到注冊中心,代碼如下:

@EnableEurekaClient
@EnableFeignClients
@SpringBootApplication
public class SpringCloudConsumerFeginApplication {

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

}
  1. 使用注解@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
  1. 添加一個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);
    }
}
  1. 配置文件

使用yml的配置文件,application.yml配置如下:

server:
  port: 8083 #服務端口
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:9001/eureka/
spring:
  application:
    name: fegin-consumer

五、服務調用實戰

  1. 啟動服務中心並注冊服務

代碼編寫之后,按順序啟動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
  1. 服務調用

打開瀏覽器訪問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、Redis、MongoDB、MySQL、Zookeeper、Spring Cloud、Dubbo/Kafka、Hadoop、Hbase、Flink等高並發分布式、大數據、機器學習等技術。
關注下方公眾號即可免費領取:

Java碎碎念公眾號Java碎碎念公眾號

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM