[JAVA] Einführung in Spring Boot + In-Memory-Datenraster (Ereignisverarbeitung)

Was ich letztes Mal gemacht habe

Beim letzten Mal habe ich mit SpringDataGeode eine SpringBoot-Anwendung mit einem speicherinternen Datenraster erstellt und mit SpringData bestätigt, dass die persistierten Daten zwischen den beiden Anwendungen geteilt wurden.

Erstellen einer Anwendung mit SpringDataGeode

Was ist diesmal zu tun?

Ereignisverarbeitung mit In-Memory-Datenraster

Dieses Mal habe ich versucht, die Ereignisverarbeitung mithilfe des Mechanismus des speicherinternen Datengitters zu implementieren Überlegen.

Implementieren Sie wie in der folgenden Abbildung gezeigt. Untitled Diagram.png

UserRegionListener.java



package spring.geode.geodeCommon.listener;

import java.time.LocalDateTime;

import org.apache.geode.cache.CacheListener;
import org.apache.geode.cache.EntryEvent;
import org.apache.geode.cache.RegionEvent;

import spring.geode.geodeCommon.model.User;
import spring.geode.geodeCommon.region.UserRegion;

/**
 * {@link UserRegion}Listener, der Änderungen in erkennt
 *
 */
public class UserRegionListener implements CacheListener<Integer,User> {
	public void afterCreate(EntryEvent<Integer,User> event) {
		System.out.println(LocalDateTime.now());
		System.out.println("afterCreate!!!!!!!!!" + event.getNewValue());
	}

	public void afterDestroy(EntryEvent<Integer, User> event) {
		System.out.println("afterDestroy!!!!!!!!!" + event);
	}

	public void afterInvalidate(EntryEvent<Integer, User> event) {
		System.out.println("afterInvalidate!!!!!!!!!" + event);
	}

	public void afterRegionDestroy(RegionEvent<Integer, User> event) {
		System.out.println("afterRegionDestroy!!!!!!!!!" + event);
	}

	public void afterRegionCreate(RegionEvent<Integer, User> event) {
		System.out.println("afterRegionCreate!!!!!!!!!" + event);
	}

	public void afterRegionInvalidate(RegionEvent<Integer, User> event) {
		System.out.println("afterRegionInvalidate!!!!!!!!!" + event);
	}

	public void afterUpdate(EntryEvent<Integer, User> event) {
		System.out.println("afterUpdate!!!!!!!!!" + event);
	}

	public void afterRegionClear(RegionEvent<Integer, User> event) {
		System.out.println("afterRegionClear!!!!!!!!!" + event);
	}

	public void afterRegionLive(RegionEvent<Integer, User> event) {
		System.out.println("afterRegionLive!!!!!!!!!" + event);
	}

	public void close() {
		System.out.println("close!!!!!!!!!");
	}
}

Um einen Listener für "Region" zu erstellen, erstellen Sie eine Klasse, die "CacheListener <K, V>" erbt. Stellen Sie Key, Value von Region ein, die Sie als Listener in Key, Value registrieren möchten.

Die folgenden beiden wurden diesmal überprüft. -'Region Erstellungsereignisverarbeitung: Die Verarbeitung der afterRegionCreate` -Methode wird ausgeführt. -Verarbeitung neuer Registrierungsereignisse: Die Verarbeitung der Methode "afterCreate" wird ausgeführt.

--Nächste die Implementierung, die den Listener bei "Region" registriert

UserRegion.java


package spring.geode.geodeCommon.region;

import org.apache.geode.cache.GemFireCache;
import org.apache.geode.cache.Region;
import org.springframework.data.gemfire.ReplicatedRegionFactoryBean;

import spring.geode.geodeCommon.listener.UserRegionListener;
import spring.geode.geodeCommon.model.User;

/**
 *Benutzer verwalten{@link Region}Einstellungen erstellen für
 *
 */
public class UserRegion {
	public Region<Integer, User> createUserRegion(final GemFireCache cache) {
        return cache.<Integer, User>getRegion("Users");
    }
	
    public ReplicatedRegionFactoryBean<Integer, User> createUserRegionFactory(GemFireCache cache) {
		ReplicatedRegionFactoryBean<Integer, User> replicatedRegionFactory = new ReplicatedRegionFactoryBean<>();
		UserRegionListener[] listeners = {new UserRegionListener()};
		listeners[0] = new UserRegionListener();
		replicatedRegionFactory.setCacheListeners(listeners);
		replicatedRegionFactory.setClose(false);
		replicatedRegionFactory.setCache(cache);
		replicatedRegionFactory.setRegionName("Users");
		replicatedRegionFactory.setPersistent(false);
        return replicatedRegionFactory;
    }

}

Erstellen Sie eine Region, die den Benutzer mit der Methode createUserRegion verwaltet, und registrieren Sie die Bean im ApplicationContext.

Mit der Methode "createUserRegionFactory" auf "Region" setzen. Hier wird auch der oben in Region erstellte Listener registriert.

GeodeClientApplication.java


package spring.geode.client.geodeClient;

import org.apache.geode.cache.GemFireCache;
import org.apache.geode.cache.Region;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.gemfire.ReplicatedRegionFactoryBean;
import org.springframework.data.gemfire.config.annotation.PeerCacheApplication;
import org.springframework.data.gemfire.repository.config.EnableGemfireRepositories;

import spring.geode.client.geodeClient.repository.UserRepository;
import spring.geode.geodeCommon.model.User;
import spring.geode.geodeCommon.region.UserRegion;

@SpringBootApplication
@PeerCacheApplication(name = "SpringGeodeClientApplication",locators = "localhost[40404]")
@EnableGemfireRepositories(basePackageClasses = UserRepository.class)
public class GeodeClientApplication {

	public static void main(String[] args) {
		SpringApplication.run(GeodeClientApplication.class, args);
	}

	@Configuration
	static class CacheInitializer {
		
		@Bean
	    Region<Integer, User> userRegion(final GemFireCache cache) {
			return new UserRegion().createUserRegion(cache);
	    }
		
		@Bean
	    public ReplicatedRegionFactoryBean<Integer, User> replicatedRegion(GemFireCache cache) {
			return new UserRegion().createUserRegionFactory(cache);
	    }
	}
}

GeodeServerApplication.java


package spring.geode.server.geodeServer;

import org.apache.geode.cache.GemFireCache;
import org.apache.geode.cache.Region;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.gemfire.ReplicatedRegionFactoryBean;
import org.springframework.data.gemfire.config.annotation.EnableEntityDefinedRegions;
import org.springframework.data.gemfire.config.annotation.EnableLocator;
import org.springframework.data.gemfire.config.annotation.EnableManager;
import org.springframework.data.gemfire.config.annotation.PeerCacheApplication;
import org.springframework.data.gemfire.repository.config.EnableGemfireRepositories;

import spring.geode.geodeCommon.model.User;
import spring.geode.geodeCommon.region.UserRegion;
import spring.geode.server.geodeServer.repository.UserRepository;

@SpringBootApplication
@PeerCacheApplication(name = "SpringGeodeServerApplication", locators = "localhost[40404]")
@EnableGemfireRepositories(basePackageClasses = UserRepository.class)
public class GeodeServerApplication {

	public static void main(String[] args) {
		SpringApplication.run(GeodeServerApplication.class, args);
	}

	@Configuration
	@EnableLocator(port = 40404)
	@EnableManager(start = true)
	static class LocatorManagerConfiguration {
	}

	@Configuration
	static class CacheInitializer {
		
		@Bean
	    Region<Integer, User> userRegion(final GemFireCache cache) {
			return new UserRegion().createUserRegion(cache);
	    }
		
		@Bean
	    public ReplicatedRegionFactoryBean<Integer, User> replicatedRegion(GemFireCache cache) {
			return new UserRegion().createUserRegionFactory(cache);
	    }
	}
}

Die Verarbeitung in der Klasse "CacheInitializer" spiegelt die Einstellungen für "Region" und "Region" wider. Implementieren Sie dies in einer App, die als integrierter Cache-Server startet. Der Klassenname lautet "Client" oder "Server", diesmal wird er jedoch im P2P-Format gestartet, sodass der Klasse die Annotation "@ PeerCacheApplication" hinzugefügt wird. Mach dir keine Sorgen über den Klassennamen. ..

Damit ist die Implementierung der Ereignisverarbeitung abgeschlossen.

Da der Prozess zum Starten von "locator" in "GeodeServerApplication.java" implementiert ist, starten Sie ihn von "GeodeServerApplication.java" und überprüfen Sie den Vorgang.

GeodeServerApplication.Auszug aus dem Java-Startprotokoll



[info 2019/02/03 02:56:32.334 JST <main> tid=0x1] Initializing region Users

[info 2019/02/03 02:56:32.334 JST <main> tid=0x1] Initialization of region Users completed

afterRegionCreate!!!!!!!!!RegionEventImpl[region=org.apache.geode.internal.cache.DistributedRegion[path='/Users';scope=DISTRIBUTED_NO_ACK';dataPolicy=REPLICATE; concurrencyChecksEnabled];op=REGION_CREATE;isReinitializing=false;callbackArg=null;originRemote=false;originMember=192.168.11.3(SpringGeodeServerApplication:5899)<ec><v0>:1024;tag=null]
[info 2019/02/03 02:56:32.705 JST <main> tid=0x1] Initializing ExecutorService 'applicationTaskExecutor'

org.apache.coyote.AbstractProtocol start
Information: Starting ProtocolHandler ["http-nio-9090"]
[info 2019/02/03 02:56:32.877 JST <main> tid=0x1] Tomcat started on port(s): 9090 (http) with context path ''

[info 2019/02/03 02:56:32.880 JST <main> tid=0x1] Started GeodeServerApplication in 3.66 seconds (JVM running for 5.179)

GeodeClientApplication.Auszug aus dem Java-Startprotokoll



[info 2019/02/03 02:56:49.107 JST <main> tid=0x1] Initializing region Users

[info 2019/02/03 02:56:49.113 JST <main> tid=0x1] Region Users requesting initial image from 192.168.11.3(SpringGeodeServerApplication:5899)<ec><v0>:1024

[info 2019/02/03 02:56:49.116 JST <main> tid=0x1] Users is done getting image from 192.168.11.3(SpringGeodeServerApplication:5899)<ec><v0>:1024. isDeltaGII is false

[info 2019/02/03 02:56:49.116 JST <main> tid=0x1] Initialization of region Users completed

afterRegionCreate!!!!!!!!!RegionEventImpl[region=org.apache.geode.internal.cache.DistributedRegion[path='/Users';scope=DISTRIBUTED_NO_ACK';dataPolicy=REPLICATE; concurrencyChecksEnabled];op=REGION_CREATE;isReinitializing=false;callbackArg=null;originRemote=false;originMember=192.168.11.3(SpringGeodeClientApplication:5901)<v1>:1025;tag=null]
[info 2019/02/03 02:56:49.510 JST <main> tid=0x1] Initializing ExecutorService 'applicationTaskExecutor'

org.apache.coyote.AbstractProtocol start
Information: Starting ProtocolHandler ["http-nio-9000"]
[info 2019/02/03 02:56:49.919 JST <main> tid=0x1] Tomcat started on port(s): 9000 (http) with context path ''
[info 2019/02/03 02:56:49.922 JST <main> tid=0x1] Started GeodeClientApplication in 4.245 seconds (JVM running for 5.513)

Wenn Sie die obigen Protokolle in den Startprotokollen der beiden Apps sehen können, ist die Verarbeitung des Regionserstellungsereignisses in Ordnung.

Region Users requesting initial image from 192.168.11.3(SpringGeodeServerApplication:5899)<ec><v0>:1024

Übrigens scheinen im obigen Protokoll "Benutzer" von "GeodeClientApplication" "Region" mit dem von "GeodeServerApplication" erstellten Bild von "Region" zu initialisieren.

Überprüfen Sie als Nächstes, ob die Listener-Verarbeitung ausgeführt wird, wenn die neuen Benutzerdaten in der Region auf der Seite GeodeClientApplcaition registriert und die Daten mit der GeodeServerApplcaition synchronisiert werden.

Benutzerregistrierungsanforderung an GeodeClientApplication


curl -X POST -H "Content-Type: application/json" -d '{"name":"Michel", "age":"100"}' localhost:9000/register/user

Melden Sie sich nach dem Senden einer Anfrage bei GeodeServerApplcaition an

GeodeServerApplication.Java-Log-Auszug


[info 2019/02/03 04:48:30.587 JST <pool-3-thread-1> tid=0x5b] Initialization of region _monitoringRegion_192.168.11.3<v1>1025 completed

[info 2019/02/03 04:48:30.593 JST <pool-3-thread-1> tid=0x5b] Initializing region _notificationRegion_192.168.11.3<v1>1025

[info 2019/02/03 04:48:30.595 JST <pool-3-thread-1> tid=0x5b] Initialization of region _notificationRegion_192.168.11.3<v1>1025 completed

2019-02-03T04:48:46.176823
afterCreate!!!!!!!!!User(id=-1816523715, name=Michel, age=100)

Wie erwartet scheint die Ereignisbehandlungsmethode in "GeodeServerApplication" ausgelöst zu werden.

Bonus

Der Unterschied zwischen "wenn Daten in" GeodeClientApplication "beibehalten werden" und "wenn die Ereignisverarbeitung in" GeodeServerApplication "ausgeführt wird" wird berücksichtigt, und nachdem Daten auf einem Cache-Server beibehalten wurden, werden sie auf einem anderen Cache-Server beibehalten. Ich habe die Latenz gemessen, bis das Datensynchronisationsereignis ausgeführt wurde.

Als ich die obige Operation 10 Mal mit der for-Anweisung wiederholte und den Durchschnittswert der Latenz nahm, war das Ergebnis sehr schnell, "0,002 ms". Es mag nicht sehr hilfreich sein, weil die Anzahl der Versuche gering ist, aber ich persönlich bin zufrieden.

Als nächstes implementieren wir die Persistenz.

Recommended Posts

Einführung in Spring Boot + In-Memory-Datenraster (Ereignisverarbeitung)
Einführung in SpringBoot + In-Memory Data Grid (Datenpersistenz)
Einführung in Spring Boot + In-Memory Data Grid
Einführung in das maschinelle Lernen mit Spark "Price Estimation" # 2 Datenvorverarbeitung (Umgang mit Kategorievariablen)
Einführung in web3j
Einführung in Micronaut 1 ~ Einführung ~
[Java] Einführung in Java
Einführung in die Migration
Einführung in Java
Einführung in Doma