万隆的笔记 万隆的笔记
博文索引
笔试面试
  • 在线学站

    • 菜鸟教程 (opens new window)
    • 入门教程 (opens new window)
    • Coursera (opens new window)
  • 在线文档

    • w3school (opens new window)
    • Bootstrap (opens new window)
    • Vue (opens new window)
    • 阿里开发者藏经阁 (opens new window)
  • 在线工具

    • tool 工具集 (opens new window)
    • bejson 工具集 (opens new window)
    • 文档转换 (opens new window)
  • 更多在线资源
  • Changlog
  • Aboutme
GitHub (opens new window)
博文索引
笔试面试
  • 在线学站

    • 菜鸟教程 (opens new window)
    • 入门教程 (opens new window)
    • Coursera (opens new window)
  • 在线文档

    • w3school (opens new window)
    • Bootstrap (opens new window)
    • Vue (opens new window)
    • 阿里开发者藏经阁 (opens new window)
  • 在线工具

    • tool 工具集 (opens new window)
    • bejson 工具集 (opens new window)
    • 文档转换 (opens new window)
  • 更多在线资源
  • Changlog
  • Aboutme
GitHub (opens new window)
  • 快速开始

  • 服务注册与发现

    • 服务注册与发现
    • 服务提供者
    • 服务消费者 - Ribbon
    • 服务消费者 - Feign
      • 概述
      • Feign简介
      • 准备工作
      • 创建服务消费者
      • 测试访问
  • 服务熔断

  • 服务网关

  • 配置中心

  • 服务追踪

  • SpringCloud-Netflix
  • 服务注册与发现
2021-08-29
目录

服务消费者 - Feign

# 服务消费者 - Feign

# 概述

在微服务架构中,业务都会被拆分成一个独立的服务,服务与服务的通讯基于多种跨进程的方式进行通信协作,而在Spring Cloud架构中比较常见的跨进程的方式是RESTful HTTP请求和RPC调用。这两种方式的实现方案有:

  • RESTful HTTP请求:Ribbon + RestTemplate,
  • RPC调用:Feign。

这一篇文章讲解下基于 Feign的通信方式。

# Feign简介

Feign是一种负载均衡的HTTP客户端, 使用Feign调用API就像调用本地方法一样,避免了调用目标微服务时,需要不断的解析/封装json 数据的繁琐。Feign集成了Ribbon。Ribbon+Eureka是面向微服务编程,而Feign是面向接口编程。

Feign 是一个声明式的伪 HTTP 客户端,它使得编写Web服务客户端 客户端变得更简单。使用 Feign,只需要创建一个接口并对它进行注解。它具有可插拔的注解特性,可使用 Feign 注解和 JAX-RS 注解,Feign 支持可插拔的编码器和解码器。Feign 默认集成了 Ribbon,并和 Eureka 结合,默认实现了负载均衡的效果。Spring Cloud 增加了对 Spring MVC的注解,Spring Web 默认使用了HttpMessageConverters, Spring Cloud 集成 Ribbon 和 Eureka 提供的负载均衡的HTTP客户端 Feign。

  • Feign 采用的是基于接口的注解
  • Feign 整合了 Ribbon

# 准备工作

演示案例方案和服务提供者集群,同服务消费者 - Ribbon,只是更改了服务的通信方式,这里不赘述。

# 创建服务消费者

创建一个工程名为 hello-spring-cloud-netflix-consumer-feign 的服务消费者项目,目的通过Feign接口的方式调用服务提供者的http://hello-spring-cloud-netflix-provider:8762/hi?msg=HelloProvider接口,并能够体现Feign的负载均衡机制。

# POM

pom.xml 配置如下:

<?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>

    <parent>
        <groupId>com.example</groupId>
        <artifactId>hello-spring-cloud-netflix-dependencies</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <relativePath>../hello-spring-cloud-netflix-dependencies/pom.xml</relativePath>
    </parent>

    <artifactId>hello-spring-cloud-netflix-consumer-feign</artifactId>
    <packaging>jar</packaging>

    <dependencies>
        <!-- Spring Boot Begin -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- Spring Boot End -->

        <!-- Spring Cloud Begin -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!-- Spring Cloud End -->

        <!-- 解决 thymeleaf 模板引擎一定要执行严格的 html5 格式校验问题 -->
        <dependency>
            <groupId>net.sourceforge.nekohtml</groupId>
            <artifactId>nekohtml</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <mainClass>com.example.hello.spring.cloud.netflix.consumer.feign.FeignConsumerApplication</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

与服务消费者 - Ribbon对比,这里主要是将spring-cloud-starter-netflix-ribbon移除,引入了spring-cloud-starter-openfeign依赖。

# Application

由于是消费者,同样需要开启 @EnableDiscoveryClient 配置,让消费者去到Eureka Server发现服务。此外,还需要使用 @EnableFeignClients 配置开启 Feign 功能。

package com.example.hello.spring.cloud.netflix.consumer.feign;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@EnableHystrixDashboard
public class FeignConsumerApplication {

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

}

# application.yml

配置Eureka Server地址,设置程序端口号为:8765

spring:
  application:
    name: hello-spring-cloud-netflix-consumer-feign
  thymeleaf:
    cache: false
    mode: LEGACYHTML5
    encoding: UTF-8
    servlet:
      content-type: text/html

server:
  port: 8765

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

# Feign Interface

使用Feign只需要编写接口并且使用@FeignClient("服务名")注解来指定调用哪个服务,

与Ribbon对比:

  1. 不需要编写ConfigurationBean,配置注入 RestTemplate
  2. 不需要将服务提供者提供的接口封装在一个Service,使用RestTemplate调用接口。
package com.example.hello.spring.cloud.netflix.consumer.feign.service;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@FeignClient(value = "hello-spring-cloud-netflix-provider")
public interface ProviderClient {

    @GetMapping(value = "hi")
    public String sayHi(@RequestParam(value = "msg", required = false) String msg);

}

注意,Feign接口的方法的签名需要跟服务方的提供的服务方法签名一致,否则无法调用。

# ControllerTest

package com.example.hello.spring.cloud.netflix.consumer.feign.ctrl;

import com.example.hello.spring.cloud.netflix.consumer.feign.service.ProviderClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class FeignConsumerCtrl {

    @Autowired
    private ProviderClient providerClient;

    @GetMapping(value = "hi")
    public String sayHi(@RequestParam(value = "msg", required = false) String msg) {
        return providerClient.sayHi(msg);
    }

}

# 测试访问

在浏览器上多次访问 http://localhost:8765/hi?msg=HelloFeign

浏览器交替显示:

Hi,your message is :"HelloFeign" i am from port:8762
Hi,your message is :"HelloFeign" i am from port:8763

请求成功则表示我们已经成功通过Feign实现了负载均衡访问不同端口的实例。

上次更新: 5/30/2023, 12:51:40 AM
服务雪崩效应

服务雪崩效应→

最近更新
01
Vue-Ajax
06-13
02
2025
01-15
03
Elasticsearch面试题
07-17
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式