alibaba / Sentinel

A powerful flow control component enabling reliability, resilience and monitoring for microservices. (面向云原生微服务的高可用流控防护组件)
https://sentinelguard.io/
Apache License 2.0
22.41k stars 8.03k forks source link

[bug report] dubbo接口 SystemSlot 检测没通过,但是在LogSlot 发生NullPointerException, 导致没有收到 BlockedException #3019

Open ddfeiyu opened 1 year ago

ddfeiyu commented 1 year ago

Issue Description

Type: bug report or feature request

[bug report] dubbo接口 SystemSlot 检测没通过,但是在LogSlot 发生NullPointerException, 导致没有收到 BlockedException

Describe what happened (or what feature you want)

  1. Sentinel版本号: 2.0.0-SNAPSHOT

    <parent>
        <groupId>com.alibaba.csp</groupId>
        <artifactId>sentinel-parent</artifactId>
        <version>2.0.0-SNAPSHOT</version>
    </parent>
    <artifactId>sentinel-core</artifactId>
  2. SystemSlot限流检测时满足条件时抛出异常 throw new SystemBlockException(resourceWrapper.getName(), "qps");

  3. 但是在 LogSlot 发生NullPointerException,导致SentinelDubboProviderFilter 没有捕获到 BlockException

    异常堆栈

    
    java.lang.NullPointerException
                at com.alibaba.csp.sentinel.slots.logger.LogSlot.entry(LogSlot.java:41)
                at com.alibaba.csp.sentinel.slots.logger.LogSlot.entry(LogSlot.java:31)
                at com.alibaba.csp.sentinel.slotchain.AbstractLinkedProcessorSlot.transformEntry(AbstractLinkedProcessorSlot.java:40)
                at com.alibaba.csp.sentinel.slotchain.AbstractLinkedProcessorSlot.fireEntry(AbstractLinkedProcessorSlot.java:32)
                at com.alibaba.csp.sentinel.slots.clusterbuilder.ClusterBuilderSlot.entry(ClusterBuilderSlot.java:104)
                at com.alibaba.csp.sentinel.slots.clusterbuilder.ClusterBuilderSlot.entry(ClusterBuilderSlot.java:49)
                at com.alibaba.csp.sentinel.slotchain.AbstractLinkedProcessorSlot.transformEntry(AbstractLinkedProcessorSlot.java:40)
                at com.alibaba.csp.sentinel.slotchain.AbstractLinkedProcessorSlot.fireEntry(AbstractLinkedProcessorSlot.java:32)
                at com.alibaba.csp.sentinel.slots.nodeselector.NodeSelectorSlot.entry(NodeSelectorSlot.java:174)
                at com.alibaba.csp.sentinel.slotchain.AbstractLinkedProcessorSlot.transformEntry(AbstractLinkedProcessorSlot.java:40)
                at com.alibaba.csp.sentinel.slotchain.AbstractLinkedProcessorSlot.fireEntry(AbstractLinkedProcessorSlot.java:32)
                at com.alibaba.csp.sentinel.slotchain.DefaultProcessorSlotChain$1.entry(DefaultProcessorSlotChain.java:31)
                at com.alibaba.csp.sentinel.slotchain.AbstractLinkedProcessorSlot.transformEntry(AbstractLinkedProcessorSlot.java:40)
                at com.alibaba.csp.sentinel.slotchain.DefaultProcessorSlotChain.entry(DefaultProcessorSlotChain.java:75)
                at com.alibaba.csp.sentinel.CtSph.entryWithPriority(CtSph.java:148)
                at com.alibaba.csp.sentinel.CtSph.entryWithType(CtSph.java:347)
                at com.alibaba.csp.sentinel.CtSph.entryWithType(CtSph.java:340)
                at com.alibaba.csp.sentinel.SphU.entry(SphU.java:294)
                at com.alibaba.csp.sentinel.adapter.dubbo.SentinelDubboProviderFilter.invoke(SentinelDubboProviderFilter.java:78)
                at org.apache.dubbo.rpc.protocol.FilterNode.invoke(FilterNode.java:61)
                at org.apache.dubbo.monitor.support.MonitorFilter.invoke(MonitorFilter.java:91)
                at org.apache.dubbo.rpc.protocol.FilterNode.invoke(FilterNode.java:61)
                at org.apache.dubbo.rpc.filter.ExceptionFilter.invoke(ExceptionFilter.java:52)
                at org.apache.dubbo.rpc.protocol.FilterNode.invoke(FilterNode.java:61)
                at com.iplatform.common.trace.apache.ApacheProviderTraceFilter.invoke(ApacheProviderTraceFilter.java:58)
                at org.apache.dubbo.rpc.protocol.FilterNode.invoke(FilterNode.java:61)
                at com.iplatform.common.router.filter.DubboProviderTrafficTagFilter.invoke(DubboProviderTrafficTagFilter.java:31)
                at org.apache.dubbo.rpc.protocol.FilterNode.invoke(FilterNode.java:61)
                at org.apache.dubbo.rpc.filter.GenericFilter.invoke(GenericFilter.java:192)
                at org.apache.dubbo.rpc.protocol.FilterNode.invoke(FilterNode.java:61)
                at org.apache.dubbo.rpc.filter.ClassLoaderFilter.invoke(ClassLoaderFilter.java:38)
                at org.apache.dubbo.rpc.protocol.FilterNode.invoke(FilterNode.java:61)
                at org.apache.dubbo.rpc.filter.EchoFilter.invoke(EchoFilter.java:41)
                at org.apache.dubbo.rpc.protocol.FilterNode.invoke(FilterNode.java:61)
                at org.apache.dubbo.rpc.filter.ContextFilter.invoke(ContextFilter.java:129)
                at org.apache.dubbo.rpc.protocol.FilterNode.invoke(FilterNode.java:61)
                at org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol$1.reply(DubboProtocol.java:148)
                at org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.handleRequest(HeaderExchangeHandler.java:100)
                at org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.received(HeaderExchangeHandler.java:175)
                at org.apache.dubbo.remoting.transport.DecodeHandler.received(DecodeHandler.java:51)
                at org.apache.dubbo.remoting.transport.dispatcher.ChannelEventRunnable.run(ChannelEventRunnable.java:57)
                at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
                at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
                at org.apache.dubbo.common.threadlocal.InternalRunnable.run(InternalRunnable.java:41)
                at java.lang.Thread.run(Thread.java:750)


### Describe what you expected to happen

### How to reproduce it (as minimally and precisely as possible)

1. 
2. 
4. 

### Tell us your environment

### Anything else we need to know?
sczyh30 commented 1 year ago

之前有个 NPE 的问题应该在 https://github.com/alibaba/Sentinel/pull/2980 修复过,可以测试下 master 最新的有没有问题

ddfeiyu commented 1 year ago

@sczyh30 经测试,报错在LogSlot的41行代码 e.getRule().getId() 处,即e.getRule()为空。

image

是因为SystemSlot检测类即SystemRuleManager抛出的异常中没有 rule对象,导致LogSlot处rule为空

    throw new SystemBlockException(resourceWrapper.getName(), "qps");

建议: 将SystemRule封装进SystemBlockException,和其他BlockException保持一致 throw new SystemBlockException(resourceWrapper.getName(), SystemRule);

sczyh30 commented 1 year ago

Would you like to contribute a PR to improve it?