Horizontal scaling
Introduction ¶
The print has a state containing the job queue and each job's state. To enable horizontal scaling, these states must be persisted.
Solution ¶
  MapFish-Print's horizontal scaling solution is based on storing states in a database, for example
  PostgreSQL. To enable this mode, the file
  mapfish-spring-application-context-override-db.xml must be copied to
  mapfish-spring-application-context-override.xml and database connection parameters must be
  configured (see below).
The database connection must be configured with the following Java system properties:
- db.host: The database server host name
- db.port: The database server port (defaults to- 5432)
- db.username: The username to connect to the database
- db.password: The password to connect to the database
- db.name: The name of the database
- db.schema: The schema to use (defaults to- public)
  The schema must exist, and the necessary tables are created automatically (print_accountings,
  print_job_results, print_job_statuses)
Database polling can be tuned with these two environment variables:
- 
    PRINT_CANCEL_OLD_POLL_INTERVAL: How often in seconds the DB is polled for jobs to be canceled (default=60s)
- 
    PRINT_POLL_INTERVAL: How often in seconds the DB is polled for new jobs (default=0.5s)
Existing MapFish-Print Packages ¶
Existing MapFish-Print distribution packages may already contain functionality to ease the setup of horizontal scaling. For example, if you use the Docker image https://hub.docker.com/r/camptocamp/mapfish_print), you do not need to manually rename the file mentioned above, and a startup script contains functionality to verify database availability before the application server is started.
Docker ¶
  In a Docker environment, the system properties should be added in the CATALINA_OPTS environment
  variable Like that: -D<property name>=<property value>.
Kubernetes ¶
In Kubernetes, you can reuse an environment variable with:
  env:
    - name: PROPERTY_VALUE
      value: test
    - name: CATALINA_OPTS
      value: -D<property name>==$(PROPERTY_VALUE)
The order is important.
Full example where we get the database credentials from a secret:
env:
  - name: PGHOST
    valueFrom:
      secretKeyRef:
        key: hostname
        name: database-credential-secret
  - name: PGPORT
    valueFrom:
      secretKeyRef:
        key: port
        name: database-credential-secret
  - name: PGUSER
    valueFrom:
      secretKeyRef:
        key: username
        name: database-credential-secret
  - name: PGPASSWORD
    valueFrom:
      secretKeyRef:
        key: password
        name: database-credential-secret
  - name: PGDATABASE
    valueFrom:
      secretKeyRef:
        key: database
        name: database-credential-secret
  - name: PGSCHEMA
    value: print
  - name: PGOPTIONS
    value: '-c statement_timeout=30000'
  - name: PRINT_POLL_INTERVAL
    value: '1'
  - name: CATALINA_OPTS
    value: >-
      -Ddb.host=$(PGHOST)
      -Ddb.port=$(PGPORT)
      -Ddb.username=$(PGUSER)
      -Ddb.password=$(PGPASSWORD)
      -Ddb.name=$(PGDATABASE)
      -Ddb.schema=$(PGSCHEMA)