1、Solon Cloud Event?
是 Solon 分散式事件匯流排的解決方案。也是 Solon “最終一致性”分散式事務的解決方案之一
2、事務特性
事務?就是要求 Event 有原子性,當多個 Event 釋出時,要麼全成功,要麼全失敗。
public class EventDemo {
public void event_tran() {
//新建一個 Event 事務
EventTran eventTran = CloudClient.event().newTran();
try {
//釋出,並使用事務
CloudClient.event().publish(new Event("user.event1", "test1").tran(eventTran));
CloudClient.event().publish(new Event("user.event2", "test2").tran(eventTran));
CloudClient.event().publish(new Event("user.event2", "test3").tran(eventTran));
//如果沒問題,提交事務
eventTran.commit();
} catch (Throwable ex) {
//如果有問題,回滾事務
eventTran.rollback();
}
}
}
上面的體驗與經典的 Jdbc 事務是很像的。加入 Solon 的事務註解管理後,體驗可以再簡潔些,也能與 Jdbc 事務整合到一起。
@Component
public class EventDemo {
//使用 @Tran 管理事務(將 jdbc, event 事務整合到一起)
@Tran
public void event_and_jdbc_tran() {
//新建一個 Event 事務,並加入 @Tran 的管理
EventTran eventTran = CloudClient.event().newTranAndJoin();
CloudClient.event().publish(new Event("user.event1", "test1").tran(eventTran));
CloudClient.event().publish(new Event("user.event2", "test2").tran(eventTran));
CloudClient.event().publish(new Event("user.event2", "test3").tran(eventTran));
}
}
3、擬模真實的場景應用:
我們設計一個使用者註冊的場景應用:
- 持久層新增使用者記錄
- 註冊後釋出一個已註冊事件;再釋出一個10天后觸發的已喚醒事件
- 在已註冊事件裡,我們給使用者送10個金幣;再送手機100元衝值
- 在已喚醒事件裡,我們檢查使用者的活動行為;如果有,再送100個金幣(作為獎勵);如果沒發推送,告知有抽獎
主服務程式,負責主業務:
@Component
public class UserService {
@Inject
UserDao userDao;
//使用者註冊
@Tran
public void userRegister(long userId, String name){
userDao.addUser(userId, name);
this.onUserRegistered(userId);
}
//當使用者完成註冊時(釋出事件)
private void onUserRegistered(long userId) {
String eventJson = String.format("{\"userId\":%d}", userId);
Date eventTime = DateTime.Now().addDay(10);
EventTran eventTran = CloudClient.event().newTranAndJoin();
//釋出使用者已註冊事件
CloudClient.event().publish(new Event("user.registered", eventJson).tran(eventTran));
//釋出使用者已喚醒事件(用於檢查使用者在10內,有沒有活動行為)
CloudClient.event().publish(new Event("user.reawakened", eventJson).scheduled(eventTime).tran(eventTran));
}
}
次服務程式,負責輔助業務(也可以合到主服務程式):
@CloudEvent("user.registered")
public class UserRegisteredEventHandler implements CloudEventHandler {
@Inject
UserService userService;
@Inject
MobileService mobileSerivce;
@Override
public boolean handler(Event event) throws Throwable {
long userId = ONode.load(event.context()).get("userId").getLong();
//送10個金幣
userService.addGold(userId, 10);
//送手機充值100塊
String mobie = userService.getMobile(userId);
mobileSerivce.recharge(mobile, 100);
return true;
}
}
@CloudEvent("user.reawakened")
public class UserReawakenedEventHandler implements CloudEventHandler {
@Inject
UserService userService;
@Inject
PushService pushService
@Override
public boolean handler(Event event) throws Throwable {
long userId = ONode.load(event.context()).get("userId").getLong();
if (userService.hasLive(userId, 10)) {
//再送100個金幣
userService.addGold(userId, 100);
} else {
//獲取裝置id
String duid = userService.getDuid(userId);
//釋出推送
pushService.push(duid, "有100個金幣等你來拿喲...")
}
return true;
}
}