Hola, Habr. Para los futuros alumnos del curso "Highload Architect" preparamos una traducción del material.
También lo invitamos a un seminario web abierto sobre el tema "La replicación como patrón de escalamiento de almacenamiento horizontal" . En la lección, los participantes, junto con un experto, desensamblarán la replicación, una de las técnicas de escalado de la base de datos, discutirán el significado y su propósito, considerarán las ventajas y desventajas de varios tipos de replicación.
Lo mejor de los microservicios en Java es que se pueden usar para construir sistemas grandes y complejos a partir de muchos componentes independientes. En lugar de una sola aplicación, terminas con múltiples widgets o servicios. Los componentes se pueden probar, implementar y mantener de forma independiente entre sí. Entonces, si quita un ladrillo, el edificio no colapsará por completo.
. 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- .
« ».