├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── async-event-core
├── pom.xml
├── src
│ ├── main
│ │ └── java
│ │ │ └── com
│ │ │ └── cubbery
│ │ │ └── event
│ │ │ ├── Channel.java
│ │ │ ├── Dispatcher.java
│ │ │ ├── EventBus.java
│ │ │ ├── EventBusRegistry.java
│ │ │ ├── EventBusSpring.java
│ │ │ ├── EventCreator.java
│ │ │ ├── EventStorage.java
│ │ │ ├── HandlerFinder.java
│ │ │ ├── ISubscribe.java
│ │ │ ├── Statistics.java
│ │ │ ├── Subscriber.java
│ │ │ ├── channel
│ │ │ ├── AbstractChannel.java
│ │ │ ├── ChannelData.java
│ │ │ ├── MemoryChannel.java
│ │ │ ├── MonitoredChannel.java
│ │ │ └── PersistentChannel.java
│ │ │ ├── conf
│ │ │ ├── Configurable.java
│ │ │ ├── ConfigureKeys.java
│ │ │ └── Context.java
│ │ │ ├── event
│ │ │ ├── DeadEvent.java
│ │ │ ├── EventState.java
│ │ │ ├── Offline.java
│ │ │ ├── RetryEvent.java
│ │ │ ├── SimpleEvent.java
│ │ │ └── impl
│ │ │ │ ├── DefaultEventCreator.java
│ │ │ │ └── EncryptEventCreator.java
│ │ │ ├── exception
│ │ │ ├── EventBusException.java
│ │ │ ├── EventHandlerException.java
│ │ │ └── EventStorageException.java
│ │ │ ├── finder
│ │ │ ├── AbstractHandlerFinder.java
│ │ │ ├── AnnotatedHandlerFinder.java
│ │ │ ├── BothHandlerFinder.java
│ │ │ └── ListenerHandlerFinder.java
│ │ │ ├── handler
│ │ │ ├── EventHandler.java
│ │ │ └── PersistenceEventHandler.java
│ │ │ ├── monitor
│ │ │ └── ChannelStatistics.java
│ │ │ ├── retry
│ │ │ ├── Lease.java
│ │ │ ├── LeaseTask.java
│ │ │ ├── RetryMarker.java
│ │ │ └── RetryService.java
│ │ │ ├── utils
│ │ │ ├── Formatter.java
│ │ │ ├── HostUtils.java
│ │ │ ├── JsonUtils.java
│ │ │ ├── MapUtils.java
│ │ │ ├── RefactorUtils.java
│ │ │ ├── ThreadFactories.java
│ │ │ ├── Threads.java
│ │ │ ├── Validation.java
│ │ │ └── security
│ │ │ │ ├── Base32.java
│ │ │ │ ├── Des.java
│ │ │ │ └── DesCrypter.java
│ │ │ └── worker
│ │ │ ├── AbstractWorker.java
│ │ │ ├── ConsumeWorker.java
│ │ │ └── RetryWorker.java
│ └── test
│ │ └── java
│ │ └── com
│ │ └── cubbery
│ │ └── event
│ │ ├── Demo.java
│ │ ├── Demo2.java
│ │ ├── EventBusSpringTest.java
│ │ ├── SemaphoreTest.java
│ │ ├── event
│ │ ├── Person.java
│ │ ├── SimpleEventTest.java
│ │ └── Sub.java
│ │ ├── finder
│ │ ├── AnnotatedHandlerFinderTest.java
│ │ ├── BothHandlerFinderTest.java
│ │ └── ListenerHandlerFinderTest.java
│ │ └── utils
│ │ ├── HostUtilsTest.java
│ │ └── security
│ │ └── DesCrypterTest.java
└── testng-qa.xml
├── async-event-example
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── cubbery
│ │ │ └── event
│ │ │ └── sample
│ │ │ ├── SampleWithAnnotaionSub.java
│ │ │ ├── SampleWithListenerSub.java
│ │ │ ├── SampleWithMonitoredChannel.java
│ │ │ ├── black
│ │ │ └── HttpMonitorUsage.java
│ │ │ ├── channel
│ │ │ └── MonitoredPersistenceChannel.java
│ │ │ ├── conf
│ │ │ └── ConfDemo.java
│ │ │ ├── event
│ │ │ ├── AnnotationSub.java
│ │ │ ├── BothSub.java
│ │ │ ├── EventA.java
│ │ │ ├── EventAny.java
│ │ │ └── ListenerSub.java
│ │ │ ├── jdbc
│ │ │ ├── MysqlSpringDemo.java
│ │ │ └── OjdbcSpringDemo.java
│ │ │ ├── mon
│ │ │ ├── HttpMonitorUsage.java
│ │ │ ├── LogMonitorUsage.java
│ │ │ └── ZkMonitorUsage.java
│ │ │ ├── monitor
│ │ │ ├── HttpMonitorUsage.java
│ │ │ └── ZkMonitorUsage.java
│ │ │ └── spring
│ │ │ └── MutipDemo.java
│ └── resources
│ │ ├── conf
│ │ └── conf.properties
│ │ ├── log4j.properties
│ │ ├── mon
│ │ ├── spring-http.xml
│ │ ├── spring-log.xml
│ │ └── spring-zk.xml
│ │ ├── ojdbc
│ │ └── db.properties
│ │ ├── spring-orac.xml
│ │ └── spring.xml
│ └── test
│ └── java
│ └── freamwork
│ ├── core
│ ├── AbstractStatisticalStressStrategy.java
│ ├── BaseStressConfig.java
│ ├── ConfigurableStressStrategy.java
│ ├── Context.java
│ ├── CountLimitedStressStrategy.java
│ ├── StressStrategy.java
│ ├── StressStrategySupport.java
│ ├── StressTask.java
│ ├── TimeLimitedStressStrategy.java
│ ├── Workbench.java
│ ├── read.md
│ └── stat
│ │ ├── DefaultStatisticImpl.java
│ │ ├── NumberUtil.java
│ │ └── Statistical.java
│ ├── simple
│ ├── common
│ │ └── UniqNumUtil.java
│ ├── core
│ │ ├── ConcurrentTask.java
│ │ └── ConcurrentTest.java
│ └── task
│ │ └── Task.java
│ └── test
│ ├── EncryptRunner.java
│ ├── Event.java
│ ├── EventBusStressTest.java
│ ├── EventPool.java
│ ├── EventSub.java
│ └── Runner.java
├── async-event-jdbc
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── cubbery
│ │ └── event
│ │ └── storage
│ │ ├── DbUtils.java
│ │ └── JdbcEventStorage.java
│ └── resources
│ ├── async-event-mysql-20160229.sql
│ └── async_event_oracle-20160307.sql
├── async-event-monitor
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── cubbery
│ │ └── event
│ │ └── monitor
│ │ ├── MonitorServer.java
│ │ ├── http
│ │ └── SimpleHttpMonitor.java
│ │ ├── log
│ │ └── LogMonitor.java
│ │ └── zk
│ │ ├── SimpleZkMonitor.java
│ │ ├── ZKManager.java
│ │ └── ZkTools.java
│ └── resources
│ └── html
│ ├── channel.html
│ └── retry.html
├── async-event-server
└── pom.xml
├── doc
└── frame.png
└── pom.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | *.class
2 |
3 | # Mobile Tools for Java (J2ME)
4 | .mtj.tmp/
5 |
6 | # Package Files #
7 | *.jar
8 | *.war
9 | *.ear
10 | .idea/*
11 | */target/*
12 | */*.iml
13 | *.iml
14 |
15 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
16 | hs_err_pid*
17 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | Change Log of Async-Event
2 | ====
3 | The current stable version : **[1.0.0]()**
4 |
5 | ###Async-Event-1.0.0 (2016-4-20)
6 | - 原始版本。
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # async-event
2 | 进程内部异步事件调用组件
3 |
4 | ## 解决什么问题:
5 |
6 | + 加速服务处理效率。提供进程级别的事件发布和异步处理能力。
7 | + 服务解耦。观察者和发布者之间互不干涉,解耦关系。
8 | + 事件驱动。提供一对多的对象关系。
9 | + 最终一致性。低延时,最终一致。
10 |
11 |
12 | ## 生产数据:
13 |
14 | + 使用异步事件组件优化服务[前]:
15 | + tps->2000,tp90->100ms,tp99->120ms
16 | + 使用异步事件组件优化服务[后]:
17 | + tps->2000,tp90->20ms,tp99->30ms
18 |
19 | ## 总体设计
20 |
21 | 
22 |
23 |
24 | ## Usage:
25 |
26 | //实例化事件总线,使用内存队列
27 | final EventBus eventBus = new EventBus(new MemoryChannel(1024));
28 | //注册消费者
29 | eventBus.register(new ListenerSub());
30 | eventBus.register(new BothSub());
31 | //启动事件总线
32 | eventBus.start();
33 |
34 | //发送事件消息(需要启动后才能发送)
35 | eventBus.publish(new SimpleEvent());
36 | eventBus.publish(new EventAny());
37 | eventBus.publish(new EventA());
38 | //停止事件总线
39 | eventBus.stop();
40 |
41 | ## 开发计划
42 |
43 |
44 | 1、持久化增加mybatis.
45 | 2、远程storage服务,统一管理。统一组件化。
46 |
--------------------------------------------------------------------------------
/async-event-core/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | async-event
7 | com.cubbery.event
8 | 1.0.1
9 |
10 | 4.0.0
11 |
12 | async-event-core
13 | com.cubbery.event
14 | async-event-core
15 | jar
16 |
17 |
18 |
19 | com.google.code.gson
20 | gson
21 |
22 |
23 |
--------------------------------------------------------------------------------
/async-event-core/src/main/java/com/cubbery/event/Channel.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2015, www.cubbery.com. All rights reserved.
3 | */
4 | package com.cubbery.event;
5 |
6 | import com.cubbery.event.channel.ChannelData;
7 | import com.cubbery.event.handler.EventHandler;
8 |
9 | import java.util.Set;
10 | import java.util.concurrent.TimeUnit;
11 |
12 | /**
13 | * 事件通道接口
14 | */
15 | public interface Channel {
16 |
17 | /**
18 | * put in to
19 | *
20 | * @param event
21 | * @return
22 | */
23 | boolean offer(Object event,Set handlers);
24 |
25 | /**
26 | * remove and get one from the q
27 | *
28 | * @param timeout
29 | * @param unit
30 | * @return
31 | */
32 | ChannelData poll(long timeout, TimeUnit unit);
33 |
34 | /**
35 | * is empty when queue.size() == 0
36 | *
37 | * @return
38 | */
39 | boolean isEmpty();
40 |
41 | /**
42 | * get storage if this is persistence
43 | *
44 | * @return
45 | */
46 | EventStorage getStorage();
47 |
48 | /**
49 | * put a storage if necessary
50 | *
51 | * @param storage
52 | */
53 | void setStorage(EventStorage storage);
54 |
55 | /**
56 | * check init is ok
57 | */
58 | boolean checkInit();
59 |
60 | /**
61 | * get a creator for event
62 | *
63 | * @return
64 | */
65 | EventCreator getCreator();
66 |
67 | /**
68 | * set a creator for event
69 | *
70 | * @param creator
71 | */
72 | void setCreator(EventCreator creator);
73 | }
74 |
--------------------------------------------------------------------------------
/async-event-core/src/main/java/com/cubbery/event/Dispatcher.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2015, www.cubbery.com. All rights reserved.
3 | */
4 | package com.cubbery.event;
5 |
6 | import com.cubbery.event.channel.ChannelData;
7 | import com.cubbery.event.worker.ConsumeWorker;
8 | import com.cubbery.event.utils.ThreadFactories;
9 | import com.cubbery.event.utils.Validation;
10 |
11 | import java.util.concurrent.TimeUnit;
12 |
13 | /**
14 | * 事件派发者,程序逻辑处理器,使用守护线程。
15 | */
16 | final class Dispatcher {
17 | private final EventBus eventBus;
18 | private volatile boolean running;
19 |
20 | protected Dispatcher(EventBus eventBus) {
21 | this.eventBus = eventBus;
22 | this.running = false;
23 | }
24 |
25 | public synchronized Dispatcher start() {
26 | if(!this.running) {
27 | this.running = true;
28 | //使用守护线程是由于:(对于持久化消息,有重试进程定时mark事件成重试状态)
29 | new ThreadFactories(true,"Dispatcher").newThread(new DispatcherTask()).start();
30 | }
31 | return this;
32 | }
33 |
34 | public synchronized void stop() {
35 | this.running = false;
36 | }
37 |
38 | class DispatcherTask implements Runnable {
39 | private final ThreadLocal counter = new ThreadLocal(){
40 | @Override
41 | protected Integer initialValue() {
42 | return 0;//Integer cache 127 ~ -127
43 | }
44 | };
45 |
46 | @Override
47 | public void run() {
48 | Channel channel = eventBus.getChannel();
49 | while (running) {
50 | //避免线程无法shutDown,所以给定一个超时时间,而不是一直阻塞
51 | ChannelData event = selfRegulation(channel,channel.poll(10, TimeUnit.MILLISECONDS));
52 | if(event != null) {
53 | eventBus.getConsumeExecutor().submit(new ConsumeWorker(event.getHandler(), event));
54 | }
55 | }
56 | }
57 |
58 | private ChannelData selfRegulation(Channel channel,ChannelData event) {
59 | //常驻线程,避免线程无法shutDown,阻塞进程关闭。所以给定一个超时时间,而不是一直阻塞
60 | try {
61 | Validation.checkNotNull(event, "Event cannot be null.");
62 | Validation.checkNotNull(event.getData(), "Event cannot be null.");
63 | return event;
64 | } catch (Exception e) {
65 | if(counter.get() > 2) {
66 | //当2个周期没有拿到数据,那么wait 1min
67 | counter.set(0);
68 | return channel.poll(60,TimeUnit.SECONDS);
69 | } else {
70 | ChannelData eventData = channel.poll(10, TimeUnit.MILLISECONDS);
71 | counter.set(counter.get() + 1);
72 | return selfRegulation(channel,eventData);
73 | }
74 | }
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/async-event-core/src/main/java/com/cubbery/event/EventBusRegistry.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2016,www.cubbery.com. All rights reserved.
3 | */
4 | package com.cubbery.event;
5 |
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 |
9 | import java.util.ArrayList;
10 | import java.util.List;
11 |
12 | /**
13 | * 类描述:
14 | * 创建人: 百墨
15 | * 创建时间: 2016/5/12 - 16:16
16 | *
17 | * @version 1.0.0
18 | */
19 | class EventBusRegistry {
20 | private final static Logger LOG = LoggerFactory.getLogger("Event-Bus-All");
21 | private final static List allBus = new ArrayList();
22 |
23 | static {
24 | Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
25 | @Override
26 | public void run() {
27 | try {
28 | destroyAll();
29 | } catch (Throwable e) {
30 | }
31 | }
32 | },"EventBusShutDownHook"));
33 | }
34 |
35 | public static void report(EventBus eventBus) {
36 | allBus.add(eventBus);
37 | }
38 |
39 | public static void destroyAll() {
40 | for(EventBus bus : allBus) {
41 | if(bus != null) {
42 | bus.stop();
43 | LOG.info("Event Bus Stopped!");
44 | }
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/async-event-core/src/main/java/com/cubbery/event/EventBusSpring.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2015, www.cubbery.com. All rights reserved.
3 | */
4 | package com.cubbery.event;
5 |
6 | import com.cubbery.event.utils.HostUtils;
7 | import com.cubbery.event.event.impl.EncryptEventCreator;
8 |
9 | import java.util.ArrayList;
10 | import java.util.List;
11 |
12 | /**
13 | * Spring辅助配置类:辅助处理:
14 | *
15 | * 黑名单字符串处理
16 | * 订阅者处理
17 | * 指定加解密
18 | *
19 | * 创建人: 百墨
20 | * 创建时间: 2016/3/4 - 10:24
21 | * @version 1.0.0
22 | */
23 | public class EventBusSpring {
24 | private EventBus eventBus;
25 | private List