/
Artem276
/
arch
Обзор
Документация
Войти
/
Artem276
/
arch
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/test/java/org/example/domain/ShardingIntegrationTest.java
140 строк
5 KB
Nazarova Ekaterina
1 commit
29 дек 2025, 11:43
29 дек 2025, 11:43
14775dd
Код
Авторство
О чём код?
package org.example.domain; import org.example.storage.InMemoryStateRepository; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.UUID; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.mock; class ShardingIntegrationTest { private ShardRouter router; private ExchangeShard usdEurShard; private ExchangeShard btcUsdShard; @BeforeEach void setup() { usdEurShard = new ExchangeShardImpl( new Exchange(new InMemoryStateRepository()), "USD/EUR" ); btcUsdShard = new ExchangeShardImpl( new Exchange(new InMemoryStateRepository()), "BTC/USD" ); router = new ShardRouter(List.of(usdEurShard, btcUsdShard)); } @Test void testSamePairAlwaysRoutedToSameShard() { ExchangeShard shard1 = mock(ExchangeShard.class); ExchangeShard shard2 = mock(ExchangeShard.class); ExchangeShard shard3 = mock(ExchangeShard.class); ShardRouter router = new ShardRouter(List.of(shard1, shard2, shard3)); ExchangeShard first = router.shardForPair("USD/EUR"); ExchangeShard second = router.shardForPair("USD/EUR"); assertSame(first, second); } @Test void testParallelShardProcessingIsFaster() throws Exception { int shardsCount = 4; List<ExchangeShard> shards = new ArrayList<>(); for (int i = 0; i < shardsCount; i++) { shards.add(new ExchangeShardImpl( new Exchange(new InMemoryStateRepository()), "PAIR-" + i )); } ShardRouter router = new ShardRouter(shards); ExecutorService pool = Executors.newFixedThreadPool(shardsCount); long start = System.currentTimeMillis(); for (int i = 0; i < 1000; i++) { int idx = i % shardsCount; String pair = "PAIR-" + idx; pool.submit(() -> router.shardForPair(pair).login(UUID.randomUUID().toString(), 100, 0)); } pool.shutdown(); pool.awaitTermination(10, TimeUnit.SECONDS); long duration = System.currentTimeMillis() - start; System.out.println("Sharded duration = " + duration + " ms"); assertTrue(duration < 2000); // эвристика } @Test void testShardingImprovesThroughput() { int orders = 2000; // Один шард ExchangeShard singleShard = new ExchangeShardImpl( new Exchange(new InMemoryStateRepository()), "USD/EUR" ); singleShard.login("a", 1_000_000, 0); singleShard.login("b", 0, 1_000_000); long t1 = System.nanoTime(); for (int i = 0; i < orders; i++) { singleShard.placeOrder(new Order("a", "USD/EUR", OrderSide.BUY, 1, 1)); singleShard.placeOrder(new Order("b", "USD/EUR", OrderSide.SELL, 1, 1)); } long singleDuration = System.nanoTime() - t1; // Несколько шардов ExchangeShard s1 = new ExchangeShardImpl(new Exchange(new InMemoryStateRepository()), "USD/EUR"); ExchangeShard s2 = new ExchangeShardImpl(new Exchange(new InMemoryStateRepository()), "EUR/JPY"); ExchangeShard s3 = new ExchangeShardImpl(new Exchange(new InMemoryStateRepository()), "BTC/USD"); for (ExchangeShard s : List.of(s1, s2, s3)) { s.login("a", 1_000_000, 0); s.login("b", 0, 1_000_000); } ShardRouter multiRouter = new ShardRouter(List.of(s1, s2, s3)); String[] pairs = {"USD/EUR", "EUR/JPY", "BTC/USD"}; long t2 = System.nanoTime(); for (int i = 0; i < orders; i++) { String p = pairs[i % pairs.length]; multiRouter.shardForPair(p).placeOrder(new Order("a", p, OrderSide.BUY, 1, 1)); multiRouter.shardForPair(p).placeOrder(new Order("b", p, OrderSide.SELL, 1, 1)); } long multiDuration = System.nanoTime() - t2; System.out.println("Single shard: " + singleDuration / 1_000_000 + " ms"); System.out.println("Multi shard: " + multiDuration / 1_000_000 + " ms"); assertTrue( multiDuration < singleDuration, "Шардирование должно уменьшать общее время обработки" ); } }