我在互联网上发现的大部分Akka材料包括许多SO问题,指出我们应该在处理它们的演员内部保留相关数据。不鼓励使用锁定机制
我正在开发基于Akka actor的Java服务,它维护着大量的动态数据。以前我使用复制写入机制进行数据更新,但由于预期的更新速率,这可能会导致下一版本出现性能问题(特别是高GC活动)。
让我们说我有一个管理股票信息的演员( StockManagerActor )。股票价格经常被阅读和更新。 (我更喜欢让一个单独的演员接收更新并提交它们,另一个演员在需要时阅读股票价格。但我不能这样做,因为它会在不同类型的演员之间分享可变的股票数据) 所以 StockManagerActor 处理两种类型的消息。 UpdateStockMessage 和 GetStockMessage 。当我们想到这个actor的一个实例正在运行时,一切似乎都很好,因为没有数据在actor之间共享。
我担心如果我只在系统中运行一个 StockManagerActor ,那么当股票市场高度活跃时,它的收件箱可能会迅速增长。因此,我希望有一个 StockManagerActor 池来同时处理这些消息。但在这种情况下,将由不同的actor实例执行并发更新/获取操作。 当 updateStock ()阻塞(在单独的调度程序中)和非阻塞时,这种情况有什么好的设计?
StockManagerActor extends UntypedActor{
StockStroe stockStore;
// Only StockManagerActors use the StockStore which is
// Initially populated from outside of actor system. Methods are not
// thread safe
public StockManagerActor(){
stockStore = StockStore.getInstanceFor(this);
}
@Override
public void onReceive(Object message) throws Exception {
if(message instanceof UpdateStockMessage){
UpdateStockMessage updateMessage = (UpdateStockMessage)message;
stockStore.updateStock(updateMessage)
}else if(message instanceof GetStockMessage){
GetStockMessage getMessage = (GetStockMessage)message;
Stock stock = stockStore.getStock(getMessage.getSymbol());
// stock here is immutable
generateStockMessageAndSend(stock, getSender());
}else{
unhandled(message);
}
}
//... More code
}
答案 0 :(得分:2)
解决方案:每个股票一名演员 - 根据需要创建。
<强> StockActor 强> - 负责维护/更新一只股票的数据。 - 对于每个库存,应在需要时创建一个StockActor,并在不需要/完成时将其杀死。
<强> StockManagerActor 强> 父actor在需要时创建StockActor并监视它们。提供其他统计数据,例如一次运行的儿童演员数量。
Akka分片 Akka与Clustering一起分片将让您无缝地为每个库存创建一个actor,并在不需要时将其钝化。 Akka负责分片功能。因此,我们不必担心正在运行的股票行为者意外死亡。
如果你不想在崩溃期间放松演员状态,也可以使用 Akka Persistence 。
这里有一些链接。 Persistence Sharding