Spring Cloud(4):Feign的使用
基于上一篇文章:https://www.cnblogs.com/xuyiqing/p/10867739.html
使用Ribbon实现了订单服务调用商品服务的Demo
下面介绍如何使用Feign实现这个Demo
Feign:伪RPC客户端,底层基于HTTP
在订单服务的POM中加入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
并在启动类中加入注解,这里已经加入的Ribbon可以保留
package org.dreamtech.orderservice; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate; @SpringBootApplication
@EnableFeignClients
public class OrderServiceApplication { public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class, args);
} @Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
Feign接口
package org.dreamtech.orderservice.service; import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; @FeignClient(name = "product-service")
public interface ProductClient {
@RequestMapping("/api/product/find")
String findById(@RequestParam(value = "id")int id);
}
使用
package org.dreamtech.orderservice.service.impl; import com.fasterxml.jackson.databind.JsonNode;
import org.dreamtech.orderservice.domain.ProductOrder;
import org.dreamtech.orderservice.service.ProductClient;
import org.dreamtech.orderservice.service.ProductOrderService;
import org.dreamtech.orderservice.utils.JsonUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate; import java.util.Date;
import java.util.Map;
import java.util.UUID; @Service
public class ProductOrderServiceImpl implements ProductOrderService { private final ProductClient productClient; @Autowired
public ProductOrderServiceImpl(ProductClient productClient) {
this.productClient = productClient;
} @Override
public ProductOrder save(int userId, int productId) { String response = productClient.findById(productId);
JsonNode jsonNode = JsonUtils.str2JsonNode(response); ProductOrder productOrder = new ProductOrder();
productOrder.setCreateTime(new Date());
productOrder.setUserId(userId);
productOrder.setTradeNo(UUID.randomUUID().toString()); productOrder.setProductName(jsonNode.get("name").toString());
productOrder.setPrice(Integer.parseInt(jsonNode.get("price").toString())); return productOrder;
}
}
工具类
package org.dreamtech.orderservice.utils; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; public class JsonUtils { private static final ObjectMapper objectMapper = new ObjectMapper(); public static JsonNode str2JsonNode(String str) {
try {
return objectMapper.readTree(str);
} catch (IOException e) {
return null;
}
}
}
重启Eureka Server和多个product-service:
访问http://localhost:8781/api/order/save?user_id=1&product_id=1,成功
使用注意:
1.Feign的路由和服务的路由必须一致(如这里的/api/product/find)
2.注意服务名的一致
3.参数必须加入@RequestParam确保参数名和服务的一致
4.如果服务的参数加入了@RequestBody,Feign客户端也要加入@RequestBody并修改为POST方式
5.这里获取到JSON直接解析,实际情况可以抽取公共实体类为JAR包引入返回实体类
FeignClient原理:

查看Clien类可以发现,Feign的实现是通过HTTP形式:
HttpURLConnection convertAndSend(Request request, Options options) throws IOException {
HttpURLConnection connection = (HttpURLConnection)(new URL(request.url())).openConnection();
if (connection instanceof HttpsURLConnection) {
HttpsURLConnection sslCon = (HttpsURLConnection)connection;
if (this.sslContextFactory != null) {
sslCon.setSSLSocketFactory(this.sslContextFactory);
}
if (this.hostnameVerifier != null) {
sslCon.setHostnameVerifier(this.hostnameVerifier);
}
}
Client的实现类中:
发现Feign调用了Ribbon做负载均衡
public Response execute(Request request, Options options) throws IOException {
try {
URI asUri = URI.create(request.url());
String clientName = asUri.getHost();
URI uriWithoutHost = cleanUrl(request.url(), clientName);
RibbonRequest ribbonRequest = new RibbonRequest(this.delegate, request, uriWithoutHost);
IClientConfig requestConfig = this.getClientConfig(options, clientName);
return ((RibbonResponse)this.lbClient(clientName).executeWithLoadBalancer(ribbonRequest, requestConfig)).toResponse();
} catch (ClientException var8) {
IOException io = this.findIOException(var8);
if (io != null) {
throw io;
} else {
throw new RuntimeException(var8);
}
}
}
处理超时问题:实际情况服务和调用者之间的通信可能较慢,这时候Feign会报错
如下配置Feign超时实际为10秒
feign:
client:
config:
default:
connectTimeout: 10000
readTimeout: 10000
Feign默认超时为1秒
Feign和Ribbon的对比:
1.Feign里面包含Ribbon,Feign的负载均衡由Ribbon实现
2.Feign更方便,可以和Hystrix结合
Spring Cloud(4):Feign的使用的更多相关文章
- spring cloud 使用feign 遇到问题
spring cloud 使用feign 项目的搭建 在这里就不写了,本文主要讲解在使用过程中遇到的问题以及解决办法 1:示例 @RequestMapping(value = "/gener ...
- spring cloud(四) feign
spring cloud 使用feign进行服务间调用 1. 新建boot工程 pom引入依赖 <dependency> <groupId>org.springframewor ...
- spring cloud关于feign client的调用对象列表参数、设置header参数、多环境动态参数试配
spring cloud关于feign client的调用 1.有些场景接口参数需要传对象列表参数 2.有些场景接口设置设置权限等约定header参数 3.有些场景虽然用的是feign调用,但并不会走 ...
- Spring Cloud 整合 Feign 的原理
前言 在 上篇 介绍了 Feign 的核心实现原理,在文末也提到了会再介绍其和 Spring Cloud 的整合原理,Spring 具有很强的扩展性,会把一些常用的解决方案通过 starter 的方式 ...
- Spring Cloud 之 Feign
新建Spring Boot工程,命名为feign 1.pom.xml添加依赖 <?xml version="1.0" encoding="UTF-8"?& ...
- Spring Cloud中Feign如何统一设置验证token
代码地址:https://github.com/hbbliyong/springcloud.git 原理是通过每个微服务请求之前都从认证服务获取认证之后的token,然后将token放入到请求头中带过 ...
- Spring Cloud 组件 —— feign
feign 作为一个声明式的 Http Client 开源项目.在微服务领域,相比于传统的 apache httpclient 与在 spring 中较为活跃的 RestTemplate 更面向服务化 ...
- spring cloud中feign的使用
我们在进行微服务项目的开发的时候,经常会遇到一个问题,比如A服务是一个针对用户的服务,里面有用户的增删改查的接口和方法,而现在我有一个针对产品的服务B服务中有一个查找用户的需求,这个时候我们可以在B服 ...
- spring cloud 之 Feign 使用HTTP请求远程服务
一.Feign 简介 在spring Cloud Netflix栈中,各个微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使用HTTP客户端.我们可以使用JDK原生的URLCo ...
- spring cloud 之 Feign的使用
1.添加依赖 2.创建FeignClient 原理:Spring Cloud应用在启动时,Feign会扫描标有@FeignClient注解的接口,生成代理,并注册到Spring容器中.生成代理时Fei ...
随机推荐
- CodeForces - 7D Palindrome Degree
最近接触了一点字符串算法,其实也就是一个简单的最大回文串算法,给定字符串s,求出最大字符串长度. 算法是这样的, 用'#'将s字符串中的每个字符分隔,比如s = "aba",分割后 ...
- yii int
@echo off rem ------------------------------------------------------------- rem Yii command line ini ...
- PyCharm使用指南及更改Python pip源为国内豆瓣
PyCharm基本使用 1.在PyCharm下为python项目配置python本地解释器 setting-->Project:pycharm workspace-->Project In ...
- 联想 Z5(L78011) 免解锁BL 免rec 保留数据 ROOT Magisk Xposed 救砖 ZUI 10.5.254
>>>重点介绍<<< 第一:本刷机包可卡刷可线刷,刷机包比较大的原因是采用同时兼容卡刷和线刷的格式,所以比较大第二:[卡刷方法]卡刷不要解压刷机包,直接传入手机后用 ...
- python行与缩进
#python行与缩进 1.了解逻辑行与物理行 2.行中分号使用规则 3.行链接 4.什么是缩进 5.如何缩进 6.注释 1.python中逻辑行主要是指一段代码,在意义上它的行数,而物理行,指的是我 ...
- 【Python-2.7】删除空格
有时我们在编程过程中,需要去除字符串两边的空格,可以用如下函数解决问题: rstrip():去除字符串右边的空格: lstrip():去除字符串左边的空格: strip():去除字符串两边的空格. 示 ...
- Codeforces_768_B_(二分)
B. Code For 1 time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...
- 模式匹配第四弹:if case,guard case,for case
2016-06-06 7388 作者:Olivier Halligon,原文链接,原文日期:2016-05-16 译者:walkingway:校对:Cee:定稿:numbbbbb 现在我们来重新回顾下 ...
- Vue指令4:v-on
监听事件 事件:click\keydown <button v-on:click="greet"></button> 可以简写为 <button @ ...
- 04Oracle Database 登陆
Oracle Database 登陆 EM Express Login https://localhost:5500/em/login cmd sqlplus SQL/PLUS system/code ...