[关闭]
@liyuj 2016-11-24T23:13:36.000000Z 字数 5197 阅读 3732

Apache-Ignite-中文文档

构建多平台的Ignite集群:Java+.NET

Ignite集群可以由它支持的任意平台启动的节点组成,包括Java、.NET和C++。本文会介绍如何通过NuGet和Maven运行一个.NET/Java集群,作为一个示例,本文会创建一个跨平台的点对点聊天系统。
1

前提条件

本文适用于对Java不熟悉的.NET开发人员,反之亦然,因此描述的会比较详细。
本文会使用如下的软件:

本文的完整源代码位于GitHub上,github.com/ptupitsyn/ignite-multi-platform-demo
为了简洁起见,下面的代码不是很完整(公共字段,没有命名空间等)。

目标

Java工程设置

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.apache.ignite</groupId>
  4. <artifactId>ignite-core</artifactId>
  5. <version>1.7.0</version>
  6. </dependency>
  7. </dependencies>
  1. import org.apache.ignite.Ignition;
  2. public class Demo {
  3. public static void main(String[] args) {
  4. Ignition.start();
  5. }
  6. }

8

.NET工程设置

9

10

  1. using System;
  2. using Apache.Ignite.Core;
  3. class Program
  4. {
  5. static void Main(string[] args)
  6. {
  7. Ignition.Start();
  8. Console.ReadKey();
  9. }
  10. }

11

调整Java节点的配置以发现.NET节点

现在,就可以同时在IDEA中启动Java节点,在Visual Studio中启动.NET节点,这时会在他们中的一个发现如下的错误:

  1. IgniteSpiException: Local node's binary configuration is not equal to remote node's binary configuration [locBinaryCfg={globSerializer=null, compactFooter=true, globIdMapper=org.apache.ignite.binary.BinaryBasicIdMapper}, rmtBinaryCfg=null]

这个错误是说,.NET节点在BinaryConfiguration中只支持BinaryBasicIdMapperBinaryBasicNameMapper,需要在Java中显式地进行设置,将Ignition.start();行改成如下的代码:

  1. BinaryConfiguration binCfg = new BinaryConfiguration();
  2. binCfg.setIdMapper(new BinaryBasicIdMapper());
  3. binCfg.setNameMapper(new BinaryBasicNameMapper());
  4. IgniteConfiguration cfg = new IgniteConfiguration().setBinaryConfiguration(binCfg);
  5. Ignition.start(cfg);

这时同时启动Java和.NET节点,验证他们可以发现对方:

  1. [15:04:17] Topology snapshot [ver=2, servers=2, clients=0, CPUs=8, heap=7.1GB]

通过Ignite缓存进行数据交换

现在各个节点已经联通,之后会在每个平台上写一个简单的聊天程序来演示数据的交换。代码非常简单,因为API是相同的,并且语言语法也差不多。
首先,定义名字和成员完全相同的类。

Java Message类

右击src\main\java项目文件夹然后选择New -> Java Class,输入Message名字,代码如下:

  1. public class Message {
  2. public Message(String author, String text) {
  3. this.author = author;
  4. this.text = text;
  5. }
  6. final String author;
  7. final String text;
  8. }

.NET Message类

右击Solution Explorer的项目节点,然后选择Add -> Class…,输入Message名字,代码如下:

  1. class Message
  2. {
  3. public Message(string author, string text)
  4. {
  5. Author = author;
  6. Text = text;
  7. }
  8. public string Author { get; }
  9. public string Text { get; }
  10. }

Basic映射器是区分大小写的,并且会忽略命名空间(包),因此这两个类是可以互相映射的,可以在一个平台中将Message实例注入缓存,然后在另一个平台中获取。
现在开始写聊天程序本身,逻辑比较简单:用户输入一个聊天信息,然后将其注入缓存,持续查询会收到所有的缓存更新通知并且显示他们。

Java聊天程序

main方法的代码改成如下:

  1. // Retrieve user name
  2. System.out.print("Hi, enter your name: ");
  3. Scanner consoleScanner = new Scanner(System.in);
  4. String name = consoleScanner.nextLine();
  5. // Get or create cache
  6. IgniteCache<Long, Message> cache = ignite.getOrCreateCache("chat");
  7. // Initialize unique ID sequence
  8. IgniteAtomicSequence messageId = ignite.atomicSequence("chatId", 0, true);
  9. // Set up continuous query
  10. ContinuousQuery<Long, Message> qry = new ContinuousQuery<>();
  11. qry.setLocalListener(iterable -> {
  12. // This will be invoked immediately on each cache update
  13. for (CacheEntryEvent<? extends Long, ? extends Message> evt : iterable)
  14. System.out.println(evt.getValue().author + ": " + evt.getValue().text);
  15. });
  16. cache.query(qry);
  17. // Run the chat loop
  18. while (true) {
  19. System.out.print("> ");
  20. String msgText = consoleScanner.nextLine();
  21. Long msgId = messageId.incrementAndGet();
  22. cache.put(msgId, new Message(name, msgText));
  23. }

.NET聊天程序

在Ignite.NET中有两处不同(这些特性预计会在下一版本中实现):

因此,创建一个单独的类,代码如下:

  1. using System;
  2. using System.Collections.Generic;
  3. using Apache.Ignite.Core.Cache.Event;
  4. class CacheListener : ICacheEntryEventListener<long, Message>
  5. {
  6. public void OnEvent(IEnumerable<ICacheEntryEvent<long, Message>> evts)
  7. {
  8. foreach (var evt in evts)
  9. Console.WriteLine($"{evt.Value.Author}: {evt.Value.Text}");
  10. }
  11. }

然后更新Main方法:

  1. // Retrieve user name
  2. Console.Write("Hi, enter your name: ");
  3. var name = Console.ReadLine();
  4. // Register Message type
  5. var cfg = new IgniteConfiguration
  6. {
  7. BinaryConfiguration = new BinaryConfiguration(typeof(Message))
  8. };
  9. // Start Ignite and retrieve cache
  10. var ignite = Ignition.Start(cfg);
  11. var cache = ignite.GetOrCreateCache<long, Message>("chat");
  12. // Initialize unique ID sequence
  13. var messageId = ignite.GetAtomicSequence("chatId", 0, true);
  14. // Set up continuous query
  15. cache.QueryContinuous(new ContinuousQuery<long, Message>(new CacheListener()));
  16. // Run the chat loop
  17. while (true)
  18. {
  19. Console.Write("> ");
  20. var msgText = Console.ReadLine();
  21. var msgId = messageId.Increment();
  22. cache[msgId] = new Message(name, msgText);
  23. }

结论

启动这两个节点,将两个窗口并排,输入一些消息,然后就会看到他们在另外一个窗口中立即显示。
12
完成!跨平台的点对点聊天程序已经创建完毕!这里没有中心服务器,任意数量的客户端都可以在任意时间加入或者离开。
作为一个练习,可以把这个做得更好:

这个方式就是说,只要有一个节点存活,整个聊天历史就会被保存,新的节点就会在加入时显示它们。

本文译自Pavel Tupitsyn的博客:Building a Multi-Platform Ignite Cluster: Java + .NET

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注