我们在项目中使用reactor,事件总线进行事件驱动的方法。
我们基本上从Kafka获取消息,然后委托给reactor,如下所示。这适用于几百条消息,然后挂起。我添加了我们使用的代码并添加了跟踪。
将消息推送到反应堆的代码......
private static RingBufferWorkProcessor<TestEvent> processor =RingBufferWorkProcessor.<TestEvent> create("test", 128);
processor.subscribe(testSubscriber);
processor.onNext(testEvent);
TestSubscriber类: -
@Component
public class TestSubscriber implements Subscriber<TestEvent> {
private static Log log = new Log(TestSubscriber.class);
@Override
public void onSubscribe(final Subscription s) {
if (s != null) {
s.request(Long.MAX_VALUE);
}
}
@Override
public void onNext(final TestEvent testEvent) {
if (testEvent == null) {
return;
}
getRootReactor().notify(testEvent.getType().getName(), Event.wrap(testEvent));
}
@Override
public void onError(final Throwable t) {
if (t != null) {
log.error(t.getMessage());
}
}
@Override
public void onComplete() {
log.info("TestSubscriber is done.");
}
}
public static EventBus getRootReactor() {
if (rootReactor == null) {
rootReactor = EventBus.create(Environment.get(), Environment.workDispatcher());
}
return rootReactor;
}
追踪1: -
"pool-9-thread-1" prio=5 tid=63 TIMED_WAITING
at sun.misc.Unsafe.park(Native Method)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:338)
at reactor.jarjar.com.lmax.disruptor.MultiProducerSequencer.next(MultiProducerSequencer.java:136)
at reactor.jarjar.com.lmax.disruptor.MultiProducerSequencer.next(MultiProducerSequencer.java:105)
at reactor.jarjar.com.lmax.disruptor.RingBuffer.next(RingBuffer.java:246)
at reactor.core.dispatch.WorkQueueDispatcher.allocateTask(WorkQueueDispatcher.java:172)
at reactor.core.dispatch.AbstractLifecycleDispatcher.dispatch(AbstractLifecycleDispatcher.java:118)
at reactor.bus.EventBus.notify(EventBus.java:368)
Local Variable: reactor.bus.Event#2
追踪2: -
"workQueueDispatcher-3" daemon prio=5 tid=42 TIMED_WAITING
at sun.misc.Unsafe.park(Native Method)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:338)
at reactor.jarjar.com.lmax.disruptor.MultiProducerSequencer.next(MultiProducerSequencer.java:136)
at reactor.jarjar.com.lmax.disruptor.MultiProducerSequencer.next(MultiProducerSequencer.java:105)
at reactor.jarjar.com.lmax.disruptor.RingBuffer.next(RingBuffer.java:246)
at reactor.core.dispatch.WorkQueueDispatcher.allocateTask(WorkQueueDispatcher.java:172)
at reactor.core.dispatch.MultiThreadDispatcher.allocateRecursiveTask(MultiThreadDispatcher.java:59)
at reactor.core.dispatch.AbstractLifecycleDispatcher.dispatch(AbstractLifecycleDispatcher.java:116)
at reactor.bus.EventBus.notify(EventBus.java:368)
Local Variable: reactor.bus.Event#6
我检查了反应堆代码所在的位置,并且没有任何线索。
@Override
112 public long More ...next(int n)
113 {
114 if (n < 1)
115 {
116 throw new IllegalArgumentException("n must be > 0");
117 }
118
119 long current;
120 long next;
121
122 do
123 {
124 current = cursor.get();
125 next = current + n;
126
127 long wrapPoint = next - bufferSize;
128 long cachedGatingSequence = gatingSequenceCache.get();
129
130 if (wrapPoint > cachedGatingSequence || cachedGatingSequence > current)
131 {
132 long gatingSequence = Util.getMinimumSequence(gatingSequences, current);
133
134 if (wrapPoint > gatingSequence)
135 {
136 LockSupport.parkNanos(1); // TODO, should we spin based on the wait strategy?
137 continue;
138 }
139
140 gatingSequenceCache.set(gatingSequence);
141 }
142 else if (cursor.compareAndSet(current, next))
143 {
144 break;
145 }
146 }
147 while (true);
148
149 return next;
150 }
谢谢,