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

To store the state we use a PostgreSQL database, the database connection should 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 should exist, and the necessary tables are created automatically (print_accountings, print_job_results, print_job_statuses). In this mode, the container will wait for the database to be reachable before actually starting the tomcat server.

The DB 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)
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)