技术问答集录(三)(超时,mvc和Webflux,skywalking原理)

本周问题:

1. 连接、读取和写入超时什么区别?一般出现这3个超时如何排查?

2. Spring MVC和Webflux区别是什么?Reactor是什么意思?

3. 请问全链路监控SkyWalking的原理?

 

1. 连接、读取和写入超时什么区别?一般出现这3个超时如何排查?

连接超时:连接是发送请求开始到连接上目标URL主机地址的时间,连接超过预设时间仍没连接上,称为连接超时(同步阻塞的)。

读取超时:读取超时是已经连接到了目标服务器,进行内容获取的时候超时,服务器在一段时间内没有任何数据发送给客户端,read操作会一直阻塞而挂起线程,直到有新的数据或异常产生(如果设置了超时时间就会抛出一个异常)。需要注意的是:客户端读取超时时,服务端逻辑可能还在处理。

写入超时:Socket写超时,是基于TCP的超时重传,超时重传是保证数据可靠性的一个重要机制,是在发送报文时开启一个计时器,在一定时间内如果没有收到确认ACK,就重新发送报文,如果多次发送仍没有确认报文,就关闭连接,Socket写超时是基于TCP协议栈的超时重传机制,不需要设置超时时间。

超时排查

连接超时:检查客户端是否设置超时时间太短,检查客户端网络环境 ,可能客户端连接的是Nginx,检查Nginx设置的超时时间,检查防火墙配置(可能会导致连接超时,或者被连接被重置)

读取超时排查:一般是读取的数据量大,或是目标服务器本身的问题(读取数据库慢,并发量大),设置读取超时时间太短

写入超时排查:是否写入了超大量的数据

可以首先使用ping、telnet排查与服务器之间、与服务器特定端口之间的网络是否通畅,如果不通,则可依次排查客户端侧、服务器侧是否能正常上网、防火墙是否进行了拦截,服务器进程是否在正常运行、是否在服务器侧监听特定端口。

排查读取/写入超时,首先依次排查欲读取/写入的数据量、与服务器之间的带宽、服务器处理能力、服务器的负荷,而后排查连接超时设置的时间是否合理(并非越长越好)。

 

2.Spring MVC和Webflux区别是什么?Reactor是什么意思?

SpringMVC是SpringFrameWork的开源Web框架,是围绕Servlet设计的,将请求发给控制器(Controller),通过模型对象(Model),展示结果视图(View),核心类是DispatcherServlet,顶层是实现Servlet接口,是同步阻塞IO模型

Spring WebFlux是 Spring5中新增加的基于Reactive Streams(反应式的异步组件之间的交互,主要目的是让订阅者控制发布者生成数据的速度或速率(负压),阻塞调用强调调用者等待,非阻塞控制事件的速率)的Web框架

Spring WebFlux是:异步非阻塞(非阻塞式的Web堆栈来处理少量线程的并发并使用更少的硬件资源进行扩展),反应式(reactive 是指围绕反应变化而构建的编程模型-网络组件响应I/O事件,处于响应通知的模式,而不是被阻塞),Spring WebFlux不局限与Servlet容器可以在Netty,Undertow和Servlet 3.1+容器运行  

反应式编程:类似与生产者对消费者提供订阅接口,当有事件发生的时候,生产者会通过回调消费者的方法来通知消费者相应的事件

负压:在基本的消息推送模式中,当消息发布者产生数据的速度过快时,会使得消息订阅者的处理速度无法跟上产生的速度,从而给订阅者造成很大的压力。当压力过大时,有可能造成订阅者本身的奔溃,所产生的级联效应甚至可能造成整个系统的瘫痪。负压的作用在于提供一种从订阅者到生产者的反馈渠道。订阅者可以通过request()方法来声明其一次所能处理的消息数量,而生产者就只会产生相应数量的消息,直到下一次 request()方法调用。这实际上变成了推拉结合的模式。

Reactive Streams: 一种支持负压(Backpressure)的异步数据流处理标准,主流实现有RxJava和Reactor

Reactor是SpringWebFlux的首选反应式库,WebFlux需要Reactor作为核心依赖项,WebFlux默认集成的Reactive Streams组件是Reactor,Reactor 是一个轻量级 JVM 基础库,帮助你的服务或应用高效(消息从A传递到B时,产生很少的内存垃圾,甚至不产生。解决消费者处理消息的效率低于生产者时带来的溢出问题。尽可能提供非阻塞异步流。),异步地传递消息。

 

3.请问全链路监控SkyWalking的原理?

通过java agent+Byte Buddy+plugins方式实现的。可以下载SkyWalking源码,查看入口类:SkyWalkingAgent

java探针java agen技术,在加载类的时候,对字节码进行修改,class被加载之前对其拦截,插入自己的代码在启动的时候指定SkyWalking的jar:java -javaagent:/path/to/skywalking-agent/skywalking-agent.jar -jar yourApp.jar

1. Skywalking Agent:链路数据采集tracing(调用链数据)和metric(指标)信息并上报,上报通过HTTP或者gRPC方式发送数据到Skywalking Collector

2. Skywalking Collector : 链路数据收集器,对agent传过来的tracing和metric数据进行整合分析通过Analysis Core模块处理并落入相关的数据存储中,同时会通过Query Core模块进行二次统计和监控告警

3. Storage: Skywalking的存储,支持以ElasticSearch、Mysql、TiDB、H2等主流存储作为存储介质进行数据存储,H2仅作为临时演示单机用。

4. SkyWalking UI: Web可视化平台,用来展示落地的数据,目前官方采纳了RocketBot作为SkyWalking的主UI

SkyWalkingAgent入口类:

public static void premain(String agentArgs, Instrumentation instrumentation) throws PluginException {

        final PluginFinder pluginFinder;
          SnifferConfigInitializer.initialize(agentArgs);
            //加载Plugins

            pluginFinder = new PluginFinder(new PluginBootstrap().loadPlugins());

                 //bytebuddy
        final ByteBuddy byteBuddy = new ByteBuddy()
            .with(TypeValidation.of(Config.Agent.IS_OPEN_DEBUGGING_CLASS));

        new AgentBuilder.Default(byteBuddy)
            .ignore(

                nameStartsWith("net.bytebuddy.")

                    .or(nameStartsWith("org.slf4j."))

                    .or(nameStartsWith("org.apache.logging."))

                    .or(nameStartsWith("org.groovy."))

                   .or(nameContains("javassist"))

                    .or(nameContains(".asm."))

                    .or(nameStartsWith("sun.reflect"))

                    .or(allSkyWalkingAgentExcludeToolkit())

                    .or(ElementMatchers.<TypeDescription>isSynthetic()))

            .type(pluginFinder.buildMatch())

            .transform(new Transformer(pluginFinder))

            .with(new Listener())

            .installOn(instrumentation);

 

        try {

            ServiceManager.INSTANCE.boot();

        } catch (Exception e) {

            logger.error(e, "Skywalking agent boot failure.");

        }

 

        Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {

            @Override public void run() {

                ServiceManager.INSTANCE.shutdown();

            }

        }, "skywalking service shutdown thread"));

    }
SkyWalkingAgent

 

posted @ 2020-08-03 17:04  暖暖-木木  阅读(928)  评论(0编辑  收藏  举报