Du bist nicht angemeldet.

Lieber Besucher, herzlich willkommen bei: DeveloperTalk. Falls dies dein erster Besuch auf dieser Seite ist, lies bitte die Hilfe durch. Dort wird dir die Bedienung dieser Seite näher erläutert. Darüber hinaus solltest du dich registrieren, um alle Funktionen dieser Seite nutzen zu können. Benutze das Registrierungsformular, um dich zu registrieren oder informiere dich ausführlich über den Registrierungsvorgang. Falls du dich bereits zu einem früheren Zeitpunkt registriert hast, kannst du dich hier anmelden.

JuKu

Profi

  • »JuKu« ist der Autor dieses Themas

Beiträge: 574

Registrierungsdatum: 29.09.2011

Danksagungen: 48

  • Private Nachricht senden

1

14.09.2015, 10:59

Distributed JCache mit Hazelcast

Mit JSP 107 wurde in Java eine neue Caching Api eingeführt.
Immer wieder steht man aber vor dem Problem, dass man gerne einen verteilten, also distributed Cache Server hätte, auf denen die Clients ihre Daten speichern können.



Hazelcast ist ein In-Memory-Data Grid, eine NoSQL-Database, die alle Daten im RAM hält.
Die NoSQL Database hat viele Features, wie einen Key-Value-Store, also eine distributed Map, als auch z.B. einen JCache Provider.
Mit diesem kann man Objekte im Cache speichern und von jedem Client aus auf diese zugreifen.
Zusätzlich verteilt Hazelcast im Cluster Backups, damit alle Daten auch beim Ausfall eines Nodes erhalten bleiben.

Um solch ein Hazelcast Cluster im Standalone Mode zu starten, muss Hazelcast zuerst von der Website hazelcast.org heruntergeladen werden.
Als nächstes benötigt die Server Instance die JCache-Api im Classpath.
Dazu kann man die jcache-api-1.0.0.jar aus dem Maven Central Repository herunterladen.

GroupID: javax.cache
ArtifactID: cache-api
Version: 1.0.0

Diese .jar muss als nächstes in den Ordner lib kopiert werden, wo sich auch die hazelcast-all-2.5.3.jar befindet.



Danach muss der Classpath in der start.bat im Directory bin geändert werden.

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
@echo off

SETLOCAL

if NOT DEFINED JAVA_HOME goto error
set RUN_JAVA=%JAVA_HOME%\bin\java


REM ******* you can enable following variables by uncommenting them

REM ******* minimum heap size
REM set MIN_HEAP_SIZE=1G

REM ******* maximum heap size
REM set MAX_HEAP_SIZE=1G


if NOT "%MIN_HEAP_SIZE%" == "" (
	set JAVA_OPTS=%JAVA_OPTS% -Xms%MIN_HEAP_SIZE%
)

if NOT "%MAX_HEAP_SIZE%" == "" (
	set JAVA_OPTS=%JAVA_OPTS% -Xmx%MAX_HEAP_SIZE%
)

set CLASSPATH=%~dp0..\lib\hazelcast-all-3.5.2.jar;%~dp0..\lib\jcache.jar

ECHO ########################################
ECHO # RUN_JAVA=%RUN_JAVA%
ECHO # JAVA_OPTS=%JAVA_OPTS%
ECHO # starting now...."
ECHO ########################################

"%RUN_JAVA%" %JAVA_OPTS% -cp "%CLASSPATH%" "com.hazelcast.core.server.StartServer"
goto endofscript

:error
ECHO JAVA_HOME environment variable must be set!
pause


:endofscript

ENDLOCAL


%~dp0..\lib\jcache.jar müsst ihr evtl. an eure .jar Datei anpassen, wenn diese jcache-1.0.0.jar heißt, muss dort auch %~dp0..\lib\jcache-1.0.0.jar stehen.
Als nächstes kann die start.bat ausgeführt werden, um einen einzelnen Hazelcast Node zu starten.
Wenn ihr die Datei 2x ausführt, startet ihr 2 Instances, wobei die 1. standardmäßig auf Port 5701 und die 2. auf Port 5702 läuft.
Beide Ports und die Server Adressen können in der Konfigurationsdatei hazelcast.xml geändert werden.

Als nächstes erstellen wir ein Maven Project für den Client, der die JCache dann auch nutzt.
Dazu müssen folgende dependencies zur pom.xml hinzugefügt werden:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<dependencies>
<dependency>
            <groupId>javax.cache</groupId>
            <artifactId>cache-api</artifactId>
            <version>1.0.0</version>
        </dependency>

<dependency>
            <groupId>com.hazelcast</groupId>
            <artifactId>hazelcast-client</artifactId>
            <version>3.5.2</version>
        </dependency>

<dependency>
            <groupId>org.ini4j</groupId>
            <artifactId>ini4j</artifactId>
            <version>0.5.4</version>
        </dependency>
</dependencies>


pom.xml:

Spoiler Spoiler


Java-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>EURE ARTIFACT ID</artifactId>
        <groupId>EURE GROUP ID</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>MODULE ARTIFACT ID</artifactId>

    <dependencies>

        <dependency>
        <dependency>
            <groupId>javax.cache</groupId>
            <artifactId>cache-api</artifactId>
            <version>1.0.0</version>
        </dependency>

        <dependency>
            <groupId>com.hazelcast</groupId>
            <artifactId>hazelcast-client</artifactId>
            <version>3.5.2</version>
        </dependency>

        <dependency>
            <groupId>org.ini4j</groupId>
            <artifactId>ini4j</artifactId>
            <version>0.5.4</version>
        </dependency>
    </dependencies>
</project>



Wer Maven nicht nutzen will, muss die .jar Dateien manuell zum Classpath hinzufügen.

Als nächstes erstellen wir eine einfache Konfigurationsdatei für den Hazelcast Client.
hazelcast.cfg:

Quellcode

1
2
3
4
5
[Hazelcast]
ip=127.0.0.1
port=5701
user=dev
password=dev-pass


In diese müssen die Server Daten eingetragen werden, wo der Hazelcast Server läuft.
Der Standard Hazelcast user ist dev und das password dev-pass .

Wichtig!: Hazelcast speichert seine Konfiguration eig. immer in xml Dateien, ich habe diese Variante genommen, da sie für Leute einfacher erscheint, die Hazelcast zuvor noch nicht verwendet haben.

Die folgende Klasse HazelcastFactory erzeugt einen Hazelcast Client, verbindet diesen mit dem Server und gibt die Instance zurück.

Java-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/*
* Coypright (c) 2015 Justin Kuenzel
* Apache 2.0 License
*/

package com.jukusoft;

import com.hazelcast.client.HazelcastClient;
import com.hazelcast.client.config.ClientConfig;
import com.hazelcast.core.HazelcastInstance;
import org.ini4j.Ini;
import org.ini4j.Profile;

import java.io.File;
import java.io.IOException;

public class HazelcastFactory {

    public static HazelcastInstance getHazelcastInstance (String ip, int port, String user, String password) {
        ClientConfig clientConfig = new ClientConfig();
        clientConfig.getGroupConfig().setName(user).setPassword(password);
        clientConfig.getNetworkConfig().addAddress(ip + ":" + port);
        HazelcastInstance hazelcastInstance = HazelcastClient.newHazelcastClient(clientConfig);

        return hazelcastInstance;
    }

    public static HazelcastInstance getHazelcastInstanceFromConfig (File configFile) throws IOException {
        Ini ini = new Ini(configFile);
        Profile.Section section = ini.get("Hazelcast");

        String ip = section.get("ip");
        int port = Integer.parseInt(section.getOrDefault("port", "5701"));
        String user = section.get("user");
        String password = section.get("password");

        return HazelcastFactory.getHazelcastInstance(ip, port, user, password);
    }

}


Main.java:

Java-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package com.jukusoft;

import com.hazelcast.core.HazelcastInstance;
import com.jukusoft.HazelcastFactory;
/* ... */

import java.io.File;
import java.io.IOException;

public class Main {

  public static void main (String[] args) {
        //create hazelcast instance and connect to hazelcast cluster
        HazelcastInstance hazelcastInstance = HazelcastFactory.getHazelcastInstanceFromConfig(new File("./cfg/hazelcast.cfg"));

        //get name of instance
        String instanceName = hazelcastInstance.getName();

        /*
        * use new JSR107 standard caching api for java with hazelcast connector,
        * so the JCache is distributed in the hazelcast cluster
        */
        CachingProvider cachingProvider = Caching.getCachingProvider();

        // Create Properties instance pointing to a named HazelcastInstance
        Properties properties = new Properties();
        properties.setProperty( HazelcastCachingProvider.HAZELCAST_INSTANCE_NAME,
                instanceName );

        URI cacheManagerName = null;

        try {
            cacheManagerName = new URI( "my-cache-manager" );
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }

        CacheManager cacheManager = cachingProvider
                .getCacheManager(cacheManagerName, null, properties);

        MutableConfiguration<Long,String> configuration = new MutableConfiguration<Long,String>();

        //remove entries after 60 minutes without access
        configuration.setExpiryPolicyFactory(AccessedExpiryPolicy.factoryOf(new Duration(TimeUnit.MINUTES, 60l)));

        //create cache instance
        Cache<Long,String> cache = manager.createCache("sessionCache", configuration);

        //ICache extends Cache interface, provides more functionality
        ICache myCache = cache.unwrap(ICache.class);

        //save object to cache
        myCache.putAsync(1l, "string");

        if (myCache.containsKey(1l)) {
            //get object
            System.out.println("JCache Object: " + myCache.get(1l));
        } else {
          System.out.println("JCache doesnt contains Object with key 1.")
        }
  }

}
Wenn euch mein Beitrag weitergeholfen hat, drückt auf "Bedanken"!
Danke! :D

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »JuKu« (14.09.2015, 11:25)


Es hat sich bereits 1 registrierter Benutzer bedankt.

Benutzer, die sich für diesen Beitrag bedankt haben:

Erik (19.09.2015)

Erik

Profi

Beiträge: 1 274

Registrierungsdatum: 22.06.2011

Wohnort: Deutschland ;)

Danksagungen: 307

  • Private Nachricht senden

2

19.09.2015, 22:59

Schönes Tutorial :)

Find diese Sache mit Hazelcast bzw. allgemein mit Clustern ziemlich interessant. Schade dass ich nicht ganz viele Server betreibe :D
Beste Webite im Internet ( ͡° ͜ʖ ͡°)
xinra.de