Files
spring-boot-data-geode/spring-geode-docs/src/docs/asciidoc/clientcache-applications.adoc
2019-09-10 23:43:34 -07:00

338 lines
16 KiB
Plaintext

[[geode-clientcache-applications]]
== Building ClientCache Applications
The first, opinionated option provided to you by Spring Boot for Apache Geode & Pivotal GemFire (SBDG) out-of-the-box is
a {apache-geode-javadoc}/org/apache/geode/cache/client/ClientCache.html[ClientCache] instance, simply by declaring
either Spring Boot for Apache Geode or Spring Boot for Pivotal GemFire on your application classpath.
It is assumed that most application developers using Spring Boot to build applications backed by either Apache Geode
or Pivotal GemFire will be building cache client applications deployed in an Apache Geode or Pivotal GemFire
{apache-geode-docs}/topologies_and_comm/cs_configuration/chapter_overview.html[Client/Server topology].
A client/server topology is the most common and traditional architecture employed by enterprise applications.
For example, you can begin building a Spring Boot, Apache Geode or Pivotal GemFire, `ClientCache` application
with either the `spring-geode-starter` or `spring-gemfire-starter` on your application's classpath:
.Spring Boot for Apache Geode on the application classpath
[source,xml]
----
<dependency>
<groupId>org.springframework.geode</groupId>
<artifactId>spring-geode-starter</artifactId>
</dependency>
----
Then, you configure and bootstrap your Spring Boot, Apache Geode `ClientCache` application with the following
main application class:
.Spring Boot, Apache Geode `ClientCache` Application
[source,java]
----
@SpringBootApplication
public SpringBootApacheGeodeClientCacheApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootApacheGeodeClientCacheApplication.class, args);
}
}
----
Your application now has a `ClientCache` instance, which is able to connect to an Apache Geode or Pivotal GemFire server
running on `localhost`, listening on the default `CacheServer` port, `40404`.
By default, an Apache Geode or Pivotal GemFire server (i.e. `CacheServer`) must be running in order to use
the `ClientCache` instance. However, it is perfectly valid to create a `ClientCache` instance and perform
data access operations using `LOCAL` Regions. This is very useful during development.
TIP: To develop with `LOCAL` Regions, you only need to define your cache Regions with the
{apache-geode-javadoc}/org/apache/geode/cache/client/ClientRegionShortcut.html#LOCAL[`ClientRegionShortcut.LOCAL`]
data management policy.
When you are ready to switch from your local development environment (IDE) to a client/server architecture in a managed
environment, you simply change the data management policy of the client Region from `LOCAL` back to the default `PROXY`,
or even a `CACHING_PROXY`, data management policy which will cause the data to be sent/received to and from 1 or more
servers, respectively.
TIP: Compare and contrast the above configuration with Spring Data for Apache Geode/Pivotal GemFire's
{spring-data-geode-docs-html}/#bootstrap-annotation-config-geode-applications[approach].
It is uncommon to ever need a direct reference to the `ClientCache` instance provided by SBDG injected into your
application components (e.g. `@Service` or `@Repository` beans defined in a Spring `ApplicationContext`) whether you
are configuring additional GemFire/Geode objects (e.g. Regions, Indexes, etc) or simply using those objects indirectly
in your applications. However, it is also possible to do so if and when needed.
For example, perhaps you want to perform some additional `ClientCache` initialization in a Spring Boot
{spring-boot-javadoc}/org/springframework/boot/ApplicationRunner.html[ApplicationRunner] on startup:
.Injecting a `GemFireCache` reference
[source,java]
----
@SpringBootApplication
public SpringBootApacheGeodeClientCacheApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootApacheGeodeClientCacheApplication.class, args);
}
@Bean
ApplicationRunner runAdditionalClientCacheInitialization(GemFireCache gemfireCache) {
return args -> {
ClientCache clientCache = (ClientCache) gemfireCache;
// perform additional ClientCache initialization as needed
};
}
}
----
[[geode-peercache-applications]]
=== Embedded (Peer & Server) Cache Applications
What if you want to build an embedded, peer `Cache` application instead?
Perhaps you need an actual peer cache member, configured and bootstrapped with Spring Boot, along with the ability
to join this member to a (possibly) existing cluster (of data servers) as a peer. Well, you can do that too.
Remember the 2nd goal in Spring Boot's {spring-boot-docs-html}/#getting-started-introducing-spring-boot[documentation]:
> "_Be opinionated out of the box but get out of the way quickly as requirements start to diverge from the defaults._"
It is the 2nd part, "_get out of the way quickly as requirements start to diverge from the defaults_"
that I refer to here.
If your application requirements require you to use Spring Boot to configure and bootstrap an embedded,
peer `Cache` Apache Geode or Pivotal GemFire application, then simply declare your intentions with either SDG's
{spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/PeerCacheApplication.html[`@PeerCacheApplication`] annotation,
or alternatively, if you need to enable connections from other cache client apps, use the SDG
{spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/CacheServerApplication.html[`@CacheServerApplication`] annotation:
.Spring Boot, Apache Geode/Pivotal GemFire CacheServer Application
[source,java]
----
@SpringBootApplication
@CacheServerApplication(name = "MySpringBootApacheGeodeCacheServerApplication")
public SpringBootApacheGeodeCacheServerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootApacheGeodeCacheServerApplication.class, args);
}
}
----
TIP: An Apache Geode/Pivotal GemFire "server" is not necessarily a "`CacheServer`" capable of serving cache clients.
It is merely a peer member in the GemFire/Geode cluster (a.k.a. distributed system) that stores and manages data.
By explicitly declaring the `@CacheServerApplication` annotation, you are telling Spring Boot that you do not want
the default, `ClientCache` instance, but rather an embedded, peer `Cache` instance with a `CacheServer` component,
which enables connections from cache client apps.
I can also enable 2 other GemFire/Geode services, an embedded _Locator_, which allows either clients or even other peers
to "locate" servers in a cluster, as well as an embedded _Manager_, which allows the GemFire/Geode application process
to be managed and/or monitored using {apache-geode-docs}/tools_modules/gfsh/chapter_overview.html[_Gfsh_],
GemFire/Geode's shell tool:
.Spring Boot, Apache Geode/Pivotal GemFire CacheServer Application with _Locator_ and _Manager_ services enabled
[source,java]
----
@SpringBootApplication
@CacheServerApplication(name = "MySpringBootApacheGeodeCacheServerApplication")
@EnableLocator
@EnableManager
public SpringBootApacheGeodeCacheServerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootApacheGeodeCacheServerApplication.class, args);
}
}
----
Then, you can even use _Gfsh_ to connect to and manage this server:
[source,text]
----
$ echo $GEMFIRE
/Users/jblum/pivdev/apache-geode-1.2.1
$ gfsh
_________________________ __
/ _____/ ______/ ______/ /____/ /
/ / __/ /___ /_____ / _____ /
/ /__/ / ____/ _____/ / / / /
/______/_/ /______/_/ /_/ 1.2.1
Monitor and Manage Apache Geode
gfsh>connect
Connecting to Locator at [host=localhost, port=10334] ..
Connecting to Manager at [host=10.0.0.121, port=1099] ..
Successfully connected to: [host=10.0.0.121, port=1099]
gfsh>list members
Name | Id
------------------------------------------- | --------------------------------------------------------------------------
SpringBootApacheGeodeCacheServerApplication | 10.0.0.121(SpringBootApacheGeodeCacheServerApplication:29798)<ec><v0>:1024
gfsh>
gfsh>describe member --name=SpringBootApacheGeodeCacheServerApplication
Name : SpringBootApacheGeodeCacheServerApplication
Id : 10.0.0.121(SpringBootApacheGeodeCacheServerApplication:29798)<ec><v0>:1024
Host : 10.0.0.121
Regions :
PID : 29798
Groups :
Used Heap : 168M
Max Heap : 3641M
Working Dir : /Users/jblum/pivdev/spring-boot-data-geode/spring-geode-docs/build
Log file : /Users/jblum/pivdev/spring-boot-data-geode/spring-geode-docs/build
Locators : localhost[10334]
Cache Server Information
Server Bind :
Server Port : 40404
Running : true
Client Connections : 0
----
You can even start additional servers in _Gfsh_, which will connect to your Spring Boot configured and bootstrapped
Apache Geode or Pivotal GemFire `CacheServer` application. These additional servers started in _Gfsh_ know about
the Spring Boot, GemFire/Geode server because of the embedded _Locator_ service, which is running on `localhost`,
listening on the default _Locator_ port, `10334`:
[source,text]
----
gfsh>start server --name=GfshServer --log-level=config --disable-default-server
Starting a Geode Server in /Users/jblum/pivdev/lab/GfshServer...
...
Server in /Users/jblum/pivdev/lab/GfshServer on 10.0.0.121 as GfshServer is currently online.
Process ID: 30031
Uptime: 3 seconds
Geode Version: 1.2.1
Java Version: 1.8.0_152
Log File: /Users/jblum/pivdev/lab/GfshServer/GfshServer.log
JVM Arguments: -Dgemfire.default.locators=10.0.0.121:127.0.0.1[10334] -Dgemfire.use-cluster-configuration=true -Dgemfire.start-dev-rest-api=false -Dgemfire.log-level=config -XX:OnOutOfMemoryError=kill -KILL %p -Dgemfire.launcher.registerSignalHandlers=true -Djava.awt.headless=true -Dsun.rmi.dgc.server.gcInterval=9223372036854775806
Class-Path: /Users/jblum/pivdev/apache-geode-1.2.1/lib/geode-core-1.2.1.jar:/Users/jblum/pivdev/apache-geode-1.2.1/lib/geode-dependencies.jar
gfsh>list members
Name | Id
------------------------------------------- | --------------------------------------------------------------------------
SpringBootApacheGeodeCacheServerApplication | 10.0.0.121(SpringBootApacheGeodeCacheServerApplication:29798)<ec><v0>:1024
GfshServer | 10.0.0.121(GfshServer:30031)<v1>:1025
----
Perhaps you want to start the other way around. As developer, I may need to connect my Spring Boot configured
and bootstrapped GemFire/Geode server application to an existing cluster. You can start the cluster in _Gfsh_
by executing the following commands:
[source,text]
----
gfsh>start locator --name=GfshLocator --port=11235 --log-level=config
Starting a Geode Locator in /Users/jblum/pivdev/lab/GfshLocator...
...
Locator in /Users/jblum/pivdev/lab/GfshLocator on 10.0.0.121[11235] as GfshLocator is currently online.
Process ID: 30245
Uptime: 3 seconds
Geode Version: 1.2.1
Java Version: 1.8.0_152
Log File: /Users/jblum/pivdev/lab/GfshLocator/GfshLocator.log
JVM Arguments: -Dgemfire.log-level=config -Dgemfire.enable-cluster-configuration=true -Dgemfire.load-cluster-configuration-from-dir=false -Dgemfire.launcher.registerSignalHandlers=true -Djava.awt.headless=true -Dsun.rmi.dgc.server.gcInterval=9223372036854775806
Class-Path: /Users/jblum/pivdev/apache-geode-1.2.1/lib/geode-core-1.2.1.jar:/Users/jblum/pivdev/apache-geode-1.2.1/lib/geode-dependencies.jar
Successfully connected to: JMX Manager [host=10.0.0.121, port=1099]
Cluster configuration service is up and running.
gfsh>start server --name=GfshServer --log-level=config --disable-default-server
Starting a Geode Server in /Users/jblum/pivdev/lab/GfshServer...
....
Server in /Users/jblum/pivdev/lab/GfshServer on 10.0.0.121 as GfshServer is currently online.
Process ID: 30270
Uptime: 4 seconds
Geode Version: 1.2.1
Java Version: 1.8.0_152
Log File: /Users/jblum/pivdev/lab/GfshServer/GfshServer.log
JVM Arguments: -Dgemfire.default.locators=10.0.0.121[11235] -Dgemfire.use-cluster-configuration=true -Dgemfire.start-dev-rest-api=false -Dgemfire.log-level=config -XX:OnOutOfMemoryError=kill -KILL %p -Dgemfire.launcher.registerSignalHandlers=true -Djava.awt.headless=true -Dsun.rmi.dgc.server.gcInterval=9223372036854775806
Class-Path: /Users/jblum/pivdev/apache-geode-1.2.1/lib/geode-core-1.2.1.jar:/Users/jblum/pivdev/apache-geode-1.2.1/lib/geode-dependencies.jar
gfsh>list members
Name | Id
----------- | --------------------------------------------------
GfshLocator | 10.0.0.121(GfshLocator:30245:locator)<ec><v0>:1024
GfshServer | 10.0.0.121(GfshServer:30270)<v1>:1025
----
Then, modify the `SpringBootApacheGeodeCacheServerApplication` class to connect to the existing cluster, like so:
.Spring Boot, Apache Geode/Pivotal GemFire CacheServer Application with _Locator_ and _Manager_ services enabled
[source,java]
----
@SpringBootApplication
@CacheServerApplication(name = "MySpringBootApacheGeodeCacheServerApplication", locators = "localhost[11235]")
public SpringBootApacheGeodeCacheServerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootApacheGeodeClientCacheApplication.class, args);
}
}
----
TIP: Notice I configured the `SpringBootApacheGeodeCacheServerApplication` class, `@CacheServerApplication` annotation,
`locators` property with the host and port (i.e. "localhost[11235]") on which I started my _Locator_ using _Gfsh_.
After running your Spring Boot, Apache Geode `CacheServer` application again, and then running `list members` in _Gfsh_,
you should see:
[source,text]
----
gfsh>list members
Name | Id
------------------------------------------- | ----------------------------------------------------------------------
GfshLocator | 10.0.0.121(GfshLocator:30245:locator)<ec><v0>:1024
GfshServer | 10.0.0.121(GfshServer:30270)<v1>:1025
SpringBootApacheGeodeCacheServerApplication | 10.0.0.121(SpringBootApacheGeodeCacheServerApplication:30279)<v2>:1026
gfsh>describe member --name=SpringBootApacheGeodeCacheServerApplication
Name : SpringBootApacheGeodeCacheServerApplication
Id : 10.0.0.121(SpringBootApacheGeodeCacheServerApplication:30279)<v2>:1026
Host : 10.0.0.121
Regions :
PID : 30279
Groups :
Used Heap : 165M
Max Heap : 3641M
Working Dir : /Users/jblum/pivdev/spring-boot-data-geode/spring-geode-docs/build
Log file : /Users/jblum/pivdev/spring-boot-data-geode/spring-geode-docs/build
Locators : localhost[11235]
Cache Server Information
Server Bind :
Server Port : 40404
Running : true
Client Connections : 0
----
In both scenarios, the Spring Boot configured and bootstrapped Apache Geode (or Pivotal GemFire) server
and the _Gfsh_ _Locator_ and Servers formed a cluster.
While you can use either approach and Spring does not care, it is far more convenient to use Spring Boot and your IDE
to form a small cluster while developing. By leveraging Spring profiles, it is far simpler to configure and start
a small cluster much faster.
Plus, this is useful for rapidly prototyping, testing and debugging your entire, end-to-end application
and system architecture, all right from the comfort and familiarity of your IDE of choice. No addition tooling
(e.g. _Gfsh_) knowledge is required to get started quickly and easily.
Just _build_ and _run_ it!
TIP: Be careful to vary your port numbers for the embedded services, like the `CacheServer`, _Locators_ and _Manager_,
especially if you start multiple instances, otherwise you will run into a `java.net.BindException`
due to port conflicts.
TIP: See the Appendix, <<geode-cluster-configuration-bootstrapping>> for more details.