简体   繁体   English

微服务架构的同步代码块

[英]Synchronized code block for microservice architecture

We have a method that needs to have synchronized for a code block across all instances of microservice.我们有一个方法需要同步所有微服务实例的代码块。

MyEntity (class) in DynamoDB Example: DynamoDB 示例中的 MyEntity(类):

field1(Partition Key), field2(Sort Key), isPrimary
1                           1               true
1                           2               false
1                           3               false
2                           1               true
2                           2               false
3                           2               true

The value of one type based on field1 can be primary which gets decided based on field2.基于 field1 的一种类型的值可以是主要的,它是根据 field2 决定的。

Like, out of all 1s one will be primary, and so on for 2s and 3s in the field1 which is decided based on the value of the field2.就像,在所有 1 中,一个将是主要的,依此类推,对于 field1 中的 2s 和 3s,这是根据 field2 的值决定的。

If the value of field1 is new in the entire table then based on FCFS logic it will become primary.如果 field1 的值在整个表中是新的,那么基于 FCFS 逻辑它将成为主要的。

Problem: The problem is in a microservice architecture, if more than one instance is trying to insert having same value of field1 which does not exists in table then they might end up making both as primary.问题:问题出在微服务架构中,如果多个实例试图插入具有相同字段 1 值但表中不存在的实例,那么它们最终可能会将两者都设为主要实例。 As we are using DynamoDB so cannot put constraint on table.由于我们使用的是 DynamoDB,因此不能对表施加约束。

public MyEntity saveMyEntity(MyEntity myEntity) {
    if (!myEntity.isPrimary()) {
        synchronized (myEntity.getField1().intern()) {
            if (!existsByField1(myEntity.getField1())) {
                myEntity.setPrimary(true);
            }
        }
    }
    dynamoDBMapper.save(myEntity);
    return myEntity;
}

private boolean existsByField1(String field1){
    //checks if field1 value exists in table column field1.
}

Tried making block level synchronization but it will work only for the same instance not for others.尝试进行块级同步,但它只适用于同一实例,不适用于其他实例。

How can we achieve microservice-level code block synchronization?如何实现微服务级别的代码块同步?

What you are looking for is distributed locking: you use a strongly consistent linearizable datastore to manage locks.您正在寻找的是分布式锁定:您使用高度一致的可线性化数据存储来管理锁。 Examples of such stores include zookeeper, etcd, and consul.此类商店的示例包括 zookeeper、etcd 和 consul。 You can also implement it yourself by having the instances communicate with each other and implement a consensus protocol like Raft or Paxos (though it must be said that rolling one's own consensus protocol is in a similar category to rolling one's own cryptography: useful as a learning exercise, but probably not something you should want in production).您也可以通过让实例相互通信并实现像 Raft 或 Paxos 这样的共识协议来自己实现它(尽管必须说滚动自己的共识协议与滚动自己的密码学属于类似的类别:作为学习很有用锻炼,但可能不是您在生产中应该想要的东西)。

Note that the consistency demands here (I'm making the assumption that if there were multiple primaries that would be Really Bad) imply that there are unavoidable scenarios where your system will grind to a halt for at least some period of time (eg an instance of the service gets stopped or crashes while holding the locks).请注意,这里的一致性要求(我假设如果有多个初选真的很糟糕)意味着存在不可避免的情况,您的系统将至少在一段时间内停止运行(例如实例服务在持有锁时停止或崩溃)。 You can reduce that period of time, but doing so in general implies an increasing risk of multiple primaries, because there's no easy way to guarantee that the instance holding the lock is actually not doing anything with it.您可以减少那段时间,但这样做通常意味着增加多个主节点的风险,因为没有简单的方法来保证持有锁的实例实际上没有对它做任何事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM