dotnetcore / CAP

Distributed transaction solution in micro-service base on eventually consistency, also an eventbus with Outbox pattern
http://cap.dotnetcore.xyz
MIT License
6.61k stars 1.28k forks source link

CAP has not been started! #1527

Closed xiaolipro closed 4 months ago

xiaolipro commented 4 months ago

异常: SJZY.InterfaceRelay.Api.Pet_Error cap-msg-id:8936888856285681876 System.InvalidOperationException: CAP has not been started! at DotNetCore.CAP.Internal.CapPublisher.PublishInternalAsync[T](String name, T value, IDictionary2 headers, Nullable1 delayTime, CancellationToken cancellationToken) at DotNetCore.CAP.Internal.CapPublisher.PublishAsync[T](String name, T value, IDictionary2 headers, CancellationToken cancellationToken) at DotNetCore.CAP.Internal.CapPublisher.PublishAsync[T](String name, T value, String callbackName, CancellationToken cancellationToken) at SJZY.InterfaceRelay.Application.Services.BatchForwardEventHandler.<>c__DisplayClass5_0.<<ConsumerAsync>b__0>d.MoveNext() in /var/lib/jenkins/workspace/interfaceapi-pet/src/SJZY.InterfaceRelay.Application/Services/BatchForwardEventHandler.cs:line 91 --- End of stack trace from previous location --- at System.Threading.Tasks.Parallel.<>c__501.<b__50_0>d.MoveNext() --- End of stack trace from previous location --- at SJZY.InterfaceRelay.Application.Services.BatchForwardEventHandler.ConsumerAsync(BatchForwardEvent event) in /var/lib/jenkins/workspace/interfaceapi-pet/src/SJZY.InterfaceRelay.Application/Services/BatchForwardEventHandler.cs:line 92 at lambda_method1039(Closure, Object) at DotNetCore.CAP.Internal.SubscribeInvoker.ExecuteWithParameterAsync(ObjectMethodExecutor executor, Object class, Object[] parameter) at DotNetCore.CAP.Internal.SubscribeInvoker.InvokeAsync(ConsumerContext context, CancellationToken cancellationToken)

每次重启服务时,如果队列里有消息,消费者会抛这个,因为我的这个消费方法会去publish发布消息。所以可以判断出消费者启动了,但是_bootstrapper.IsStarted还是false,如何解决?

if (!_bootstrapper.IsStarted)
        {
            throw new InvalidOperationException("CAP has not been started!");
        }

CAP版本:8.1.2 RabbitMQ .NET 7.0

whuanle commented 4 months ago

已读乱回。

yang-xiaodong commented 4 months ago

@xiaolipro

I can't reproduce your issue, the IsStarted state is created earlier than the Consumer Processor . Can you reproduce it using our example?

UPDATE: I think I know why, it could be that after the application restart sends the Ctrl+C cancel signal, since the CAP immediately synchronizes IsStarted to false when it receives the cancel signal, but your Consumer method doesn't respond to the cancel event right away or doesn't support cancellation, its still trying to send the message but at that point the CAP has stopped.

xiaolipro commented 4 months ago

@yang-xiaodong 很有可能,k8s重启的时候的旧的服务收到了关闭信号,将IsStarted置为false了,但是消费者并没有响应cancel并仍publish消息

yang-xiaodong commented 4 months ago

@xiaolipro Can you reproduce it using our example?