日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring,Reactor和ElasticSearch:使用伪造的测试数据进行标记

發布時間:2023/12/3 javascript 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring,Reactor和ElasticSearch:使用伪造的测试数据进行标记 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在上一篇文章中,我們創建了一個從ElasticSearch的API到Reactor的Mono的簡單適配器,如下所示:

import reactor.core.publisher.Mono;private Mono indexDoc(Doc doc) {//... }

現在,我們希望以受控的并發級別運行此方法數百萬次。 基本上,我們想看看索引代碼在負載下的行為,對其進行基準測試。

用jFairy偽造數據

首先,我們需要一些美觀的測試數據。 為此,我們將使用方便的jFairy庫。 我們將索引的文檔是一個簡單的POJO:

@Value class Doc {private final String username;private final String json; }

生成邏輯包裝在Java類中:

import io.codearte.jfairy.Fairy; import io.codearte.jfairy.producer.person.Address; import io.codearte.jfairy.producer.person.Person; import org.apache.commons.lang3.RandomUtils;@Component class PersonGenerator {private final ObjectMapper objectMapper;private final Fairy fairy;private Doc generate() {Person person = fairy.person();final String username = person.getUsername() + RandomUtils.nextInt(1_000_000, 9_000_000);final ImmutableMap<String, Object> map = ImmutableMap.<String, Object>builder().put("address", toMap(person.getAddress())).put("firstName", person.getFirstName()).put("middleName", person.getMiddleName()).put("lastName", person.getLastName()).put("email", person.getEmail()).put("companyEmail", person.getCompanyEmail()).put("username", username).put("password", person.getPassword()).put("sex", person.getSex()).put("telephoneNumber", person.getTelephoneNumber()).put("dateOfBirth", person.getDateOfBirth()).put("company", person.getCompany()).put("nationalIdentityCardNumber", person.getNationalIdentityCardNumber()).put("nationalIdentificationNumber", person.getNationalIdentificationNumber()).put("passportNumber", person.getPassportNumber()).build();final String json = objectMapper.writeValueAsString(map);return new Doc(username, json);}private ImmutableMap<String, Object> toMap(Address address) {return ImmutableMap.<String, Object>builder().put("street", address.getStreet()).put("streetNumber", address.getStreetNumber()).put("apartmentNumber", address.getApartmentNumber()).put("postalCode", address.getPostalCode()).put("city", address.getCity()).put("lines", Arrays.asList(address.getAddressLine1(), address.getAddressLine2())).build();}}

相當無聊的代碼實際上確實很酷。 每次運行它時,它都會生成隨機但合理的JSON,如下所示:

{"address": {"street": "Ford Street","streetNumber": "32","apartmentNumber": "","postalCode": "63913","city": "San Francisco","lines": ["32 Ford Street","San Francisco 63913"]},"firstName": "Evelyn","middleName": "","lastName": "Pittman","email": "pittman@mail.com","companyEmail": "evelyn.pittman@woodsllc.eu","username": "epittman5795354","password": "VpEfFmzG","sex": "FEMALE","telephoneNumber": "368-005-109","dateOfBirth": "1917-05-14T16:47:06.273Z","company": {"name": "Woods LLC","domain": "woodsllc.eu","email": "contact@woodsllc.eu","vatIdentificationNumber": "30-0005081","url": "http://www.woodsllc.eu"},"nationalIdentityCardNumber": "713-79-5185","nationalIdentificationNumber": "","passportNumber": "jVeyZLSt3" }

整齊! 不幸的是,沒有記錄jFairy是否是線程安全的,因此以防萬一在實際代碼中,我正在使用ThreadLocal 。 好的,所以我們只有一個文檔,但是我們需要數百萬個文檔! 使用for -loop太過時了。 您會告訴我們無限的隨機人流嗎?

import reactor.core.scheduler.Scheduler; import reactor.core.scheduler.Schedulers;private final Scheduler scheduler = Schedulers.newParallel(PersonGenerator.class.getSimpleName());Mono<Doc> generateOne() {return Mono.fromCallable(this::generate).subscribeOn(scheduler); }Flux<Doc> infinite() {return generateOne().repeat(); }

generateOne()在Mono<Doc>包裝阻塞的generate()方法。 另外, generate()在parallel Scheduler上運行。 為什么? 事實證明,jFairy在單個內核上還不夠快(很多隨機數生成,表查找等),因此我不得不并行化數據生成。 通常不應該是一個問題。 但是,當生成偽造數據的速度比接觸外部服務器的響應式應用程序慢時,它會告訴您有關基于Netty的Spring Web-flux(!)的性能。

同時調用ElasticSearch

好的,擁有無數好看的假測試數據流,我們現在要在ElasticSearch中對其進行索引。

@PostConstruct void startIndexing() {index(1_000_000, 1_000); }private void index(int count, int maxConcurrency) {personGenerator.infinite().take(count).flatMap(this::indexDocSwallowErrors, maxConcurrency).window(Duration.ofSeconds(1)).flatMap(Flux::count).subscribe(winSize -> log.debug("Got {} responses in last second", winSize)); }private Mono<IndexResponse> indexDocSwallowErrors(Doc doc) {return indexDoc(doc).doOnError(e -> log.error("Unable to index {}", doc, e)).onErrorResume(e -> Mono.empty()); }

當應用程序啟動時,它將啟動對一百萬個文檔的索引編制。 注意,告訴Reactor(它與RxJava相同)多么容易,它應該調用多達1000個對ElasticSearch的并發請求。 每秒我們計算收到的回復數:

Got 2925 responses in last second Got 2415 responses in last second Got 3336 responses in last second Got 2199 responses in last second Got 1861 responses in last second

不錯! 特別是當您考慮到有多達一千個并發HTTP請求并且我們的應用程序啟動時幾乎只有30個線程峰值(!),好吧,這是localhost <-> localhost ,有罪! 但是,我們實際上如何知道所有這些呢? 日志記錄很好,但是到了二十一世紀,我們可以做得更好! 監視將是下一批的主題。

源代碼可在react reactive-elastic-search分支中的github.com/nurkiewicz/elastic-flux中獲得。

翻譯自: https://www.javacodegeeks.com/2018/01/spring-reactor-elasticsearch-bechmarking-fake-test-data.html

總結

以上是生活随笔為你收集整理的Spring,Reactor和ElasticSearch:使用伪造的测试数据进行标记的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。