全国免费咨询:

13245491521

VR图标白色 VR图标黑色
X

中高端软件定制开发服务商

与我们取得联系

13245491521     13245491521

2024-04-19_Spring Cloud Gateway实战

您的位置:首页 >> 新闻 >> 行业资讯

Spring Cloud Gateway实战 点击关注公众号,“技术干货”及时达!1 Spring Cloud Gateway的选择1.1 什么是Spring Cloud GatewaySpring Cloud Gateway(以下简称Gateway)是Spring生态系统中的一个API网关,它可以「处理HTTP请求和响应」,并「充当微服务架构中的入口点」。它是一个基于Spring Framework 5和Spring Boot 2.x的开源项目,采用响应式编程模型,旨在提供「高性能、高可靠性和易于使用的API网关」解决方案。 1.2 为什么选择Spring Cloud GatewaySpring Cloud Gateway有以下几个主要的功能,笔者当时采用该组件的原因就是其灵活的路由以及过滤功能,还有就是它和springboot项目良好的契合性,可以算是简单易上手、无侵入性了。 「请求路由」:当一个客户端发送请求到Spring Cloud Gateway时,Gateway会将请求路由到适当的微服务实例。Gateway会根据请求的URI和HTTP方法来匹配预定义的路由规则,并将请求转发给目标微服务。「过滤器」:Gateway还支持过滤器,开发人员可以编写过滤器来实现请求和响应的定制逻辑,例如鉴权、限流、日志记录等。「负载均衡」:Gateway可以通过Spring Cloud的负载均衡器来负载均衡请求,这可以确保请求被均匀分配到各个微服务实例中,从而提高系统的可用性和性能。「响应转换」:Gateway还支持响应转换,可以将微服务返回的响应转换成另一种格式,例如JSON或XML。「故障转移」:Gateway还支持故障转移,当微服务实例出现故障时,Gateway会自动将请求转发到备用实例,以确保系统的可用性。2 Spring Cloud Gateway的使用2.1 Spring Cloud Gateway在项目中的应用?spring cloud gateway至少要求JDK8(函数式编程); ?新建一个maven项目,引入springboot的一些基础依赖,再引入关键依赖: dependency groupIdorg.springframework.cloud/groupId artifactIdspring-cloud-starter-gateway/artifactId /dependency ?笔者在使用maven打包时,最终打包出来的jar包不可用,在项目下加入以下编译配置就解决了 ?build plugins plugin groupIdorg.springframework.boot/groupId artifactIdspring-boot-maven-plugin/artifactId configuration includeSystemScopetrue/includeSystemScope /configuration executions execution goals goalrepackage/goal /goals /execution /executions /plugin /plugins /build 在使用Gateway时,有两种配置方式:配置文件配置和Java代码配置,在日常的使用时,都是以配置文件配置为主(建议使用yaml文件)。 配置文件server: port:8000 spring: application: name:xxx-gateway cloud: gateway: routes:#路由数组[路由就是指定当请求满足什么条件的时候转到哪个微服务] -id:service-a#当前路由的标识,要求唯一 uri:http://127.0.0.1:8080#请求要转发到的地址 order:1#路由的优先级,数字越小级别越高 predicates:#断言(就是路由转发要满足的条件) -Path=/a/** #当请求路径满足Path指定的规则时,才进行路由转发 filters: -StripPrefix=1 #去掉一级前缀 -id:service-bcd uri:http://127.0.0.1:8081 predicates: -Path=/b/**,/c/**,/d/** #多路径匹配时用英文逗号分隔 Java Bean配置importorg.springframework.cloud.gateway.route.RouteLocator; importorg.springframework.cloud.gateway.route.builder.RouteLocatorBuilder; importorg.springframework.context.annotation.Bean; importorg.springframework.context.annotation.Configuration; @Configuration publicclassGatewayConfig{ @Bean publicRouteLocatorcustomRouteLocator(RouteLocatorBuilderbuilder){ returnbuilder.routes() .route("service-a",r-r.order(1) .path("/a/**") .filters(f-f.stripPrefix(1)) .uri("http://127.0.0.1:8080")) .route("service-bcd",r-r.path("/b/**") .or().path("/c/**") .or().path("/d/**") .uri("http://127.0.0.1:8081")) .build(); } } ?上述配置文件和Java Bean的效果相同 ?Gateway提供了多种配置组合来完成对应的路由转发规则: uri:目标服务地址,可配置uri和lb://应用服务名称order:路由优先级,值越小优先级越高predicates:匹配条件,根据规则匹配是否请求该路由filters: 过滤规则,这个过滤包含多种过滤器StripPrefix=1,表示去掉几级前缀,例如上述配置中,我们访问 http://127.0.0.1:8000/a/test 将会转发到 http://127.0.0.1:8080/test 中。其中predicates和filters是实现各种自定义转发的关键。 2.1.1 Route Predicate(路由谓词)predicates拥有多种匹配条件,以下只列举常用的几种,详细的谓词介绍见Route Predicate(路由谓词)工厂。 时间谓词「After」,这个谓词匹配发生在指定日期时间之后的请求。「Before」,这个谓词匹配发生在指定日期时间之前的请求。「Between」,这个谓词匹配发生在两个时间之间的请求。spring: cloud: gateway: routes: -id:after_route uri:https://example.org predicates: -After=2017-01-20 #匹配2017-01-20之后的请求 -id:before_route uri:https://example.org predicates: -Before=2017-01-20 #匹配2017-01-20之前的请求 -id:between_route uri:https://example.org predicates: -Between=2017-01-20,2017-01-21 #匹配2017-01-20到2017-01-21之间的请求 Cookie这个谓词匹配具有给定名称且其值符合正则表达式的cookie。 spring: cloud: gateway: routes: -id:cookie_route uri:https://example.org predicates: -Cookie=username,^[A-Za-z_] #匹配cookie中要包含名为username且值必须以字母开头的参数 Header这个谓词匹配具有给定名称且其值与正则表达式相匹配的请求头。 spring: cloud: gateway: routes: -id:header_route uri:https://example.org predicates: -Header=X-Request-Id,\d+ #匹配请求头中X-Request-Id的值为数字的请求 Host这个谓词匹配符合该正则的主机名称的请求。 spring: cloud: gateway: routes: -id:host_route uri:https://example.org predicates: -Host=**.somehost.org #匹配来自somehost.org子域名的请求 Method这个谓词匹配指定请求方式的请求。 spring: cloud: gateway: routes: -id:method_route uri:https://example.org predicates: -Method=GET,POST #匹配GET、POST请求 Path这个谓词匹配指定请求路径的请求。 spring: cloud: gateway: routes: -id:path_route uri:https://example.org predicates: -Path=/a/* #匹配所有请求路径/a/*的请求,例如/a/test 2.1.2 Route filters(路由过滤器)Gateway 支持多种内置的过滤器,可以对请求进行多种处理。以下也只列举几种常用的filter,详细的filter见GatewayFilter 工厂。 AddRequestHeader该过滤器可以在转发请求时新增或替换指定请求头信息。 spring: cloud: gateway: routes: -id:add_request_header_route uri:https://example.org filters: -AddRequestHeader=X-Request-color,blue #该过滤器将X-Request-color:blue请求头附加在请求中 AddRequestParameter该过滤器可以给转发的请求添加指定的查询参数。 spring: cloud: gateway: routes: -id:add_request_parameter_route uri:https://example.org filters: -AddRequestParameter=color,blue #该过滤器添加了color=blue的查询参数 AddResponseHeader与AddRequestHeader相对应,该过滤器可以在接收请求的返回信息时新增或替换指定请求头信息。 spring: cloud: gateway: routes: -id:add_response_header_route uri:https://example.org filters: -AddResponseHeader=X-Response-color,Blue #该过滤器将X-Request-color:blue请求头附加在请求中 PrefixPath该过滤器可以将所有转发的请求加上指定的前缀。 spring: cloud: gateway: routes: -id:prefixpath_route uri:https://example.org filters: -PrefixPath=/prefix #经过该路由的请求都会加上/prefix前缀,例如原来为/hello的请求会转发到/prefix/hello RedirectTo该过滤器可以将请求重定向至指定URL并附带300系列的重定向HTTP状态码。 spring: cloud: gateway: routes: -id:prefixpath_route uri:https://example.org filters: -RedirectTo=302,https://redirect.org #该过滤器将发送一个带有 Location:https://redirect.org header的 302 状态码的响应,以执行重定向。 RewritePath该过滤器可以将请求路径重写。 ?注意,由于YAML的规范,$应该写成$\。 ?spring: cloud: gateway: routes: -id:rewritepath_route uri:https://example.org predicates: -Path=/red/** filters: -RewritePath=/red/?(?segment.*),/$\{segment} #请求为/red/blue的情况下会变成/blue StripPrefix该过滤器可以去除请求路径中指定层级的前缀。 spring: cloud: gateway: routes: -id:stripprefix_route uri:https://example.org predicates: -Path=/name/** filters: -StripPrefix=1 #经过网关的请求/name/aa/bb会变成/aa/bb,如果StripPrefix=2,请求会变成/bb,依此类推 Retry该过滤器提供重试机制。该过滤器拥有以下参数: retries: 重试次数。默认为3。statuses: 需要重试的HTTP状态代码,用org.springframework.http.HttpStatus表示。methods: 重试的HTTP方法,用org.springframework.http.HttpMethod来表示。默认是GET请求。series: 要重试的状态代码系列,用org.springframework.http.HttpStatus.Series表示。默认是5XX系列状态码。exceptions: 要重试的异常类型。默认是IOException和TimeoutException。backoff: 为重试配置的指数式backoff。重试是在backoff间隔firstBackoff * (factor ^ n)之后进行的,其中n是迭代次数。如果配置了maxBackoff,应用的最大 backoff 时间被限制在maxBackoff。如果basedOnPreviousValue为true,则通过使用prevBackoff * factor来计算backoff。默认未启用。spring: cloud: gateway: routes: -id:retry_test uri:http://localhost:8080/flakey predicates: -Host=*.retry.com filters: -name:Retry args: retries:3 statuses:500 methods:GET,POST backoff: firstBackoff:10ms maxBackoff:50ms factor:2 basedOnPreviousValue:false #请求发生500错误时,在10ms、40ms后重试两次 全局过滤器 default-filters如果要添加指定的filter并将其应用于所有的路由,可以使用spring.cloud.gateway.default-filters。 spring: cloud: gateway: default-filters: -AddResponseHeader=X-Response-Default-Color,Blue -PrefixPath=/aa #所有请求会添加/aa的请求前缀,还会在返回报文的请求头处加入X-Response-Default-Color:Blue的请求头参数 2.1.3 SSL证书配置在使用Gateway进行路由转发时,不可避免的会涉及到需要SSL证书的情况,Gateway可以通过遵循通常的 Spring server configuration 来监听 HTTPS 请求。 server: ssl: enabled:true key-alias:scg key-store-password:scg1234 key-store:classpath:scg-keystore.p12 key-store-type:PKCS12 如果需要转发到使用HTTPS的下游,你可以将Gateway配置为信任所有下游的证书。 ?只建议在内网环境且下游是后端服务时使用。 ?spring: cloud: gateway: httpclient: ssl: useInsecureTrustManager:true 在生产等对安全要求较高的环境中,可以配置指定网关所信任的证书。 spring: cloud: gateway: httpclient: ssl: trustedX509Certificates: -cert1.pem -cert2.pem 如果 Spring Cloud Gateway 没有配置受信任的证书,就会使用默认的 trust store(即启动项目的JDK中配置的证书,可以通过设置 javax.net.ssl.trustStore 系统属性来配置它)。 2.1.4 CORS跨域配置Global CORS 配置,也就是对所有向Gateway发起的请求的跨域配置 spring: cloud: gateway: globalcors: cors-configurations: '[/**]': allowedOrigins:"https://example.org" allowedMethods: -GET #允许来自https://example.org的GET请求 2.1.5 网关日志记录在本文中,笔者采用重写 GlobalFilter 的方式来实现日志记录,这也是官方提供的一种自定义 Filter 的方式。 importlombok.extern.slf4j.Slf4j; importorg.springframework.cloud.gateway.filter.GatewayFilterChain; importorg.springframework.cloud.gateway.filter.GlobalFilter; importorg.springframework.http.server.reactive.ServerHttpRequest; importorg.springframework.stereotype.Component; importorg.springframework.web.server.ServerWebExchange; importreactor.core.publisher.Mono; @Component @Slf4j publicclassLoggingFilterimplementsGlobalFilter{ @Override publicMonoVoidfilter(ServerWebExchangeexchange,GatewayFilterChainchain){ ServerHttpRequestrequest=exchange.getRequest(); //获取客户端IP地址 Stringip=request.getRemoteAddress()!=null?request.getRemoteAddress().getAddress().getHostAddress():"Unknown"; //记录IP和请求行 log.info("RequestfromIP:{},Method:{},Path:{}",ip,request.getMethodValue(),request.getPath()); StringrealIp=request.getHeaders().getFirst("X-Forwarded-For"); log.info("X-Forwarded-For:{}",realIp); //继续filter链的处理,如果没有这步操作会导致Gateway转发失效 returnchain.filter(exchange); } } ?上述代码只是简单的记录了一下请求的来源、请求类型、请求路径以及可能经过nginx转发的真实IP。需要注意的是如果想要记录POST、PUT等请求body里面的内容时,需要额外实现数据流重复读取的机制,否则会导致下游服务无法读取到body信息。 ?3 性能影响在实际项目中,大多会有一层Nginx进行的路由转发,如果再加上Gateway的转发消耗的话,可能会对原有的接口性能造成影响。 参考以下大佬做的测试,对实际的请求还是有一定影响的,但是相比于Netflix的zuul,已经好很多了。读者可以参考自己的业务需求再决定是否使用Spring Cloud Gateway。 服务平均时延(ms)RPS(每秒请求数)性能损失Origin2.9433014.700Netflix Zuul12.3913175.2160.09%Spring Cloud Gateway4.9521685.1434.32%本文参考手把手快速入门springcloud之Gateway网关spring gateway性能损耗 -- 记一次性能测试Spring Cloud Gateway(一)为什么用网关、能做什么、为什么选择Gateway、谓词工厂、过滤器配置Spring Cloud Gateway 中文文档点击关注公众号,“技术干货”及时达! 阅读原文

上一篇:2024-03-25_「转」资深广告导演张哲 首直播:如何才能操盘百万级项目 下一篇:2019-07-07_7 papers | 3篇综述论文,全面了解机器阅读理解、图表征学习等

TAG标签:

17
网站开发网络凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设网站改版域名注册主机空间手机网站建设网站备案等方面的需求...
请立即点击咨询我们或拨打咨询热线:13245491521 13245491521 ,我们会详细为你一一解答你心中的疑难。
项目经理在线

相关阅读 更多>>

猜您喜欢更多>>

我们已经准备好了,你呢?
2022我们与您携手共赢,为您的企业营销保驾护航!

不达标就退款

高性价比建站

免费网站代备案

1对1原创设计服务

7×24小时售后支持

 

全国免费咨询:

13245491521

业务咨询:13245491521 / 13245491521

节假值班:13245491521()

联系地址:

Copyright © 2019-2025      ICP备案:沪ICP备19027192号-6 法律顾问:律师XXX支持

在线
客服

技术在线服务时间:9:00-20:00

在网站开发,您对接的直接是技术员,而非客服传话!

电话
咨询

13245491521
7*24小时客服热线

13245491521
项目经理手机

微信
咨询

加微信获取报价