This section gathers some miscellaneous notes on production deployment and performance tuning.
Some image formats are inherently more efficient to process than others, which will affect server load and response times. If you have control over your source image formats, see the Images section for recommendations.
A health check endpoint is available at /health. It is enabled by default, but can be disabled by setting the endpoint.health.enabled
configuration option to false
.
By default, it simply returns HTTP 200 OK
, but if endpoint.health.dependency_check
is set to true
, it also performs several other checks:
This makes the for a more thorough check, but also a slower one that may be redundant if these services are already being monitored.
The JSON response includes one of three color codes:
GREEN
indicates normal functionality.YELLOW
indicates a warning condition.RED
indicates a failure condition.HTTP 200 is returned for GREEN
status, and HTTP 500 for all others.
Galia allocates one thread per request, and maintains a thread pool to carry out certain tasks asynchronously and spread work across processors. Response times will benefit from multiple fast cores.
Some source formats are more processor-intensive than others. JPEG2000 via OpenJPEGDecoder, for example, will work the CPU much more than uncompressed TIFF via TIFFDecoder.
Memory requirements will vary greatly depending on decoders used, source image format, source image size, request image size, and request frequency. Image formats that don't support tiling or that can't be selectively decoded will require more memory to process (see Images). The application will log an ERROR
-level message if the JVM runs out of memory.
As a Java application, Galia runs inside a Java Virtual Machine (JVM), and can only use the memory the JVM makes available to it. The main area of memory of concern inside the JVM is called the heap, and its size characteristics can be modified using the config/jvm.options file. Some of the most relevant are:
-Xms
-Xmx
-XX:InitialRAMPercentage
-XX:MaxRAMPercentage
When no heap size arguments are present, the JVM will initialize itself with defaults that are likely to be too small for a production server.
Operating system utilities like top
, Task Manager, Activity Monitor, etc. can show you what a process looks like as the OS sees it, but they can't show what's happening inside a process. A tool like JConsole, included in the Java Development Kit (JDK), can visualize memory usage inside a running JVM.
Some codec plugins utilize the Java Foreign Function & Memory API in order to call into native codec libraries. These libraries do their work outside of the JVM in native memory. While it is important to ensure that there is always enough memory available to the JVM, it is also important to ensure that there is enough memory available outside of it.
Heap memory is freed automatically by a garbage collector (GC) that runs in the JVM. One of the problems with Java garbage collection in general is that it can cause periodic freezes of all applications running in the VM.
Over the years, the JVM's default GC implementation has changed as new GCs have been developed that try to improve efficiency and reduce freezes. Java 7 and 8 use the Parallel GC. The G1 GC became the default in Java 9. Java 11 introduced ZGC as an experimental new GC, and Java 12 introduced Shenandoah as another experimental GC. All of these GCs can be experimented with by adding their command-line arguments to the config/jvm.options file. By default, Galia uses the JVM's default.
Most source formats benefit from fast read performance—in terms of both latency and throughput—in the underlying storage system. Throughput is more important for less efficient source formats—like JPEG, PNG, and striped TIFF—especially as source image size increases. Local filesystem storage usually performs best.
As variant images tend to be small, latency tends to be more important than throughput for variant caches.
See the Caching section for information about the built-in caching options, which can dramatically improve performance. When using automatic maintenance in a cluster, consider enabling it on only one node.
max_scale
configuration option can be used to disallow requests for large scales that could overwhelm the server.max_pixels
configuration option is available to limit the maximum returned size of processed images. This is a "safety net" to prevent excessively expensive requests. It does not affect requests for full-sized unmodified images, which do not significantly load the server.
max_pixels
, with more granular control.http.min_threads
, http.max_threads
, and http.accept_queue_limit
can be used to adjust the characteristics of the built-in web server's request thread pool and queue. When any of the values are exceeded, the application will refuse to fulfill requests by returning HTTP 503 Service Unavailable
.Galia can run behind a reverse-proxy web server like Apache or nginx. The proxy should be set up to pass-through encoded URI characters without decoding them. It should also be configured to send the following headers:
Header | Description | Required? |
---|---|---|
X-Forwarded-Proto |
Protocol of the client request; either HTTP or HTTPS . If missing, HTTP is assumed. |
No |
X-Forwarded-Host |
FQDN of the client-facing reverse proxy. | Yes |
X-Forwarded-Port |
TCP port of the client-facing reverse proxy. If missing, the following are consulted in priority order:
|
No |
X-Forwarded-BasePath |
Path to use as a base path. | No |
X-Forwarded-For |
Client IP address. If missing, any features that require a client IP address will either not work (such as IP-based authorization), or be incorrect (such as access logs). | No |
X-Forwarded-ID |
Originally-requested image identifier. Should be set only when the proxy server will change the value of the identifier in the forwarded request; i.e. when the client is asking for a different identifier than the image server ends up seeing. | No |
If the proxy cannot be configured to send the X-Forwarded
headers, the base_uri
configuration option can be used instead; set it to the URI of the client-facing reverse proxy including any base path.
In a reverse-proxying scenario, consider disabling the access log, if it would be redundant.
The following example will make an instance running at http://image-server:8182/ available at http://apache-server/.
<VirtualHost *:80>
# X-Forwarded-Host will be set automatically by the web server.
RequestHeader set X-Forwarded-Proto HTTP
RequestHeader set X-Forwarded-Port 80
RequestHeader set X-Forwarded-BasePath /
ServerName apache-server
AllowEncodedSlashes NoDecode
ProxyPassReverseCookiePath / /
ErrorLog logs/image-error.log
CustomLog logs/image-access.log combined
ProxyPass / http://image-server:8182/ nocanon
ProxyPassReverse / http://image-server:8182/
ProxyPassReverseCookieDomain image-server:8182 apache-server
ProxyPreserveHost on
</VirtualHost>
The following example will make an instance running at http://image-server:8182/ available at http://nginx-server/.
location / {
if ($request_uri ~* "/(.*)") {
proxy_pass http://image-server:8182/$1;
}
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-BasePath /;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect http://image-server:8182/ /;
}
Galia supports TLS connections over HTTPS, configurable via the https.*
keys in the configuration file. The general process for getting this working is to add a signed X.509 certificate to either a Java KeyStore (JKS) or PKCS#12 key store, and then refer to the key store file with the https.key_store_path
configuration option.