基于上一篇文章: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@LoadBalancedpublic 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;@Autowiredpublic ProductOrderServiceImpl(ProductClient productClient) {this.productClient = productClient;}@Overridepublic 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: 10000readTimeout: 10000

Feign默认超时为1秒

Feign和Ribbon的对比:

1.Feign里面包含Ribbon,Feign的负载均衡由Ribbon实现

2.Feign更方便,可以和Hystrix结合

转载于:https://www.cnblogs.com/xuyiqing/p/10869026.html

Spring Cloud(4):Feign的使用相关推荐

  1. Spring Cloud (Eureka,Feign,Hystrix整合)

    Spring Cloud(Eureka,Feign,Hystrix整合) Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智能路由,微代 ...

  2. Spring Cloud(四):Spring Cloud Alibaba Feign Dubbo

    扩展点 RequestInterceptor#apply 扩展点 feign.Client#execute spring cloud dubbo 调用 RPC RPC 全称是 Remote Proce ...

  3. Spring Cloud中Feign如何统一设置验证token

    前面我们大致的聊了下如何保证各个微服务之前调用的认证问题 Spring Cloud中如何保证各个微服务之间调用的安全性 Spring Cloud中如何保证各个微服务之间调用的安全性(下篇) 原理是通过 ...

  4. 解决Spring Cloud中Feign/Ribbon第一次请求失败的方法

    前言 在Spring Cloud中,Feign和Ribbon在整合了Hystrix后,可能会出现首次调用失败的问题,要如何解决该问题呢? 造成该问题的原因 Hystrix默认的超时时间是1秒,如果超过 ...

  5. Java笔记(3) - 使用Spring Cloud Zookeeper + Feign实现服务发现

    配置映射主机名和IP 为每台虚拟主机的/etc/hosts文件加上如下内容,服务发现需要用到默认主机名作为访问地址,这样可以不用为每个服务实例配置IP 192.168.253.30 megumi-30 ...

  6. spring cloud + nacos + feign调用

    //by yan 20211119 需求: 简单建个项目,用来测试调用注册在nacos的服务接口. 步骤: idea -> new project-> Spring Initializr ...

  7. Spring Cloud 之 Feign 使用HTTP请求远程服务

    Feign是从Netflix中分离出来的轻量级项目,能够在类接口上添加注释,成为一个REST API 客户端,Feign默认集成了Ribbon. Feign中对 Hystrix 有依赖关系.Feign ...

  8. spring cloud利用feign和sentinel进行内部或外部远程调用

    一.FeignClient注解 FeignClient注解被@Target(ElementType.TYPE)修饰,表示FeignClient注解的作用目标在接口上 /* Copyright 2013 ...

  9. spring cloud整合feign和nacos报错:No Feign Client for loadBalancing defined. Did you forget to include

    Did you forget to include spring-cloud-starter-loadbalancer 问题描述 项目环境 解决方案 1.引入eureka依赖--无效 2.降低spri ...

  10. Spring Cloud Open Feign系列【11】Feign 编码解码器Encoder和Decoder源码分析

    文章目录 概述 接口及相关实现类 Encoder 接口 Decoder接口 执行流程源码分析 1. 项目结构改造 2. 编码器流程 3. 解码器流程 4. 异常解码处理流程 5. 404异常特殊处理 ...

最新文章

  1. Webpack 的 HtmlWebpackPlugin 如何控制某个 chunks 的 inject 位置?
  2. https的基本原理,看完你的程序员女朋友再也不和你提分手了
  3. linux图形化应用程序快捷方式制作方法
  4. 在家点点接入云信,打造全新社区商业和社交生态
  5. //随机生成1位大写字母\小写字母\数字
  6. openwrt mt7620 内存大小检测
  7. PythonRabbitmq文档阅读笔记-生产者数据直接送入队列消费者消费
  8. Master of Typing 3 for mac (打字大师3)支持m1
  9. 网络蜘蛛采用三种策略来决定抓取网页的先后顺序
  10. 一阶系统开环传递函数表达式_自动控制总结:第五章、线性系统的校正方法
  11. 空手套白狼-我的互联网草根创业亲身经历
  12. git大坑---cleanup
  13. 工作前5年决定你一生的财富
  14. 开源!!!100 多个常用 API 数据接口免费分享!建议收藏!
  15. UGC、元宇宙概念、与迷你世界玩法
  16. Selenium自动化下载文件Firefox配置教程
  17. [企业权限管理项目](二)环境搭建
  18. 【单调队列优化dp】jzoj4883灵知的太阳信仰 纪中集训提高B组
  19. python求最小公倍数_Python实现的求解最小公倍数算法示例
  20. 证书服务器,备份,还原

热门文章

  1. Python3实现顺序查找、冒泡排序、选择排序
  2. nyoj--2--括号配对
  3. 003 python 注释/数据类型/运算符/输入输出/格式化输出
  4. 开启Mac原生NTFS支持
  5. 2018-4-18 Linux学习笔记
  6. 多个需要验证的输入框思路问题
  7. [转]如何:定义和处理 SOAP 标头
  8. JSP中“预定义变量”的使用
  9. linux下apache2两种工作模式及两者切换
  10. php 可用内存大小,关于php:致命错误:允许的内存大小为67108864字节耗尽