微服务统一网关

核心提示实战路由过滤器工厂路由过滤器允许以某种方式修改传入的HTTP请求或传出的HTTP响应。路由过滤器的作用域是特定的路由。SpringCloud Gateway包括许多内置的GatewayFilter工厂。目前官网提供33种路由过滤器工厂,前面

真正的战斗

路由过滤器工厂

路由筛选器允许以某种方式修改传入的HTTP请求或传出的HTTP响应。路由过滤器的范围是特定的路由。云网关包括许多内置的GatewayFilter工厂。目前官网提供了33种路由过滤器工厂,上例中过滤器中的StripPrefix就是其中之一:

在库存微服务控制器中添加打印

@RequestMapping公共字符串存储{ log . info);返回“扣除库存”;}

Nacos中网关的配置增加了AddressHeader = x-request-red,blue。

服务器:端口:4090spring:云:网关:路由:-id:storage _ route uri:lb://ECOM-storage-service谓词:-Path =/storage-service/* *-Quantity = 100,200 filters:-strip prefix = 1-AddRequestHeader = X-Request-red,blue

访问http://localhost:4090/storage-service/承接数量= 100。从库存微服务的日志中可以看到,网关的过滤器已经添加了请求头信息。

还有许多其他滤波器实现方式。有时间可以一个一个的试试。

自定义本地过滤器工厂

建立一个授权的定制工厂过滤器工厂,从redis读取授权信息进行验证,首先创建RedisConfig配置类。

包cn . itxs . ECOM . gateway . config;导入com . faster XML . Jackson . annotation . jsonautodetect;import com . faster XML . Jackson . annotation . property accessor;导入com . faster XML . Jackson . databind . object mapper;导入lombok . extern . SLF 4j . SLF 4j;导入org . spring framework . context . annotation . bean;导入org . spring framework . context . annotation . configuration;导入org . spring framework . data . redis . connection . redisconnectionfactory;导入org . spring framework . data . redis . core . redis template;导入org . spring framework . data . redis . serializer . Jackson 2 jsonredisserializer;导入org . spring framework . data . redis . serializer . stringredserializer;@ Configuration @ SLF 4j public class redis config { @ Bean public redis template redis template { redis template template = new redis template;template.setConnectionFactoryJackson 2 jsonredisserializer Jackson 2 jsonredisserializer = new Jackson 2 jsonredisserializer;object mapper om = new object mapper;om.setVisibility//om . activatedefaulttyping;Jackson 2 jsonredisserializer . set object mapper;stringredessorializer stringredessorializer = new stringredessorializer;// key采用String template . setkey serializer的序列化方式;hash的key也采用String template . sethashkeyserializer的序列化方式;//值序列化模式为Jackson//template . setvalueserializer;template.setValueSerializerhash的值序列化采用Jackson//template . sethashvalueserializer;template . sethashvalueeserializer;template . after properties set;返回模板;}}折叠

Redis信息放在Nacos配置commons-dev.yaml中

AuthorizeGatewayFilterFactory.java,过滤器工厂创建,是继承自AbstractGatewayFilterFactory。

包cn . itxs . ECOM . gateway . factory;导入lombok . extern . SLF 4j . SLF 4j;导入org . spring framework . beans . factory . annotation . auto wired;导入org . spring framework . cloud . gateway . filter . gateway filter;导入org . spring framework . cloud . gateway . filter . factory . abstractgatewayfilterfactory;导入org . spring framework . data . redis . core . redis template;导入org . spring framework . http . http headers;导入org . spring framework . http . http status;导入org . spring framework . http . server . reactive . server http request;import org . spring framework . http . server . reactive . server httpresponse;导入org . spring framework . stereotype . component;导入org . spring framework . util . string utils;导入Java . util . arrays;导入Java . util . list;@ Component @ SLF 4j public class AuthorizeGatewayFilterFactory扩展AbstractGatewayFilterFactory { private static final String AUTHORIZE _ TOKEN = " TOKEN ";private static final String AUTHORIZE _ UID = " UID ";@ Autowired private redis template redis template;public AuthorizeGatewayFilterFactory { super;log.info} @ Override public List shortcutfield order { return arrays . as List;} @ Override public gateway filter apply { return--> { if){ return chain . filter;} server http request = exchange . get request;http headers headers = request . get headers;String token = headers.getFirstString uid = headers.getFirstif { token = request . getquery params . get first;} if { uid = request . getquery params . get first;} server httpresponse response = exchange . getresponse;如果||!string utils . hastext){ response . setstatuscode;返回response . set complete;} String authToken = redis template . ops for value . get;if){ response . setstatuscode;返回response . set complete;}返回chain.filter};}公共静态类配置{//控制是否打开身份验证私有布尔启用;public Config { public boolean is enabled { return enabled;} public void set enabled { this . enabled = enabled;}}}折叠

如果授权失败,返回HttpStatus。未授权,也就是http 401。

【外链图片传输失败,源站可能有防盗链机制,建议保存图片直接上传】

网关Nacos配置文件增加Authorize=true

服务器:端口:4090spring:云:网关:路由:-id:storage _ route uri:lb://ECOM-storage-service谓词:-Path =/storage-service/* *-Quantity = 100,200 filters:-strip prefix = 1-AddRequestHeader = X-Request-red,blue - Authorize=true

目前redis中没有关于uid和token的信息。访问http://localhost:4090/storage-service/conducted quantity = 100 UID = 1001 Token = ABC返回401状态。

我们将uid为1001的数据写入redis

再次访问http://localhost:4090/storage-service/conducted quantity = 100 uid = 1001 token = ABC,可以正常得到结果。

全局过滤器

先前配置中使用的lb由全局滤波器实现。ReactiveLoadBalanceClientFilter在名为serverwebexchangeutils . gateway _ request _ URL _ attr的exchange属性中查找URIs。如果URL具有lb方案,它使用Spring Cloud ReactorLoadBalancer将名称解析为实际的主机和端口,并替换相同属性中的URI。未修改的原始URL被附加到ServerWebExchangeUtils中的列表。网关_原始_请求_ URL _属性。GATEWAY_SCHEME_PREFIX_ATTR属性,看是否等于lb。如果等于,则适用相同的规则。

全局过滤器成功注册为bean后,无需配置即可直接生效。全局过滤器的范围适用于所有请求,而本地过滤器适用于路由。GlobalFilter是用于定义全局过滤器的接口。通过实现GlobalFilter接口,可以实现各种自定义过滤器。当有多个拦截器时,getOrder方法通过Ordered接口实现,以指定执行顺序。返回值越小,执行顺序越高。您需要添加@Component注释。

通过全局过滤器,可以实现统一的认证处理和日志处理。

在配置过程中,配置好的过滤器可以通过spring . cloud . gateway . default-filters全局生效,但这种方式在实际中很少使用。

目前有官方的全球滤镜。详情请参考。

org . spring framework . cloud . gateway . filter . nettywriteresponsefilter,order = -1

将Netty代理调用的响应数据流写入ServerHttpResponse的主体。当NettyRouting获得远程调用的结果数据流时,它会将其写入当前请求交换的属性中。

org . spring framework . cloud . gateway . filter . routetorequesturlfilter,order = 10000

将网关上的请求转化为对应业务应用的真实ip的请求。请求进来时,path的前缀是网关的地址,它的uri需要映射到服务id;比如映射192.168.20.134:10080的路径到服务LB://{ service id };对于绝对路径配置的服务,exchange的GATEWAY_ROUTE_ATTR属性会为空,直接过滤到下一个过滤器,不会发生路径的真正映射。

org . spring framework . cloud . gateway . filter . reactiveloadbalancerclientfilter,order = 10150

负责映射服务的真实ip和服务的负载平衡。

org . spring framework . cloud . gateway . filter . websocketroutingfilter,order = 2147483646

网关支持websocket,通过websocketClient把一个http请求协议改成websocket,这样调用方就可以无感知的请求websocket服务。这就像将schme设置为ws或wss一样简单。

org . spring framework . cloud . gateway . filter . nettyroutingfilter,order = 2147483647

org . spring framework . cloud . gateway . filter . forwardroutingfilter,order = 2147483647

这是一次终结行动。经过filter chain的链式调用,exchange最终返回给web handler进行http请求处理。

自定义全局过滤器

为简单的日志打印创建ItxsGloablFilter.java的全局过滤器。

包cn . itxs . ECOM . gateway . factory;导入lombok . extern . SLF 4j . SLF 4j;导入org . spring framework . cloud . gateway . filter . gatewayfilterchain;导入org . spring framework . cloud . gateway . filter . global filter;导入org . spring framework . core . ordered;导入org . spring framework . stereotype . component;导入org . spring framework . web . server . server webexchange;导入reactor . core . publisher . mono;@Component@Slf4jpublic类ItxsGloablFilter实现GlobalFilter,Ordered { @ Override public Mono filter { log . info;返回chain.filter} @ Override public int get order { return-1;}}

类将ItxsGloablFilter配置为Spring的Bean。

包cn . itxs . ECOM . gateway . config;导入cn . itxs . ECOM . gateway . factory . itxsgloablfilter;导入org . spring framework . cloud . gateway . filter . global filter;导入org . spring framework . context . annotation . bean;导入org . spring framework . context . annotation . configuration;@ configuration public class filter config { @ Bean public global filter itxsFilter { return new ItxsGloablFilter;}}

启动网关微服务,访问http://localhost:4090/storage-service/conduct quantity = 100 uid = 1001 token = ABC,可以看到打印日志信息。

反应堆网络访问日志

要使Reactor Netty能够访问日志,请设置-d Reactor . Netty . http . server . accesslogenabled = true。您可以将日志记录系统配置为具有单独的访问日志文件。创建回退配置的示例如下:

access_log.log %msg%n

CORS构型

通过配置网关控制CORS行为。全局CORS配置是URL模式到Spring框架CORS配置的映射。配置CORS的示例如下:

spring:cloud:gateway:global CORS:CORS-configuration:'[/* *]':allowed origins:" http://www . itxiaoshen . com " allowed methods:-GET

此配置允许所有GET请求路径的CORS请求,以及来自www.itxiaoshen.com的请求。要为网关路由谓词未处理的请求提供相同的CORS配置,可以设置spring . cloud . gateway . global CORS。属性add-to-simple URL-handler-mapping为true。

集成网关哨兵流量控制降级

SpringCloud Gateway本身具有限流功能,但是结合sentinel等更强大的专业限流组件才是生产环境下的首选,虽然之前两篇文章《SpringCloud阿里巴巴的分布式流控组件Sentinel的实战与源代码分析》介绍了Sentinel的内容。Sentinel可以作为每个微服务或网关的限流组件,也就是说流量控制可以放在每个微服务或网关中。在这一部分,我们将完成sentinel流量控制的网关集成。

Sentinel从1.6.0版本开始提供Spring Cloud Gateway的适配,可以提供两个资源维度的限流:

路由维度:即配置文件中配置的路由条目,资源名称是对应的routeId。这种粗粒度的电流限制通常会限制微服务的流动。

用户自定义API维度:用户可以使用Sentinel提供的API自定义一些API组。这种细粒度的流量限制可以匹配某种类型的uri,可以跨越多个微服务。

向网关微服务添加sentinel和sentinel-网关依赖性。

com . Alibaba . cloud spring-cloud-阿里巴巴-sentinel-gateway com . Alibaba . cloud spring-cloud-starter-阿里巴巴-sentinel

将控制台配置添加到网关的配置文件。

春天:云:哨兵:运输:仪表板:本地主机:8858

我们仍然将Nacos配置放在网关中。

启动sentinel的控制台,启动上一篇文章《SpringCloud阿里巴巴分布式流控组件Sentinel的实战与源代码分析——第一部分》中的命令

访问http://localhost:4090/storage-service/conduct quantity = 100 uid = 1001 token = ABC后,可以看到sentinel控制台与之前的sentinel启动控制台有一些不同,比如增加了一个API管理菜单,在请求链接中失去了一些操作功能,包括流量控制功能。可以一个一个的感受。

在添加网关流控规则的测试下,在请求链接中找到API名称刚刚被询问的接入路由id,点击流控按钮。该页面不同于原始的Sentinel控制台。选择API类型作为路由ID,添加规则后,

连续两次访问http://localhost:4090/storage-service/conducted quantity = 100 uid = 1001 token = ABC后,出现流控提示,网关集成哨兵流控功能已经生效。

Sentinel流量控制降级详细配置

突发大小设置

点击流控规则菜单,从网关流控规则列表中选择最后设置storage_route的流控规则,点击右边的编辑按钮,将Burst size改为2,点击保存。

此时快速连续访问http://localhost:4090/storage-service/conducted quantity = 100 uid = 1001 token = ABC后不会进行流量控制,但快速连续访问http://localhost:4090/storage-service/conducted quantity = 100后,四次后会提示再次进行流量控制。

为请求属性设置

编辑storage_route,检查请求的属性,其中我们选择URL参数,填写参数名称和属性值匹配,点击保存。

此时快速连续访问http://localhost:4090/storage-service/vector quantity = 100 uid = 1001 token = ABC code = 1002将不受控制。但是连续访问http://localhost:4090/storage-service/conducted quantity = 100 uid = 1001 token = ABC code = 1001后会出现流量控制的提示。也可以设置为子串或常规匹配模式。

API分组

如果需要对URL进行流控,可以使用API分组的功能,先删除之前的流控规则,这里使用库存微服务中的两个接口。

添加一个自定义API,并输入两个匹配的字符串/storage-service/induce和/storage-service/list。

在请求链接中设置流控规则,API类型为API分组,然后选择刚刚创建的storage-api,点击添加。

连续两次快速访问http://localhost:4090/storage-service/conducted quantity = 100 uid = 1001 token = ABC,出现流量控制提示。

连续2次快速访问http://localhost:4090/storage-service/list quantity = 100 uid = 1001 token = ABC,还出现流量控制的提示。

其他降级设置请参考之前的哨兵文章,这里就不介绍了。

返回统一降级提示的yaml配置如下,也可以通过GatewayCallbackManager的java配置实现。

spring:cloud:sentinel:SCG:fallback:mode:response response-body:' { " code ":403," message ":"降级" } '

资料来源:file/tupian/20220829/16463099.html

 
友情链接
鄂ICP备19019357号-22