基于上一篇文章: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的使用的更多相关文章

  1. spring cloud 使用feign 遇到问题

    spring cloud 使用feign 项目的搭建 在这里就不写了,本文主要讲解在使用过程中遇到的问题以及解决办法 1:示例 @RequestMapping(value = "/gener ...

  2. spring cloud(四) feign

    spring cloud 使用feign进行服务间调用 1. 新建boot工程 pom引入依赖 <dependency> <groupId>org.springframewor ...

  3. spring cloud关于feign client的调用对象列表参数、设置header参数、多环境动态参数试配

    spring cloud关于feign client的调用 1.有些场景接口参数需要传对象列表参数 2.有些场景接口设置设置权限等约定header参数 3.有些场景虽然用的是feign调用,但并不会走 ...

  4. Spring Cloud 整合 Feign 的原理

    前言 在 上篇 介绍了 Feign 的核心实现原理,在文末也提到了会再介绍其和 Spring Cloud 的整合原理,Spring 具有很强的扩展性,会把一些常用的解决方案通过 starter 的方式 ...

  5. Spring Cloud 之 Feign

    新建Spring Boot工程,命名为feign 1.pom.xml添加依赖 <?xml version="1.0" encoding="UTF-8"?& ...

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

    代码地址:https://github.com/hbbliyong/springcloud.git 原理是通过每个微服务请求之前都从认证服务获取认证之后的token,然后将token放入到请求头中带过 ...

  7. Spring Cloud 组件 —— feign

    feign 作为一个声明式的 Http Client 开源项目.在微服务领域,相比于传统的 apache httpclient 与在 spring 中较为活跃的 RestTemplate 更面向服务化 ...

  8. spring cloud中feign的使用

    我们在进行微服务项目的开发的时候,经常会遇到一个问题,比如A服务是一个针对用户的服务,里面有用户的增删改查的接口和方法,而现在我有一个针对产品的服务B服务中有一个查找用户的需求,这个时候我们可以在B服 ...

  9. spring cloud 之 Feign 使用HTTP请求远程服务

    一.Feign 简介 在spring Cloud Netflix栈中,各个微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使用HTTP客户端.我们可以使用JDK原生的URLCo ...

  10. spring cloud 之 Feign的使用

    1.添加依赖 2.创建FeignClient 原理:Spring Cloud应用在启动时,Feign会扫描标有@FeignClient注解的接口,生成代理,并注册到Spring容器中.生成代理时Fei ...

随机推荐

  1. mysql 更改字符集

    Windows: 安装目录下新建my.ini文件,输入一下内容 [mysqld]#修改服务器端默认字符编码格式为utf8character-set-server = utf8 [client]#修改客 ...

  2. Java学习笔记-eclipse配置

    一.配置Java环境变量 JAVA_HOME:D:\Program Files\Java\jdk1.7.0_76 CLASSPATH:.;%JAVA_HOME%\lib\dt.jar;%JAVA_HO ...

  3. offset家族基本简介

    Offset家族简介 offset这个单词本身是--偏移,补偿,位移的意思. js中有一套方便的获取元素尺寸的办法就是offset家族: offsetWidth和offsetHight 以及offse ...

  4. CSS垂直居中和水平居中的几种方法

    垂直居中 方法一 这个方法把div 的显示方式设置为表格,因此我们可以使用表格的 vertical-align属性. <!DOCTYPE html> <html lang=" ...

  5. spark查看stage和tasks信息

    spark提供了web-ui接口.外部命令等多种方法监视spark程序的执行状态.利用spark的监视功能,可以方便的查看spark应用程序执行的状态,具体包括:1)stage和tasks列表信息  ...

  6. GDB 学习

    通常使用gdb在Linux下调试C/C++程序,编译的时候加上-g选项(gcc -g ......).下面总结的是我自己经常使用(当然也有一些用的比较少)的gdb命令. (1)开始及退出 开始:gdb ...

  7. (转)淘淘商城系列——使用solrj来测试索引库

    http://blog.csdn.net/yerenyuan_pku/article/details/72892280 我们使用solrj来操作索引库,一般习惯先建一个单元测试类测试下增删改查方法是否 ...

  8. HDU_1584_(DFS)

    蜘蛛牌 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  9. 安卓app测试之Monkeyscript

    MonkeyScript是一组可以被Monkey识别的命令集合 优点:MonkeyScript可以完成重复固定的操作 使用:adb shell monkey -f <scriptfile> ...

  10. 微信小程序 客服自动回复图片

    产品需求是,在客服对话框里,发送特定的文字,回复我们的二维码: 小城程开发完成后,这个自动回复图片的功能就摆在了眼前.刚开始我们想到的是:在线客服功能的设置里设置好自动回复的图片,但是目前设置不支持自 ...