Skip to content

Getting Started

This guide walks you through adding CoSky service discovery and configuration management to a Spring Cloud application. By the end, your application will register with a Redis-backed service discovery, load its configuration from CoSky, and be ready for production traffic.

Overview

You will build a Spring Boot microservice that:

  • Loads configuration from Redis via the CoSky config starter
  • Registers itself as a service instance on startup
  • Renewing its registration via periodic heartbeat
  • Can discover other services through the CoSky discovery client
mermaid
%%{init: {'theme':'dark', 'themeVariables': {'primaryColor':'#2d333b','primaryBorderColor':'#6d5dfc','primaryTextColor':'#e6edf3','lineColor':'#8b949e','secondaryColor':'#161b22','tertiaryColor':'#161b22'}}}%%
graph LR
    subgraph YourApp["Your Spring Boot App"]
        style YourApp fill:#161b22,stroke:#30363d,color:#e6edf3
        MAIN["main()"] --> BOOT["@SpringBootApplication"]
        BOOT --> CONFIG["Config Starter<br>loads from Redis"]
        BOOT --> DISC["Discovery Starter<br>registers to Redis"]
    end

    subgraph Infra["Infrastructure"]
        style Infra fill:#161b22,stroke:#30363d,color:#e6edf3
        REDIS[("Redis")]
    end

    CONFIG --> REDIS
    DISC --> REDIS

    style MAIN fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style BOOT fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style CONFIG fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style DISC fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style REDIS fill:#2d333b,stroke:#6d5dfc,color:#e6edf3

Prerequisites

RequirementVersionPurposeNotes
Java17+JVM runtimeCoSky uses JVM 17 toolchain (build.gradle.kts:93)
Redis5.0+Backend storage for services and configsStandalone or cluster mode
Gradle or MavenAnyBuild toolKotlin DSL shown for Gradle
Spring Boot3.xApplication frameworkSpring Cloud compatible

Quick Start

Step 1: Add Dependencies

Gradle (Kotlin DSL)

kotlin
val coskyVersion = "5.5.8"

dependencies {
    implementation("me.ahoo.cosky:spring-cloud-starter-cosky-config:${coskyVersion}")
    implementation("me.ahoo.cosky:spring-cloud-starter-cosky-discovery:${coskyVersion}")
    implementation("org.springframework.cloud:spring-cloud-starter-loadbalancer:3.0.3")
}

Maven

xml
<properties>
    <cosky.version>5.5.8</cosky.version>
</properties>
<dependencies>
    <dependency>
        <groupId>me.ahoo.cosky</groupId>
        <artifactId>spring-cloud-starter-cosky-config</artifactId>
        <version>${cosky.version}</version>
    </dependency>
    <dependency>
        <groupId>me.ahoo.cosky</groupId>
        <artifactId>spring-cloud-starter-cosky-discovery</artifactId>
        <version>${cosky.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        <version>3.0.3</version>
    </dependency>
</dependencies>

Current version defined in gradle.properties:14.

Step 2: Configure Bootstrap

Create src/main/resources/bootstrap.yaml:

yaml
spring:
  application:
    name: ${service.name:my-service}
  data:
    redis:
      url: redis://localhost:6379
  cloud:
    cosky:
      namespace: ${cosky.namespace:cosky-{default}}
      config:
        config-id: ${spring.application.name}.yaml
    service-registry:
      auto-registration:
        enabled: ${cosky.auto-registry:true}
logging:
  file:
    name: logs/${spring.application.name}.log
PropertyDefaultDescription
spring.data.redis.url(required)Redis connection URL
spring.cloud.cosky.namespacecosky-{default}Namespace for service/config isolation (CoSkyProperties.kt:30)
spring.cloud.cosky.config.config-id${spring.application.name}.yamlConfig file ID to load (CoSkyConfigAutoConfiguration.kt:48)
spring.cloud.service-registry.auto-registration.enabledtrueAuto-register service on startup
spring.cloud.cosky.config.file-extensionyamlDefault file extension for config lookup (CoSkyConfigProperties.kt:27)

Source: examples/cosky-service-provider/src/main/resources/bootstrap.yaml

Step 3: Create the Main Class

kotlin
package com.example.myservice

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication

@SpringBootApplication
class MyServiceApplication

fun main(args: Array<String>) {
    runApplication<MyServiceApplication>(*args)
}

That's it. CoSky's auto-configuration handles everything else. When the application starts:

  1. CoSkyAutoConfiguration sets the namespace context from your properties (CoSkyAutoConfiguration.kt:33)
  2. CoSkyConfigBootstrapConfiguration loads your config from Redis into the Spring Environment (CoSkyConfigBootstrapConfiguration.kt:28)
  3. CoSkyDiscoveryAutoConfiguration auto-registers your service instance (CoSkyDiscoveryAutoConfiguration.kt:42)

Startup Flow

mermaid
%%{init: {'theme':'dark', 'themeVariables': {'primaryColor':'#2d333b','primaryBorderColor':'#6d5dfc','primaryTextColor':'#e6edf3','lineColor':'#8b949e','secondaryColor':'#161b22','tertiaryColor':'#161b22'}}}%%
sequenceDiagram
    autonumber
    participant Boot as Spring Boot
    participant Auto as CoSkyAutoConfiguration
    participant PSL as CoSkyPropertySourceLocator
    participant CS as ConfigService
    participant Redis as Redis
    participant Reg as CoSkyServiceRegistry
    participant Renew as RenewInstanceService

    Note over Boot,Renew: Bootstrap Phase
    Boot->>Auto: load CoSkyAutoConfiguration
    Auto->>Auto: set namespace on NamespacedContext

    Boot->>PSL: locate(environment)
    PSL->>CS: getConfig(namespace, configId)
    CS->>Redis: GET config data
    Redis-->>CS: Config JSON
    CS-->>PSL: Config object
    PSL-->>Boot: inject PropertySource into Environment

    Note over Boot,Renew: Application Context Refresh
    Boot->>Boot: initialize all beans

    Note over Boot,Renew: Service Registration
    Boot->>Reg: ApplicationStartedEvent -> register()
    Reg->>Redis: Lua script: register instance
    Redis-->>Reg: OK
    Reg->>Renew: start heartbeat scheduler
    Renew->>Redis: periodic renew() every 10s

Architecture of the Starters

mermaid
%%{init: {'theme':'dark', 'themeVariables': {'primaryColor':'#2d333b','primaryBorderColor':'#6d5dfc','primaryTextColor':'#e6edf3','lineColor':'#8b949e','secondaryColor':'#161b22','tertiaryColor':'#161b22'}}}%%
graph TB
    subgraph ConfigStarter["Config Starter"]
        style ConfigStarter fill:#161b22,stroke:#30363d,color:#e6edf3
        CB["CoSkyConfigBootstrapConfiguration"] --> CA["CoSkyConfigAutoConfiguration"]
        CA --> RCS["RedisConfigService"]
        CA --> CRCS["RedisConsistencyConfigService<br>(cached, 256M+ ops/s)"]
        CA --> CR["CoSkyConfigRefresher<br>(real-time refresh via PubSub)"]
        CB --> PSL["CoSkyPropertySourceLocator"]
    end

    subgraph DiscoveryStarter["Discovery Starter"]
        style DiscoveryStarter fill:#161b22,stroke:#30363d,color:#e6edf3
        DA["CoSkyDiscoveryAutoConfiguration"] --> RSD["RedisServiceDiscovery"]
        DA --> CRSD["ConsistencyRedisServiceDiscovery<br>(cached, 76M+ ops/s)"]
        DA --> LB["BinaryWeightRandomLoadBalancer"]
        DA --> SS["RedisServiceStatistic"]
    end

    subgraph Shared["Shared (cosky-spring-cloud-core)"]
        style Shared fill:#161b22,stroke:#30363d,color:#e6edf3
        PROPS["CoSkyProperties<br>(namespace, enabled)"]
        AUTO["CoSkyAutoConfiguration"]
    end

    AUTO --> CB
    AUTO --> DA
    PROPS --> AUTO

    RCS --> REDIS[("Redis")]
    RSD --> REDIS
    CRCS --> REDIS
    CRSD --> REDIS

    style CB fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style CA fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style RCS fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style CRCS fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style CR fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style PSL fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style DA fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style RSD fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style CRSD fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style LB fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style SS fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style PROPS fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style AUTO fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style REDIS fill:#2d333b,stroke:#6d5dfc,color:#e6edf3

Verify It Works

  1. Start Redis locally:

    bash
    docker run -d -p 6379:6379 redis:7
  2. Run your Spring Boot application:

    bash
    ./gradlew bootRun
  3. Check registered services in Redis:

    bash
    redis-cli SMEMBERS "cosky-{default}:svc_idx"
  4. You should see your service name in the output, confirming registration succeeded.

Next Steps

TopicDescriptionLink
Installation DetailsMaven, Gradle, Docker, K8s setupInstallation
Architecture Deep DiveModule structure, Redis key design, event systemArchitecture
Configuration ManagementConfig CRUD, versioning, rollback, import/exportConfiguration Service
Service DiscoveryRegistration, heartbeat, discovery, load balancingService Registry
REST API ServerHTTP endpoints, dashboard, RBACREST API

References

Released under the Apache License 2.0.