Spring Cloud 学习 | - 05 - 服务消费(Feign方式)

本文介绍如何使用Feign简化Spring Cloud应用中的服务消费过程,通过声明式接口实现HTTP API调用,支持负载均衡。

Spring Cloud 学习 | - 05 - 服务消费(Feign方式)

学习 Spring Cloud 之路,文中 Spring Boot 版本为 2.1.3.RELEASESpring Cloud 版本为 Greenwich.SR1 。因能力有限,难免会有不足或者错误之处,还望不吝指正,谢!

之前 Spring Cloud 学习 | - 03 - 服务消费(Rest + Ribbon实现负载均衡),我们使用Rest+Ribbon方式实现消费的负载均衡。如果只是这样,那么以后我们可能需要编写大量重复代码,而且格式基本相同,只是参数不同罢了,能不能有一种更优雅简洁的方式实现呢?我们可以用Feign方式实现。

1. Feign简介

Feign是Netflix开发的声明式、模块化的HTTP客户端。Feign可以帮助我们更加便捷、优雅的调用HTTP API, 可以做到使用HTTP请求远程服务时能与调用本地方法一样的编码体验,完全感知不到这是远程方法,更感知不到这是个HTTP请求。
在Spring Cloud中,使用Feign非常简单——创建一个接口,并在接口上添加一些注解,代码便完成了。Feign支持多种注解,礼服Feign自带的注解或JAX-RS注解等。
Spring Cloud对Feign进行了增强,使Feign支持了Spring MVC注解,并整合了RIbbon和Eureka,从而让Feign的使用更加方便。

2. 启动Eureka注册中心

详细请查阅Spring Cloud 学习 | - 01 - Eureka服务注册与发现一文。

3. 启动服务提供者

3.1 修改提供者Service

Service接口:

public interface UserService {
    /**
     * 查询所有用户
     * @return
     */
    List findAll();

    /**
     * hello,${name}
     * @param name
     * @return
     */
    String hello(String name);
}

实现类:

@Service
public class UserServiceImpl implements UserService {
    /**
     * 查询所有用户
     * @return
     */
    @Override
    public List findAll() {
        List list = Arrays.asList("Cindy","Pony","Marry");
        return list;
    }

    @Override
    public String hello(String name) {
        return "Hello, " + name;
    }
}

3.2 修改提供者Controller

代码如下:

@RestController
@RequestMapping("/user")
public class UserController {
    @Value("${server.port}")
    private String port;
    @Autowired
    private UserService userService;

    private Map<String, Object> data = null;

    @GetMapping("/{name}")
    public Map<String, Object> hello(@PathVariable String name) {
        String hello = userService.hello(name);
        data = new HashMap<>(4);
        data.put("port", port);
        data.put("msg", hello);
        return data;
    }
}

3.3 启动2个服务提供者

启动2个user-provider服务,端口分别为8090和8091,详细步骤请参阅https://blog.youkuaiyun.com/xudc0521/article/details/88878904#31_2_181

4. Feign方式服务消费者

4.1 新建项目及其依赖

利用Spring Initializr快速创建一个Spring Boot项目,主要依赖如下:

		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

4.2 启用Feign功能

在XxxApplication主启动类上加上注解@EnableFeignClients,同时也要加上服务发现的注解@EnableDiscoveryClient,完整代码如下:

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients // 启用Feign功能
public class UserConsumerFeignApplication {

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

}

4.3 编写Feign客户端

新建一个接口UserService,修改代码如下:

@FeignClient("user-provider")
public interface UserService {
    /**
     * hello,${name}
     * @param name
     * @return
     */
    @GetMapping("/user/{name}")
    Map<String, Object> hello(@PathVariable String name);
}
  • 首先这是一个接口,Feign会通过动态代理,帮我们生成实现类
  • @FeignClient()声明这是一个Feign客户端,value值指定服务提供者名称,即调用哪个服务
  • 接口中的定义方法,完全采用SpringMVC的注解,Feign会根据注解帮我们生成URL,并访问获取结果

4.4 测试接口

添加一个Junit方法测试,代码如下:

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserConsumerFeignApplicationTests {

    @Autowired
    private UserService userService;

    @Test
    public void contextLoads() {
        for (int i = 0; i < 10; i++) {
            Map<String, Object> map = userService.hello("Cindy" + i);
            System.err.println(map);
        }
    }
}

输出结果:
在这里插入图片描述

4.5 负载均衡

Feign中本身已经集成了Ribbon依赖和自动配置,默认实现了负载均衡。
在这里插入图片描述
因此我们不需要额外引入依赖,也不需要再注册RestTemplate对象。

`spring-cloud-starter-feign` 是早期版本中使用的依赖名称,但在 Spring Cloud 的后续版本中已经被废弃。取而代之的是 `spring-cloud-starter-openfeign`[^3]。 如果需要在 Maven 项目中引入 OpenFeign 支持,则应在项目的 `pom.xml` 文件中添加如下依赖: ```xml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> ``` 需要注意的是,OpenFeign 已经成为 Spring Cloud 的一部分,并且默认集成了与 Spring Boot 和 Spring MVC 的良好兼容性。因此无需再单独寻找 `spring-cloud-starter-feign` 这一旧版依赖[^4]。 此外,为了确保项目的正常运行,还需要确认所使用的 Spring Cloud 版本号是否匹配当前的 Spring Boot 版本。可以在 `pom.xml` 中定义 Spring Cloud BOM(Bill of Materials),以便管理所有相关依赖的版本一致性。例如: ```xml <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR12</version> <!-- 替换为适合您项目的版本 --> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> ``` 最后,当使用 Feign 或 OpenFeign 时,通常会结合 Eureka 或 Consul 等服务注册中心来实现动态的服务发现功能。这可以通过启用相应的注解完成,比如 `@EnableDiscoveryClient` 或者 `@EnableEurekaClient`。 ### 示例代码 以下是完整的 Maven 配置示例: ```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>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.5</version> <!-- 根据实际需求调整版本 --> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <java.version>11</java.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR12</version> <!-- 使用合适的 Spring Cloud 版本 --> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-httpclient</artifactId> </dependency> </dependencies> </project> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值