Refer to images by location using the 'images-dir' Asciidoc attribute.
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
= Spring Boot Actuator for Apache Geode & Pivotal GemFire
|
||||
:apache-geode-version: {master-apache-geode-version}
|
||||
:apache-geode-docs: https://geode.apache.org/docs/guide/{apache-geode-version}
|
||||
:images-dir: ../images
|
||||
:images-dir: ./images
|
||||
:spring-boot-docs: https://docs.spring.io/spring-boot/docs/current/reference/html
|
||||
:spring-framework-docs: https://docs.spring.io/spring/docs/current/spring-framework-reference
|
||||
:toc: left
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
:apache-geode-docs: https://geode.apache.org/docs/guide/{apache-geode-version}
|
||||
:apache-geode-javadoc: https://geode.apache.org/releases/latest/javadoc
|
||||
:apache-geode-website: https://geode.apache.org/
|
||||
:images-dir: ../images
|
||||
:images-dir: ./images
|
||||
:spring-boot-docs: https://docs.spring.io/spring-boot/docs/current/reference/html
|
||||
:spring-boot-javadoc: https://docs.spring.io/spring-boot/docs/current/api
|
||||
:spring-data-geode-docs: https://docs.spring.io/spring-data/geode/docs/current/reference/html
|
||||
@@ -74,7 +74,7 @@ experience to which we alluded to above. These applications instances will need
|
||||
|
||||
An application architecture with HTTP Session State Caching appears as follows:
|
||||
|
||||
image::../images/HTTP-Session-Caching.png[]
|
||||
image::{images-dir}/HTTP-Session-Caching.png[]
|
||||
|
||||
Essentially, anytime an HTTP Session is requested by your Spring Boot, Web Application, the Servlet Container
|
||||
(e.g. Apache Tomcat) delegates to Spring Session to provide the implementation of `javax.servlet.http.HttpSession`.
|
||||
@@ -89,7 +89,7 @@ that implement the Spring Session framework's `SessionRepository` interface.
|
||||
|
||||
Spring Session's architecture can be depicted as follows:
|
||||
|
||||
image::../images/Spring-Session-Framework-Architecture.png[]
|
||||
image::{images-dir}/Spring-Session-Framework-Architecture.png[]
|
||||
|
||||
Again, the `SessionRepository` interface is the central component of the framework enabling any backend data store
|
||||
to be adapted and serve as a provider for managing the HTTP Sessions.
|
||||
@@ -198,11 +198,11 @@ Container using a derived `WebApplicationContext`.
|
||||
|
||||
Let's run the example:
|
||||
|
||||
image::../images/HttpSessionCachingApplication.png[]
|
||||
image::{images-dir}/HttpSessionCachingApplication.png[]
|
||||
|
||||
When we navigate to the `/session` Web service endpoint:
|
||||
|
||||
image::../images/HttpSessionCachingApplication-ServletContainerSession.png[]
|
||||
image::{images-dir}/HttpSessionCachingApplication-ServletContainerSession.png[]
|
||||
|
||||
We see that the Servlet Container's implementing class for the `javax.servlet.http.HttpSession` interface is
|
||||
`org.apache.catalina.session.StandardSession`.
|
||||
@@ -211,7 +211,7 @@ If we continue to hit refresh in the Web browser, thereby causing additional cli
|
||||
the HTTP server, then our HTTP Request count increments. If we wait for 15 seconds, then the HTTP Session will expire,
|
||||
and we will see the HTTP Session count increment along with the HTTP Request count reset to 1:
|
||||
|
||||
image::../images/HttpSessionCachingApplication-ServletContainerSessionExpiration.png[]
|
||||
image::{images-dir}/HttpSessionCachingApplication-ServletContainerSessionExpiration.png[]
|
||||
|
||||
Now, we can repeat this same exercise, but this time, using Spring Session.
|
||||
|
||||
@@ -242,7 +242,7 @@ robust, highly available, highly resilient, clustered solution provided by Sprin
|
||||
|
||||
When we run the example again, and access the `/session` Web service endpoint, we will see:
|
||||
|
||||
image::../images/HttpSessionCachingApplication-SpringSession.png[]
|
||||
image::{images-dir}/HttpSessionCachingApplication-SpringSession.png[]
|
||||
|
||||
Now we see that the implementing class for the `javax.servlet.http.HttpSession` is
|
||||
`org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper$HttpSessionWrapper`.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
:apache-geode-version: {master-apache-geode-version}
|
||||
:apache-geode-docs: https://geode.apache.org/docs/guide/{apache-geode-version}
|
||||
:apache-geode-javadoc: https://geode.apache.org/releases/latest/javadoc
|
||||
:images-dir: ../images
|
||||
:images-dir: ./images
|
||||
:spring-boot-docs: https://docs.spring.io/spring-boot/docs/current/reference/html
|
||||
:spring-boot-javadoc: https://docs.spring.io/spring-boot/docs/current/api
|
||||
:spring-data-geode-docs: https://docs.spring.io/spring-data/geode/docs/current/reference/html
|
||||
@@ -104,7 +104,7 @@ strictly adhere to and be diligent in your use of _Inline Caching_.
|
||||
|
||||
_Inline Caching_ can be depicted in the following diagram:
|
||||
|
||||
image::../images/Inline-Caching-Pattern.png[]
|
||||
image::{images-dir}/Inline-Caching-Pattern.png[]
|
||||
|
||||
In the diagram above, there are 2 flows: 1 for _read-through_ (right-side) and another for _write-through_ (left-side).
|
||||
Both can occur in a single operation, on a read.
|
||||
@@ -465,14 +465,14 @@ include::{samples-dir}/caching/inline/src/main/resources/data.sql[]
|
||||
|
||||
If you call `http://localhost:8080/caculator/factorial/4`, you will see the following output:
|
||||
|
||||
image::../images/factorial-of-four-before.png[]
|
||||
image::{images-dir}/factorial-of-four-before.png[]
|
||||
|
||||
The output shows the result of `factorial(4)` is *24*, that the calculation took *3096 _milliseconds_* and the operation
|
||||
resulted in a *_cache miss_*. However, now that we computed `factorial(4)`, the result was put into the "cache"
|
||||
as well as INSERTED into the backend (embedded, in-memory HSQLDB) database. So, if we run the operation again,
|
||||
the `latency` drops to zero (and *_cacheMiss_* is *_false_*):
|
||||
|
||||
image::../images/factorial-of-four-after.png[]
|
||||
image::{images-dir}/factorial-of-four-after.png[]
|
||||
|
||||
That is because the result (i.e. *24*) of `factorial(4)` is "cached" in Apache Geode (as well as persisted to
|
||||
the database; _write-through_) and therefore, the `CaculatorService.factorial(:int)` method is *not* called.
|
||||
@@ -482,7 +482,7 @@ To see the effects of the `factorial(:int)` method involving the database as par
|
||||
call `http://localhost:8080/caculator/factorial/5`. *5* is stored in the database, but is not currently present
|
||||
in the cache:
|
||||
|
||||
image::../images/factorial-of-five-before.png[]
|
||||
image::{images-dir}/factorial-of-five-before.png[]
|
||||
|
||||
While the latency is much better than invoking the _factorial_ function, it is still not as fast as pulling the result
|
||||
from the cache.
|
||||
@@ -492,7 +492,7 @@ the result was loaded from the database and put into the cache (_read-through_)
|
||||
we see that the latency drops from *12 ms* to *0 ms*. However, in both cases, the *_cacheMiss_* was *_false_*
|
||||
because the value was found (in the database) without invoking the `CalculatorService.factorial(:int)` method:
|
||||
|
||||
image::../images/factorial-of-five-after.png[]
|
||||
image::{images-dir}/factorial-of-five-after.png[]
|
||||
|
||||
You can play around with the _square root_ operation to see the same effects of _Inline Caching_.
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
:apache-geode-version: {master-apache-geode-version}
|
||||
:apache-geode-docs: https://geode.apache.org/docs/guide/{apache-geode-version}
|
||||
:apache-geode-javadoc: https://geode.apache.org/releases/latest/javadoc
|
||||
:images-dir: ../images
|
||||
:images-dir: ./images
|
||||
:spring-boot-docs: https://docs.spring.io/spring-boot/docs/current/reference/html
|
||||
:spring-boot-javadoc: https://docs.spring.io/spring-boot/docs/current/api
|
||||
:spring-data-geode-docs: https://docs.spring.io/spring-data/geode/docs/current/reference/html
|
||||
@@ -81,7 +81,7 @@ the `findBy(..)` method is called with the same `AccountNumber` (i.e. "abc123")
|
||||
|
||||
The _Look-Aside Caching_ pattern can be depicted in the following diagram:
|
||||
|
||||
image::../images/Look-Aside-Caching-Pattern.png[]
|
||||
image::{images-dir}/Look-Aside-Caching-Pattern.png[]
|
||||
|
||||
In the diagram above, we see that the caching provider (e.g. Apache Geode) is consulted first, #2, after the client
|
||||
initiated the request, #1. If the result of the cacheable operation for the given input has already been computed
|
||||
@@ -442,7 +442,7 @@ from your IDE, or from the command-line, as is:
|
||||
|
||||
Then open your Web browser and navigate to `http://localhost:8080/ping`:
|
||||
|
||||
image::../images/LookAsideCachingApplication-Ping.png[]
|
||||
image::{images-dir}/LookAsideCachingApplication-Ping.png[]
|
||||
|
||||
After that, we can create and increment counters, for example:
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
:apache-geode-version: {master-apache-geode-version}
|
||||
:apache-geode-docs: https://geode.apache.org/docs/guide/{apache-geode-version}
|
||||
:apache-geode-javadoc: https://geode.apache.org/releases/latest/javadoc
|
||||
:images-dir: ../images
|
||||
:images-dir: ./images
|
||||
:spring-boot-docs: https://docs.spring.io/spring-boot/docs/current/reference/html
|
||||
:spring-boot-javadoc: https://docs.spring.io/spring-boot/docs/current/api
|
||||
:spring-data-geode-docs: https://docs.spring.io/spring-data/geode/docs/current/reference/html
|
||||
@@ -65,7 +65,7 @@ To keep up with demand and not overload backend systems, like a database, you wo
|
||||
more CPU, more Disk, more Network bandwidth, basically, more of everything, which can be a very costly endeavor as you
|
||||
try to keep up with the every growing demand (which is a good problem to have, but...):
|
||||
|
||||
image::../images/Small-Database-To-Big-Database.png[]
|
||||
image::{images-dir}/Small-Database-To-Big-Database.png[]
|
||||
|
||||
Rather than scale-up, you could scale-out by using a sophisticated caching technology that uniformly partitions data
|
||||
across a cluster of data nodes thereby enabling data access operations to be intelligently routed and evenly distributed
|
||||
@@ -74,7 +74,7 @@ cluster more resilient to failure. Such a data management technology is ideal i
|
||||
as a single, logical unit of pooled resources (Memory, CPU, Disk, and Network) but uses a shared-nothing architecture.
|
||||
That is, no node in the cluster can be a single point of failure.
|
||||
|
||||
image::../images/Cluster.png[]
|
||||
image::{images-dir}/Cluster.png[]
|
||||
|
||||
From a Spring Boot application's point-of-view, it is the client in this application architecture, and multiple
|
||||
application instances can access and share the same data. Indeed, in a Microservices architecture, another application
|
||||
@@ -107,7 +107,7 @@ These 3 things in conjunction with each other should have a net effect of reduci
|
||||
Effectively, an applied "_Near Caching_" software design pattern looks like the following in our application/system
|
||||
architecture:
|
||||
|
||||
image::../images/Near-Caching-Pattern.png[]
|
||||
image::{images-dir}/Near-Caching-Pattern.png[]
|
||||
|
||||
It is now time to see the _Near Caching_ pattern in action.
|
||||
|
||||
@@ -470,14 +470,14 @@ from your Web browser. Look for a line containing: `[info 2019/08/12 13:14:19.7
|
||||
Once both application instances are running, you can access the Webapp from your Web browser at the following URL:
|
||||
`http::/localhost:8181/`.
|
||||
|
||||
image::../images/Near-Caching-Example-Webapp.png[]
|
||||
image::{images-dir}/Near-Caching-Example-Webapp.png[]
|
||||
|
||||
TIP: To switch between the 2 client app instances, it is useful to have 2 Web browser tabs or windows open
|
||||
accessing each Web Server port (e.g. `8181` and `8282`).
|
||||
|
||||
Next, let's create some data using client app instance one.
|
||||
|
||||
image::../images/Near-Caching-Example-Webapp-Create-JonDoe.png[]
|
||||
image::{images-dir}/Near-Caching-Example-Webapp-Create-JonDoe.png[]
|
||||
|
||||
This operation takes a bit of (simulated) time (`2167 milliseconds (ms)`, or `~2 seconds (s)`) since "_Jon Doe_"
|
||||
did not previously exist in the cache, which can be noted by the `cacheMiss` value of *true*. "_JonDoe's_"
|
||||
@@ -488,7 +488,7 @@ is being pulled from the "_local_" cache (i.e. "_Near Cache_) on the client.
|
||||
|
||||
Now, in our second client app instance, if we access the same person, "_JonDoe_", then we see the following:
|
||||
|
||||
image::../images/Near-Caching-Example-Webapp-Read-JonDoe.png[]
|
||||
image::{images-dir}/Near-Caching-Example-Webapp-Read-JonDoe.png[]
|
||||
|
||||
Notice that `cacheMiss` is *false* and the `latency` is only `1 ms`. That is because the 2nd client app instance
|
||||
was already pushed the data from the server based on the client's interest registration. This is also apparent
|
||||
@@ -503,7 +503,7 @@ in the log output for the client application instances:
|
||||
To see the effects of updating a cache entry from a client app instance, let's update "_JonDoe_" from the 2nd client app
|
||||
instance by changing his email address and phone number:
|
||||
|
||||
image::../images/Near-Caching-Example-Webapp-Update-JonDoe.png[]
|
||||
image::{images-dir}/Near-Caching-Example-Webapp-Update-JonDoe.png[]
|
||||
|
||||
Before we refresh the Web browser tab or window pointing to our 1st client app instance, if you look at the log output
|
||||
for the 1st client app instance, you will see:
|
||||
@@ -517,7 +517,7 @@ for the 1st client app instance, you will see:
|
||||
Then, switch back to the 1st client app instance Web browser tab or window and hit the refresh button, or navigate
|
||||
to the URL, `http://localhost:8181/yellow-pages/JonDoe`, and you should see the updated contact information:
|
||||
|
||||
image::../images/Near-Caching-Example-Webapp-Reload-JonDoe.png[]
|
||||
image::{images-dir}/Near-Caching-Example-Webapp-Reload-JonDoe.png[]
|
||||
|
||||
You can repeat this exercise as often as you like.
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ John Blum
|
||||
:apache-geode-docs: https://geode.apache.org/docs/guide/{apache-geode-version}
|
||||
:apache-geode-javadoc: https://geode.apache.org/releases/latest/javadoc
|
||||
:apache-geode-website: https://geode.apache.org/
|
||||
:images-dir: ./images
|
||||
:pivotal-cloudcache-version: {master-pivotal-cloudcache-version}
|
||||
:pivotal-cloudcache-docs: https://docs.pivotal.io/p-cloud-cache/{pivotal-cloudcache-version}
|
||||
:pivotal-cloudcache-website: https://pivotal.io/pivotal-cloud-cache
|
||||
@@ -92,14 +93,14 @@ see that `2.2.0.RC1` was selected when the project was generated. For more on v
|
||||
|
||||
Your selections should look similar to:
|
||||
|
||||
image::../images/spring-initializer-screenshot.png[]
|
||||
image::{images-dir}/spring-initializer-screenshot.png[]
|
||||
|
||||
Be sure to click the "*+*" button next to the "_Spring for Apache Geode_" dependency to select and add it to
|
||||
the generated project Maven POM file.
|
||||
|
||||
You can explore the contents of the generated project by pressing the `CTRL+SPACE` keys:
|
||||
|
||||
image::../images/spring-initializer-explore-project-screenshot.png[]
|
||||
image::{images-dir}/spring-initializer-explore-project-screenshot.png[]
|
||||
|
||||
Click the "_Generate the project_" button. This generates a *Java 8* project with *JAR* packaging.
|
||||
|
||||
@@ -977,7 +978,7 @@ Caused by: o.a.g.cache.client.NoAvailableServersException: null
|
||||
The application will continue to run if you included the Spring Web dependencies in your application classpath,
|
||||
in which case, you can then inspect the application using a Web client (e.g. Web browser):
|
||||
|
||||
image::../images/customer-service-application-jondoe.png[]
|
||||
image::{images-dir}/customer-service-application-jondoe.png[]
|
||||
|
||||
[[spring-geode-samples-getting-started-run-app-clientserver]]
|
||||
== Run the Application in a Client/Server Topology
|
||||
@@ -1797,21 +1798,21 @@ We see the "_crm-app_" in the table of apps, which is currently stopped.
|
||||
We can either start and stop the app, restage the app, bind services, and so on, all from the command-line using `cf`,
|
||||
or we can perform these actions from within _Pivotal AppsManager_, which is what we will do:
|
||||
|
||||
image::../images/pvtl-appsmanager-org-space-apps.png[]
|
||||
image::{images-dir}/pvtl-appsmanager-org-space-apps.png[]
|
||||
|
||||
Again, we see the "_crm-app_". You can click on the app name and drill in to get more details:
|
||||
|
||||
image::../images/pvtl-appsmanager-org-space-apps-crm-app-overview.png[]
|
||||
image::{images-dir}/pvtl-appsmanager-org-space-apps-crm-app-overview.png[]
|
||||
|
||||
If you click on "_Service (1)_" in the left navigation bar, you will see that the "_crm-app_" is bound to
|
||||
the "_pccServiceOne_" Pivotal Cloud Cache service instance:
|
||||
|
||||
image::../images/pvtl-appsmanager-org-space-apps-crm-app-service.png[]
|
||||
image::{images-dir}/pvtl-appsmanager-org-space-apps-crm-app-service.png[]
|
||||
|
||||
If you click on "_Settings_" in the left navigation bar and "REVEAL ENV VARS" you will find the "_Gfsh login string_"
|
||||
that you can use to connect to the Pivotal Cloud Cache cluster using _Gfsh_ from your local development environment:
|
||||
|
||||
image::../images/pvtl-appsmanager-org-space-apps-crm-app-settings.png[]
|
||||
image::{images-dir}/pvtl-appsmanager-org-space-apps-crm-app-settings.png[]
|
||||
|
||||
Let's do that now. Copy the "_Gfsh login string_" and enter it in _Gfsh_:
|
||||
|
||||
@@ -1863,12 +1864,12 @@ Now, we can start the CRM, Spring Boot application using _Pivotal AppsManager_ f
|
||||
|
||||
The "_crm-app_" will be staged and then started:
|
||||
|
||||
image::../images/pvtl-appsmanager-org-space-apps-crm-app-start.png[]
|
||||
image::{images-dir}/pvtl-appsmanager-org-space-apps-crm-app-start.png[]
|
||||
|
||||
Click the "_play_" button in the upper right corner above the log output frame to tail the log file of the CRM,
|
||||
Spring Boot application. Eventually, you should see the application log the interaction with "_JonDoe_".
|
||||
|
||||
image::../images/pvtl-appsmanager-org-space-apps-crm-app-logs-output.png[]
|
||||
image::{images-dir}/pvtl-appsmanager-org-space-apps-crm-app-logs-output.png[]
|
||||
|
||||
As you can see in the image above, the application successfully logged the interactions with "_JonDoe_". This only
|
||||
appears in red "[ERR]" since the interactions with logged with `System.err.printf` statements.
|
||||
@@ -1876,11 +1877,11 @@ appears in red "[ERR]" since the interactions with logged with `System.err.print
|
||||
If you now click on "VIEW APP" link in the upper right-hand corner, it will open a new tab to the CRM Web app's
|
||||
home page:
|
||||
|
||||
image::../images/getting-started-crm-app-homepage.png[]
|
||||
image::{images-dir}/getting-started-crm-app-homepage.png[]
|
||||
|
||||
Then, you get all customers in JSON by using HTTP `GET http://host:port/customers` REST API Web service endpoint:
|
||||
|
||||
image::../images/getting-started-crm-app-getallcustomers.png[]
|
||||
image::{images-dir}/getting-started-crm-app-getallcustomers.png[]
|
||||
|
||||
Now, back in _Gfsh_, you can see that the 1) "_/Customers_" Region was added to the cluster of PCC servers
|
||||
and that 2) "_JonDoe_" was persisted to the cluster and you are able to query for "_JonDoe_".
|
||||
|
||||
Reference in New Issue
Block a user