Akka實踐一些總結(java專案)
本文來自 fairjm@圖靈社群 轉截請註明出處
最近在一些服務中使用了akka,主要用來做非同步解耦和本地訊息分發(路由).
總體使用比較簡單,這裡做下小結,具體的業務和拓撲圖就不提供了~.
與spring整合
網上有不少整合的例子,要使用到spring的擴充套件.
我這邊沒有這樣處理,而是簡單把ActorSystem
建立的actor的過程放在了spring configuration裡,把ActorRef
作為bean,畢竟actor本身不能為單例但是ref可以.
actor要使用一些bean的話就全部都由建構函式傳入.
如下:
public class UserActor extends AbstractLoggingActor {
private UserService userService;
public static Props props(UserService userService) {
return Props.create(UserActor.class, () -> new UserActor(userService));
}
public User(UserService userService) {
this.userService = userService;
}
在java中使用
使用中能感覺和java還是有些隔閡的...
特別是容器(Collection)之間的轉換和處理.
給出一些例子,可能是我沒發現更方便的寫法..
List<Routee> routees = new ArrayList<>();
senders.forEach(e -> {
try {
ActorRef ref = getContext().actorOf(createdProps.apply(e), prefix + "-" + e.getId());
routees.add(new ActorRefRoutee(ref));
} catch (InvalidActorNameException ex) {
log().error(ex, "name already in use");
}
});
router = new Router(new RoundRobinRoutingLogic(), routees);
這邊本來用一個map就能解決了,但會要求型別強轉Router的第二個引數是java.lang.Iterable<Routee>
而不是java.lang.Iterable<? extends Routee>
(ActorRefRoutee是其子類),再加上還要處理重名錯誤,還是用了這種錯誤的forEach使用方式.
private void stopRoutee(Router router) {
List<Routee> routees = new ArrayList<>(seqAsJavaList(router.routees()));
routees.forEach(e -> {
ActorRefRoutee ae = (ActorRefRoutee) e;
ActorRef ref = ae.ref();
// 移除這個routee
router.removeRoutee(ae);
// 停止這個ref
context().stop(ref);
});
}
router.routees()返回的是個IndexSeq...和java的沒有相容和對應.
最開始找了一些,後來發現有scala.collection.JavaConversions
可以做相容...感受到了隔閡.
此外ask模式,akka為java提供了PatternsCS
.這個類返回的是java的CompletionStage
型別相比Patterns
,比較友好.
使用誤區
最容易誤用的一點就是訊息處理中有阻塞操作,比如直接在actor中進行資料庫操作和處理網路請求,而使用的actor也沒有和執行緒繫結,這種情況需要使用額外的執行緒池,這個其實和用netty是一樣的情況,用來進行應用排程的執行緒數有限.
由於上面提到的點,於是在actor內可能就會存在一些回撥,一不小心就可能直接呼叫/改變actor內部的狀態(例如在回撥直接訪問field).
private List<String> list;
... ...
public Receive createReceive() {
return receiveBuilder()
.match(Message.class, e -> xxxx.onSuccess(r -> list.add(r)))
... ...
這樣等於內部狀態被多執行緒訪問,破壞了actor內部的狀態,正確的做法是在回撥中給自己傳送訊息.
相關文章
- vue + iview 專案實踐總結 【完】VueView
- Kotlin 初嘗之專案實踐總結Kotlin
- Mybatis Plus 框架專案落地實踐總結MyBatis框架
- uniapp專案實踐總結(二十)URLScheme 協議知識總結APPScheme協議
- 什麼是框架?(最佳實踐、專案總結)框架
- SpringMVC——HTTP請求專案實踐整理總結SpringMVCHTTP
- 2019年終總結之SAP專案實踐篇
- 2018年終總結之SAP專案實踐篇
- 專案中多級快取設計實踐總結快取
- 用vue做專案的一些總結Vue
- 記一次redux-saga的專案實踐總結Redux
- MySQL專案實戰總結MySql
- uniapp專案實踐總結(十七)實現滾動觸底載入APP
- uniapp專案實踐總結(十六)自定義下拉重新整理元件APP元件
- 總結開源專案中的常見壞實踐(Bad Practice)
- uniapp專案實踐總結(十五)使用websocket實現簡易聊天室APPWeb
- 實習專案開發總結
- 【Vue專案總結】後臺管理專案總結Vue
- BBS專案專案總結
- LNMP 環境部署 Laravel 專案的一些總結LNMPLaravel
- Linux專案實踐中常用操作彙總Linux
- Vue開發總結 及 一些最佳實踐 (已更新)Vue
- Linux實踐總結Linux
- 【微信小程式專案實踐總結】30分鐘從陌生到熟悉微信小程式
- 番茄專案總結
- Nuxt專案總結UX
- 今日專案總結
- Laravel 專案總結Laravel
- Java專案中MongoDb學習和使用總結JavaMongoDB
- 【Java EE】從零開始寫專案【總結】Java
- 實驗室後臺管理專案總結
- 實戰專案後對 React Hooks 總結ReactHook
- 【快速學習】docker構建java專案實踐DockerJava
- mobx專案實踐
- 阿里DDD專案最佳實踐-COLA 架構總覽阿里架構
- RESTful API實踐總結RESTAPI
- vue實踐06-專案實踐Vue
- Vue + Canvas專案總結VueCanvas