Hallo Habr. Für zukünftige Studenten des Kurses "Highload Architect" haben wir eine Übersetzung des Materials vorbereitet.
Wir laden Sie auch zu einem offenen Webinar zum Thema "Replikation als Muster der horizontalen Speicherskalierung" ein . In der Lektion werden die Teilnehmer zusammen mit einem Experten die Replikation zerlegen - eine der Datenbankskalierungstechniken, die Bedeutung und den Zweck erörtern, die Vor- und Nachteile verschiedener Replikationstypen berücksichtigen.
Das Tolle an Microservices in Java ist, dass sie zum Erstellen großer und komplexer Systeme aus vielen unabhängigen Komponenten verwendet werden können. Anstelle einer einzelnen App stehen Ihnen mehrere Widgets oder Dienste zur Verfügung. Komponenten können unabhängig voneinander getestet, bereitgestellt und gewartet werden. Wenn Sie also einen Stein entfernen, wird das Gebäude nicht vollständig einstürzen.
. Java, , . , .
Spring Boot — Java. , Spring Boot-.
:
External-service ( ): "" , HTTP.
Facade-service (): , external-service . .
Java 8
Jmeter 5.3
Java IDE
Gradle 6.6.1
, , , .
External service
Spring Initializer. , :
@RestController
public class ExternalController {
@GetMapping(“/external-data/{time}”)
public ExternalData getData(@PathVariable Long time){
try {
Thread.sleep(time);
} catch (InterruptedException e) {
// do nothing
}
return new ExternalData(time);
}
}
ExternalServiceApplication
. https://localhost:8543/external-data/300 .
Facade service
Spring Initializer. : ExternalService
ExternalServiceClient
.
ExternalService
External Service externalServiceClient
.
@Service
public class ExternalService {
@Autowired
private ExternalServiceClient externalServiceClient;
public ResultData load(List<Long> times) {
Long start = System.currentTimeMillis();
LongSummaryStatistics statistics = times
.parallelStream()
.map(time -> externalServiceClient.load(time).getTime())
.collect(Collectors.summarizingLong(Long::longValue));
Long end = System.currentTimeMillis();
return new ResultData(statistics, (end — start));
}
}
external service ExternalServiceClient
openfeign. HTTP- OKHttp :
@FeignClient( name = “external-service”, url = “${external-service.url}”, configuration = ServiceConfiguration.class) public interface ExternalServiceClient { @RequestMapping( method = RequestMethod.GET, value = “/external- data/{time}”, consumes = “application/json”) Data load(@PathVariable(“time”) Long time); }
FacadeServiceApplication
http://localhost:8080/data/1,500,920,20000.
:
{
“statistics”: {
“count”: 4,
“sum”: 1621,
“min”: 1,
“max”: 920,
“average”: 405.25
},
“spentTime”: 1183
}
Jmeter 5.3.1 perfomance-testing.jmx .
:
URL-: http://localhost:8080/data/1,500,920,200
Jmeter .
Jmeter
. , ExternalService
parallelStream()
. Stream API ForkJoinPool
. ForkJoinPool
. . - . , ForkJoinPool
1000.
-Djava.util.concurrent.ForkJoinPool.common.parallelism=1000
Jmeter .
Jmeter
, (throughput) 6 26 . . , . (average time) 9 . , HTTP-. :
@Configuration
public class ServiceConfiguration {
…
@Bean
public OkHttpClient client()
throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException, NoSuchProviderException {
…
okhttp3.OkHttpClient client = new okhttp3.OkHttpClient.Builder()
.sslSocketFactory(sslContext.getSocketFactory(), trustManager)
.hostnameVerifier((s, sslSession) -> true)
.connectionPool(new ConnectionPool(2000, 10, TimeUnit.SECONDS))
.build();
OkHttpClient okHttpClient = new OkHttpClient(client);
return okHttpClient;
}
, 2000 HTTP- 10 .
Jmeter
: 26 71 .
10 : 6 71 / , , (maximum time) 7 . , UI.
. , Tomcat application.properties
:
server.tomcat.accept-count=80
server.tomcat.max-connections=80
server.tomcat.max-threads=160
"Connection refused" ( ) , 160.
Jmeter
71 94 . 29%. "Connection refused".
15 6 94 / - . , , AWS. , . — , .
Java-, . , . Java- .
« ».