SHA256
Сервер: начать перенос runtime БД на PostgreSQL
This commit is contained in:
@@ -1,116 +1,96 @@
|
||||
# Интеграция синхронизации `shine_users` в основной сервер
|
||||
# Интеграция Solana users sync в сервер SHiNE
|
||||
|
||||
Этот документ описывает, что нужно для встраивания Solana sync-модуля пользовательских PDA в основной SHiNE-server.
|
||||
Этот документ фиксирует серверную конфигурацию модуля синхронизации `shine_users`
|
||||
и базовую инициализацию новой PostgreSQL runtime-схемы сервера.
|
||||
|
||||
Основной архитектурный документ:
|
||||
## Что уже есть
|
||||
|
||||
- [docs/Solana/SOLANA_USERS_SYNC_MODULE_DESIGN.md](/home/ai/work/SHiNE/SHiNE-server-sha256/SHiNE-product/docs/Solana/SOLANA_USERS_SYNC_MODULE_DESIGN.md)
|
||||
|
||||
## Что уже готово
|
||||
|
||||
Отдельный модуль `sync-solana` уже умеет:
|
||||
|
||||
- подключаться к Solana RPC и WebSocket;
|
||||
- вычислять `users_economy_config_pda`;
|
||||
- хранить checkpoint синхронизации в PostgreSQL;
|
||||
- читать историю через `getSignaturesForAddress(users_economy_config_pda)`;
|
||||
- поддерживать realtime через websocket;
|
||||
- выполнять страховочный periodic poll раз в 5 минут;
|
||||
- хранить:
|
||||
- основной сервер запускает `SolanaUsersSyncStartupService` до продолжения startup;
|
||||
- модуль синхронизации держит актуальными таблицы:
|
||||
- `solana_sync_state`
|
||||
- `solana_sync_tx_history`
|
||||
- `solana_user_pda_current`
|
||||
- `solana_user_pda_history`
|
||||
- блокировать дальнейший startup до входа в `READY`.
|
||||
- источник истины по пользовательским PDA: `solana_user_pda_current`.
|
||||
|
||||
## Что нужно перенести в основной сервер
|
||||
## Что должно быть настроено в `application.properties`
|
||||
|
||||
Из `sync-solana` в сервер нужно перенести рабочие классы:
|
||||
|
||||
- `sync-solana/src/main/java/sync-solana/config/`
|
||||
- `sync-solana/src/main/java/sync-solana/service/`
|
||||
- `sync-solana/src/main/java/sync-solana/source/`
|
||||
- `sync-solana/src/main/java/sync-solana/source/rpc/`
|
||||
- `sync-solana/src/main/java/sync-solana/storage/postgres/`
|
||||
- `sync-solana/src/main/java/sync-solana/codec/`
|
||||
- `sync-solana/src/main/java/sync-solana/model/`
|
||||
- `sync-solana/src/main/java/sync-solana/util/`
|
||||
|
||||
`Main.java` нужен только как reference для bootstrap и как отдельный `main` в сервере уже не понадобится.
|
||||
|
||||
Рекомендуемый вариант:
|
||||
|
||||
- оформить это как отдельный Gradle submodule внутри `SHiNE-server`;
|
||||
- запускать его из server startup как lifecycle-сервис.
|
||||
|
||||
## Порядок запуска в сервере
|
||||
|
||||
При старте основного сервера последовательность должна быть такой:
|
||||
|
||||
1. прочитать общий server config;
|
||||
2. создать Solana users sync service;
|
||||
3. вызвать `start()`;
|
||||
4. вызвать `awaitReady()`;
|
||||
5. только после этого продолжать остальной startup сервера:
|
||||
- синхронизацию с другими нодами;
|
||||
- запуск WS/HTTP;
|
||||
- остальную серверную инициализацию.
|
||||
|
||||
Если Solana initial sync не дошёл до `READY`, startup сервера должен считаться неуспешным.
|
||||
|
||||
## Переменные окружения сервера
|
||||
|
||||
На сервере должны быть доступны:
|
||||
|
||||
```text
|
||||
SOLANA_RPC_URL=
|
||||
SOLANA_WS_URL=
|
||||
SOLANA_PROGRAM_ID=SHiNEPr1APdAgNBteUyBXcNovaHctpSjUu8oH2ZJdN6
|
||||
SYNC_POLL_INTERVAL_SECONDS=300
|
||||
```properties
|
||||
solana.users.sync.enabled=true
|
||||
solana.users.sync.rpcUrl=https://api.devnet.solana.com
|
||||
solana.users.sync.wsUrl=wss://api.devnet.solana.com/
|
||||
solana.users.sync.databaseUrl=jdbc:postgresql://127.0.0.1:5432/shine_server_db
|
||||
solana.users.sync.dbUser=shine_server
|
||||
solana.users.sync.dbPassword=CHANGE_ME
|
||||
solana.users.sync.pollIntervalSeconds=300
|
||||
```
|
||||
|
||||
Для PostgreSQL sync-модуль может использовать уже существующую server PostgreSQL-конфигурацию, если сервер уже предоставляет:
|
||||
Замечания:
|
||||
|
||||
- `solana.users.sync.enabled=true` обязателен, иначе сервер пропустит startup sync.
|
||||
- `solana.users.sync.databaseUrl` должен указывать на ту же PostgreSQL БД, где создана серверная runtime-схема.
|
||||
- `solana.users.sync.wsUrl` задаётся явно, автоматически из `rpcUrl` не строится.
|
||||
|
||||
## Как создать пустую PostgreSQL runtime БД
|
||||
|
||||
SQL-скрипт инициализации лежит в:
|
||||
|
||||
```text
|
||||
DATABASE_URL=
|
||||
PGUSER=
|
||||
PGPASSWORD=
|
||||
SHiNE-server/shine-server-db/src/main/resources/postgres/schema_v1.sql
|
||||
```
|
||||
|
||||
Если в сервере используется другая схема конфигов, нужно сделать адаптер на уровне server config, а не менять саму логику sync.
|
||||
Пример запуска:
|
||||
|
||||
## Логи
|
||||
```bash
|
||||
psql \
|
||||
"postgresql://shine_server:CHANGE_ME@127.0.0.1:5432/shine_server_db" \
|
||||
-f SHiNE-server/shine-server-db/src/main/resources/postgres/schema_v1.sql
|
||||
```
|
||||
|
||||
Sync-модуль должен писать в общие server logs через тот же `slf4j/logback`, что и основной сервер.
|
||||
Скрипт:
|
||||
|
||||
Минимум, который должен быть виден в логах:
|
||||
- создаёт таблицу версии схемы `db_schema_version`;
|
||||
- ставит `schema_version = 1`;
|
||||
- создаёт таблицы sync-модуля Solana users;
|
||||
- создаёт server runtime tables;
|
||||
- не создаёт legacy SQLite-таблицы `solana_users` и `direct_messages`;
|
||||
- использует `signed_messages` как единственную таблицу серверных DM.
|
||||
|
||||
- старт sync-модуля;
|
||||
- вход в `READY`;
|
||||
- realtime sync;
|
||||
- periodic poll;
|
||||
- reconnect websocket;
|
||||
- fallback на full snapshot;
|
||||
- ошибки RPC/WS/DB.
|
||||
## Как поднять PostgreSQL в Docker
|
||||
|
||||
## Что потребуется по deploy
|
||||
Шаблоны лежат в:
|
||||
|
||||
Отдельных deploy-скриптов для sync-модуля не требуется, если он встроен в основной server jar.
|
||||
```text
|
||||
deploy/postgres/docker-compose.yml.example
|
||||
deploy/postgres/.env.example
|
||||
```
|
||||
|
||||
По deploy нужно:
|
||||
Минимальная последовательность:
|
||||
|
||||
- обновить server env/override-конфиг новыми переменными `SOLANA_*` и `SYNC_POLL_INTERVAL_SECONDS`;
|
||||
- убедиться, что на сервере доступен PostgreSQL, в который модуль будет писать свои таблицы;
|
||||
- при необходимости описать новые env в документации конкретного server-контура.
|
||||
```bash
|
||||
mkdir -p /home/player/SHiNE/postgres
|
||||
cp deploy/postgres/.env.example /home/player/SHiNE/postgres/.env
|
||||
cp deploy/postgres/docker-compose.yml.example /home/player/SHiNE/postgres/docker-compose.yml
|
||||
cd /home/player/SHiNE/postgres
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
## Что ещё проверить после интеграции
|
||||
После старта контейнера:
|
||||
|
||||
После встраивания в основной сервер нужно отдельно проверить:
|
||||
```bash
|
||||
cp /path/to/SHiNE-product/application.properties ./application.properties
|
||||
# задать db.url/db.user/db.password и запустить сервер
|
||||
```
|
||||
|
||||
- startup сервера с ожиданием `awaitReady()`;
|
||||
- создание таблиц в server PostgreSQL;
|
||||
- initial sync после пустой БД;
|
||||
- restart recovery после уже существующего checkpoint;
|
||||
- realtime update через websocket;
|
||||
- periodic poll без новых транзакций;
|
||||
- fallback на full snapshot при потере history anchor.
|
||||
Сложность тут низкая:
|
||||
|
||||
- сам Docker Postgres поднимается просто;
|
||||
- сервер сам создаёт runtime schema v1, если БД пустая и в ней нет `db_schema_version`;
|
||||
- основная аккуратность нужна в паролях, bind-mount каталоге и backup;
|
||||
- для SHiNE важно не открывать `5432` наружу, только `127.0.0.1:5432`.
|
||||
|
||||
## Что пока остаётся как есть
|
||||
|
||||
- `sync_servers` сервер по-прежнему загружает из server PDA в Solana;
|
||||
- старый SQLite runtime код ещё может лежать в репозитории, но новая runtime-схема на него не должна опираться;
|
||||
- механический перенос DAO и runtime SQL на PostgreSQL делается отдельным шагом после утверждения схемы `v1`.
|
||||
|
||||
Reference in New Issue
Block a user