ΠΡΠΈΠ²Π΅Ρ, Π₯Π°Π±Ρ! ΠΡΠΎ ΡΠΈΠΊΠ²Π΅Π» ΠΌΠΎΠ΅ΠΉ
ΠΡ Π΄Π΅Π»Π°Π΅ΠΌ ΡΠΈΠ½Ρ Π΄Π°Π½Π½ΡΡ Π΄Π»Ρ ΠΊΡΡΠΏΠ½ΠΎΠΉ ΡΠ΅Π΄Π΅ΡΠ°Π»ΡΠ½ΠΎΠΉ ΠΊΠΎΠΌΠΏΠ°Π½ΠΈΠΈ. Π Π°Π·Π»ΠΈΡΠ½ΡΠ΅ ΡΠΎΡΠΌΠ°ΡΡ Π·Π°ΠΏΡΠΎΡΠΎΠ², ΠΏΡΠ΅ΠΎΠ±ΡΠ°Π·ΠΎΠ²Π°Π½ΠΈΡ, Π·Π°ΠΌΡΡΠ»ΠΎΠ²Π°ΡΠ°Ρ ΠΌΠ°ΡΡΡΡΡΠΈΠ·Π°ΡΠΈΡ. ΠΠ»Ρ ΡΠ΅ΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ Π½ΡΠΆΠ½ΠΎ ΠΎΡΠΏΡΠ°Π²Π»ΡΡΡ ΠΌΠ½ΠΎΠ³ΠΎ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ Π² ΠΎΡΠ΅ΡΠ΅Π΄ΠΈ. ΠΡΡΡΠ½ΡΡ β Π±ΠΎΠ»Ρ, Ρ ΠΊΠΎΡΠΎΡΠΎΠΉ ΡΠΏΡΠ°Π²ΠΈΡΡΡ Π½Π΅ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΠΌΠ°Π½ΡΠ°Π»ΡΡΠΈΠΊ.
ΠΠ²Π΅Π΄Π΅Π½ΠΈΠ΅
Π₯ΠΎΡΡ Ρ ΡΡΠΎΠΉ Π±ΠΎΠ»ΡΡ ΠΏΡΠΈΡ ΠΎΠ΄ΠΈΠ»ΠΎΡΡ ΠΌΠΈΡΠΈΡΡΡΡ Π½Π° ΠΏΠ΅ΡΠ²ΡΡ ΠΏΠΎΡΠ°Ρ . ΠΡΡ Π½Π°ΡΠ°Π»ΠΎΡΡ Ρ RFHUtil. ΠΠΎΡΠ½ΡΠΉ, Π½ΠΎ Π½Π΅ΡΠ΄ΠΎΠ±Π½ΡΠΉ ΠΈ ΡΡΡΠ°ΡΠ½ΡΠΉ: ΠΡ Π²Ρ Π·Π½Π°Π΅ΡΠ΅ Π ΡΡΠ°.
ΠΠ΅Π·Π°ΠΌΠ΅Π½ΠΈΠΌΡΠΉ Π² Π½Π΅ΠΊΠΎΡΠΎΡΡΡ
ΡΠ»ΡΡΠ°ΡΡ
, Π½ΠΎ ΡΡΠ°Π±ΠΈΠ»ΡΠ½ΠΎ ΠΏΠ°Π΄Π°ΡΡΠΈΠΉ Π² ΡΠ»ΡΡΠ°Π΅ Π°ΠΊΡΠΈΠ²Π½ΠΎΠ³ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ.
Π£Π΄ΠΎΠ±Π½ΠΎΠ΅ ΡΠ΅ΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ Ρ Π½ΠΈΠΌ Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ.
Π‘ JMeter Π²ΡΡ ΡΡΠ°Π»ΠΎ ΠΏΡΠΎΡΠ΅. ΠΠΎΡΠ»Π΅ ΠΏΠ΅ΡΠ²ΠΎΠ³ΠΎ ΡΡΠ°ΠΏΠ° Ρ ΠΎΡΠ²ΠΎΠ΅Π½ΠΈΠ΅ΠΌ ΠΈ ΠΏΡΠΈΠ²ΡΠΊΠ°Π½ΠΈΠ΅ΠΌ Π·Π°Π±ΡΠ΅Π·ΠΆΠΈΠ»Π° Π½Π°Π΄Π΅ΠΆΠ΄Π° Π½Π° ΡΡΠ°ΡΡΠ»ΠΈΠ²ΠΎΠ΅ ΡΠ΅ΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅.
ΠΠΊΡΠΈΠ²Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ ΡΡΠΌΠΏΠ»Π΅ΡΡ JMS Publisher ΠΈ JMS Subscriber. Π ΠΎΡΠ»ΠΈΡΠΈΠΈ ΠΎΡ JMS Point-to-Point, ΡΡΠ° ΠΏΠ°ΡΠΎΡΠΊΠ° ΠΏΠΎΠΊΠ°Π·Π°Π»Π°ΡΡ ΡΠ΄ΠΎΠ±Π½Π΅Π΅ Π² ΡΠ°Π±ΠΎΡΠ΅. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Ρ Subscriber Π² JMS Selector ΠΌΠΎΠΆΠ½ΠΎ ΡΠΊΠ°Π·Π°ΡΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ, Ρ Point-to-Point β Π½Π΅Ρ (Π»ΠΈΠ±ΠΎ ΡΡΠΎΡ ΡΠΏΠΎΡΠΎΠ± Π½Π΅ ΡΠ»ΠΈΡΠΊΠΎΠΌ ΠΎΡΠ΅Π²ΠΈΠ΄Π΅Π½).
ΠΠΎΠ΄Π³ΠΎΡΠΎΠ²ΠΊΠ° ΡΡΠΌΠΏΠ»Π΅ΡΠΎΠ²
JMS Publisher
- Setup β Each Sample. Apache
ΡΠ΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡΠ΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΡΡ ΠΎΠΏΡΠΈΡ, Π΅ΡΠ»ΠΈ ΠΎΡΠ΅ΡΠ΅Π΄ΠΈ/ΡΠΎΠΏΠΈΠΊΠΈ Π·Π°Π΄Π°Π½Ρ ΡΠ΅ΡΠ΅Π· ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅. - Expiration (ms) = 120000. Π ΡΠ»ΡΡΠ°Π΅ ΡΠ±ΠΎΡ ΡΠ΅ΡΡΠΎΠ²ΡΠ΅ Π·Π°ΠΏΡΠΎΡΡ ΠΈΡΡΠ΅Π·Π½ΡΡ ΠΈΠ· ΠΎΡΠ΅ΡΠ΅Π΄ΠΈ ΡΠ΅ΡΠ΅Π· 2 ΠΌΠΈΠ½ΡΡΡ.
- Use non-persistent delivery mode? β true. IBM
ΡΡΠ²Π΅ΡΠΆΠ΄Π°Π΅Ρ , ΡΡΠΎ persistent mode ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΠ²Π°Π΅Ρ Π½Π°Π΄Π΅ΠΆΠ½ΠΎΠ΅ ΡΠΎΡ ΡΠ°Π½Π΅Π½ΠΈΠ΅ ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°Π΅ΠΌΡΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ Π² ΡΠ»ΡΡΠ°Π΅ Π²Π½Π΅Π·Π°ΠΏΠ½ΠΎΠ³ΠΎ ΡΠ±ΠΎΡ. Π Π±ΠΎΠ»Π΅Π΅ Π±ΡΡΡΡΡΠΉ ΠΎΠ±ΠΌΠ΅Π½ Π² non-persistent mode. ΠΠ»Ρ ΡΠ΅ΡΡΠΎΠ²ΡΡ ΡΠ΅Π»Π΅ΠΉ Π²Π°ΠΆΠ½Π΅Π΅ ΡΠΊΠΎΡΠΎΡΡΡ.
Π ΠΊΠ°ΠΆΠ΄ΠΎΠΌ Publisher Π·Π°Π΄Π°Ρ jms-ΡΠ²ΠΎΠΉΡΡΠ²ΠΎ, ΠΊΠΎΡΠΎΡΠΎΠ΅ Subscriber Π±ΡΠ΄Π΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π² JMS Selector. ΠΠ»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ Π³Π΅Π½Π΅ΡΠΈΡΡΠ΅ΡΡΡ ΡΠ»ΡΡΠ°ΠΉΠ½ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Π² ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ΅ ΡΠ΅ΡΡ-ΠΏΠ»Π°Π½Π° User Parameters:
Π’Π°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ Π±ΡΡΡ ΡΠ²Π΅ΡΠ΅Π½Π½ΡΠΌ, ΡΡΠΎ ΠΏΡΠΎΡΠΈΡΠ°Π½ΠΎ ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΠΎΠ΅ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅.
ΠΡΠΎΠ³ΠΎΠ²Π°Ρ Β«Π±ΠΎΠ»Π²Π°Π½ΠΊΠ°Β» ΠΏΡΠ΅Π΄Π²Π°ΡΠΈΡΠ΅Π»ΡΠ½ΠΎ Π½Π°ΡΡΡΠΎΠ΅Π½Π½ΠΎΠ³ΠΎ JMS Publisher:
JMS Subscriber
- Setup β Each Sample. ΠΡ Π²Ρ ΠΏΠΎΠ½ΡΠ»ΠΈ.
- Timeout (ms) = 100000. ΠΡΠ»ΠΈ Π·Π°ΠΏΡΠΎΡ Π½Π΅ ΠΏΡΠΈΡ ΠΎΠ΄ΠΈΡ Π² ΠΎΡΠ΅ΡΠ΅Π΄Ρ ΠΏΠΎΡΠ»Π΅ 100 ΡΠ΅ΠΊΡΠ½Π΄ ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΡ, Π·Π½Π°ΡΠΈΡ ΡΡΠΎ-ΡΠΎ ΠΏΠΎΡΠ»ΠΎ Π½Π΅ ΡΠ°ΠΊ.
- Stop between sample? β true.
JMS Selector β Π΄ΠΎΠ²ΠΎΠ»ΡΠ½ΠΎ ΡΠ΄ΠΎΠ±Π½Π°Ρ
ΠΠ°ΠΊ Π±ΡΡΡ Ρ ΠΊΠΈΡΠΈΠ»Π»ΠΈΡΠ΅ΠΉ Π² ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°Π΅ΠΌΡΡ
ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡΡ
. Π JMeter ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ ΠΏΠΎΡΠ»Π΅ Π²ΡΡΠΈΡΡΠ²Π°Π½ΠΈΡ ΠΎΠ½Π° ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ°Π΅ΡΡΡ ΠΊΡΠΈΠ²ΠΎ. Π§ΡΠΎΠ±Ρ ΡΡΠΎΠ³ΠΎ ΠΈΠ·Π±Π΅ΠΆΠ°ΡΡ ΠΈ Π½Π°ΡΠ»Π°ΠΆΠ΄Π°ΡΡΡΡ Π²Π΅Π»ΠΈΠΊΠΈΠΌ ΠΈ ΠΌΠΎΠ³ΡΡΠΈΠΌ Π²ΡΠ΅Π³Π΄Π° ΠΈ Π²Π΅Π·Π΄Π΅, Π½ΡΠΆΠ½ΠΎ:
- ΠΠΎΠ±Π°Π²ΠΈΡΡ Π² Β«Π·Π°ΠΏΡΡΠΊΠ°ΡΠΎΡΒ» JMeter Π°ΡΠ³ΡΠΌΠ΅Π½Ρ JVM:
-Dfile.encoding=UTF-8
- ΠΠΎΠ±Π°Π²ΠΈΡΡ JSR223 PostProcessor Π² Subscriber ΡΠΎ ΡΡΡΠΎΡΠΊΠΎΠΉ Π½Π° groovy:
prev.setDataEncoding("UTF-8")
ΠΠ΅ΡΠ΅Π΄Π°ΡΠ° ΡΠ΅ΠΊΡΡΠ°
Π‘Π°ΠΌΡΠΉ Π»Π΅Π½ΠΈΠ²ΡΠΉ Π²Π°ΡΠΈΠ°Π½Ρ. ΠΠΎΠ΄Ρ ΠΎΠ΄ΠΈΡ Π΄Π»Ρ ΠΎΡΠ»Π°Π΄ΠΊΠΈ ΡΠ²Π΅ΠΆΠ΅Π½Π°ΠΏΠΈΡΠ°Π½Π½ΡΡ ΡΠ΅ΡΡΠΎΠ². ΠΠΈΠ±ΠΎ Π΄Π»Ρ ΡΠ»ΡΡΠ°Π΅Π², ΠΊΠΎΠ³Π΄Π° Π½ΡΠΆΠ½ΠΎ ΠΎΡΠΏΡΠ°Π²ΠΈΡΡ Ρ ΠΎΡΡ ΡΡΠΎ-ΡΠΎ Π½Π΅Π±ΠΎΠ»ΡΡΠΎΠ΅. ΠΡΠ±ΡΠ°ΡΡ ΠΎΠΏΡΠΈΡ Message source β Textarea ΠΈ ΡΠ°Π·ΠΌΠ΅ΡΡΠΈΡΡ ΡΠ΅Π»ΠΎ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ Π² ΡΠ΅ΠΊΡΡΠΎΠ²ΠΎΠΌ Π±Π»ΠΎΠΊΠ΅:
ΠΠ΅ΡΠ΅Π΄Π°ΡΠ° ΡΠ°ΠΉΠ»Π°
Π‘Π°ΠΌΡΠΉ ΡΠ°ΡΡΡΠΉ Π²Π°ΡΠΈΠ°Π½Ρ. ΠΠΎΠ΄Ρ ΠΎΠ΄ΠΈΡ Π΄Π»Ρ Π±ΠΎΠ»ΡΡΠΈΠ½ΡΡΠ²Π° ΡΡΠ΅Π½Π°ΡΠΈΠ΅Π². ΠΡΠ±ΡΠ°ΡΡ ΠΎΠΏΡΠΈΡ Message source β From file ΠΈ ΡΠΊΠ°Π·Π°ΡΡ ΠΏΡΡΡ ΠΊ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ Π² ΠΏΠΎΠ»Π΅ File β Filename:
ΠΠ΅ΡΠ΅Π΄Π°ΡΠ° ΡΠ°ΠΉΠ»Π° Π² ΠΏΠΎΠ»Π΅ ΡΠ΅ΠΊΡΡΠ°
Π‘Π°ΠΌΡΠΉ ΡΠ½ΠΈΠ²Π΅ΡΡΠ°Π»ΡΠ½ΡΠΉ Π²Π°ΡΠΈΠ°Π½Ρ. ΠΠΎΠ΄Ρ ΠΎΠ΄ΠΈΡ Π΄Π»Ρ Π±ΠΎΠ»ΡΡΠΈΠ½ΡΡΠ²Π° ΡΡΠ΅Π½Π°ΡΠΈΠ΅Π² + ΠΌΠΎΠΆΠ΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ Π² JMS Point-to-Point, Π² ΠΊΠΎΡΠΎΡΠΎΠΌ Π½Π΅Ρ Π²ΡΠΎΡΠΎΠ³ΠΎ Π²Π°ΡΠΈΠ°Π½ΡΠ° ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ:
ΠΠ΅ΡΠ΅Π΄Π°ΡΠ° Π±Π°ΠΉΡΠΎΠ²ΠΎΠ³ΠΎ ΠΌΠ°ΡΡΠΈΠ²Π°
Π‘Π°ΠΌΡΠΉ ΡΠ»ΠΎΠΆΠ½ΡΠΉ Π²Π°ΡΠΈΠ°Π½Ρ. ΠΠΎΠ΄Ρ
ΠΎΠ΄ΠΈΡ Π΄Π»Ρ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ Π½Π΅ΠΏΠΎΠ³ΡΠ΅ΡΠΈΠΌΠΎ-ΡΠΎΡΠ½ΠΎΠΉ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠΈ Π·Π°ΠΏΡΠΎΡΠΎΠ² Π΄ΠΎ Π±Π°ΠΉΡΠ°, Π±Π΅Π· ΠΈΡΠΊΠ°ΠΆΠ΅Π½ΠΈΠΉ, ΡΠΌΡ ΠΈ ΠΏΠ΅ΡΡΡΡΠ±Π°ΡΠΈΠΈ. Π‘Π΄Π΅Π»Π°ΡΡ ΡΡΠΎ Π² Π΄Π΅ΡΠΎΠ»ΡΠ½ΠΎΠΌ JMeter Π½Π΅ ΠΏΠΎΠ»ΡΡΠΈΡΡΡ,
ΠΠΎΡΡΠΎΠΌΡ ΠΏΡΠΈΡΠ»ΠΎΡΡ ΡΠΊΠ°ΡΠ°ΡΡ
ΠΠ°ΠΌΠ΅Π½ΠΈΠ» Π² ΠΌΠ΅ΡΠΎΠ΄Π΅ extractContent(..)
ΡΡΡΠΎΠΊΡ:
buffer.append(bytesMessage.getBodyLength() + " bytes received in BytesMessage");
Π½Π°:
byte[] bytes = new byte[(int) bytesMessage.getBodyLength()];
bytesMessage.readBytes(bytes);
try {
buffer.append(new String(bytes, "UTF-8"));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
ΠΈ ΠΏΠ΅ΡΠ΅ΡΠΎΠ±ΡΠ°Π» JMeter.
ΠΡΡΠ°Π»ΠΎΡΡ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ ΠΏΠ°ΡΡ JSR223 Sampler. ΠΠ΅ΡΠ²ΡΠΉ β ΠΏΠ΅ΡΠ΅Π΄ ΠΏΠ°ΡΠΎΠΉ Publisher/Subscriber Π΄Π»Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ DAT-ΡΠ°ΠΉΠ»Π°, ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠ΅Π³ΠΎ ΡΠ»ΡΡΠ°ΠΉΠ½ΡΠ΅ Π±Π°ΠΉΡΡ:
import org.apache.commons.lang3.RandomUtils;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
vars.put("PATH_TO_BYTES", "C:temprandomBytes.dat");
File RESULT_FILE = new File(vars.get("PATH_TO_BYTES"));
byte[] arr = RandomUtils.nextBytes((int)(Math.random()*10000));
try {
FileOutputStream fos = new FileOutputStream(RESULT_FILE);
fos.write(arr);
fos.close();
} catch (IOException e) {
System.out.println("file not found");
}
ΠΡΠΎΡΠΎΠΉ β Π² ΠΊΠΎΠ½ΡΠ΅ ΡΡΠ΅Π½Π°ΡΠΈΡ, ΡΠ΄Π°Π»ΡΠ΅Ρ ΡΠ°ΠΉΠ»:
import java.io.File;
File RESULT_FILE = new File(vars.get("PATH_TO_BYTES"));
RESULT_FILE.delete();
Π Π½Π΅ Π·Π°Π±ΡΡΡ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ ΠΏΡΡΡ ΠΊ ΡΠ°ΠΉΠ»Ρ Ρ Publisher:
Π ΡΠ°ΠΊΠΆΠ΅ ΠΏΡΠΎΠ²Π΅ΡΠΊΡ Π² JSR223 Assertion Π΄Π»Ρ Subscriber β ΡΡΠ°Π²Π½ΠΈΡΡ ΠΈΡΡ
ΠΎΠ΄Π½ΡΠ΅ Π±Π°ΠΉΡΡ Ρ ΡΠ΅ΠΌΠΈ, ΡΡΠΎ ΠΏΡΠΈΡ
ΠΎΠ΄ΡΡ Π² ΠΎΡΠ΅ΡΠ΅Π΄Ρ ΠΏΠΎΠ»ΡΡΠ°ΡΠ΅Π»Ρ:
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
Path path = Paths.get(vars.get("PATH_TO_BYTES"), new String[0]);
byte[] originalArray = Files.readAllBytes(path);
byte[] changedArray = ctx.getPreviousResult().getResponseData();
System.out.println(changedArray.length);
if (Arrays.equals(originalArray, changedArray))
{
SampleResult.setResponseMessage("OK");
} else {
SampleResult.setSuccessful(false);
SampleResult.setResponseMessage("Comparison failed");
SampleResult.setResponseData("Bytes have changed","UTF-8");
IsSuccess=false;
}
ΠΠ°ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅
ΠΠΏΠΈΡΠ°Π» ΡΠ΅ΡΡΡΠ΅ ΡΠΏΠΎΡΠΎΠ±Π° ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ Π² ΠΎΡΠ΅ΡΠ΅Π΄ΠΈ, ΠΊΠΎΡΠΎΡΡΠ΅ Π΅ΠΆΠ΅Π΄Π½Π΅Π²Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ Π½Π° ΠΏΡΠ°ΠΊΡΠΈΠΊΠ΅. ΠΠ°Π΄Π΅ΡΡΡ, ΡΡΠ° ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ ΠΎΠ±Π»Π΅Π³ΡΠΈΡ Π²Π°ΠΌ ΠΆΠΈΠ·Π½Ρ. Π ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ΠΈΠΈ ΠΏΠ»Π°Π½ΠΈΡΡΡ ΡΠ°ΡΡΠΊΠ°Π·Π°ΡΡ ΠΎ ΡΠ²ΠΎΠ΅ΠΌ ΠΎΠΏΡΡΠ΅ ΡΠ΅ΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΎΠ±ΠΌΠ΅Π½Π°, Π³Π΄Π΅ Π½Π° ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠΎΠ½ΡΠ΅ β ΠΎΡΠ΅ΡΠ΅Π΄Ρ, Π° Π½Π° Π΄ΡΡΠ³ΠΎΠΌ β Π±Π°Π·Π° Π΄Π°Π½Π½ΡΡ ΠΈΠ»ΠΈ ΡΠ°ΠΉΠ»ΠΎΠ²Π°Ρ ΡΠΈΡΡΠ΅ΠΌΠ°.
ΠΠ΅ΡΠ΅Π³ΠΈΡΠ΅ ΡΠ²ΠΎΡ Π²ΡΠ΅ΠΌΡ. Π ΡΠΏΠ°ΡΠΈΠ±ΠΎ Π·Π° Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅.
ΠΡΡΠΎΡΠ½ΠΈΠΊ: habr.com