Java分布式微服务2——声明式Http客户端(Feign)与网关(Gateway)

文章目录

  • Http声明式客户端Feign
    • Feign介绍与使用
    • Feign自定义配置
    • Feign性能优化
    • Feign最佳实践方案
  • 网关Gateway
    • 网关Gateway的作用与搭建
    • 路由断言工厂Route Predicate Factory
    • 路由过滤器GatewayFilter
    • 全局过滤器
    • 过滤器执行顺序
    • 网关的跨域处理

Http声明式客户端Feign

Feign介绍与使用

RestTemplate方式进行远程调用存在的问题

  • 可读性差
  • 对复杂url不方便操作

Feign是一个声明式的Http客户端

  1. 它把远程调用的方式与Spring MVC的Controller相似化了
  2. 它接入了Ribbon自动实现负载均衡

使用步骤:

  1. 引入依赖
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
  1. 在启动类添加@EnableFeignClients开启Feign的自动装配功能,@Enable开头的注解什么意思
  2. 编写Feign客户端,创建一个接口加上@FeignClient,其利用了SpringMVC的映射注解声明远程调用的信息。

@GetMapping注解在Spring MVC中和Feign中都可以使用,用于定义Restful的接口,但它们的用途不同。在Spring MVC中,它用于将HTTP GET请求映射到指定的处理方法上;而在Feign中,它用于定义Feign客户端接口中的方法,用于向远程服务发送HTTP GET请求。

@FeignClient("userservice") // 指定要请求的服务名称
public interface UserClient {@GetMapping("/user/{id}") // GetMapping是标明请求方式,不仅仅是Controller中的监听Get请求,这里是发送请求的方式User findById(@PathVariable Long id);
}
  1. 使用客户端进行远程调用
@Resource
private UserClient userClient;User user = userClient.findById(order.getUserId());

Feign自定义配置

在这里插入图片描述
方式一:改配置文件

# Feign日志级别
feign:client:config:default:loggerLevel: HEADERS

方式二:在Configuration类中声明一个对应类型的Bean
在这里插入图片描述

Feign性能优化

Feign的底层客户端实现有三种:

  • URLConnection: 默认实现,不支持连接池
  • Apache HttpClient: 支持连接池(这里是Http连接的连接池,与Druid数据库连接池不同)
  • OKHttp: 支持连接池

这样我们就可以切换客户端并配置连接池来改善性能
Feign的性能优化可以从下面2个方面入手:

  • 使用连接池
  • 日志级别设为basic或者none

替换客户端实现为HttpClient:

  1. 引入HttpClient依赖
<!--        feign的httpclient--><dependency><groupId>io.github.openfeign</groupId><artifactId>feign-httpclient</artifactId></dependency>
  1. 在配置文件中新增连接池配置
feign:client:config:default:loggerLevel: BASIChttpclient:enabled: falsemax-connections: 200max-connections-per-route: 50 # 每个路径的最大连接

Feign最佳实践方案

在这里插入图片描述缺点是会造成紧耦合,并且还需要在实现类中重新写一遍@PathVariable这种注解

在这里插入图片描述缺点是会引入大量的方法,但是并不是都能用得上

抽取Feign为单独模块时,要注意到其他微服务的@ComponentScan是只能扫描到同级别及以下的类,为了让其他微服务扫描到Feign模块中的FeignClient,需要在@EnableFeignClients注解上增加参数(推荐第二种)
在这里插入图片描述

网关Gateway

网关Gateway的作用与搭建

  • 身份认证,权限校验
  • 服务路由,负载均衡
  • 请求限流
    SpringCloudGateway是响应式编程的网关实现
    搭建步骤:
  1. 新建一个网关的Module,在其中引入依赖
<!--        nacos客户端依赖--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--        网关依赖--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency>
  1. 编写路由和Nacos地址(application.yml)
server:port: 10010
spring:application:name: gatewaycloud:nacos:server-addr: localhost:8848 # nacos服务器地址gateway:routes:- id: user-service # 路由id,自定义,只要唯一即可uri: lb://userservice # 路由的目标地址 lb=LoadBalance负载均衡, 后面跟服务名称,会被nacos注册中心对照为服务地址predicates: # 路由断言,也就是判断哪些请求模式是属于这个路由的- Path=/user/** 
  1. 写好Application启动类

这就搭建完成了,以后请求都发到网关,网关判断后通过注册中心找到对应服务,把请求转过去
在这里插入图片描述

路由断言工厂Route Predicate Factory

配置文件中写的断言规则path只是字符串,会被Predicate Factory读取并处理,转变为路由判断条件,之后由对应的断言工厂进行判断,还有其他断言可以使用:
在这里插入图片描述

路由过滤器GatewayFilter

网关中的过滤器,可以对进入网关的请求和微服务返回的响应进行处理

在这里插入图片描述在这里插入图片描述过滤器的添加也是在配置文件.yml中,给某服务加过滤器,就修改之前的配置为:

server:port: 10010
spring:application:name: gatewaycloud:nacos:server-addr: localhost:8848 gateway:routes:- id: user-service uri: lb://userservice filter:- AddRequestHeader=Greeting, Hello World! # 添加请求头过滤器工厂predicates:- Path=/user/** 

如果想给所有的服务都加过滤器,可以用默认过滤器,对所有路由都生效

spring:application:name: gatewaycloud:nacos:server-addr: localhost:8848 # nacos服务器地址gateway:routes:......default-filters:- AddRequestHeader=Greeting, Hello world! # 添加请求头

全局过滤器

全局过滤器也是作用于所有请求和微服务响应,与默认过滤器的区别是,它需要自己使用代码实现其逻辑:

  1. 实现GlobalFilter接口
    在这里插入图片描述2. 配置优先级(@Order或者实现Ordered接口)
//@Order(1) 设置过滤器的优先级,越小越高, -1最大,也可以通过实现Ordered接口完成优先级配置
@Component
public class AuthorizeFilter implements GlobalFilterOrdered{@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain){// 1.获取请求参数ServerHttpRequest request = exchange.getRequest();MultiValueMap<String, String> params = request.getQueryParams();// 2.获取参数中的authorization参数String authorization = params.getFirst("authorization");// 3.判断参数值是否等于adminif("admin".equals(authorization)){// 4.相等就放行return chain.filter(exchange);}else{// 5.不等就拦截// 设置状态码exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);// 拦截return exchange.getResponse().setComplete();}}@Overridepublic int getOrder(){ return -1;}
}

过滤器执行顺序

三种过滤器是放在一个集合里排序的,排序规则是:

  1. 优先级Order的值
  2. 同优先级按defaultFilter>路由过滤器>GlobalFilter的顺序执行
  3. GlobalFilter优先级是自己指定的,其他两个是按在配置文件中的书写顺序从1递增的(第一个写的过滤器Order=1,第二个写的Order=2)

在这里插入图片描述
为什么三种过滤器可以放在一个集合中排序?

  • 路由过滤器和默认过滤器都是GatewayFilter的实现类
  • 全局过滤器GlobalFilter会作为参数交给GatewayFilterAdapter的构造函数,而GatewayFilterAdapter是实现了GatewayFilter接口的,相当于把GlobalFilter装饰为了GatewayFilter的实现类
  • 所以他们三个能以GatewayFilter实现类的身份加入一个集合

网关的跨域处理

跨域问题:浏览器禁止请求发起者与服务端发生跨域ajax请求,请求被浏览器拦截
浏览器采用同源策略,需要网页和其调用的接口的 协议、域名、端口 都一致,不一致它会觉得有风险。
CORS 是一个 W3C 标准,全称是“跨源资源共享”(Cross-origin resource sharing),或者通俗地
称为“跨域资源共享”。它允许浏览器向跨源的服务器,发出XMLHttpRequest请求,从而克服AJAX
只能同源使用的限制。
网关处理跨域采用的就是CORS,只需要在配置中进行添加:

spring:cloud:gateway:globalcors: # 全局的跨域处理add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题corsConfigurations:'[/**]': # 对所有的请求生效allowedOrigins: # 允许哪些网站的跨域请求- "http://localhost:8090"- "http://www.leyou.com"allowedMethods: # 允许的跨域ajax的请求方式- "GET"- "POST"- "DELETE"- "PUT"- "OPTIONS"allowedHeaders: "*" # 允许在请求中携带的头信息allowCredentials: true # 是否允许携带cookiemaxAge: 360000 # 这次跨域检测的有效期

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/78733.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python魔法解析:探索变量类型的丰富多彩世界!

在Python这个魔法般的编程语言中&#xff0c;变量是连接你与计算机世界的神奇桥梁。然而&#xff0c;这些变量并不是单一的&#xff0c;它们有着丰富多彩的类型。无论你是刚刚踏入编程的大门&#xff0c;还是想要深入了解Python的高级特性&#xff0c;本篇博客将带你探索变量的…

c++学习(特殊类设计)[30]

只能在堆上创建对象的类 如果你想要确保对象只能在堆上创建&#xff0c;可以通过将析构函数声明为私有&#xff0c;并提供一个静态成员函数来创建对象。这样&#xff0c;类的实例化只能通过调用静态成员函数来完成&#xff0c;而无法直接在栈上创建对象。 以下是一个示例&…

【PCIE】PCIE的驱动和pcie的端口驱动关系

pice驱动和pcie端口驱动区别 PCIe的端口服务驱动与PCIe驱动之间存在一定的关系&#xff0c;但它们是不同的概念。 PCIe驱动是用于管理和操作PCIe设备的驱动程序。它负责与硬件进行通信&#xff0c;并实现对PCIe设备的配置、数据传输以及其他相关操作。PCIe驱动通常涉及设备的…

【NLP概念源和流】 05-引进LSTM网络(第 5/20 部分)

一、说明 在上一篇博客中,我们讨论了原版RNN架构,也讨论了它的局限性。梯度消失是一个非常重要的缺点,它限制了RNN对较短序列的建模。香草 RNN 在相关输入事件和目标信号之间存在超过 5-10 个离散时间步长的时间滞时无法学习。这基本上限制了香草RNN在许多实际问题上的应用,…

NestJs Debug配置文件

&#xff08;事缓则圆,人缓则安,语迟则贵,虎行似病,鹰立似睡。清俞万春《荡寇志》&#xff09; {"version": "0.2.0","configurations": [{"type": "node","request": "launch","name": &quo…

基于LNMP架构搭建Discuz论坛

LNMP: L---->linux系统&#xff0c;操作系统。 N----->nginx网站服务&#xff08;前端),提供前端的静态页面服务。同时具有代理、转发的作用。&#xff08;转发就是转发后端请求&#xff0c;转发PHP&#xff09;&#xff0c;nginx没有处理动态资源的功能&#xff0c;他有…

IO模型-信号驱动IO

linux内核中存在一个信号SIGIO&#xff0c;这个信号就是用于实现信号驱动IO的。当应用程序中想要以信号驱动IO的模型读写硬件数据时&#xff0c;首先注册一个SIGIO信号的信号处理函数,当硬件数据就绪&#xff0c;硬件会发起一个中断&#xff0c;在硬件的中断处理函数中向当前进…

Plus 框架分页合理化问题

需要关闭 MyBatis Plus的分页合理化 RuoYi-Vue-Plus框架默认的Mybatis Plus分页拦截器配置是打开了分页合理化&#xff0c;这样会导致溢出的分页数据本来应该返回空数据&#xff0c;打开之后而会永远返回默认的前10条数据。 /*** mybatis-plus配置类(下方注释有插件介绍)** au…

CSS元素的显示模式

1、现在我想做成小米左侧边栏这样的效果&#xff0c;该怎么做呢&#xff1f; 2、小米商城触碰之后会显示出新的商品案例 3、一碰到之后会出现这个列表 4、这里涉及到了元素显示模式&#xff1a; 5、用人进行划分可以分为男人和女人&#xff0c;根据男人和女人的特性进行相应的…

【ChatGPT 指令大全】怎么利用ChatGPT写报告

目录 选定切入角度 报告开头 大纲生成 草稿撰写 研究报告 提出反对观点 报告总结 研究来源 总结 随着人工智能技术的快速发展&#xff0c;自然语言处理技术在各个领域的应用越来越广泛。其中&#xff0c;ChatGPT作为目前最先进的自然语言处理模型之一&#xff0c;其强…

读写分离实现sharding-jdbc

一、背景 二、使用sharding-JDBC实现 1、导入依赖 2、配置文件&#xff08;名字要对应&#xff09; ​​​​​​​ 查询策略&#xff08;轮询&#xff0c;指定哪个是主库哪个是从库&#xff09; 允许bean定义覆盖

刷题笔记 day8

1004 最大连续1的个数 III 这道题要求将原数组中的0翻转成1&#xff0c;求出最大元素全是1的子数组长度&#xff0c;看这道题第一感觉还要将里面的0变成1&#xff0c;感觉这道题解决起来很麻烦&#xff0c;但是我们可以转变思路&#xff0c;找出其最大子数组&#xff0c;使得子…

手搓 LLM (不用rnn 不用attention 完全新思路)padding 实验

数据集地址 诗 实验过的几种策略 主体代码 import paddle import numpy as np from tqdm import tqdm import pandas as pd class EmMask(paddle.nn.Layer):def

8.6 day07 休息+剑指offer

文章目录 06从尾到头打印链表03数组中重复的数字04二维数组中的查找05 替换空格06重建二叉树背英语单词&#xff0c;看了二十页 06从尾到头打印链表 从尾到头遍历链表 方法一就是用栈来辅助&#xff0c;栈的结构是先进后出的&#xff0c;将链表中的元素加入到栈中去&#xff0…

无人驾驶实战-第八课(定位算法)

无人驾驶中定位的作用&#xff1a; 定位高精度地图&#xff1a;提供当前位置的静态环境感知 &#xff08;车道线/交通指示牌/红绿灯/柱子/建筑物/等&#xff09; 定位动态物体感知&#xff1a;将感知到的动态物体正确放入静态环境 定位获取位置姿态&#xff1a;用于路径规划/决…

单细胞测序基础知识

构建文库 上机测序 根据不同的荧光检测不同的碱基 质量控制&#xff08;质控QC&#xff09; 去除低质量的序列 表达定量 统计reads数&#xff0c;进而得到表达矩阵 标准化 让所有样本处在同一起跑线上 主成分分析PCA 图中每个点都代表一个样本&#xff0c;不同颜色…

pycharm、idea、golang等JetBrains其他IDE修改行分隔符(换行符)

文章目录 pycharm、idea、golang系列修改行分隔符我应该选择什么换行符JetBrains IDE&#xff0c;默认行分隔符 是跟随系统修改JetBrains IDE&#xff0c;默认行分隔符 pycharm、idea、golang系列修改行分隔符 一般来说,不同的开发环境和项目对换行格式的使用偏好不同: Windo…

解决vite+vue3项目npm装包失败

报错如下&#xff1a; Failed to remove some directories [ npm WARN cleanup [ npm WARN cleanup D:\\V3Work\\v3project\\node_modules\\vue, npm WARN cleanup [Error: EPERM: operation not permitted, rmdir D:\V3Work\v3project\node_modules\vue\reactivity\…

HTML5中Canvas学习笔记:Canvas

目录 一、HTML中Canvas画图strokeStyle 和 fillStyle 的区别是什么&#xff1f; 二、如何设置一幅canvas图中某个颜色透明&#xff1f; 三、H5 canvas中strokeRect参数如果是小数&#xff0c;如何处理&#xff1f; 四、H5 Canvas中如何画圆角矩形框&#xff1f; 一、HTML中…

设计模式行为型——迭代器模式

什么是迭代器模式 迭代器模式&#xff08;Iterator Pattern&#xff09;属于行为型模式&#xff0c;其提供一种方法顺序访问一个聚合对象中的各种元素&#xff0c;而又不暴露该对象的内部表示&#xff0c;即不需要知道集合对象的底层表示。编程环境中非常常用的设计模式。 迭代…