我们有web服务API来支持在千万台设备上运行的客户端。通常客户机一天调用服务器一次。也就是说每秒可以看到116个客户机。对于每个客户端(每个客户端具有唯一的ID),它可能并发地进行几个API调用。然而,Server只能逐个处理来自同一客户端的API调用。因为,那些API调用将更新后端Mongodb数据库中该客户端的相同文档。例如:需要更新本客户端文档中的last seen time和其他嵌入文档。
我有的一个解决方案是将同步块放在一个“Intern”对象上,表示这个客户机的唯一ID。这将允许来自同一客户机的一个请求同时获得锁并被处理。此外,还可以同时处理来自其他客户端的请求。但是,这种解决方案需要打开负载均衡器的“粘性”。这意味着负载均衡器将在预设的时间间隔内(如15分钟)将所有请求从同一ip地址路由到特定的服务器。我不确定这是否对整个系统设计的健壮性有任何影响。我能想到的一件事是,有些客户端可能会发出更多请求,并使负载不平衡(创建热点)。
Interner<Key> myIdInterner = Interners.newWeakInterner();
public ResponseType1 processApi1(String clientUniqueId, RequestType1 request) {
synchronized(myIdInterner.intern(new Key(clientUniqueId))) {
// code to process request
}
}
public ResponseType2 processApi2(String clientUniqueId, RequestType2 request) {
synchronized(myIdInterner.intern(new Key(clientUniqueId))) {
// code to process request
}
}
public ResponseType1 processApi1(String clientUniqueId, RequestType1 request) {
try {
obtainDocumentLock(new Key(clientUniqueId));
// code to process request
} finally {
releaseDocumentLock(new Key(clientUniqueId));
}
}
public ResponseType2 processApi2(String clientUniqueId, RequestType2 request) {
try {
obtainDocumentLock(new Key(clientUniqueId));
// code to process request
} finally {
releaseDocumentLock(new Key(clientUniqueId));
}
}
例如,有两个请求:请求#1和请求#2。请求#1读取客户端的文档,更新一个子文档#5的一个字段,并将整个文档保存回来。请求#2读取同一文档,更新子文档#8的一个字段,并将整个文档保存回来。这时我们将得到一个OptimisticLockingFailureException,因为我们使用了来自spring-data-mongodb的@version注释来检测版本冲突。因此,必须在任何时候只处理来自同一客户端的一个请求。
附注。对于选择解决方案#1(打开负载均衡器粘性的单个进程/实例上的锁)或解决方案#2(分布式锁)来进行可伸缩性和高并发性系统设计的任何建议。目标是支持数千万个客户机,每秒同时有数百个客户机访问系统。
在您的解决方案中,您正在根据客户id进行锁拆分,以便两个客户可以同时处理服务。唯一的问题是粘性会话。一种解决方案可以是使用分布式锁,这样您就可以将任何请求分派到任何服务器,并且服务器获得锁进程。只有一个考虑是它涉及远程调用。我们正在使用Hazelcast/Ignite,它在平均节点数上工作得很好。榛子
面试题 如何设计一个高并发系统? 面试官心理分析 说实话,如果面试官问你这个题目,那么你必须要使出全身吃奶劲了。为啥?因为你没看到现在很多公司招聘的 JD 里都是说啥,有高并发就经验者优先。 如果你确实有真才实学,在互联网公司里干过高并发系统,那你确实拿 offer 基本如探囊取物,没啥问题。面试官也绝对不会这样来问你,否则他就是蠢。 假设你在某知名电商公司干过高并发系统,用户上亿,一天流量几十亿
问题内容: 单个Servlet如何处理以用户请求形式出现的多个客户端请求?基于单例设计模式,我知道我们创建了一个servlet实例,但是单个servlet如何处理数百万个请求。对其所涉及的线程也感到困惑。 同样,这里提供了任何浏览器规范或设置,可用于跨请求发送请求或生成针对请求发送的线程。 所有框架都相同还是不同(例如,struts v / s springs)? 问题答案: Struts / S
我正在开发一个具有多个客户端的标准java RMI服务器。这些客户机有一个菜单,在那里他们可以调用服务器为他们做各种事情。 一种方法涉及一个队列,他们可以在其中将作业发送到队列并等待它得到处理。RMI服务器自动为所有客户端处理线程,但当涉及到此方法和队列时,我如何阻止此请求,例如: 首先调用客户端1,然后再调用客户端2(此处客户端1应首先从服务器接收消息,客户端2应等待服务器处理客户端1请求所需的
树的种子包含了成长的思想,但不完全实现成长体的形式与力量。胚胎会成长。它会变大。它看起来更像成长体,并越来越有用。最终它孕育果实。最后,它死亡并且它的躯体喂养了其他的有机体。 对待软件我们也应当有这样的荣耀。一架桥不是这样的,永远不会有一架婴儿桥,但只是有一座未完成的桥。桥比软件要简单得多。 认识到软件的成长是有益的,因为这允许我们在有一个完美的思维图景前取得有用的进步。我们可以从用户那里获得反馈
我有两个项目,一个是由reactjs开发的,另一个是由laravel开发的。我想从laravel项目中获取一些数据,因此,我通过api调用访问laravel项目控制器文件夹中的一个方法。如果我使用reactjs项目中的方法,如何调试laravel项目?
我尝试使用Java中的Sockets连接到多个客户端。一切似乎都正常,但问题是,服务器只监听第一个客户端。如果有多个客户端,服务器可以向它们发送所有消息,但他可以只监听来自第一个客户端的消息。我尝试了所有这些(我从昨天开始就遇到了这个问题)。所以我很确定,错误一定在“ClientListener”类中。 说明:有一个客户端列表(用于与字符串通信的连接)。在GUI中有一个列表,我可以在其中选择要与哪