30、从 C++ 访问 Coherence 及相关应用指南

从 C++ 访问 Coherence 及相关应用指南

1. 可调用映射接口与远程缓存

可调用映射(InvocableMap)接口在本地和远程缓存中都得到支持,但更常见的是在远程(集群)缓存中使用。若自定义的 EntryProcessors 和 Aggregators 要用于远程缓存,需确保对应的 Java 版本存在于缓存服务器的类路径中。和 .NET 情况类似,如果仅在远程使用,C++ 实现只需包含状态和序列化逻辑,可跳过实际处理逻辑。

2. 在 C++ 中实现 DepositProcessor

以下是一个可用于向远程账户缓存存入资金的条目处理器:

class DepositProcessor
    : public class_spec<DepositProcessor,
        extends<AbstractProcessor>,
        implements<PortableObject> >
    {
    friend class factory<DepositProcessor>;
    // ----- constructors --------------------------------------------
    protected:
        DepositProcessor()
            : m_vMoney(self()), m_vsDescription(self())
            {}
        DepositProcessor(Managed<Money>::View vMoney,  
                         String::View vsDescription)
            : m_vMoney(self(), vMoney),  
              m_vsDescription(self(), vsDescription)
            {}
    // ----- InvocableMap::EntryProcessor interface ------------------
    public:
        virtual Object::Holder process( 
                InvocableMap::Entry::Handle hEntry) const
            {
            COH_THROW (UnsupportedOperationException::create());
            }
    // ----- PortableObject interface --------------------------------
    public:
        virtual void readExternal(PofReader::Handle hIn)
            {
            initialize(m_vMoney, cast<Managed<Money>::View>( 
                hIn->readObject(0))); 
            initialize(m_vsDescription, hIn->readString(1)); 
         }
        virtual void writeExternal(PofWriter::Handle hOut) const
            {
            hOut->writeObject(0, m_vMoney);
            hOut->writeString(1, m_vsDescription);
            }
    // ----- data members --------------------------------------------
    protected:
        FinalView<Managed<Money> > m_vMoney;
        FinalView<String>          m_vsDescription;
    };
COH_REGISTER_PORTABLE_CLASS(POF_TYPE_DEPOSIT_PROCESSOR,  
    DepositProcessor);

这个存根实现不包含处理逻辑,其唯一目的是在序列化并传输到 Java 缓存服务器时传达操作类型和状态,由反序列化后的 Java 版本处理具体工作。Aggregators 也遵循类似模式,作为客户端状态传达存根,此处因与上述条目处理器存根相似,省略示例。

3. 监听缓存事件

和 Java 一样,C++ 客户端可注册事件监听器,在缓存条目插入、更新或删除时接收通知。这些事件流对于构建基于缓存状态的实时非轮询应用非常有用。

3.1 缓存监听器

Coherence C++ 遵循 Java 风格的观察者模式,事件注册通过 ObservableMap 接口的方法完成。

class ObservableMap
    : public interface_spec<ObservableMap,
        implements<Map> >
    {
    public:
        virtual void addKeyListener(MapListener::Handle hListener,
                Object::View vKey, bool fLite);
        virtual void removeKeyListener(MapListener::Handle hListener,
                Object::View vKey);
        virtual void addFilterListener(MapListener::Handle hListener,
                Filter::View vFilter = NULL, bool fLite = false);        
        virtual void removeFilterListener( 
                MapListener::Handle hListener,
                Filter::View vFilter = NULL);
    };

其功能集与 Java 版的 ObservableMap 相同,包括基于键和过滤器的注册,以及请求轻量级事件的能力。轻量级事件可省略旧值和新值,以避免网络传输的额外资源开销。当匹配事件发生时,会通过自定义的 MapListener 实现的回调通知。MapListener 接口与 Java 版本相似。

class MapListener
    : public interface_spec<MapListener,
        implements<EventListener> >
    {
    public:
        virtual void entryInserted(MapEvent::View vEvent);
        virtual void entryUpdated(MapEvent::View vEvent);
        virtual void entryDeleted(MapEvent::View vEvent);
    };

以下是一个简单的自定义监听器,将缓存更改打印到标准输出:

class VerboseMapListener
    : public class_spec<VerboseMapListener,
        extends<Object>,
        implements<MapListener> >
    {
    friend class factory<VerboseMapListener>;
    public:
        virtual void entryInserted(MapEvent::View vEvent)
            {
            std::cout << "inserted " << vEvent->getKey() << ", "
                      << vEvent->getNewValue() << std::endl;
            }
        virtual void entryUpdated(MapEvent::View vEvent)
            {
            std::cout << "updated " << vEvent->getKey() << " from "
                      << vEvent->getOldValue() << " to "
                      << vEvent->getNewValue() << std::endl;
            }
        virtual void entryDeleted(MapEvent::View vEvent)
            {
            std::cout << "deleted " << vEvent->getKey() << std::endl;
            }
    };

事件监听器的注册方式与 Java 相同:

hCache->addFilterListener(VerboseMapListener::create());

事件通知在与缓存关联的专用事件调度线程上本地发生,因此应考虑将长时间运行的监听器逻辑推送到应用程序线程,以免后续事件被阻塞或延迟。

4. 标准类型集成

Coherence C++ 的最后一个特性是与标准 C++ 数据类型的集成。除了 Coherence 管理的 String 可与 char 和 std::string 互操作外,还有其他类型集成值得关注。
| 管理类型 | 非管理类型 |
| ---- | ---- |
| Boolean | bool |
| Octet | uint8_t, unsigned char |
| Character16 | char16_t, wchar_t |
| Integer16 | int16_t, short |
| Integer32 | int32_t, int |
| Integer64 | int64_t, long long |
| Float32 | float32_t, float |
| Float64 | float64_t, double |
| String | char
, wchar_t*, std::string, std::wstring |
| Array | T[], for primitive type T |
| ObjectArray | Object::Holder[] |
| RawDateTime | struct tm |
| Exception | std::exception |

对于这些类型集成,管理类型支持与标准类型的某种形式的赋值。多数情况下,管理类型可从标准类型构造,并可解引用赋值给标准类型。

Integer32::View vInt = Integer32::create(5);
int32_t         nInt = *vInt; // assigns 5 to nInt

另一个集成点是与 std::map 的集成。Coherence 缓存基于 coherence::util::Map 接口,而非 std::map,但为了满足部分用户需求,提供了一个适配器 boxing_map,使任何 Coherence 映射或缓存实现可通过 std::map 风格的 API 使用。

boxing_map<Integer64, Managed<Account> > 
    cache(CacheFactory::getCache("accounts"));
// construct plain old Account object 
Account account(32105, "checking", Money(7374, 10, "USD"), 55, 62409);
// cache account
cache[32105] = account;
// retrieve the cached value 
Account accountResult = cache[32105];

使用 std::copy 将 std::map 中的数据复制到缓存:

std::map<int64_t, Account> mapBatch;
// fill up mapBatch with records
// ...
// use std::copy to transfer them to the cache
std::copy(mapBatch.begin(), mapBatch.end(),
    std::inserter(cache, cache.begin()));

虽然以 std::map 方式访问缓存很有用,但也有局限性,因为 std::map API 没有对应概念,无法使用 Coherence 缓存的大多数高级功能。boxing_map 主要适用于以 get/put 方式访问缓存的应用,更高级的缓存使用需通过 Coherence 缓存接口。

5. 构建可扩展系统的建议

在设计和构建可扩展系统时,无论是否使用 Coherence,都有一些通用建议:
1. 减少网络调用 :应用程序应避免进行大量网络调用,如 Web 请求、数据库调用、Web 服务调用等。每个网络调用都会引入延迟,可能导致应用响应缓慢、性能不佳。可在每个应用层使用缓存来减少网络调用次数。Coherence 为应用对象提供了很好的缓存解决方案,但不应仅依赖它,还应利用所选 Web 服务器和交付技术提供的页面和片段缓存,正确设置 HTTP 过期头,对于大型公共网站可考虑使用内容分发网络(CDN)缓存静态内容。即使使用 Coherence,访问分区缓存中的对象也涉及网络调用,可利用其近缓存和连续查询缓存等功能减少网络调用。
2. 减少数据传输 :尽量减少为执行处理而在网络上传输的数据量。移动大量数据来回答少量数据的问题会消耗时间并增加应用各组件的负载。可将逻辑移动到数据所在位置,而不是将数据移动到逻辑所在位置。使用 Coherence 时,尽可能使用条目处理器和并行聚合器;不使用时,可利用数据库的存储过程等功能。需要移动数据时,尽量批量处理,如在持久化缓存对象时使用数据库的写后和批处理功能,在将数据加载到 Coherence 缓存时使用客户端批处理和 putAll。
3. 选择合适的工具 :关系数据库旨在保护持久存储中的数据并处理复杂的关系查询,不适合作为键值存储或进行扩展。而 Coherence 从一开始就设计用于实现大规模扩展和高可用性,将对象存储在内存中还带来了性能提升。但这并不意味着关系数据库会消失,在需要持久化或进行复杂关系查询时仍有其作用。如果需要扩展数据层,可在关系数据库前使用内存数据网格。

6. 银行示例应用

示例应用是一个包含三个组件的银行应用:
1. 核心组件 :基于 Coherence 的在线银行 Java 应用,包含大部分业务逻辑,封装在一组丰富的领域对象中。使用 Spring MVC 向 ExtJS 前端暴露 REST 端点,使用 H2 数据库作为 Coherence 背后的持久数据存储,并嵌入 Jetty 网络服务器以简化测试和部署。
2. .NET 应用 :使用 WPF 作为表示层,通过数据绑定到连续查询缓存(CQC)实时显示账户余额变化和交易列表。
3. C++ 命令行应用 :模拟 ATM,展示了 C++ 中并行域模型的实现,以及如何从 C++ 客户端使用条目处理器在集群中执行业务逻辑。

7. 运行示例应用的先决条件

在构建、部署和运行示例应用的各个组件之前,需要满足以下先决条件:
1. 操作系统 :建议首次运行时在单台 Windows XP 机器上运行所有组件,因为 Windows 是唯一能运行所有三个应用的操作系统。熟悉应用架构和配置后,可在多台机器上进行实验。
2. 软件安装
- Sun Java JDK 1.6 :下载并安装最新版本的 Sun JDK 1.6,确保安装的是完整的 JDK 而非 JRE,并设置 JAVA_HOME 环境变量指向 JDK 安装目录。例如:

JAVA_HOME=C:\Program Files\Java\jdk1.6.0_18
- **Microsoft Visual Studio 2008**:用于构建 .NET 和 C++ 示例应用。若没有,可从 http://www.microsoft.com/express/Windows/ 下载 Microsoft Visual C# 和 Microsoft Visual C++ 的 Express 版本,但仅对完整版本的 Visual Studio 2008 进行了构建测试。.NET 应用需要 .NET Framework 3.5,安装 Visual Studio 2008 时应已安装。
- **Oracle Coherence 3.5.3**:应用也可与其他 Coherence 版本配合使用,但仅对 3.5.3 进行了测试,强烈建议使用该版本。需要下载并安装以下包:
    - 下载 Coherence Java 版本并按说明安装,设置 COHERENCE_HOME 环境变量指向包含 bin、lib 等 Coherence 文件夹的安装目录。
    - 下载并安装 32 位 Windows 版的 Coherence for C++,将下载的存档中的 coherence-cpp 目录提取到 COHERENCE_HOME 目录中。例如,若 COHERENCE_HOME 为 C:\coherence,则 Coherence for C++ 应安装在 C:\coherence\coherence-cpp。

综上所述,Coherence 是一款优秀的软件,在使用它构建应用时,遵循上述建议和步骤,能帮助我们设计和实现高效、可扩展的系统。同时,示例应用为我们提供了实际应用的参考,可通过运行示例应用深入了解 Coherence 的使用。

从 C++ 访问 Coherence 及相关应用指南

8. 示例应用的搭建与运行步骤

为了让示例应用顺利运行起来,我们需要按照以下步骤进行操作:
1. 安装软件
- 按照前面提到的要求,安装 Sun Java JDK 1.6、Microsoft Visual Studio 2008 和 Oracle Coherence 3.5.3,并正确设置相应的环境变量。
2. 配置环境变量
- 确保 JAVA_HOME、COHERENCE_HOME 等环境变量设置正确,这是应用正常运行的基础。
3. 构建项目
- 使用 Visual Studio 2008 打开 .NET 和 C++ 示例应用的项目文件,进行编译构建。
- 对于 Java 应用,可使用相关的构建工具(如 Maven 或 Gradle)进行构建。
4. 启动 Coherence 集群
- 进入 Coherence 的安装目录,执行相应的启动脚本,启动 Coherence 集群。
5. 运行应用
- 依次启动 Java 应用、.NET 应用和 C++ 命令行应用。

下面是一个简单的 mermaid 流程图,展示了示例应用的搭建与运行流程:

graph LR
    A[安装软件] --> B[配置环境变量]
    B --> C[构建项目]
    C --> D[启动 Coherence 集群]
    D --> E[运行应用]
9. 示例应用的测试与验证

在应用运行起来后,我们需要对其进行测试和验证,确保各个组件正常工作:
1. Java 应用测试
- 打开浏览器,访问 Java 应用暴露的 REST 端点,检查是否能正常获取数据。
- 进行一些业务操作,如账户查询、存款、取款等,验证业务逻辑是否正确。
2. .NET 应用测试
- 观察 .NET 应用的界面,检查账户余额变化和交易列表是否能实时更新。
- 进行一些交互操作,验证数据绑定和实时显示功能是否正常。
3. C++ 应用测试
- 在 C++ 命令行应用中输入相应的指令,模拟 ATM 操作,检查业务逻辑是否正确执行。

10. 总结与展望

通过对 Coherence 的学习和示例应用的实践,我们可以看到 Coherence 在构建可扩展系统方面具有很大的优势。它不仅提供了强大的缓存功能,还支持分布式计算和高可用性,能够帮助我们解决很多实际问题。

在未来的开发中,我们可以进一步探索 Coherence 的高级功能,如分区策略、数据备份与恢复等,以满足更复杂的业务需求。同时,我们也可以结合其他技术,如大数据处理、人工智能等,构建更加智能和高效的应用系统。

总之,Coherence 是一款非常优秀的软件,值得我们深入学习和使用。希望通过本文的介绍,能帮助大家更好地理解和应用 Coherence,构建出更加出色的应用系统。

11. 常见问题及解决方案

在使用 Coherence 和运行示例应用的过程中,可能会遇到一些常见问题,下面为大家列举一些并提供相应的解决方案:
| 问题描述 | 解决方案 |
| ---- | ---- |
| 无法启动 Coherence 集群 | 检查 COHERENCE_HOME 环境变量是否设置正确,以及相关的配置文件是否存在错误。 |
| .NET 应用无法连接到 Coherence 集群 | 检查网络连接是否正常,以及 Coherence 集群的配置是否正确。 |
| Java 应用启动报错 | 检查 JAVA_HOME 环境变量是否设置正确,以及依赖的库文件是否完整。 |
| C++ 应用编译出错 | 检查 Visual Studio 2008 的配置是否正确,以及代码中是否存在语法错误。 |

12. 技巧与建议

为了更好地使用 Coherence,提高开发效率和应用性能,这里给大家提供一些技巧和建议:
1. 合理使用缓存 :根据业务需求,合理设置缓存的过期时间和容量,避免缓存数据过多导致内存占用过高。
2. 优化网络调用 :尽量减少不必要的网络调用,使用批量操作和异步处理来提高性能。
3. 代码复用 :在开发过程中,尽量复用已有的代码和组件,提高开发效率。
4. 持续学习 :Coherence 是一个不断发展的技术,持续学习其新特性和功能,能够让我们更好地应对各种挑战。

13. 结语

Coherence 为我们提供了一个强大而灵活的解决方案,帮助我们构建高效、可扩展的系统。通过本文的介绍,我们了解了从 C++ 访问 Coherence 的方法、标准类型集成、缓存事件监听等重要知识,同时也通过示例应用的实践,深入体验了 Coherence 在实际项目中的应用。

希望大家在实际开发中能够充分利用 Coherence 的优势,结合上述的建议和技巧,构建出更加优秀的应用系统。同时,也鼓励大家不断探索和尝试,发现更多 Coherence 的潜力和价值。相信在 Coherence 的助力下,我们能够打造出更加出色的软件产品。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值