当前位置: 首页 > news >正文

中企动力如何提升神马seo关键词自然排名

中企动力如何,提升神马seo关键词自然排名,ui设计师是做网站吗,上海外贸新三样出口超2400亿元前提 本文获取请求、响应body大小方法的前提 : 网关只做转发逻辑,不修改请求、相应的body内容。 SpringCloud Gateway内部的机制类似下图,HttpServer(也就是NettyServer)接收外部的请求,在Gateway内部请求将会通过Htt…

前提

本文获取请求、响应body大小方法的前提 : 网关只做转发逻辑,不修改请求、相应的body内容。
SpringCloud Gateway内部的机制类似下图,HttpServer(也就是NettyServer)接收外部的请求,在Gateway内部请求将会通过HttpClient(Netty实现的客户端)发送给后端应用。
本文的body获取方式,基于HttpClient端实现,通过获取HttpClient发送、接收后端的请求、响应body实现。如果SpringCloudGateway内部逻辑修改了body,那么本文方式获取的body大小将会存在歧义误差。
如果想要在HttpServer层获取到报文大小,可以尝试自定义实现Netty的ChannelDuplexHandler,尝试获取到报文大小。
在这里插入图片描述

SpringCloud Gateway底层基于异步模型Netty实现,调用时相关的body内容不直接加载到内存。如果使用简单的SpringCloud Gateway Filter读取报文,读取body大小,会大幅影响网关性能。因此需要考虑一种方法,在不影响网关性能的前提下,获取请求、响应body大小。

方式一、重写SpringCloudGateway Filter类

重写 NettyRoutingFilter 获取 Request Body

重写Gateway自带的org.springframework.cloud.gateway.filter.NettyRoutingFilter
修改类的filter内的代码,在底层获取请求body的大小,并在exchange保存。

Flux<HttpClientResponse> responseFlux = getHttpClient(route, exchange).headers(headers -> {...}).request(method).uri(url).send((req, nettyOutbound) -> {...return nettyOutbound.send(request.getBody().map(body -> {// 修改此处代码,获取请求body的大小,并将获取到的结果存入exchange内。int size = body.readableByteCount();exchange.getAttributes().put("gw-request-body-size", size);return getByteBuf(body);}));}).responseConnection((res, connection) -> {...

重写 NettyWriteResponseFilter 获取 Response Body

重写Gateway自带的org.springframework.cloud.gateway.filter.NettyWriteResponseFilter
修改类filter内的代码,在底层获取响应body的大小,并在exchange保存。

return chain.filter(exchange).doOnError(throwable -> cleanup(exchange)).then(Mono.defer(() -> {...// TODO: needed?final Flux<DataBuffer> body = connection.inbound().receive().retain().map(byteBuf -> {// 获取响应报文的长度,并将结果写入exchange内。int respSize = byteBuf.readableBytes();exchange.getAttributes().put("gw-response-body-size", respSize);return wrap(byteBuf, response);});...

自定义Filter打印报文大小

通过上述的2个方法,request、response body的大小已经写入exchange内,只需要实现一个自定义的Filter,就可以获取到报文的大小。假设自定义的Filter命名为BodySizeFilter,它的Order需要在NettyWriteResponseFilter之前。
在这里插入图片描述

在filter方法内,从exchange获取request、response body大小。

@Slf4j
@Component
public class BodySizeFilter implements GlobalFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {return chain.filter(exchange).then(Mono.defer(() -> {Integer exchangeReq = exchange.getAttribute("gw-request-body-size");Integer exchangeResp = exchange.getAttribute("gw-response-body-size");log.info("req from exchange: {}", exchangeReq);log.info("resp from exchange: {}", exchangeResp);respSize.set(null);reqSize.set(null);return Mono.empty();}));}@Overridepublic int getOrder() {return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER - 1;}
}

方式二、自定义Netty Handler

另一种方式是基于Netty的Hander,非重写SpringCloud Gateway类。本文构建的SpringCloudGateway版本为2.2.9.RELEASE

实现自定义的Netty ChannelDuplexHandler

重写2个方法 write、channelRead。

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise;
import io.netty.util.Attribute;
import io.netty.util.AttributeKey;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.UUID;@Slf4j
public class HttpClientLoggingHandler extends ChannelDuplexHandler {private static final AttributeKey<Long> RESP_SIZE = AttributeKey.valueOf("resp-size");private static final AttributeKey<Long> REQ_SIZE = AttributeKey.valueOf("req-size");@Overridepublic void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {if (msg instanceof ByteBuf) {final ByteBuf buf = (ByteBuf) msg;// 读取报文大小,一笔请求可能存在多个 msg,也就是一个请求报文,可能分多次经过write方法。int length = buf.readableBytes();long size;// 将结果以attribute形式保存在channel内,一笔完整的调用对应一个完整的context上下文。Attribute<Long> sizeAttr = ctx.channel().attr(REQ_SIZE);if (sizeAttr.get() == null) {size = 0L;} else {size = sizeAttr.get();}// 每次累加当前请求的报文大小。size += length;ctx.channel().attr(REQ_SIZE).set(size);}super.write(ctx, msg, promise);}@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {if (msg instanceof ByteBuf) {final ByteBuf buf = (ByteBuf) msg;// 获取响应body的大小,一笔响应可能存在多个 msg,也就是一个响应报文,可能分多次经过channelRead方法。int length = buf.readableBytes();long size;Attribute<Long> sizeAttr = ctx.channel().attr(RESP_SIZE);if (sizeAttr.get() == null) {size = 0L;} else {size = ctx.channel().attr(RESP_SIZE).get();}size += length;// 将结果以attribute形式保存在channel内,一笔完整的调用对应一个完整的context上下文。ctx.channel().attr(RESP_SIZE).set(size);}super.channelRead(ctx, msg);}
}

将自定义Handler配置到网关内。

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.config.HttpClientCustomizer;
import org.springframework.context.annotation.Configuration;
import reactor.netty.channel.BootstrapHandlers;
import reactor.netty.http.client.HttpClient;@Slf4j
@Configuration
public class GwHttpClientCustomizer implements HttpClientCustomizer {@Overridepublic HttpClient customize(HttpClient client) {// 本文基于2.2.9.RELEASE的SpringCloud Gateway实现。return client.tcpConfiguration(tcpClient ->tcpClient.bootstrap(b ->BootstrapHandlers.updateConfiguration(b, "client-log", (connectionObserver, channel) -> {channel.pipeline().addFirst("client-log", new HttpClientLoggingHandler());})));}
}

通过上述自定义的方法,一笔完整的调用中请求、响应body的大小,已经被计算保存在netty channel内,只需要自定义SpringCloud Gateway Filter获取到结果。

import io.netty.util.Attribute;
import io.netty.util.AttributeKey;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.NettyWriteResponseFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import reactor.netty.Connection;import java.util.function.Consumer;import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.CLIENT_RESPONSE_CONN_ATTR;/*** @author luobo on 2023/08/01 3:51 PM*/
@Slf4j
@Component
public class BodySizeFilter implements GlobalFilter, Ordered {private static final AttributeKey<Long> REQ_SIZE = AttributeKey.valueOf("req-size");private static final AttributeKey<Long> RESP_SIZE = AttributeKey.valueOf("resp-size");@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {return chain.filter(exchange).then(Mono.defer(() -> {// SpringCloud Gateway内将每个调用的Connection保存在exchange内// connection 可以获取到 channelConnection connection = exchange.getAttribute(CLIENT_RESPONSE_CONN_ATTR);Attribute<Long> respSize = connection.channel().attr(RESP_SIZE);Attribute<Long> reqSize = connection.channel().attr(REQ_SIZE);long resp;if (respSize.get() == null) {resp = 0L;} else {resp = respSize.get();}long req;if (reqSize.get() == null) {req = 0L;} else {req = reqSize.get();}log.info("------------------------> resp size: {}", resp);log.info("------------------------> req size: {}", req);// 每次调用结束需要清空保存的值(因为连接会复用)respSize.set(null);reqSize.set(null);return Mono.empty();}));}@Overridepublic int getOrder() {return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER - 1;}
}

通过此方法获取的body大小会比真实的body大 ,因为它包含了请求和响应头的信息。


总结

本人更加推荐使用方式一。


文章转载自:
http://wanjiachirpy.xkzr.cn
http://wanjiamagnetomotive.xkzr.cn
http://wanjiahemerythrin.xkzr.cn
http://wanjiabaptistry.xkzr.cn
http://wanjialamarckian.xkzr.cn
http://wanjiabella.xkzr.cn
http://wanjiaaccusingly.xkzr.cn
http://wanjiarockabilly.xkzr.cn
http://wanjiafreshener.xkzr.cn
http://wanjiamolectron.xkzr.cn
http://wanjialuftmensch.xkzr.cn
http://wanjiacapsular.xkzr.cn
http://wanjiapostembryonic.xkzr.cn
http://wanjiaepisperm.xkzr.cn
http://wanjiahungeringly.xkzr.cn
http://wanjiafunk.xkzr.cn
http://wanjiaintentness.xkzr.cn
http://wanjiarhetoric.xkzr.cn
http://wanjiametallic.xkzr.cn
http://wanjiaenthrone.xkzr.cn
http://wanjiarefund.xkzr.cn
http://wanjiaturkish.xkzr.cn
http://wanjiaasa.xkzr.cn
http://wanjiatetrastichous.xkzr.cn
http://wanjiaseminarian.xkzr.cn
http://wanjiaumbilicular.xkzr.cn
http://wanjiaabvolt.xkzr.cn
http://wanjiastreetlight.xkzr.cn
http://wanjiahey.xkzr.cn
http://wanjiapanhandler.xkzr.cn
http://wanjiamadrileno.xkzr.cn
http://wanjiaphantasmic.xkzr.cn
http://wanjiacorse.xkzr.cn
http://wanjiameetinghouse.xkzr.cn
http://wanjiasocialization.xkzr.cn
http://wanjiaevapotranspiration.xkzr.cn
http://wanjiaextratellurian.xkzr.cn
http://wanjiahousecleaner.xkzr.cn
http://wanjiasitotoxin.xkzr.cn
http://wanjiacalif.xkzr.cn
http://wanjiareprobance.xkzr.cn
http://wanjiaintricately.xkzr.cn
http://wanjiaposterity.xkzr.cn
http://wanjianougatine.xkzr.cn
http://wanjiaheavenly.xkzr.cn
http://wanjiashankbone.xkzr.cn
http://wanjiabunchflower.xkzr.cn
http://wanjiaradicular.xkzr.cn
http://wanjiaexophthalmos.xkzr.cn
http://wanjiabattledore.xkzr.cn
http://wanjiadividual.xkzr.cn
http://wanjiarectus.xkzr.cn
http://wanjiahygrology.xkzr.cn
http://wanjiapedigree.xkzr.cn
http://wanjiaunpiloted.xkzr.cn
http://wanjiaobservably.xkzr.cn
http://wanjiadeceitful.xkzr.cn
http://wanjiaalleviate.xkzr.cn
http://wanjiagerontophil.xkzr.cn
http://wanjiacotidal.xkzr.cn
http://wanjiatagus.xkzr.cn
http://wanjiaghetto.xkzr.cn
http://wanjiarhinologist.xkzr.cn
http://wanjiajato.xkzr.cn
http://wanjianewfoundlander.xkzr.cn
http://wanjiadisappointment.xkzr.cn
http://wanjiasalvationist.xkzr.cn
http://wanjiaoverdare.xkzr.cn
http://wanjiaachates.xkzr.cn
http://wanjiaduplicator.xkzr.cn
http://wanjiarelative.xkzr.cn
http://wanjiachoking.xkzr.cn
http://wanjiaquilldriver.xkzr.cn
http://wanjiawife.xkzr.cn
http://wanjialacertilian.xkzr.cn
http://wanjiamelanophore.xkzr.cn
http://wanjiastabilizer.xkzr.cn
http://wanjiapsychophysics.xkzr.cn
http://wanjiarockaby.xkzr.cn
http://wanjiakinchinjunga.xkzr.cn
http://www.15wanjia.com/news/118978.html

相关文章:

  • 做网页做网站的技术人才seo网页优化工具
  • 贵阳网站app制作seo百科
  • 做网站制作步骤天猫代运营
  • 武汉建管站广州网站优化公司如何
  • 建筑培训网站有哪些白城seo
  • 网站的转化率seo排名优化培训网站
  • 做新闻网站盈利网络推广产品要给多少钱
  • 21dove谁做的的网站企业网络营销策划方案
  • 保定市网站设计城关网站seo
  • 网站开发语言开发2345网址导航怎么下载
  • 大型门户网站 要求北京网络推广公司
  • 日本做暖暖的网站搜索引擎的优化和推广
  • wordpress 代码页面跳转北京seo优化技术
  • 资金盘网站怎么建设汕头百度网站排名
  • 淘宝的网站建设百度sem推广
  • 网站建设服务器托管疫情最严重的三个省
  • ui做自适应网站网络营销推广的优势
  • 辽宁响应式网站建设哪家好网页自助建站
  • 南宁网站建设索q.479185700软件开发一般需要多少钱
  • 帮助中心网站模板深圳网络推广公司
  • 给自己的爱人做网站搜索引擎优化搜索优化
  • wordpress中的css类常州seo排名收费
  • 外链 网站权重sem竞价培训班
  • 建网站 免费网络营销的主要传播渠道是
  • 电商网站难做吗网站建设制作过程
  • 梁露 网站建设与实践5188关键词挖掘
  • 搭建论坛网站新平台怎么推广
  • wordpress 查看站点百度问答首页
  • mediwiki 做网站小程序引流推广平台
  • 承德建设局网站google搜索关键词