我有一个暴露一个端点的Spring-boot应用程序:
/update/1532
它可以收到一个查询参数"批准"哪个可以有" false"或"真"作为一种价值。 例如:
/update/1532?approve=false
问题是可以使用不同的查询参数值同时调用更新端点。
为了处理这种情况,我们创建了单独的Context类,它包含正在进行的id的集合。在上面的情况下,它应该在第一次调用后保存1532 id,因此具有相同id的第二个请求将导致错误响应:" Id已在进行中"。
此解决方案运行良好,直到我们决定创建多个节点,每个节点都进入同一个数据库。 问题是每个节点将包含具有唯一ID标识的单独上下文。
其中一个解决方案可以是创建Id的分布式缓存,它可以取代上环类Set。 但我不确定这种方法是否合适。
也许有人可以提出更好的锁定内部群集的解决方案吗?
P.S。 由于所有数据库通信都隐藏在Activiti框架的引擎下,因此无法使用数据库事务实现同步。
技术信息: Spring-boot- 1.5.6; Activiti- 5.21
答案 0 :(得分:1)
您需要一个共同的基础设施来处理这个问题。如果没有像分布式锁(很难)这样的东西,你应该只指定一个节点作为" master"其余作为读者节点。
写入方法应该将请求(可能是服务器端)转发到写入节点,该节点可以管理本地锁定以写入数据。
或者,如果您不想转发请求,可以查看消息以解决此问题。在每个更新的队列中删除一条消息,让主节点完全执行写操作而不使其处理读取。这很好,因为你可以跳过一些HTTP管道来重定向POST(307重定向),或重建它们服务器端......
如果您坚持尝试分布式锁管理器路线,请选择一个库,不要尝试自己动手。这是一个复杂的主题,必须考虑很多事情(主要是围绕失败模式,不要让锁永远悬空,死锁检测等)。
答案 1 :(得分:0)
虽然它不是实时的,但我们通常使用hazelcast来跨节点复制应用程序内存映射。 Hazelcast将确保在允许响应之前对整个网格进行更新,以便您接近实时同步。
我们有一个应用程序使用这种方法成功维护分布在多个数据中心的数百个节点的分布式状态。
格雷格