场景:存在'n'个团队,每个团队都在他们的虚拟“墙”上工作(如facebook的墙)。每个团队只看到自己的墙和上面的帖子。这些帖子可以由帖子的作者或其他团队成员编辑(如果这样配置的话。假设确实如此,因为这是必须的)。
设计/技术决策:使用Restlet + Glassfish / Java + Mysql的RESTful Web应用程序(编辑:使用Apache DBUtils进行数据库访问。没有ORM - 似乎有点矫枉过正)
问题:多个团队登录T1,T2和T3(比如说),每个团队都有一些成员。团队级数据访问存在并发性,但团队之间不存在并发性 - 即不同的团队访问不相交的数据集。为了优化对DB的频繁读/写,我们正在考虑一个TeamGateway,它控制对DB的访问以处理并发。 Web服务器将缓存团队检索的数据以加快读取速度(并帮助更新墙上帖子列表)
如果每个T1-T3中有6个人登录,则只会创建3个TableGateways,它是否有助于捕获并发写入(提交前的简单时间戳比较或“冲突标记”附加)并有效管理缓存(我们计划为实体制作身份地图 - 需要跟踪4-5个不同的实体.4个实体用于组合层次结构,另一个实体与4个实体相关联?
一个单元如何测试网关(基于TDD或事后)?
提前致谢!
答案 0 :(得分:0)
单元测试可能不是并发问题的最佳方法。相反,您可以尝试使用基于Web的性能工具(如JMeter或Rational Performance Tester)来测试它的执行方式,并在增加用户数量时获得有效的墙内容。您可以使用这些工具为每个用户提供不同的发布行为。
答案 1 :(得分:0)
如果您只是在数据库上写入数据库或缓存解决方案(例如Spring + Hibernate + EhCache等),则无需担心损坏表等。从低级别的角度来看,没有并发问题。
如果您想自己编写缓存并自己处理并发问题,那么这将需要一些努力。如果你对缓存进行分片并在每个分区上有一个“全局锁定”(即synchronized
在一个公共互斥锁上),并为任何访问获取此锁,那么这将是有效的,而它并不是最高效的方法。但是做一些其他事情而不是全局锁定会涉及很多工作。
虽然这很简单,但不确定为什么要使用身份哈希映射...我想不出你想要做的任何特殊原因(如果你正在考虑性能,那么表现一个在这种情况下,正常的哈希映射是你需要担心的最后一件事!)。
如果您的实体是文章,那么您可能还有其他形式的并发问题。就像SVN,Mercurial等版本控制软件解决的那样。如果你没有把合并功能放到你的应用程序中,如果有人编辑某人的文章只是为了发现其他人已经“提交”了你之前的另一个编辑而变得烦恼。是否你需要添加这样的能力将取决于使用案件。
至于测试您的应用。对于并发性,单元测试也不错。通过编写并发单元测试,捕获并发错误要容易得多。编写并发测试非常困难,因此我建议您在编写之前阅读“Java Concurrency in Practice”等优秀书籍。在集成测试之前更好地捕获并发错误,因为很难猜到到底发生了什么!
<强>更新强>
@Nupul:这是一个难以回答的问题。但是,如果你只有18个人输入东西,我的赌注是每次写入数据库就好了。
如果你没有在其他地方存储任何状态(即只存在于数据库中),你应该删除任何不必要的互斥锁(除非你有充分的理由这样做,否则你不应该存储除数据库以外的任何其他状态。在你的情况IMO)。
在执行网络操作等操作时很容易出错并获取互斥锁,从而导致极端的可用性问题(例如,应用程序几秒钟内没有响应等)。并且很容易出现令人讨厌的并发错误,如线程死锁等。
所以我的建议是保留你的应用程序。无状态,每次只写DB。如果您发现由于数据库访问导致的任何性能问题,那么转向像EhCache这样的缓存解决方案将是最好的选择。
除非您想从项目中学习或必须提供应用程序。由于性能要求极高,我认为编写自己的缓存层并不合理。
答案 2 :(得分:0)
专注于标题中的2个问题。
这里是否存在并发问题?
是。明显。避免并发问题可能性的唯一方法是使产品具有单线程,并且会产生重大性能和可用性问题。
如何在开发过程中测试它?
这是个难题。
显然你需要进行单元测试。但是经典的单元测试并没有真正削减它的并发性问题,因为棘手的并发错误往往很少出现。
更好的方法是负载测试。正如@Gnat所述。
但为了获得最佳结果,您需要确认测试不是(整个)解决方案,并添加以下内容: