Running the Proxy

This page describes how to start, stop, and manage the Axon Server Proxy.

Starting the proxy

Running the jar

Start the proxy using the Java runtime:

java -jar axon-server-proxy.jar

The proxy will look for proxy.properties in the current working directory. Configuration can also be provided via environment variables. There are no command-line property overrides.

Set JVM options

java -Xmx512m -Xms256m -jar axon-server-proxy.jar

Custom logging configuration

By default the proxy writes colorized, timestamped output to the console. To use a custom Logback configuration, either place a logback.xml file in the working directory (detected automatically at startup) or specify the path explicitly:

java -Dlogback.configurationFile=/etc/axon-proxy/logback.xml -jar axon-server-proxy.jar

See Logging configuration for details on the logback.xml format.

Running the native binary

Start the native executable:

./axon-server-proxy

The native binary reads proxy.properties from the working directory and respects the same environment variables as the JAR. JVM options such as -Xmx do not apply to the native binary.

Running as a service

Systemd (Linux)

Create a systemd service file at /etc/systemd/system/axon-proxy.service:

[Unit]
Description=Axon Server Proxy
After=network.target

[Service]
Type=simple
User=axonproxy
WorkingDirectory=/opt/axon-proxy
ExecStart=/usr/bin/java -jar /opt/axon-proxy/axon-server-proxy.jar
Restart=on-failure
RestartSec=10

# Security
NoNewPrivileges=true
PrivateTmp=true

# Logging
StandardOutput=journal
StandardError=journal
SyslogIdentifier=axon-proxy

[Install]
WantedBy=multi-user.target

Enable and start the service:

sudo systemctl daemon-reload
sudo systemctl enable axon-proxy
sudo systemctl start axon-proxy

Check status:

sudo systemctl status axon-proxy

View logs:

sudo journalctl -u axon-proxy -f

Docker

Create a Dockerfile:

FROM eclipse-temurin:21-jre-alpine

# Create app directory
WORKDIR /app

# Copy the JAR
COPY axon-server-proxy.jar .
COPY proxy.properties .

# Expose ports
EXPOSE 8124 8080

# Run the application
ENTRYPOINT ["java", "-jar", "axon-server-proxy.jar"]

Build and run:

docker build -t axon-server-proxy .

docker run -d \
  --name axon-proxy \
  -p 8124:8124 \
  -p 8080:8080 \
  -v /path/to/proxy.properties:/app/proxy.properties:ro \
  axon-server-proxy

Docker Compose

Create a docker-compose.yml:

version: '3.8'

services:
  axon-proxy:
    image: axon-server-proxy:latest
    ports:
      - "8124:8124"
      - "8080:8080"
    volumes:
      - ./proxy.properties:/app/proxy.properties:ro
      - ./logs:/app/logs
    environment:
      - PROXY_SERVERS=axonserver1:8124,axonserver2:8124
      - PROXY_PORT=8124
    restart: unless-stopped

Start with:

docker-compose up -d

Kubernetes

Create a deployment:

apiVersion: v1
kind: ConfigMap
metadata:
  name: axon-proxy-config
data:
  proxy.properties: |
    proxy.servers=axonserver-headless:8124
    proxy.port=8124
    proxy.maxMessageSize=10MB
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: axon-proxy
spec:
  replicas: 2
  selector:
    matchLabels:
      app: axon-proxy
  template:
    metadata:
      labels:
        app: axon-proxy
    spec:
      containers:
      - name: axon-proxy
        image: axon-server-proxy:latest
        ports:
        - containerPort: 8124
          name: grpc
        - containerPort: 8080
          name: http
        volumeMounts:
        - name: config
          mountPath: /app/proxy.properties
          subPath: proxy.properties
        livenessProbe:
          httpGet:
            path: /health/liveness
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /health/readiness
            port: 8080
          initialDelaySeconds: 10
          periodSeconds: 5
      volumes:
      - name: config
        configMap:
          name: axon-proxy-config
---
apiVersion: v1
kind: Service
metadata:
  name: axon-proxy
spec:
  selector:
    app: axon-proxy
  ports:
  - name: grpc
    port: 8124
    targetPort: 8124
  - name: http
    port: 8080
    targetPort: 8080
  type: LoadBalancer

Apply the configuration:

kubectl apply -f axon-proxy-deployment.yaml

Verifying the proxy is running

Check health endpoint

curl http://localhost:8080/health

Expected response:

{
  "components": {
    "proxyServer": {"status": "UP"},
    "channelFactory": {"status": "UP"}
  },
  "status": "UP"
}

Check connections

curl http://localhost:8080/connections

This shows active client connections to the proxy.

Test with an application

Configure an Axon Framework application to connect to the proxy:

axon.axonserver.servers=localhost:8124

Start the application and verify it connects successfully.

Stopping the proxy

Graceful shutdown

Send a SIGTERM signal to allow graceful shutdown:

# If running in foreground, press Ctrl+C

# If running in background
kill <pid>

The proxy will:

  1. Stop accepting new connections

  2. Allow existing operations to complete

  3. Close connections gracefully

  4. Shut down within the configured proxy.disconnectTimeout

Force stop

If the proxy doesn’t stop gracefully:

kill -9 <pid>

Systemd service

sudo systemctl stop axon-proxy

Docker

docker stop axon-proxy

Kubernetes

kubectl delete deployment axon-proxy

Monitoring during operation

While the proxy is running, monitor it using:

Restart and reload

Configuration changes

Configuration changes require a restart:

sudo systemctl restart axon-proxy

Multiple instances

You can run multiple proxy instances for high availability:

  • Each instance connects to the same Axon Server cluster

  • Use a load balancer to distribute connections

  • Applications see a single endpoint

Load balancer configuration (HAProxy example):

frontend axon_proxy
    bind *:8124
    mode tcp
    default_backend axon_proxy_servers

backend axon_proxy_servers
    mode tcp
    balance roundrobin
    server proxy1 proxy1.local:8124 check
    server proxy2 proxy2.local:8124 check
    server proxy3 proxy3.local:8124 check

Performance tuning

JVM settings (.jar only)

For high-throughput scenarios when running the .jar, JVM heap and GC settings can be tuned:

java -Xmx2g -Xms2g \
  -XX:+UseG1GC \
  -XX:MaxGCPauseMillis=200 \
  -jar axon-server-proxy.jar
JVM options such as -Xmx do not apply to the native binary. The native binary manages its own memory and does not use a JVM heap.

File descriptors

Ensure sufficient file descriptors are available (Linux):

# Check current limit
ulimit -n

# Set higher limit (requires root)
ulimit -n 65535

In systemd service file:

[Service]
LimitNOFILE=65535

Connection pooling

The proxy maintains connection pools to backend servers. No tuning is typically needed, but monitor:

  • Active connections via /connections

  • gRPC channel state

  • Memory usage