SpringCloud学习笔记(四)
创始人
2024-02-14 05:05:45
0

文章目录

  • SpringCloud学习笔记(四)
    • 1.说在前面
    • 2.OpenFeign 简介
    • 3.OpenFeign 快速入门
      • 3.1 本次调用的设计图
      • 3.2 启动一个 eureka-server 服务,这里不重复演示,参考 eureka
      • 3.3 先创建 01-order-service,选择依赖
      • 3.4 创建 02-user-consumer,选择依赖
      • 3.5需求分析以及相应代码编写
        • 3.5.1 01-order-service 创建 controller
        • 3.5.2 02-user-consumer 创建 controller和接口
      • 3.6访问测试
      • 3.7调用超时设置
    • 4.OpenFeign 调用参数处理(开发重点)
      • 4.1 说在前面
      • 4.2 修改 provider-order-service
        • 4.2.1 创建 BaseResult 类
        • 4.2.2 创建 Order 类
        • 4.2.3 创建 TestParamController 类
      • 4.3 修改 consumer-user-service
        • 4.3.1 将 Order 类和 BaseResult 类拷贝过来,后面会抽到公共模块里
        • 4.3.2 修改 UserOrderFeign 接口
        • 4.3.3 创建 TestController 类
        • 4.3.4 测试调用
        • 4.3.5 时间日期参数问题
    • 6.OpenFeign 总结
    • 7.OpenFeign 其他
      • 7.1 OpenFeign 的日志功能
        • 7.1.1 OpenFeign 的日志级别
        • 7.1.2 创建配置类
        • 7.1.3 修改配置文件

SpringCloud学习笔记(四)

1.说在前面

上 一 节 我 们 讲 到 Ribbon 做 了 负 载 均 衡 , 用 Eureka-Client 来 做 服 务 发 现 , 通 过RestTemplate 来完成服务调用,但是这都不是我们的终极方案,终极方案是使用 OpenFeign

2.OpenFeign 简介

https://docs.spring.io/spring-cloud-openfeign/docs/2.2.4.RELEASE/reference/html/#spring-cloud-feign
Feign 是声明性(注解)Web 服务客户端。它使编写 Web 服务客户端更加容易。要使用 Feign,请创建一个接口并对其进行注解。它具有可插入注解支持,包括 Feign 注解和 JAX-RS 注解。Feign 还支持可插拔编码器和解码器。Spring Cloud 添加了对 Spring MVC 注解的支持,并
支持使用 HttpMessageConverters,Spring Web 中默认使用的注解。Spring Cloud 集成了 Ribbon 和 Eureka 以及 Spring CloudLoadBalancer,以在使用 Feign 时提供负载平衡的 http 客户端。

Feign 是一个远程调用的组件 (接口,注解) http 调用的
Feign 集成了 ribbon ribbon 里面集成了 eureka

3.OpenFeign 快速入门

3.1 本次调用的设计图

在这里插入图片描述

在这里插入图片描述

3.2 启动一个 eureka-server 服务,这里不重复演示,参考 eureka

文档

3.3 先创建 01-order-service,选择依赖

在这里插入图片描述添加eureka Client依赖、lombok依赖、spring Web依赖。
修改yml配置文件
在这里插入图片描述

3.4 创建 02-user-consumer,选择依赖

添加lombok、web、eureka client、openFeign依赖。
在这里插入图片描述修改yml配置文件

server:port: 8081
spring:application:name: consumer-user-service
eureka:client:service-url:defaultZone: http://localhost:8761/eurekainstance:instance-id: ${spring.application.name}:${server.port}prefer-ip-address: true

3.5需求分析以及相应代码编写

需求:
创建一个消费者去消费订单表的接口(也就是访问消费者接口,能够直接访问到订单的接口)

3.5.1 01-order-service 创建 controller

在这里插入图片描述OrderController

package com.jierlung.controller;import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class OrderController {@GetMapping("doOrder")public String doOrder() {System.out.println("有用户来下单了");return "下单成功";}
}

3.5.2 02-user-consumer 创建 controller和接口

创建接口

在这里插入图片描述UserOrderFeign

package com.jierlung.feign;import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;@FeignClient(value = "provider-order-service")
public interface UserOrderFeign {@GetMapping("doOrder")public String doOrder();}

创建controller
在这里插入图片描述
UserController

package com.jierlung.controller;import com.jierlung.feign.UserOrderFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class UserController {@Autowiredprivate UserOrderFeign userOrderFeign;@GetMapping("doUser")public String doOrder() {System.out.println("有用户进来了");String s = userOrderFeign.doOrder();return s;}
}

在启动类上添加注解
在这里插入图片描述

3.6访问测试

在这里插入图片描述

3.7调用超时设置

因 为 ribbon 默 认 调 用 超 时 时 长 为 1s , 可 以 修 改 , 超 时 调 整 可 以 查 看
DefaultClientConfigImpl

ribbon: #feign 默认调用 1s 超时ReadTimeout: 5000 # 修改调用时长为 5sConnectTimeout: 5000 # 修改连接时长为 5s

4.OpenFeign 调用参数处理(开发重点)

4.1 说在前面

Feign 传参确保消费者和提供者的参数列表一致 包括返回值 方法签名要一致

  1. 通过 URL 传参数,GET 请求,参数列表使用@PathVariable(“”)
  2. 如果是 GET 请求,每个基本参数必须加@RequestParam(“”)
  3. 如果是 POST 请求,而且是对象集合等参数,必须加@Requestbody 或者@RequestParam

4.2 修改 provider-order-service

4.2.1 创建 BaseResult 类

package com.jierlung.domain;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.io.Serializable;@Data
@NoArgsConstructor
@AllArgsConstructor
public class BaseResult implements Serializable {private Integer code;private String msg;private Object data;public static BaseResult success(Integer code, String msg, Object data) {BaseResult baseResult = new BaseResult();baseResult.setCode(code);baseResult.setData(data);baseResult.setMsg(msg);return baseResult;}
}
}
}

4.2.2 创建 Order 类

package com.jierlung.domain;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.io.Serializable;
import java.util.Date;@Data
@AllArgsConstructor
@NoArgsConstructor
public class Order implements Serializable {private String orderSn;private String orderName;private String orderDetail;private Date orderTime;private String userId;
}

4.2.3 创建 TestParamController 类

@RestController
public class TestParamController {
/**
* 测试单个参数
*
* @param name
* @return
*/
@GetMapping("testOneParam")
public BaseResult oneParam(@RequestParam("name") String name) {
System.out.println(name);
return BaseResult.success(200, "成功", "ok");
}
/**
* 测试两个参数
*
* @param name
* @param age
* @return
*/
@PostMapping("testTwoParam")
public BaseResult twoParam(@RequestParam("name") String name,@RequestParam("age") Integer age) {
System.out.println(name + ":" + age);
return BaseResult.success(200, "ok", "ok");
}
/**
* 测试一个对象的传参
*
* @param order
* @return
*/
@PostMapping("testObjectParam")
public BaseResult objectParam(@RequestBody Order order) {
System.out.println(order);
return BaseResult.success(200, "ok", order);
}
/**
* 测试一个对象 一个参数
*
* @param order
* @param name
* @return
*/
@PostMapping("testOneObjectOneParam")
public BaseResult oneObjectOneParam(@RequestBody Order order,
@RequestParam String name) {
System.out.println(order);
System.out.println(name);
return BaseResult.success(200, "ok", order);
}
/**
* 测试 url 传参
*
www.bjpowernode.com 13 / 29 Copyright©动力
节点
* @param id
* @return
*/
@GetMapping("testUrlParam/{id}")
public BaseResult testUrlParam(@PathVariable("id") Integer id) {
System.out.println(id);
return BaseResult.success(200, "ok", id);
}
}

4.3 修改 consumer-user-service

4.3.1 将 Order 类和 BaseResult 类拷贝过来,后面会抽到公共模块里

4.3.2 修改 UserOrderFeign 接口

package com.jierlung.feign;import com.jierlung.domain.BaseResult;
import com.jierlung.domain.Order;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;@FeignClient(value = "provider-order-service")
public interface UserOrderFeign {/*** 远程调用下单的方法** @return*/@RequestMapping("doOrder")String doOrder();/*** 测试单个参数** @param name* @return*/@GetMapping("testOneParam")public BaseResult oneParam(@RequestParam("name") String name);/*** 测试两个参数** @param name* @param age* @return*/@PostMapping("testTwoParam")public BaseResult twoParam(@RequestParam("name") String name,@RequestParam("age") Integer age);/*** 测试一个对象的传参** @param order* @return*/@PostMapping("testObjectParam")public BaseResult objectParam(@RequestBody Order order);/*** 测试一个对象 一个参数** @param order* @param name* @return*/@PostMapping("testOneObjectOneParam")public BaseResult oneObjectOneParam(@RequestBody Order order,@RequestParam String name);/*** 测试 url 传参** @param id* @return*/@GetMapping("testUrlParam/{id}")public BaseResult testUrlParam(@PathVariable("id") Integer id);
}

4.3.3 创建 TestController 类

@RestController
public class TestController {@Autowiredprivate UserOrderFeign userOrderFeign;@RequestMapping("testFeignParam")public String testFeignParam() {// 测试一个参数BaseResult result1 = userOrderFeign.oneParam("bjpowernode");System.out.println(result1);System.out.println("--------------------------------------------------");// 测试多个参数BaseResult result2 = userOrderFeign.twoParam("bjpowernode", 666);System.out.println(result2);System.out.println("--------------------------------------------------");// 测试一个对象Order order = new Order("111", "牛排", "一份牛排 256g", new Date(), "159357");BaseResult result3 = userOrderFeign.objectParam(order);System.out.println(result3);System.out.println("--------------------------------------------------");// 测试 url 传参BaseResult result4 = userOrderFeign.testUrlParam(999);System.out.println(result4);System.out.println("--------------------------------------------------");// 测试一个对象 一个参数BaseResult result5 = userOrderFeign.oneObjectOneParam(order,"bjpowernodebjpowernode");System.out.println(result5);System.out.println("--------------------------------------------------");return "ok";}
}

4.3.4 测试调用

在这里插入图片描述在这里插入图片描述

在这里插入图片描述

4.3.5 时间日期参数问题

使用 feign 远程调用时,传递 Date 类型,接收方的时间会相差 14 个小时,是因为时区造成的
处理方案:

  1. 使用字符串传递参数,接收方转换成时间类型(推荐使用)不要单独传递时间
  2. 使用 JDK8 的 LocalDate(日期) 或 LocalDateTime(日期和时间,接收方只有秒,没有毫秒)
  3. 自定义转换方法
    传参总结:
    get 请求只用来传递基本参数 而且加注解@RequestParam
    post 请求用来传递对象参数 并且加注解@RequestBody

6.OpenFeign 总结

OpenFeign 主要基于接口和注解实现了远程调用
源码总结:面试

  1. OpenFeign 用过吗?它是如何运作的?
    在主启动类上加上@EnableFeignClients 注解后,启动会进行包扫描,把所有加了
    @FeignClient(value=”xxx-service”)注解的接口进行创建代理对象通过代理对象,使用
    ribbon 做了负载均衡和远程调用
  2. 如何创建的代理对象?
    当 项 目 在 启 动 时 , 先 扫描 , 然 后 拿 到 标 记了 @FeignClient 注 解的 接 口 信息 , 由ReflectiveFeign 类的 newInstance 方法创建了代理对象 JDK 代理
  3. OpenFeign 到底是用什么做的远程调用?
    使用的是 HttpURLConnection (java.net)
  4. OpenFeign 怎么和 ribbon 整合的?
    在代理对象执行调用的时候

7.OpenFeign 其他

7.1 OpenFeign 的日志功能

从前面的测试中我们可以看出,没有任何关于远程调用的日志输出,如请头,参数
Feign 提供了日志打印功能,我们可以通过配置来调整日志级别,从而揭开 Feign 中 Http 请求的所有细节

7.1.1 OpenFeign 的日志级别

NONE 默认的,不显示日志
BASE 仅记录请求方法,URL ,响应状态码及执行时间
HEADERS 在 BASE 之上增加了请求和响应头的信息
FULL 在 HEADERS 之上增加了请求和响应的正文及无数据

7.1.2 创建配置类

@Configuration
public class FeignConfig {@BeanLogger.Level feignLogger() {return Logger.Level.FULL;}
}

7.1.3 修改配置文件

在这里插入图片描述

相关内容

热门资讯

成都警方通报:网上约拍线下发生... 中新网成都1月19日电 (记者 安源)1月19日,成都市公安局锦江区分局发布警情通报称,网上约拍线下...
最高法:对因拖欠工资、高额彩礼... 新京报讯(记者陈璐)1月19日,最高人民法院召开全国高级法院院长会议,会议总结2025年法院工作,并...
最高检:去年前11月起诉危险驾... 南都讯 记者刘嫚 发自北京 记者从1月19日召开的全国检察长会议上了解到,去年前11月,检察机关受理...
萃华珠宝(002731)披露累... 截至2026年1月19日收盘,萃华珠宝(002731)报收于13.1元,较前一交易日上涨3.23%,...
上海自贸区构建国际化、专业化调... 中新网上海1月19日电 (记者 陈静)随着上海自贸区涉外经贸活动日益频繁,商事纠纷解决机制的创新完善...
最高法:有力惩治利用人工智能技... 新京报讯(记者陈璐)1月19日,最高人民法院召开全国高级法院院长会议。记者从会上获悉,2026年人民...
上合示范区2025年推出20项... 中新网青岛1月19日电(王禹)记者19日从中国—上海合作组织地方经贸合作示范区(简称“上合示范区”)...
2025年破坏社会主义市场经济... 中新网北京1月19日电 (记者 张素)记者19日从在北京举行的全国高级法院院长会议获悉,2025年,...
司法部:2025年审查完成53... 中新网北京1月19日电 (记者 谢雁冰)记者19日从司法部召开的全国司法厅(局)长会议上获悉,202...
宏达股份(600331)披露提... 截至2026年1月19日收盘,宏达股份(600331)报收于13.44元,较前一交易日上涨0.6%,...