简介
openfeign 是一个服务调用的组件,用来实现两个服务之间的相互调用,Feign是一个声明式的Web服务客户端,让编写Web服务客户端变得非常容易,只需创建一个接口并在接口上申明注解。使用起来比传统的RestTemplate 更加简单。
使用
使用前阅读
由于openfeign 是只是服务调用,需要注册中心的先注册服务在可以被调用,本文注册中心使用的是eureka,当然也可以使用其它的注册中心,有兴趣的可以自行创建。
openfeign的使用方法很简单,只需要简答的配置就可以实现服务之间的调用,使用起来和传统的单体项目很相似,但是一般使用的过程中,openfeign要和 hystrix 一起使用,可以实现更加丰富的功能,本文主要是对openfeign 进行简单的使用。
springcloud-eureka-server 为注册中心
springcloud-openfeign-a: 服务调用端A
springcloud-openfeign-b: 服务调用端B
项目中使用
创建eureka服务注册中心,提供服务注册和发现,新建springBoot项目springcloud-eureka-server,并导入pom依赖:
<!-- eureka-server -->
<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-web</artifactId>
</dependency>
在启动类类上加注解:
@EnableEurekaServer
编写配置文件application.yml:
server:
port: 2222
eureka:
instance:
hostname: localhost #eureka服务端的实例名称
client:
#false表示不向注册中心注册自己(想注册也可以,不过没必要)
register-with-eureka: false
#false表示自己端就是注册中心,职责就是维护服务实例,并不需要去检索服务
fetch-registry: false
service-url:
#设置与eurekaServer交互的地址查询服务和注册服务都需要依赖这个地址
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
新建SpringBoot项目,服务调用端springcloud-openfeign-a,并导入pom文件:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- openfeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--工具包-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.5.4</version>
</dependency>
启动类上加注解
@EnableEurekaClient
@EnableFeignClients //开启Feign
编写测试用例DemoController:
@RestController
@RequestMapping("/demo")
public class DemoController {
@Value("${server.port}")
private String serverPort;
@Value("${spring.application.name}")
private String serverName;
@Autowired
BOpenFeignService bOpenFeignService;
@GetMapping("/getServerInfo/{name}")
public String getServerInfo(@PathVariable("name") String name) {
if (StrUtil.isBlank(name)) {
return "请输入请求数据!";
}
String result = "当前服务器:" + serverName + " 端口号:" + serverPort + " 时间戳:" + DateUtil.now();
;
if (!"a".equalsIgnoreCase(name)) {
result += "<br>目标服务器:<br>" + bOpenFeignService.getServerInfo(name);
}
return result;
}
@GetMapping("/test/threadSleep/{seconds}")
public String threadSleep(@PathVariable("seconds")Long seconds){
try {
TimeUnit.SECONDS.sleep(seconds);
}catch (Exception e){
e.printStackTrace();
}
return "执行完成!";
}
}
编写openfeign 的服务调用service:
@Component
@FeignClient(value = "SPRINGCLOUD-OPENFEIGN-B") //value是另一个项目的服务名
public interface BOpenFeignService {
@GetMapping("/demo/getServerInfo/{name}")
@ResponseBody
public String getServerInfo(@PathVariable("name") String name);
}
编写配置文件application.yml:
server:
port: 3333
spring:
application:
name: springcloud-openfeign-a
eureka:
client:
#true表示向注册中心注册自己,默认为true
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
defaultZone: http://localhost:2222/eureka
新建SpringBoot项目,服务调用端springcloud-openfeign-b,并导入pom文件:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- openfeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--工具包-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.5.4</version>
</dependency>
启动类上加注解
@EnableEurekaClient
@EnableFeignClients //开启Feign
编写测试用例DemoController:
@RestController
@RequestMapping("/demo")
public class DemoController {
@Value("${server.port}")
private String serverPort;
@Value("${spring.application.name}")
private String serverName;
@Autowired
AOpenFeignService aOpenFeignService;
@GetMapping("/getServerInfo/{name}")
public String getServerInfo(@PathVariable("name") String name) {
if (StrUtil.isBlank(name)) {
return "请输入请求数据!";
}
String result = "当前服务器:" + serverName + " 端口号:" + serverPort + " 时间戳:" + DateUtil.now();
;
if (!"b".equalsIgnoreCase(name)) {
result += "<br>目标服务器:<br>" + aOpenFeignService.getServerInfo(name);
}
return result;
}
@GetMapping("/test/threadSleep/{seconds}")
public String threadSleep(@PathVariable("seconds") Long seconds){
return aOpenFeignService.threadSleep(seconds);
}
}
编写openfeign 的服务调用service:
@Component
@FeignClient(value = "SPRINGCLOUD-OPENFEIGN-A")
public interface AOpenFeignService {
@GetMapping("/demo/getServerInfo/{name}")
@ResponseBody
public String getServerInfo(@PathVariable("name") String name);
@GetMapping("/demo/test/threadSleep/{seconds}")
public String threadSleep(@PathVariable("seconds") Long seconds);
}
编写配置文件application.yml:
server:
port: 5555
spring:
application:
name: springcloud-openfeign-b
eureka:
client:
#true表示向注册中心注册自己,默认为true
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
defaultZone: http://localhost:2222/eureka
feign:
client:
config:
default:
#建立连接所用的时间,适用于网络状况正常的情况下,两端连接所需要的时间
ConnectTimeOut: 5000
#指建立连接后从服务端读取到可用资源所用的时间
ReadTimeOut: 5000
启动项目
依次启动项目
springcloud-eureka-server ,springcloud-openfeign-a,springcloud-openfeign-b
检测注册中心是否有服务
访问:
如下图,可以看到两个服务已经被注册进来了
a 调用 a:
a 调用 b:
b 调用 a 发生超时:
springcloud-openfeign-b 中加入 openfeign超时配置application.yml:
feign:
client:
config:
default:
#建立连接所用的时间,适用于网络状况正常的情况下,两端连接所需要的时间
ConnectTimeOut: 7000
#指建立连接后从服务端读取到可用资源所用的时间
ReadTimeOut: 7000
再次调用:
项目地址
git@gitee.com:anxc/study-demo-eureka.git