上一篇文章,讲述了Ribbon去做负载请求的服务消费者,本章讲述声明性REST客户端:Feign的简单使用方式

- Feign简介

Feign是一个声明式的Web服务客户端。这使得Web服务客户端的写入更加方便 。它具有可插拔注释支持,包括Feign注释和JAX-RS注释。Feign还支持可插拔编码器和解码器。Spring Cloud增加了对Spring MVC注释的支持,并HttpMessageConverters在Spring Web中使用了默认使用的相同方式。Spring Cloud集成了Ribbon和Eureka,在使用Feign时提供负载平衡的http客户端。

官方文档:http://cloud.spring.io/spring-cloud-static/Dalston.SR2/#spring-cloud-feign

- 准备工作

1.启动Consul,所有文章都将以Consul作为服务注册中心

2.创建 battcn-feign-hellobattcn-feign-hi

battcn-feign-hello

- pom.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</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>
</dependencies>

- BattcnFeignHelloApplication.java

1
2
3
4
5
6
7
8
@SpringBootApplication
@EnableDiscoveryClient
public class BattcnFeignHelloApplication { public static void main(String[] args) {
SpringApplication.run(BattcnFeignHelloApplication.class, args);
}
}

创建一个打招呼的的Controller

- HelloController.java

1
2
3
4
5
6
7
8
9
10
11
@RestController
@RequestMapping("/hello")
public class HelloController { @ResponseStatus(HttpStatus.OK)
@GetMapping
public String findStudentByName(@RequestParam("name") String name) {
// TODO:不做具体代码实现,只打印Log
return "挽歌- My Name's" + name;
}
}

- bootstrap.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server:
port: 8765 spring:
application:
name: battcn-feign-hello
cloud:
consul:
host: localhost
port: 8500
enabled: true
discovery:
enabled: true
prefer-ip-address: true

访问:http://localhost:8765/hello?name=Levin

结果:挽歌- My Name's Levin 表示我们第一个服务运行一切正常

battcn-feign-hi

- pom.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</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>
</dependencies>

- BattcnFeignHiApplication.java

1
2
3
4
5
6
7
8
9
@EnableDiscoveryClient
@EnableFeignClients(basePackages = {"com.battcn.client"})
@SpringBootApplication
public class BattcnFeignHiApplication { public static void main(String[] args) {
SpringApplication.run(BattcnFeignHiApplication.class, args);
}
}

- HelloClient.java

创建一个声明式FeignClient的接口 HelloClient

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@FeignClient(name = "battcn-feign-hello")
public interface HelloClient { /**
* 在新版本中,Feign 已经可以解析 RestFul 标准的接口API,比如GET POST DELETE PATCH PUT
* 旧版中
* @RequestMapping(method = RequestMethod.GET, value = "/hello")
* 或者是
* @RequestMapping(method = RequestMethod.POST, value = "/hello")
*
* 早期文章:http://blog.battcn.com/2017/07/07/springcloud-feign-analysis/
* /
@ResponseStatus(HttpStatus.OK)
@GetMapping("/hello")
String findStudentByName(@RequestParam("name") String name);
}

- HiController.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@RestController
@RequestMapping("/hi")
public class HiController { @Autowired
HelloClient helloClient; @ResponseStatus(HttpStatus.OK)
@GetMapping
public String find(@RequestParam("name") String name) {
// TODO:只是演示Feign调用的方法
return "Hi," + helloClient.findStudentByName(name);
}
}

- bootstrap.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server:
port: 8766 spring:
application:
name: battcn-feign-hi
cloud:
consul:
host: localhost
port: 8500
enabled: true
discovery:
enabled: true
prefer-ip-address: true

访问:http://localhost:8766/hi?name=Levin

结果:Hi,挽歌- My Name'sLevin 表示第二个服务(hi)通过FeignClient调用服务(hello)一切正常

- 源码分析

org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(Object... args),该方法的 args 就是我们传递的请求参数

InvocableHandlerMethod

feign.Target -> HardCodedTarget 解析出 FeignClient中的 name 形成VIP模式 GET http://battcn-feign-hello/hello?name=Levin HTTP/1.1 然后发送请求

HardCodedTarget

feign.SynchronousMethodHandler -> this.client.execute(request, this.options);

第一个就是:feign.Request的一些信息,比如headermethodbodyurl 等一些基本属性,因为这里是feign的Request所以我们servlet中的请求头是无法传递过来的(下篇会讲述这写小技巧)

第二个就是:connectTimeoutMillis 和 readTimeoutMillis 很多人肯定不陌生

SynchronousMethodHandler

通过三面三个步骤,我们不难看出 Feign 就是解析注解然后发送HTTP(阻断器,OKHTTP模式留到下篇),有兴趣的可以自己Debug(如果该处有错误也希望各位指正)

服务消费者(Feign-上)的更多相关文章

  1. SpringCloud学习系列之二 ----- 服务消费者(Feign)和负载均衡(Ribbon)使用详解

    前言 本篇主要介绍的是SpringCloud中的服务消费者(Feign)和负载均衡(Ribbon)功能的实现以及使用Feign结合Ribbon实现负载均衡. SpringCloud Feign Fei ...

  2. Spring Cloud学习笔记【三】服务消费者Feign

    Feign 是一个声明式的 Web Service 客户端,它的目的就是让 Web Service 调用更加简单.它整合了 Ribbon 和 Hystrix,从而让我们不再需要显式地使用这两个组件.F ...

  3. SpringCloud-创建服务消费者-Feign方式(附代码下载)

    场景 SpringCloud-服务注册与实现-Eureka创建服务注册中心(附源码下载): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/deta ...

  4. Spring Cloud(四)服务提供者 Eureka + 服务消费者 Feign

    上一篇文章,讲述了如何通过RestTemplate + Ribbon去消费服务,这篇文章主要讲述如何通过Feign去消费服务. Feign简介 Feign是一个声明式的伪Http客户端,它使得写Htt ...

  5. 服务消费者Feign和Ribbon的区别

    1.Ribbon通过注解@EnableEurekaClient/@EnableDiscoveryClient向服务中心注册:    PS:选用的注册中心是eureka,那么就推荐@EnableEure ...

  6. 创建服务消费者(Feign)

    概述 Feign 是一个声明式的伪 Http 客户端,它使得写 Http 客户端变得更简单.使用 Feign,只需要创建一个接口并注解.它具有可插拔的注解特性,可使用 Feign 注解和 JAX-RS ...

  7. 一起来学Spring Cloud | 第四章:服务消费者 ( Feign )

    上一章节,讲解了SpringCloud如何通过RestTemplate+Ribbon去负载均衡消费服务,本章主要讲述如何通过Feign去消费服务. 一.Feign 简介: Feign是一个便利的res ...

  8. 8、服务发现&服务消费者Feign

    spring cloud的Netflix中提供了两个组件实现软负载均衡调用,分别是Ribbon和Feign.上一篇和大家一起学习了Ribbon. Ribbon :Spring Cloud Ribbon ...

  9. Spring Cloud (4) 服务消费者-Feign

    Spring Cloud Feign Spring Cloud Feign 是一套基于Netflix Feign实现的声明式服务调用客户端.它使得编写Web服务客户端变得更加简单,我们只需要创建接口并 ...

  10. 玩转SpringCloud(F版本) 二.服务消费者(2)feign

    上一篇博客讲解了服务消费者的ribbon+restTemplate模式的搭建,此篇文章将要讲解服务消费者feign模式的搭建,这里是为了普及知识 平时的项目中两种消费模式选择其一即可 本篇博客基于博客 ...

随机推荐

  1. Java实现 LeetCode 729 我的日程安排表 I(二叉树)

    729. 我的日程安排表 I 实现一个 MyCalendar 类来存放你的日程安排.如果要添加的时间内没有其他安排,则可以存储这个新的日程安排. MyCalendar 有一个 book(int sta ...

  2. (Java实现) 细胞

    细胞 Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other) Total Submission(s ...

  3. java实现串的反转

    串的反转 反转串 我们把"cba"称为"abc"的反转串. 求一个串的反转串的方法很多.下面就是其中的一种方法,代码十分简洁(甚至有些神秘),请聪明的你通过给出 ...

  4. Java实现第十届蓝桥杯质数

    试题 D: 质数 本题总分:10 分 [问题描述] 我们知道第一个质数是 2.第二个质数是 3.第三个质数是 5--请你计算 第 2019 个质数是多少? [答案提交] 这是一道结果填空的题,你只需要 ...

  5. Charles(青花瓷/花瓶)的基本使用

    前言 Charles 其实是一款代理服务器,通过成为电脑或者浏览器的代理,然后截取请求和请求结果达到分析抓包的目的.其次该软件是用 Java 写的,能够在 Windows,Mac,Linux 上使用. ...

  6. iOS-Reactive Cocoa的常见用法

    今天是周末,临近年底,工作上遇到不可抗力,会有点一些变动!这多少会让人有一点静不下来,但需克制,Reactive Cocoa是今天的主角! 废话不多说,今天聊聊Reactive Cocoa的常见使用! ...

  7. Cacti断图、大量报错故障

    一.Cacti日志出现大量错误 最近查看Cacti日志,出现大量红色告警,并且每五分钟出现1次,虽然不影响流量的查看,但是肯定会有问题. 错误日志如下 ERROR: A DB Exec Failed! ...

  8. [Web][学习随笔]Session&cookie

    Session 从登录建立连接到退出就是一次会话.Session数据就会在会话期间用户存在服务器端的数据.这样,当用户在Web页之间跳转时,存储在Session对象中的变量将不会丢失,而是在整个用户会 ...

  9. pdf文件处理--QPDF

    1.分割pdf文件 从原文件中取出n-m页,保留原文件的目录格式: qpdf infile.pdf --pages . n-m -- outfile.pdf 从原文件中取出n-m页,不保留原文件的目录 ...

  10. 讨论session共享方案设计

    默认情况下,php的session文件是保存在磁盘文件中. 在php.ini配置文件中的配置项如下: session.save_handler = files session.save_path = ...