0

场景:存在“n”个团队,每个团队都在他们的虚拟“墙”(如 facebook 的墙)上工作。每个团队只能看到他们自己的墙和上面的帖子。帖子可以由帖子的作者或其他团队成员编辑(如果这样配置。假设确实如此,因为它是必须的)。

设计/技术决策:使用 Restlet+ Glassfish/Java + Mysql 的 RESTful Web 应用程序(编辑:使用 Apache DBUtils 进行数据库访问。没有 ORM - 似乎有点矫枉过正)

问题:多个团队登录 T1、T2 和 T3(比如说),每个团队都有一定数量的成员。团队级别的数据访问存在并发性,但跨团队不存在 - 即不同的团队访问不相交的数据集。为了优化对 DB 的频繁读/写,我们正在考虑使用 TeamGateway 来控制对 DB 的访问以处理并发。网络服务器将缓存团队检索到的数据以加快读取速度(并帮助更新墙帖列表)

  • Q1:这(每个团队的 TableGateway + 缓存)甚至是必需的吗?如果不是,您建议如何处理?
  • Q2:如果是这样,TableGateway(每个团队)是否需要编码为线程安全(同步方法)?假设我们有一个带有静态方法的类/注册表 TableGatewayFinder,该方法返回 TableGateway 以供该特定团队使用(使用哈希图)。

如果每个 T1 - T3 有 6 人登录,那么将只创建 3 个 TableGateway,它是否有助于捕获并发写入(提交前的简单时间戳比较或“冲突标记”附加)并有效管理缓存(我们计划有实体的身份映射 - 需要跟踪 4-5 个不同的实体。组合层次结构中有 4 个实体,另外一个与 4) 中的每一个相关联?

一个单元如何测试网关(基于 TDD 或事后)?

提前致谢!

4

3 回答 3

0

单元测试可能不是解决并发问题的最佳方法。相反,您可以尝试使用基于 Web 的性能工具,例如 JMeter 或 Rational Performance Tester 来测试它的性能,以及随着用户数量的增加,您已经获得了有效的墙内容。您可以使用这些工具为每个用户提供不同的发布行为。

于 2011-02-17T02:17:48.253 回答
0

如果您只是写入数据库或数据库顶部的缓存解决方案(例如 Spring+Hibernate+EhCache 等),您无需担心损坏您的表等。即从低级别点没有并发问题观点。

如果您想自己编写缓存并自己处理并发问题,则需要付出一些努力。如果您对缓存进行分片synchronized并且每个分区都有一个“全局锁”(即在一个公共互斥锁上),并为任何访问获取此锁,那么这将起作用,虽然它不是最高效的方法。但是做一个全局锁以外的事情会涉及很多工作。

虽然这很简单,但不确定您为什么要使用身份哈希映射...我想不出您想要这样做的任何特定原因(如果您正在考虑性能,那么普通哈希映射的性能将是您在这种情况下最不需要担心的事情!)。

如果您的实体是文章,那么您可能有另一种形式的并发问题。就像 SVN、Mercurial 等版本控制软件解决的问题一样。也就是说,如果您没有将合并功能添加到您的应用程序中。如果有人编辑某人的文章却发现其他人已经“提交”了另一篇文章,这将成为一种烦恼在您之前进行编辑等。您是否需要添加此类功能取决于用例。

至于测试你的应用程序。对于并发,单元测试也不错。通过编写并发单元测试,更容易发现并发错误。编写并发测试非常困难,因此我建议您在编写它们之前阅读《Java 并发实践》之类的好书。当很难猜出到底发生了什么时,最好在集成测试之前发现并发错误!

更新:
@Nupul:这是一个很难回答的问题。但是,如果你只有 18 个人打字,我敢打赌每次都写到数据库就可以了。

如果您不在其他地方存储任何状态(即仅在数据库中),您应该摆脱任何不必要的互斥锁(并且您不应该在数据库以外的任何地方存储任何状态,除非您有充分的理由在您的情况下这样做国际海事组织)。

在执行网络操作之类的操作时很容易出错并获取互斥锁,从而导致极端的可用性问题(例如,应用程序在几秒钟内没有响应等)。而且还很容易出现令人讨厌的并发错误,例如线程死锁等。

所以我的建议是保留你的应用程序。无状态,每次只写入数据库。如果您发现由于数据库访问而导致的任何性能问题,那么转向像 EhCache 这样的缓存解决方案将是最好的选择。

除非您想从项目中学习或必须交付应用程序。具有极高的性能要求,我认为编写自己的缓存层是不合理的。

于 2011-02-17T04:09:17.750 回答
0

专注于标题中的2个问题。

这里有并发问题吗?

是的。明显地。避免并发问题的唯一方法是使产品成为单线程的,这将产生重大的性能和可用性问题。

在开发过程中如何测试它?

这是一个很难的问题。

显然你需要单元测试。但是经典的单元测试并没有真正解决并发问题,因为棘手的并发错误往往很少出现。

更好的方法是负载测试。正如@Gnat 所述。

但为了获得最佳结果,您需要承认测试不是(整体)解决方案,并添加以下内容:

  • 在设计、编码和测试并发应用程序方面经验丰富的员工。
  • 非常关注 Goetz 等人的“Java - Concurrency in Practice”的方法/建议。
  • 大量的设计和代码审查。
  • 彻底使用静态代码分析器来发现潜在的并发问题。
于 2011-02-17T04:54:12.803 回答