Public API for Team Details and Statistics

Business logic

The main purpose of this service is get functionality of teamDetails, teamStatistics, playerStatistics endpoints. Team API provide information about concrete team (participant) for mobile and web LS clients. This information can be: team details (stages and events with this team), team statistics (overall ball possession, goals scored, assists made etc.), player statictics (info about concrete players in the team: ranks of them by goals scoring, assists, red/yellow cards given etc.)

The main advantage is to load and store a full offer in memory

The client response is created only from in-memory data, it allow to avoid slow database queries and minimises response times. Responses are created in special serializer classes

OpenAPI specification

Internal models

Handle next internal models: participant, stage, season, event, region, categorise, actors. Internal models retrieved from kafka topics are written to mongodb collections and Internal cache.

Kafka

Listening five topics: team-api-events', 'team-api-participants', 'team-api-stages', 'team-api-seasons', 'team-api-regions', 'team-api-actors', 'team-api-categories'.

Mongodb

Write resulting models into five collections: participant, stage, season, event, region, actors, categories.

Startup

On application startup firstly we try to load all records from kafka topics (api-short-events, api-participants, api-stage-info, api-season). Process these records and put them into four internal caches.

Internal cache

Loaded from DB (MongoDB) and stored in ConcurrentMap. It’s thread-safety map with high throughput under high concurrency.

CDN cache

Cache lifetime is set in application config file 'cache-control:max-age-seconds':

code-410: 300

details: 10

teamstat: 20

teamsquad: 20

playersstat: 10

nextevent: 10

teamform: 10

leaguetable: 3600

Time presented in seconds.

VM instance configuration recommendations

CPU: 2 cores, RAM: 2 Gb, HDD: 20 Gb

Metrics

Grafana dashboard: 'Team API prometheus monitoring'.

There are 3 types of metrics: GAUGE, COUNTER, TIMER (contains 2 dimensions: count and sum)

Custom metrics

cache_size (GAUGE)

cache capacity with internal Model. Tags: name

invalid_model_total (COUNTER)

total count of invalid records(models) received from mongo/kafka. Tags: model

model_updates_total (COUNTER)

total count of handled messages, received from kafka. Tags: model, operation

Predefined metrics

jetty.*

metrics show the state of jetty thread pool.

http_server_requests_seconds.*

displays how the api is used. Tags: exception, method, outcome, status, uri

spring_kafka_listener_seconds.*

displays information on kafka connection and consumption. Tags: exception, name, result

Test REST API Endpoints

Health

Default Actuator endpoint with custom data that specify is caches was initial loaded.

Request example
$ http GET 'http://example.com:8088/actuator/health'
Response example
HTTP/1.1 200 OK
Content-Type: application/vnd.spring-boot.actuator.v3+json
Content-Length: 302

{
  "status" : "UP",
  "components" : {
    "diskSpace" : {
      "status" : "UP",
      "details" : {
        "total" : 1023599964160,
        "free" : 179837513728,
        "threshold" : 10485760,
        "exists" : true
      }
    },
    "ping" : {
      "status" : "UP"
    }
  }
}

Logging

Go to

GET /actuator/loggers

to see all log levels currently in use.

To change log level in runtime for needed class, send.

POST /actuator/loggers/com.livescore.teams.api.team.TeamController
Content-Type: application/json
Host: example.com:8087

{"configuredLevel": "DEBUG"}

Load testing scenarios

Scaling policy recommendations

If the CPU load is more than 70%, then we launch the second node