2014-10-20 15 views
7

Akka Cluster-Sharding trông giống như một trường hợp sử dụng, tôi phải tạo một cá thể duy nhất của các diễn viên liên tục trên các nút Akka.Akka cluster-sharding: Các diễn viên có thể có các đạo cụ động hay không

Tôi không rõ liệu có thể có loại nhập diễn viên yêu cầu đối số để xây dựng nó hay không. Hoặc có lẽ tôi cần phải xem xét lại cách diễn viên Entry nhận được thông tin này.

Object Account { 
    def apply(region: String, accountId: String): Props = Props(new Account(region, accountId)) 
} 

class Account(val region: String, val accountId: String) extends Actor with PersistentActor { ... } 

Trong một trường hợp Đạo cụ duy nhất để tạo tất cả các diễn viên nhập cảnh.

Từ akka cluster-sharding:

val counterRegion: ActorRef = ClusterSharding(system).start(
    typeName = "Counter", 
    entryProps = Some(Props[Counter]), 
    idExtractor = idExtractor, 
    shardResolver = shardResolver) 

Và sau đó nó giải quyết các diễn viên nhập cảnh tiếp nhận thông điệp dựa trên cách bạn xác định idExtractor. Từ mã nguồn cho mảnh vỡ có thể thấy nó sử dụng id là tên cho một trường hợp nam diễn viên nhập cảnh đưa ra:

def getEntry(id: EntryId): ActorRef = { 
val name = URLEncoder.encode(id, "utf-8") 
context.child(name).getOrElse { 
    log.debug("Starting entry [{}] in shard [{}]", id, shardId) 

    val a = context.watch(context.actorOf(entryProps, name)) 
    idByRef = idByRef.updated(a, id) 
    refById = refById.updated(id, a) 
    state = state.copy(state.entries + id) 
    a 
} 

}

Có vẻ như tôi thay vì phải có con số diễn viên nhập cảnh của tôi ra khỏi khu vực của mình và accountId theo tên nó được đưa ra, mặc dù điều này không cảm thấy một chút hacky bây giờ mà tôi sẽ phân tích nó ra khỏi một chuỗi thay vì trực tiếp nhận được các giá trị. Đây có phải là lựa chọn tốt nhất của tôi không?

Trả lời

10

Tôi đang ở trong tình huống tương tự như của bạn. Tôi không có câu trả lời chính xác nhưng tôi có thể chia sẻ với bạn và độc giả những gì tôi đã làm/thử/suy nghĩ.

Tùy chọn 1) Như bạn đã đề cập, bạn có thể trích xuất thông tin id, phân đoạn và vùng từ cách bạn đặt tên cho công cụ của mình và phân tích đường dẫn. Ngược lại là a) dễ dàng thực hiện. Các nhược điểm là a) Akka mã hóa đường dẫn diễn viên là UTF-8, vì vậy nếu bạn đang sử dụng bất kỳ thứ gì làm dấu tách không phải là ký tự url chuẩn (chẳng hạn như || hoặc w/e), trước tiên bạn sẽ cần giải mã nó từ utf8. Lưu ý rằng bên trong Akka utf8 được mã hóa cứng như phương thức mã hóa, không có cách nào để trích xuất định dạng mã hóa như trong một hàm, do đó, nếu ngày mai thay đổi bạn cũng sẽ phải điều chỉnh mã của bạn. b) hệ thống của bạn không bảo tồn được đồng cấu nữa (ý bạn là gì bởi "nó cảm thấy bị hack"). Điều này ngụ ý rằng bạn đang thêm rủi ro mà dữ liệu của bạn, một ngày, có thể chứa chuỗi phân tách thông tin của bạn dưới dạng dữ liệu có ý nghĩa và hệ thống của bạn có thể gây rối.

Tùy chọn 2) Sharding sẽ sinh ra diễn viên của bạn nếu nó không tồn tại. Vì vậy, bạn có thể buộc mã của bạn luôn gửi một thông điệp init đến các tác nhân không khởi tạo, chứa các tham số hàm tạo của bạn. diễn viên sharded của bạn sẽ có một cái gì đó bên trong của họ về các loại:

val par1: Option[param1Type] = None 

def receive = { 
    case init(par1value) => par1 = Some(par1value) 
    case query(par1) => sender ! par1 
} 

Và từ diễn viên truy cập khu vực của bạn, bạn luôn có thể gửi đầu tiên được thông báo truy vấn và sau đó được thông báo init nếu sự trở lại là None. Điều này giả định rằng diễn viên truy cập khu vực của bạn không mantain một danh sách các diễn viên khởi tạo, trong trường hợp đó bạn chỉ có thể sinh ra với init và sau đó sử dụng chúng bình thường. Ngược ở đây là a) Đó là thanh lịch b) nó "cảm thấy" đúng

Nhược điểm: a) phải mất thông điệp 2x (nếu bạn không duy trì một danh sách các diễn viên được khởi động)

Lựa chọn 3) TÙY CHỌN NÀY ĐÃ ĐƯỢC KIỂM TRA VÀ KHÔNG LÀM VIỆC. Tôi sẽ để nó ở đây để mọi người tránh lãng phí thời gian. Tôi không biết liệu điều này có hiệu quả không, tôi chưa thử nghiệm vì tôi đang sử dụng kịch bản này trong sản xuất với những ràng buộc đặc biệt và những thứ ưa thích không được phép^_^Nhưng hãy thử và làm ơn cho tôi biết hoặc bình luận! Về cơ bản, bạn bắt đầu khu vực của bạn với

val counterRegion: ActorRef = ClusterSharding(system).start(
    typeName = "Counter", 
    entryProps = Some(Props[Counter]), 
    idExtractor = idExtractor, 
    shardResolver = shardResolver) 

gì nếu bạn ở diễn viên sáng tạo khu vực của bạn, làm một cái gì đó như:

var providedPar1 = v1 
def providePar1 = providedPar1 

val counterRegion: ActorRef = ClusterSharding(system).start(
    typeName = "Counter", 
    entryProps = Some(Props(classOf[Counter], providePar1), 
    idExtractor = idExtractor, 
    shardResolver = shardResolver) 

Và sau đó bạn thay đổi giá trị của providedPar1 cho mỗi sự sáng tạo? Nhược điểm của điều này là, trong tùy chọn nó hoạt động, bạn cần phải tránh thay đổi giá trị của cung cấpPar1 cho đến khi bạn chắc chắn 100% rằng tác nhân đã được tạo, hoặc bạn có thể mạo hiểm nó truy cập vào giá trị mới, sai (yay , điều kiện chủng tộc!)

Nói chung, bạn nên sử dụng tùy chọn 2 imho, nhưng trong hầu hết các trường hợp, rủi ro được giới thiệu bởi 1 là nhỏ và bạn có thể giảm thiểu chúng một cách phù hợp với ưu điểm đơn giản (và hiệu suất).

Hy vọng điều này giúp ích, hãy cho tôi biết nếu bạn thử 3 cách hoạt động!

+1

Cảm ơn các ý tưởng. Như một câu trả lời trực tiếp cho phần đầu tiên của câu hỏi mà chúng tôi đã chỉ ngụ ý, không có cách tích hợp với ClusterSharding để hỗ trợ các đạo cụ động. Vì vậy, ngữ cảnh hóa câu trả lời của bạn liên quan đến câu hỏi tiếp theo của tôi về 'đây có phải là lựa chọn tốt nhất của tôi không?' Mà tôi tin rằng bạn đã trả lời tốt. – Rich

+0

Vâng, tôi không chắc liệu tốt hơn là loại bỏ nó hoàn toàn hoặc đánh dấu nó là không hoạt động để có thể ai đó ở akka sẽ nhặt nó lên * nháy mắt * (hoặc ít nhất mọi người sẽ biết nó không phải là một lựa chọn và sẽ không lãng phí thời gian thử nó). Ngoài ra, nó có thể có thể có được một cái gì đó với Guice và hack vào một InjectedProps, tôi đã thấy một cái gì đó như thế một nơi nào đó, tiếc là tôi không nhớ các chi tiết. –

Các vấn đề liên quan