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 事務整合到一起)@Tranpublic 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 {@InjectUserDao userDao;//用戶注冊@Tranpublic 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 {@InjectUserService userService;@InjectMobileService mobileSerivce;@Overridepublic 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 {@InjectUserService userService;@InjectPushService pushService@Overridepublic 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 {//獲取設備idString duid = userService.getDuid(userId);//發布推送pushService.push(duid, "有100個金幣等你來拿喲...")}return true;}
}