springcloud 声明式调用客户端Feign
调用方,简化微服务api调用,feign是一种声明式,模板化的http客户端,简化http客户端开发,只需要创建一个接口和@注解 默认继承了ribbon,与eureka结合,实现了负载均衡。
项目创建
打开IDEA File>New>Project 创建新项目。
选择springboot 项目,点击next
填写项目基本信息,继续next,选择所需要的依赖,这里也可以不选,创建项目后再继续添加。
其中web是用于编写接口,eureka-client是需要向注册中心注册服务,openfeign则是本次所需依赖,用于远程调用其他服务,继续next.
填写项目名称和项目路径后点击Finish,项目搭建完成,结构如下。
pom文件如下
<?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 https://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.5.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.springcloud</groupId>
<artifactId>feign</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>feign</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>2020.0.3</spring-cloud.version>
</properties>
<dependencies>
<!--web api-->
<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>
<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>
接下来就是开始服务调用了,新建一个包service,包下新建一个HelloFeign的接口。
package com.springcloud.feign.service;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
@FeignClient(name = "hello-microservice")
public interface HelloFeign {
@RequestMapping("/hello")
String hi();
}
其中注解 @FeignClient(name = "hello-microservice") 表示这个接口会调用名称为 hello-microservice 的微服务,就是上一章中向注册中心注册的服务,@RequestMapping("/hello") 则是该服务提供的某一个接口,方法的传参和返回值和接口一致。
再创建一个测试controll,新建一个包,取名controll,包下创建一个类TestController。
package com.springcloud.feign.controller;
import com.springcloud.feign.service.HelloFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @program: feign
* @description:
* @author: Mr.Wang
* @create: 2021-06-16 14:05
**/
@RestController
public class TestController {
@Autowired
HelloFeign helloFeign;
@GetMapping("/hello")
public String hi() {
return this.helloFeign.hi();
}
}
其中有一个简单的get请求接口 "/hello" ,接口通过feign远程调用服务,返回一个字符串。
修改application.properties 文件
#服务名称
spring.application.name=feign-microservice
#端口
server.port=9001
#服务注册中心地址
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
# 是否从Eureka获取注册信息,缺省:true
# 这里需要向注册中心获取服务列表然后调用服务,所以需要值为true
eureka.client.fetch-registry=true
# 是否向注册中心注册自己,缺省:true
# 这里作为客户端api 需要向注册中心注册服务
eureka.client.register-with-eureka=true
项目搭建结束了,接下来开始测试接口。
首先启动项目 eureka服务注册中心,端口在8761。
此时显示服务列表还没有服务注册。
再启动项目Hello,端口为8001
此时注册中心多了一个服务
此时可以直接通过ip访问该服务 http://localhost:8001/hello,返回一个字符串。
这里访问是直接调用的,还没有通过eureka来进行调用,再启动项目feign,端口为9001。
此时注册中心多了一个名为feign-microservice的服务
此时访问http://localhost:9001/hello,接口返回字符串。
此时的调用关系则是服务feign 通过服务名hello-microservice 去服务注册中心找到一个名为 hello-microservice 的服务,然后调用接口"/hello",成功返回一个字符串,需要注意feign在微服务中不是必须的,只有你的服务需要调用其他服务接口时才需要,用于服务之间的相互远程调用,调用其他服务时通过服务名来查找,默认实现了负载均衡。
feign负载均衡,服务集群调用
每个微服务可以独立部署,当该服务请求过于频繁时,则需要集群部署,部署在不同机器上,调用服务时则默认轮询调用服务。
修改hello项目的接口,返回字符串时同时返回服务的端口。
启动服务,访问http://localhost:8001/hello,返回hello spring cloud 我是:8001,表示该服务在端口8001运行。
先修改idea,让其允许运行在不同端口上。
修改hello服务端口为 8002,启动服务,访问http://localhost:8002/hello,返回hello spring cloud 我是:8002,表示该服务在端口8002上运行,此时模拟了服务的集群部署。
此时该服务分别启动在8001和8002两个端口上。注册中心的服务列表中服务名为HELLO-MICROSERVICE显示有两个服务。
这时再不停访问 http://localhost:9001/hello 则会轮询返回不同值 hello spring cloud 我是:8001 和hello spring cloud 我是:8002,表示每次访问都被转发到了不同的服务中去了。
说明feign在调用服务时默认实现了负载均衡的。
评论区