我有一个在 Solaris 上混合使用 Java 和 C++ 的应用程序。代码的 Java 方面运行 Web UI 并在我们正在交谈的设备上建立状态,而 C++ 代码则对从设备返回的数据进行实时处理。共享内存用于将设备状态和上下文信息从 Java 代码传递到 C++ 代码。Java 代码使用 PostgreSQL 数据库来保存其状态。

我们遇到了一些相当严重的性能瓶颈,目前我们可以扩展的唯一方法是增加内存和 CPU 数量。由于共享内存设计,我们被困在一个物理盒子上。


这里真正受到重大打击的是 C++ 代码。Web 界面很少用于配置设备;我们真正困难的是处理设备在配置后提供的数据量。

我们从设备返回的每条数据都有一个标识符,它指向设备上下文,我们需要查找它。现在有一系列由 Java/UI 代码维护并由 C++ 代码引用的共享内存对象,这就是瓶颈。由于该架构,我们无法将 C++ 数据处理移至另一台机器。我们需要能够横向扩展,以便不同的机器可以处理不同的设备子集,但随后我们就失去了进行上下文查找的能力,这就是我试图解决的问题:如何将实时数据处理卸载到其他设备,同时仍然能够引用设备上下文。

我应该指出,我们无法控制设备本身使用的协议,并且这种情况不可能改变。


我们知道我们需要摆脱这种情况,以便能够通过向集群添加更多机器来进行扩展,而且我正处于研究如何做到这一点的早期阶段。

现在,我正在将 Terracotta 视为扩展 Java 代码的一种方式,但我还没有弄清楚如何扩展 C++ 来匹配。

除了性能扩展之外,我们还需要考虑高可用性。应用程序需要几乎一直可用——不是绝对 100%,这不符合成本效益,但我们需要合理地避免机器中断。

如果你必须承担我交给的任务,你会怎么做?

编辑:根据 @john channing 提供的数据,我正在关注 GigaSpaces 和 Gemstone。Oracle Coherence 和 IBM ObjectGrid 似乎仅支持 java。

有帮助吗?

解决方案

我要做的第一件事是构建系统模型来映射数据流,并尝试准确了解瓶颈所在。如果您可以将您的系统建模为 管道, ,那么你应该能够使用约束理论(大多数文献是关于优化业务流程的,但它同样适用于软件)来不断提高性能并消除瓶颈。

接下来,我将收集一些准确表征系统性能的硬性经验数据。俗话说,你无法管理无法衡量的东西,但我见过很多人试图根据直觉来优化软件系统,但都惨遭失败。

然后我会使用 帕累托原则(80/20 规则) 选择少数能够产生最大收益的事情,并只专注于这些事情。

为了水平扩展 Java 应用程序,我使用了 甲骨文一致性 广泛地。尽管有些人认为它非常昂贵 分布式哈希表, ,功能比这丰富得多,例如,您可以直接访问缓存中的数据 C++代码 .

水平扩展 Java 代码的其他替代方案是 千兆空间, IBM 对象网格 或者 宝石宝石火.

如果您的 C++ 代码是无状态的并且纯粹用于数字运算,您可以考虑使用 冰网格 它绑定了您正在使用的所有语言。

其他提示

你需要横向和向外扩展。也许像 消息队列 可能是前端和处理之间的后端。

安德鲁(除了作为管道等进行建模之外),测量事物也很重要。您是否对代码运行了分析器并获取了大部分时间花费在何处的指标?

对于数据库代码,多久更改一次?您现在正在考虑缓存吗?我假设您已经查看了数据上的索引等以加快数据库速度?

您前端的流量是多少?您正在缓存网页吗?(使用 JMS 类型 api 在组件之间进行通信并不难。然后,您可以将网页组件放在一台机器(或多台)上,然后将集成代码(c++)放在另一台机器上,对于许多 JMS 产品,通常有本机 C++ api 的即。我想到了 ActiveMQ),但了解有多少时间花在 Web(JSP?)、C++、数据库操作上确实很有帮助。

数据库是存储业务数据,还是也用于在 Java 和 C++ 之间传递数据?你说你使用的是共享内存而不是 JNI ?目前APP中的多线程级别是什么?您会将代码描述为本质上是同步的还是异步的?

Solaris 代码和必须维护的设备之间是否存在物理关系(即所有设备都使用 c++ 代码注册,或者可以指定)。IE。如果您要在前端放置一个 Web 负载均衡器,并且今天只放置了 2 台机器,那么哪些设备由预先或提前初始化的盒子管理?

医管局有什么要求?IE。只是状态信息?HA 可以仅在 Web 层通过集群会话数据来完成吗?

数据库是否在另一台机器上运行?

数据库有多大?您是否优化了您的查询,即。尝试使用显式内部/外部联接有时比嵌套子查询更有帮助(有时)。(再次查看 sql 统计信息)。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top