JAVA微服务_网关

这篇具有很好参考价值的文章主要介绍了JAVA微服务_网关。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

关键字:GateWay, SpringCloud, Alibaba

服务网关

  • 什么是服务网关/API网关

API Gateway(APIGW / API 网关),顾名思义,是系统对外的唯一入口。API网关封装了系统内部架构,为每个客户端提供定制的API。 近几年来移动应用与企业间互联需求的兴起。从以前单一的Web应用,扩展到多种使用场景,且每种使用场景对后台服务的要求都不尽相同。 这不仅增加了后台服务的响应量,还增加了后台服务的复杂性。随着微服务架构概念的提出,API网关成为了微服务架构的一个标配组件。

  • 为什么要使用网关

微服务的应用可能部署在不同机房,不同地区,不同域名下。此时客户端(浏览器/手机/软件工具)想 要请求对应的服务,都需要知道机器的具体 IP 或者域名 URL,当微服务实例众多时,这是非常难以记忆的,对 于客户端来说也太复杂难以维护。此时就有了网关,客户端相关的请求直接发送到网关,由网关根据请求标识 解析判断出具体的微服务地址,再把请求转发到微服务实例。这其中的记忆功能就全部交由网关来操作了。

负载均衡、路由、限流、协议适配、服务降级、熔断、重试、鉴权、计量计费

各种网关方案

Nginx + Lua

没有熔断、重试等功能。可以限流,GateWay集成Redis限流就是用的这种方式。

Kong

对Nginx+Lua再次封装

SpringCloud Gateway

Spring Cloud Gateway是Spring官方基于Spring 5.0,Spring Boot 2.0和Project Reactor等技术开发的网关,Spring Cloud Gateway旨在为微服务架构提供一种简单而有效的统一的API路由管理方式。Spring Cloud Gateway作为Spring Cloud生态系中的网关,目标是替代ZUUL,其不仅提供统一的路由方式,并且基于Filter链的方式提供了网关基本的功能,例如:安全,监控/埋点,和限流等。

WebFlux(异步非阻塞IO)

Zuul

1.0版本单线程,后来跳票,又已经出了GateWay,就不更新了

SpringCloud Gateway

快速上手

添加依赖

注:gateway中不能添加springMVC的依赖,因为用的是WebFlux模型

配置文件,以route(路由)为单位的微服务资源被Gateway管理

spring:
	cloud:
		gateway:
			route: 
				- id: #路由对象唯一标识(随便写,唯一就行)
				  uri: #该服务的访问地址
				  predicates:	# 断言,相当于前置fliter
				  	- Path=/path1,/path2/**	# 将该Path的访问转发到url(通过网关访问服务的路径)
				  	- After=2021-02-23T14:20:00.000+08:00[Asia/Shanghai] # 还有Before和Between(前后两个时间 )
				  	- Cookie=loginname, ruoyi
				  	- Header=X-Request-Id, \d+ #\d+值匹配正则表达式,其他项设置也可用
				  filters:				    
				    -AddRequestParameter=key, value #给当前路由对象所有请求加入添加参数(直接用形参接收的那个)
				    -AddRequestHeader=key, value	#****加入请求头信息(HttpServletRequest接收,getHeader())
				    -PrefixPath=/mypath	#最终转发路径为:uri+该前缀+path

访问规则:path后面保留,前面网关的网址替换为uri地址

负载均衡

之前用http协议写死uri的方式,没法负载均衡;
此处案例,以服务id管理路由(route),并以"lb"为前缀
lb是LoadBalance的缩写。这样表示从微服务注册中心(如Eureka)订阅服务

  • 所以负载均衡是自己实现的还是注册中心实现的?
spring:
	cloud:
		gateway:
			route:
				- id: #路由对象唯一标识(随便写,唯一就行)
				  uri: lb://服务id #地址
				  predicates:	# 断言,配置规则
				  	- Path=/path1,/path2/**	# 将该Path的访问转发到url(通过网关访问服务的路径)

类似ribbon,根据服务id去服务中心拉取该服务的列表,然后进行负载均衡

  • 拉到本地?那不是Dubbo干的事情?

自定义Filter

自定义的Filter,选择合适的接口实现,如GlobalFilter;
通过@Bean或者类上的@Component注解将自定义Filter交给Spring容器管理

官网关于全局过滤器的例子。

@Bean
public GlobalFilter customFilter() {
    return new CustomGlobalFilter();
}

public class CustomGlobalFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("custom global filter");
        return chain.filter(exchange);		//放行
    }
	
    //过滤器顺序,按自然数顺序,-1为在所有fliter之前
    @Override
    public int getOrder() {
        return -1;
    }
}

注意全局过滤器不需要在配置文件里配置到某一路由上了,因为全局有效;

非全局的自定义filter要进行配置到route上,将类名写上

      routes:
        # 认证中心
        - id: ruoyi-auth
          uri: lb://ruoyi-auth
          predicates:
            - Path=/auth/**
          filters:
            # 验证码处理
            - CacheRequestFilter
            - ValidateCodeFilter
            - StripPrefix=1
  • 原理是什么?通过类名获取bean吗?

Gateway 网关层的白名单实现原理是在过滤器内判断请求地址是否符合白名单,如果通过则跳过当前过滤器。

ServerWebExchange封装了request和response,可以通过get方法拿到

但gateway采用的是webFlux模型,返回的是ServerHttpRequest类的对象

整个Filter类似Servlet的Filter处理流程(doFilter方法)

注意放行后的代码也会被执行,因为gateway组件下响应返回时又要经过Fliter

更多功能

限流

常见的限流算法有:计数器算法,漏桶(Leaky Bucket)算法,令牌桶(Token Bucket)算法。

Spring Cloud Gateway官方提供了RequestRateLimiterGatewayFilterFactory过滤器工厂,使用RedisLua脚本实现了令牌桶的方式。

1、添加依赖

<!-- spring data redis reactive 依赖 -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>

配置fliter

spring:
  cloud:
    gateway:
      routes:
        # 系统模块
        - id: ruoyi-system
          uri: lb://ruoyi-system
          predicates:
            - Path=/system/**
          filters:
            - StripPrefix=1
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 1 # 令牌桶每秒填充速率
                redis-rate-limiter.burstCapacity: 2 # 令牌桶总容量
                key-resolver: "#{@pathKeyResolver}" # 使用 SpEL 表达式按名称引用 bean

StripPrefix=1表示截取路径的前缀个数为1;
比如前端过来请求/test/good/1/view,匹配成功后,路由到后端的请求路径就会变成http://localhost:8888/good/1/view。
别忘了配置redis

  • 为什么过滤器要截取前缀?
    key-resolver,用于限流的键的解析器的 Bean 对象的名字。它使用 SpEL 表达式根据#{@beanName}从 Spring 容器中获取 Bean 对象。

编写URI限流规则配置类

import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import reactor.core.publisher.Mono;

/**
 * 限流规则配置类
 */
@Configuration
public class KeyResolverConfiguration
{
    @Bean
    public KeyResolver pathKeyResolver()
    {
        return exchange -> Mono.just(exchange.getRequest().getURI().getPath());
    }
}

这里根据请求路径中"user"参数限流

@Bean
KeyResolver pathKeyResolver() {
  return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
}

KeyResolver需要实现resolve方法,比如根据userid进行限流,则需要用userid去判断。实现完KeyResolver之后,需要将这个类的Bean注册到Ioc容器中。

如果需要根据IP限流,定义的获取限流Key的bean为:

@Bean
public KeyResolver ipKeyResolver() {
  return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName());
}

通过exchange对象可以获取到请求信息,这边用了HostName,如果你想根据用户来做限流的话这边可以获取当前请求的用户ID或者用户名就可以了,比如:

如果需要根据接口的URI进行限流,则需要获取请求地址的uri作为限流key,定义的Bean对象为:

@Bean
KeyResolver apiKeyResolver() {
  return exchange -> Mono.just(exchange.getRequest().getPath().value());
}

通过exchange对象可以获取到请求信息,这边用了HostName,如果你想根据用户来做限流的话这边可以获取当前请求的用户ID或者用户名就可以了,比如:

如果需要根据接口的URI进行限流,则需要获取请求地址的uri作为限流key,定义的Bean对象为:

@Bean
KeyResolver apiKeyResolver() {
  return exchange -> Mono.just(exchange.getRequest().getPath().value());
}
  • 你也是reactor?

多次请求会发现返回HTTP ERROR 429,同时在redis中会操作两个key,表示限流成功。

request_rate_limiter.{xxx}.timestamp
request_rate_limiter.{xxx}.tokens

其他限流规则

参数限流:key-resolver: "#{@parameterKeyResolver}"

@Bean
public KeyResolver parameterKeyResolver()
{
	return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("userId"));
}

Spring Cloud Gateway官方提供了RequestRateLimiterGateway这个过滤器,适用在Redis内的通过执行Lua脚本实现了令牌桶的方式。具体实现逻辑在RequestRateLimiterGatewayFilterFactory类中,lua脚本spring-cloud-gateway-core中。

熔断降级

见Hystrix

原理解析

官网的流程图

java 网关,微服务,java,微服务,开发语言

gateway = 断言(前置filter)+过滤(后置filter)

此处前置后置指转发前后(这是一种比喻的说法,其实前置不像是filter,而像是predicate,满足条件才通过)

Filter来回都要走一次哦

断言和过滤都有很多工厂类,不一一讲了

似乎是抽象工厂模式,顶层接口RoutePredicateFactory下有抽象工厂类,然后又工厂类
也有责任链模式的味道

断言 Route Predicate Factories

官网有11个

常用的就是配置文件中predicate下的那些

过滤 GatewayFilter Factories

官网有31个

过滤器不止过滤的功能,而是类似切面做各种操作(如添加请求头信息)

附录:

java代码配置路由

reactor的异步非阻塞模型

java代码配置的生效优先级高,原因是先加载配置再加载代码,导致代码覆盖了配置设置的数据

	@Bean
	public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
		return builder.routes()
			.route("path_route", r -> r.path("/get")
				.uri("http://httpbin.org"))
			.route("host_route", r -> r.host("*.myhost.org")
				.uri("http://httpbin.org"))
			.route("rewrite_route", r -> r.host("*.rewrite.org")
				.filters(f -> f.rewritePath("/foo/(?<segment>.*)", "/${segment}"))
				.uri("http://httpbin.org"))
			.route("hystrix_route", r -> r.host("*.hystrix.org")
				.filters(f -> f.hystrix(c -> c.setName("slowcmd")))
				.uri("http://httpbin.org"))
			.route("hystrix_fallback_route", r -> r.host("*.hystrixfallback.org")
				.filters(f -> f.hystrix(c -> c.setName("slowcmd").setFallbackUri("forward:/hystrixfallback")))
				.uri("http://httpbin.org"))
			.route("limit_route", r -> r
				.host("*.limited.org").and().path("/anything/**")
				.filters(f -> f.requestRateLimiter(c -> c.setRateLimiter(redisRateLimiter())))
				.uri("http://httpbin.org"))
			.build();
	}


可视化监控

Gateway暴漏了actuator端口,可用于监控路由信息等

http://localhost:8989/actuator/gateway/routes

management:
	endpoints:
		web:
			exposure:
				include: "*"	#开启所有的Web端点暴漏,有些版本要填写数组,应为["*"]

官网例子:

management.endpoint.gateway.enabled=true # default value
management.endpoints.web.exposure.include=gateway

需要注意在Gateway服务中的pom.xml文件中不要存在这个jar

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>

否则调用接口时会报以下错误因为gateway使用的是webflux,默认使用netty,所以从依赖中排除 tomcat相关的依赖

java.lang.ClassCastException: org.springframework.core.io.buffer.DefaultDataBufferFactory cannot be cast to org.springframework.core.io.buffer.NettyDataBufferFactory
at org.springframework.cloud.gateway.filter.NettyWriteResponseFilter.lambda$filter$1(NettyWriteResponseFilter.java:82) ~[spring-cloud-gateway-core-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:44) [reactor-core-3.2.12.RELEASE.jar:3.2.12.RELEASE]文章来源地址https://www.toymoban.com/news/detail-676589.html

到了这里,关于JAVA微服务_网关的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java之SpringCloud Alibaba【七】【Spring Cloud微服务网关Gateway组件】

    Java之SpringCloud Alibaba【一】【Nacos一篇文章精通系列】 跳转 Java之SpringCloud Alibaba【二】【微服务调用组件Feign】 跳转 Java之SpringCloud Alibaba【三】【微服务Nacos-config配置中心】 跳转 Java之SpringCloud Alibaba【四】【微服务 Sentinel服务熔断】 跳转 Java之SpringCloud Alibaba【五】【微服务

    2024年02月06日
    浏览(60)
  • 开发语言漫谈-Java

            由于C++过于复杂,Java诞生了。与C++相比,Java更易于学习和使用,它去掉C++中的指针和解决了内存管理问题。Java提供了垃圾自动回收机制,自动管理不再使用的内存。Python又进一步简化,使得语法更简洁,更易于阅读和编写。当然随着简化,性能就越来越低。    

    2024年04月10日
    浏览(46)
  • 海康威视相机SDK二次开发(JAVA语言)

    前言 有个项目需要使用java程序读取海康威视的相机图片。相机通过以太网连接服务器,部署在服务器上的java程序将相机拍摄的画面保存在指定路径下。 海康威视提供了sdk开发包,可以在官网中下载,windows和linux系统都有。但是开发包中给出的示例代码,无法满足实际需要,

    2024年04月29日
    浏览(46)
  • 【开发经验】gateway网关开发调试优先选择本地服务

    背景 在微服务开发时,本地要启动太多的服务,比如基本服务,注册中心、网关、鉴权等等。还要启动当前代码所在的服务。这样,本地环境会特别卡,影响开发效率。 : 如下图所示: 在局域网内搭建一套开发环境,在开发时,这个开发环境启动的服务用来做“备胎”。

    2024年02月02日
    浏览(39)
  • 【Java】后端开发语言Java和C#,两者对比注解和属性的区别以及作用

    欢迎来到《小5讲堂》 大家好,我是全栈小5。 这是《Java》序列文章,每篇文章将以博主理解的角度展开讲解, 特别是针对知识点的概念进行叙说,大部分文章将会对这些概念进行实际例子验证,以此达到加深对知识点的理解和掌握。 温馨提示:博主能力有限,理解水平有限

    2024年01月16日
    浏览(51)
  • BsinCopilot:Java版端到端大语言模型开发框架

    BsinCopilot是基于BsinPaaS开源框架构建的大语言模型应用SaaS服务,借鉴langchain的框架思想,引入  langchian4j组件,微前端微服务的架构设计,可快速助您构建和体验端到端的AI应用。 概念 说明 Bsin 毕昇缩写,毕昇,中国北宋发明家,活字印刷术的发明者。毕昇出身平民,长期在

    2024年03月13日
    浏览(57)
  • Android 安卓开发语言kotlin与Java该如何选择

            如今在Android开发中,应用层开发语言主要是Java和Kotlin,Kotlin是后来加入的,主导的语言还是Java。kotlin的加入仿佛让会kotlin语言的开发者更屌一些,其实不然。         有人说kotlin的引入是解决开发者复杂的逻辑,并且对空指针控制的比较友好,但是我们在开

    2024年02月11日
    浏览(61)
  • Java转Go:java开发者转学go语言,请给我一些建议和学习推荐

    在做开发时遇到最无理的需求就是部门没了😂 遇到最无理的需求就是部门没了😂,差点人也在这个公司没了,但好在是跟着大部队换了一个部门,就是要转go,也可能要用js和solidity开发 一开始知道部门没了,第一时间一定是会担心,甚至后面知道有的同事要被毕业,有的同

    2024年02月13日
    浏览(50)
  • Java语言B/S智慧工地云平台源码(微服务+Java+Spring Cloud +UniApp +MySql)

    目录 劳务管理 视频监控 绿色施工 危大工程管理 绿色施工——环境与能耗 高效施工——进度管控 文明施工——劳务管理 智慧工地建设效益     智慧工地云平台源码技术架构:微服务+Java+Spring Cloud +UniApp +MySql       智慧工地管理平台是依托 物联网、互联网、AI、可视化建

    2024年04月16日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包