Bonjour, Habr. Pour les futurs étudiants du cours «Highload Architect» , nous avons préparé une traduction du matériel.
Nous vous invitons également à un webinaire ouvert sur le thÚme «La réplication en tant que modÚle de mise à l'échelle horizontale du stockage» . Dans la leçon, les participants, avec un expert, démonteront la réplication - l'une des techniques de mise à l'échelle de la base de données, discuteront de la signification et de son objectif, examineront les avantages et les inconvénients des différents types de réplication.
L'avantage des microservices en Java est qu'ils peuvent ĂȘtre utilisĂ©s pour crĂ©er des systĂšmes volumineux et complexes Ă partir de nombreux composants indĂ©pendants. Au lieu d'une seule application, vous vous retrouvez avec plusieurs widgets ou services. Les composants peuvent ĂȘtre testĂ©s, dĂ©ployĂ©s et maintenus indĂ©pendamment les uns des autres. Donc, si vous enlevez une brique, le bĂątiment ne s'effondrera pas complĂštement.
. 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- .