基于SpringCloud的微服务架构学习笔记(4)http客户端Feign和网关GateWay
创始人
2024-06-02 23:43:39
0

目录

  • 2. http客户端Feign
    • 2.1 Feign替代RestTemplate
      • 2.1.1 RestTmmplate方法调用存在的问题
      • 2.1.2. Feign的介绍
      • 2.1.3. Feign的使用
    • 2.2 自定义配置
    • 2.3 Feign使用优化
      • 2.3.1 优化的底层原理
      • 2.3.2 优化的方向
      • 2.3.3 连接池配置
    • 2.4 最佳实践
      • 2.4.1 方式一:继承
      • 2.4.2 方式二:抽取
  • 3. 统一网关Gateway
    • 3.1 为什么需要网关
    • 3.2 GateWay的快速入门
    • 3.3 断言工厂
    • 3.4 过滤器工厂
    • 3.5 全局过滤器(GlobalFilter)
      • 3.5.1 什么是全局过滤器,为什么需要全局过滤器
      • 3.5.2. 全局过滤器的实现方式
      • 3.5.3. 全局过滤器的实现案例
    • 3.5 过滤器的执行顺序
    • 3.6 限流过滤器
    • 3.7 小总结
  • 图片:
  • 红色字体

2. http客户端Feign

Feign是一种新的使用http进行远程调用的方式。

2.1 Feign替代RestTemplate

2.1.1 RestTmmplate方法调用存在的问题

1)使用方法:在启动类书写一个方法,然后通过url在service中进行调用

String url = "http://userservice/user/" + order.getUserId();
User user = restTemplate.getForObject(url, User.class);
  • 代码可读性太差,需要固定输入一个URL,不够灵活
  • 当参数变得复杂的时候,URL难以维护。

2.1.2. Feign的介绍

1)是一种申明式的http客户端,作用是帮助我们优雅实现http请求的发送,解决上面提到的问题。
2) 实现逻辑还是差不多的,都是为了生成一个url进行远程调用。只不过在Feign中,采用申明式结构进行URL的拆分再组装。

2.1.3. Feign的使用

  1. 在order-service的pom文件中引入依赖:spring-cloud-starter-openfeign
org.springframework.cloudspring-cloud-starter-openfeign 

  1. 在orderservice的启动类中添加注解,开启Feign的功能:@EnableFeignClients
  1. 在Feign-api项目中编写Feign的客户端(Feign-client)
    为了相对应,需要和user中的controller中的类保持参数的一直性
@FeignClient("userservice")
public interface UserClient {@GetMapping("/user/{id}") User findById(@PathVariable("id") Long id);
}

上述定义Feign客户端中,包含很多信息:
(1)服务名称:userservice
(2)请求方式:Get
(3)请求路径:/user/{id}
(4)请求参数:Long id
(5)返回对象:User

  1. 用Feign客户端代替RestTemplate

第二行红色,两行给为一行了!

        String url="http://localhost:8081/user/"+order.getUserId();  //获取用户的id信息User user=restTemplate.getForObject(url,User.class);   //通过url进行远程调用,并把得到的数据变为user格式
  1. 小结
    1)引入依赖
    2)启动类添加注解@EnableFeignClients
    3)编写FeignClient接口
    4)使用FeignClient中定义的方法替代RestTemplate

2.2 自定义配置

一般使用比较多的是:日志级别的修改,共有四种级别:NONE,BASIC,HEADERS,FULL,一般默认选用NONE即可

2.3 Feign使用优化

2.3.1 优化的底层原理

主要是在Feign底层进行优化,即采用具有连接池的原理。
Feign底层的客户端实现:
1)URLConnection:默认实现,不支持连接池(性能一般)
2)Apache HttpClient:支持连接池(不用每次都请求链接,效率更高)
3)OKHttp:支持连接池

2.3.2 优化的方向

优化的方向:
1)使用连接池代替默认的URLConnection
2)日志级别的修改:使用NONE和BASIC,更加简洁。

2.3.3 连接池配置

Feign添加HttpClient的支持,故需要引入依赖和配置连接池

  1. 在Feign-api中引入依赖

cn.itcast.demofeign-api1.0

  1. 配置连接池(同时修改日志级别)
feign:client:config:default: # default全局的配置loggerLevel: BASIC # 日志级别,BASIC就是基本的请求和响应信息 httpclient:    enabled: true # 开启feign对HttpClient的支持max-connections: 200 # 最大的连接数max-connections-per-route: 50 # 每个路径的最大连接数

2.4 最佳实践

2.4.1 方式一:继承

  1. 方式:从 2.1.3. Feign的使用中可知,Feign客户端的编写与user服务service的编写很像,故可以抽象出相同部分,然后给这两个地方继承。
  2. 缺点:1)两个服务会产生紧耦合,并且父接口参数列表中的映射并不会被继承。

2.4.2 方式二:抽取

  1. 方法:将FeignClient抽取为独立的模块,并把与接口与欧冠的POJO,默认的Feign配置都放到这个模块中来,提供给所有的消费者使用。(其他消费者只需要在启动类中添加注解@EnableFeignClients即可使用)
    注意事项:由于是新建的一个项目Feign-api,故其他服务在使用过程中需要引入依赖才能使用其他项目的服务
        cn.itcast.demofeign-api1.0
  1. 抽取FeignClient的步骤
    1)创建mudule并依赖首先创建一个module,取名为feign-api,然后引入feign的starter依赖
    2)将order中编写的UserLcient,User,DefaultFeignConfiguration都复制到feign-api项目中
    3)在order-service引入feign-api的依赖
    4)修改order-service中的所有与上述三个组件有关的import部分,改成导入feign-api的包
    5)重启测试
  2. FeignClient不在启动类扫描包饭内内解决方法
    1)指定FeignClient所在包(范围大,全导进来了)
@EnableFeignClients(basePackages = "cn.itcast.feign.clients")

2)指定FeignClient字节码(小范围)

@EnableFeignClients(clients = {UserClient.class})

3. 统一网关Gateway

3.1 为什么需要网关

1. 网关的作用
1)身份认证和权限校验等:不是什么用户通过链接都能够访问的,需要指定的用户名等情况,或者需要某一些权限处于开启状态;
2)服务路由和负载均衡:将用户请求路由到微服务,并实现负载均衡。网关具有负载均衡的作用,故不需要自己去配置Ribbon

3)请求限流:同一个时刻,对于服务的访问,限制流量,不能够过于频繁访问。
2. 网关技术的实现
目前SpringCloud中,网关的实现包括两种:
1)gateway:SpringCloudGateWay则属于Spring5中提供的WebFlux,属于响应式编程的实现,具有更好的性能。
2)zuul:基于Servlet的实现,属于阻塞式的编程
3)区别:响应式编程和阻塞式编程。

3.2 GateWay的快速入门

  1. 建module,引依赖:网关依赖和服务发现依赖

org.springframework.cloudspring-cloud-starter-gateway


com.alibaba.cloudspring-cloud-starter-alibaba-nacos-discovery 

  1. 配置文件:编写路由配置和nacos的地址(编码形式设置网关)
    根据上面可知,网关路由route的配置包含以下四个部分:

1) 路由id:路由的id,是路由的唯一表示
2)路由目标(uri):路由的目标地址,http代表固定地址,lb代表根据服务名负载均衡
3)路由断言(predicates):判断路由的规则,例如Path=/user/**,判断路径是否以/user开头,如果是则符合
4)路由过滤器(filters):对请求和相应做处理

  1. 网关的执行过程

3.3 断言工厂

上述配置中的断言都是通过断言工厂进行执行的:读取用户定义的断言条件,对请求做出判断

1)我们在配置文件中书写的断言规则只是字符串,这些字符串会被Predicate Factory读取并处理,转变为路由判断的条件
2)例如Path=/user/**是按照路径匹配,规则是org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory类处理的
3)像这样的断言工厂还有好几十个,可自行通过说明进行使用。

3.4 过滤器工厂

1. 过滤器工厂介绍
在路由确定之后会通过过滤器进行过滤操作,再通过负载均衡分配到具体的服务中去。
过滤器可以对进入网关的请求微服务返回的响应做处理

2. 过滤器工厂种类
Spring提供了31种不同的路由过滤器工厂

3. 过滤器工厂使用案例
1)要求:给所有进入userservice的请求,添加一个请求头:Truth=itcast is freaking awesome!
2)实现步骤
(1)在gateway中修改配置文件,给userservice的路由添加过滤器

spring:cloud:gateway:routes: # 网关路由配置- id: user-service         #路由iduri: lb://userservice    #路由路径predicates:              #路由断言- Path=/user/‘**’      #判断是否存在/user路径filters: # 过滤器,带有s,可以有多个操作   - AddRequestHeader=Truth, Itcast is freaking awesome!  # 添加请求头

(2)如果要对所有的路由都生效,故需要将过滤器工厂写到default下面,格式如下:

3.5 全局过滤器(GlobalFilter)

3.5.1 什么是全局过滤器,为什么需要全局过滤器

1)全局过滤器能够处理一切进入网关的请求和微服务相应,与GatewayFilter的作用是一致的。
2)与GatewayFilter的区别:GatewayFilter是通过配置文件实现的,处理逻辑固定;GlobalFilter的逻辑需要自己写代码实现,更加灵活!

3.5.2. 全局过滤器的实现方式

1)实现GlobalFilter接口:

全局过滤器 GlobalFilter
public interface GlobalFilter {/***  处理当前请求,有必要的话通过{@link GatewayFilterChain}将请求交给下一个过滤器处理** @param exchange 请求上下文,里面可以获取Request、Response等信息* @param chain 用来把请求委托给下一个过滤器 * @return {@code Mono} 返回标示当前过滤器业务结束*/Mono filter(ServerWebExchange exchange, GatewayFilterChain chain);
}

2)添加@Order注解或者实现Ordered接口:为了给过滤器进行优先级排序
3)编写处理逻辑
4)添加注解@Component,注入bean中,方便使用

3.5.3. 全局过滤器的实现案例

  1. 问题说明:定义全局过滤器,拦截并判断用户身份
    需求:定义全局过滤器,拦截请求,判断请求的参数是否满足下面条件:

参数中是否有authorization,
authorization参数值是否为admin

  • 参数中是否有authorization,
  • authorization参数值是否为admin
  • 如果同时满足则放行,否则拦截
  1. 逻辑实现

五步走:
(1)获取请求参数
(2)获取authorization参数
(3)校验
(4)放行
(5)禁止访问/结果处理

3.5 过滤器的执行顺序

三种过滤器:当前路由过滤器,DefaultFilter过滤器,GlobalFilter
在这里插入图片描述

  1. 首先根据指定的order值进行比较:order值越小,优先级越高,执行顺序越靠前。
    1)GlobalFilter通过实现Odered接口,或者添加@Order注解指定order值,有我们自己指定
    2)路由过滤器和defaultfilter过滤器的order的值由Spring指定,默认是按照声明顺序从1开始递增
    3)在order值相同时,会按照:defaultFilter > 路由过滤器 > GlobalFilter 的顺序执行

3.6 限流过滤器

  1. 作用:限流是保护服务器,避免因为过多的请求而导致服务器过载或者宕机
  2. 限流算法:计算机算法,漏桶算法,令牌桶算法。

3.7 小总结

网关其实并不需要改变其他服务中的代码,只是一个额外的功能,单独在网关服务中,其实现的原理有:
1)首先生成一个网关服务,添加启动类
2)引入注册发现依赖,引入网关依赖
3)网关的过滤作用在配置文件中声明实现(路由过滤器和defaultfilter,都是申明式的)
4)通过GlobalFilter过滤器实现:通过添加一个类,继承GlobalFilter接口,再书写逻辑,可以更加灵活的操作。

在微服务体系中,配置文件和依赖非常重要

参考文献
1)黑马程序员SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈课

图片:

红色字体

用于复制

相关内容

热门资讯

描写冷月的古诗句 描写冷月的古诗句  在日常生活或是工作学习中,大家一定都接触过一些使用较为普遍的诗句吧,诗句具有音韵...
表达思念的诗句亲人 表达思念的诗句亲人  江水三千里,家书十五行。行行无别语,只道早还乡。下面是描写表达思念的诗句亲人,...
描写爱情美好的诗句 描写爱情美好的诗句  曾经沧海难为水,除却巫山不是云------唐.元稹<<离思五首>>  从此无心...
宋玉神女赋原文及译文 宋玉神女赋原文及译文  在平平淡淡的学习中,大家对文言文一定不陌生吧?现在我们一般将古文称为文言文。...
2020纪念抗战胜利75周年... 七十五年,可以让一棵小树苗,长成青葱的参天大树,75年也可以让一个朝气勃发的少年变成一个已年过花甲的...
描写咏柳的诗句 描写咏柳的诗句  昔我往矣,杨柳依依。历代都有咏柳的诗句名篇。以下是专门为你收集整理的`描写咏柳的诗...
描写雪的诗句 描写雪的诗句(精选50句)  在平日的学习、工作和生活里,说到诗句,大家肯定都不陌生吧,诗句一般饱含...
大班诗歌《秋天的颜色》 大班诗歌《秋天的颜色》  在平日的学习、工作和生活里,大家都对那些朗朗上口的诗歌很是熟悉吧,诗歌节奏...
倚窗思秋,心缠绵散文 倚窗思秋,心缠绵散文(通用22篇)  在生活、工作和学习中,大家都接触过散文吧?狭义上的散文是指与诗...
端午节诗歌朗诵稿小学 端午节诗歌朗诵稿小学(通用20首)  在社会发展不断提速的今天,大家最不陌生的就是朗诵稿了吧,朗诵是...
前世今生缘诗歌 前世今生缘诗歌  我曾是佛前一朵靑莲。  为实现前世今生的缘,  佛前我千年沉睡。  千百度轮回,等...
我就在你身旁诗歌 我就在你身旁诗歌  风紧了  你可曾感到一丝的寒  而我就在你的身旁  默默地追随着  你的足迹  ...
经典感人父爱诗歌朗诵 经典感人父爱诗歌朗诵  父爱如山。那关于经典感人父爱诗歌朗诵有那洗饿呢?下面是小编整理的关于经典感人...
五一赞美劳动者现代诗歌简短1... 五一劳动节是一个法定节假日,具有重要的意义,2021年五一劳动节就要到了,那五一赞美劳动者现代诗歌简...
秋天诗歌 秋天诗歌大全  在现实生活或工作学习中,说到诗歌,大家肯定都不陌生吧,诗歌在形式上,不是以句子为单位...
两相忘爱情诗歌 两相忘爱情诗歌  昨夜雨落旦微凉  休怪小女思君长  天微凉  思君长  青丝丈量君远行  君远行 ...
母亲节赞美母爱励志唯美诗歌 母爱是灿烂的阳光,当我们失败的时候,母爱总会给我们带来的温暖和鼓励!那母亲节赞美母爱励志唯美诗歌有哪...
赞美家乡的诗歌 赞美家乡的诗歌(精选10首)  在学习、工作或生活中,说到诗歌,大家肯定都不陌生吧,诗歌是表现诗人思...
歌颂抗击疫情的诗歌 歌颂抗击疫情的诗歌歌颂抗击疫情的诗歌1  抗击新肺炎,一场没有硝烟的战争  活跃着一群身影  他们的...
终究不是一路人诗歌 终究不是一路人诗歌  磁场不合的人,终究不是一路人  有些人,  你见到第一眼,就感觉很舒服;  有...