java jdbc 连接ignite_构建多平台的Ignite集群:Java+.NET

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

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

java jdbc 连接ignite_构建多平台的Ignite集群:Java+.NET_第1张图片

前提条件

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

Visual Studio 2015(包括NuGet; 免费社区版);

IntelliJ IDEA (包括Maven; 免费社区版)。

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

目标

连接Java和.NET节点;

使用Java和.NET类,通过同样的名字和字段访问Ignite缓存中的共享数据;

运行持续查询,观察来自另一个平台的实时数据更新。

Java工程设置

启动IntelliJ IDEA,然后点击“Create New Project”:

java jdbc 连接ignite_构建多平台的Ignite集群:Java+.NET_第2张图片

选择Maven然后点击“Next”:

java jdbc 连接ignite_构建多平台的Ignite集群:Java+.NET_第3张图片

输入Maven信息,点击“Next”然后“Finish”:

java jdbc 连接ignite_构建多平台的Ignite集群:Java+.NET_第4张图片

java jdbc 连接ignite_构建多平台的Ignite集群:Java+.NET_第5张图片

完成之后,会看到新项目打开的pom.xml文件:

java jdbc 连接ignite_构建多平台的Ignite集群:Java+.NET_第6张图片

为project片段增加Ignite依赖:

org.apache.ignite

ignite-core

1.7.0

IDEA可能会询问是否导入项目改变,点击任意的链接:

37c3c649ccc168877aa796706b2a835e.png

在src\main\java中添加Demo类,代码如下:

import org.apache.ignite.Ignition;

public class Demo {

public static void main(String[] args) {

Ignition.start();

}

}

通过Shift+F10运行,然后在IDEA的控制台上确认节点是否启动:

java jdbc 连接ignite_构建多平台的Ignite集群:Java+.NET_第7张图片

通过Ctrl+F2或者停止按钮终止程序。

.NET工程设置

启动Visual Studio然后点击File -> New -> Project:

选择Visual C# -> Windows -> Console Application:

确保在上边选择了.NET Framework版本4及以上:

java jdbc 连接ignite_构建多平台的Ignite集群:Java+.NET_第8张图片

点击“OK”,然后就会生成一个空的控制台工程;

打开NuGet控制台:Menu -> Tools -> NuGet Package Manager -> Package Manager Console;

输入Install-Package Apache.Ignite:

java jdbc 连接ignite_构建多平台的Ignite集群:Java+.NET_第9张图片

点击回车,然后就会输出Successfully installed 'Apache.Ignite 1.7.0' to IgniteMultiPlatform这样的消息。

将Program.cs的内容改成如下这样:

using System;

using Apache.Ignite.Core;

class Program

{

static void Main(string[] args)

{

Ignition.Start();

Console.ReadKey();

}

}

通过Ctrl-F5启动程序,然后在控制台中确认Ignite节点已经启动:

java jdbc 连接ignite_构建多平台的Ignite集群:Java+.NET_第10张图片

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

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

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中只支持BinaryBasicIdMapper和BinaryBasicNameMapper,需要在Java中显式地进行设置,将Ignition.start();行改成如下的代码:

BinaryConfiguration binCfg = new BinaryConfiguration();

binCfg.setIdMapper(new BinaryBasicIdMapper());

binCfg.setNameMapper(new BinaryBasicNameMapper());

IgniteConfiguration cfg = new IgniteConfiguration().setBinaryConfiguration(binCfg);

Ignition.start(cfg);

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

[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名字,代码如下:

public class Message {

public Message(String author, String text) {

this.author = author;

this.text = text;

}

final String author;

final String text;

}

.NET Message类

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

class Message

{

public Message(string author, string text)

{

Author = author;

Text = text;

}

public string Author { get; }

public string Text { get; }

}

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

Java聊天程序

将main方法的代码改成如下:

// Retrieve user name

System.out.print("Hi, enter your name: ");

Scanner consoleScanner = new Scanner(System.in);

String name = consoleScanner.nextLine();

// Get or create cache

IgniteCache cache = ignite.getOrCreateCache("chat");

// Initialize unique ID sequence

IgniteAtomicSequence messageId = ignite.atomicSequence("chatId", 0, true);

// Set up continuous query

ContinuousQuery qry = new ContinuousQuery<>();

qry.setLocalListener(iterable -> {

// This will be invoked immediately on each cache update

for (CacheEntryEvent extends Long, ? extends Message> evt : iterable)

System.out.println(evt.getValue().author + ": " + evt.getValue().text);

});

cache.query(qry);

// Run the chat loop

while (true) {

System.out.print("> ");

String msgText = consoleScanner.nextLine();

Long msgId = messageId.incrementAndGet();

cache.put(msgId, new Message(name, msgText));

}

.NET聊天程序

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

需要在BinaryConfiguration中注册一个用于缓存的类型(Java会自动做这个事);

API中还不支持Lambda表达式,需要单独地实现ICacheEntryEventListener接口。

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

using System;

using System.Collections.Generic;

using Apache.Ignite.Core.Cache.Event;

class CacheListener : ICacheEntryEventListener

{

public void OnEvent(IEnumerable> evts)

{

foreach (var evt in evts)

Console.WriteLine($"{evt.Value.Author}: {evt.Value.Text}");

}

}

然后更新Main方法:

// Retrieve user name

Console.Write("Hi, enter your name: ");

var name = Console.ReadLine();

// Register Message type

var cfg = new IgniteConfiguration

{

BinaryConfiguration = new BinaryConfiguration(typeof(Message))

};

// Start Ignite and retrieve cache

var ignite = Ignition.Start(cfg);

var cache = ignite.GetOrCreateCache("chat");

// Initialize unique ID sequence

var messageId = ignite.GetAtomicSequence("chatId", 0, true);

// Set up continuous query

cache.QueryContinuous(new ContinuousQuery(new CacheListener()));

// Run the chat loop

while (true)

{

Console.Write("> ");

var msgText = Console.ReadLine();

var msgId = messageId.Increment();

cache[msgId] = new Message(name, msgText);

}

结论

启动这两个节点,将两个窗口并排,输入一些消息,然后就会看到他们在另外一个窗口中立即显示。

java jdbc 连接ignite_构建多平台的Ignite集群:Java+.NET_第11张图片

完成!跨平台的点对点聊天程序已经创建完毕!这里没有中心服务器,任意数量的客户端都可以在任意时间加入或者离开。 作为一个练习,可以把这个做得更好:

将缓存模式改为Replicated(参考缓存模式),这样每个聊天节点都会持有完整的聊天历史;

设置ContinuousQuery.InitialQuery属性(参考初始查询),这样每个新的节点都会立即显示之前的消息。

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

你可能感兴趣的:(java,jdbc,连接ignite)