рд╕реНрдЯреЙрд░реНрдо рдлреНрд░реЗрдорд╡рд░реНрдХ рд╕реАрдЦрдирд╛ред рднрд╛рдЧ I

2011 рдореЗрдВ, рдЯреНрд╡рд┐рдЯрд░ рдиреЗ рд▓реЙрдиреНрдЪ рдХрд┐рдпрд╛, рдПрдХреНрд▓рд┐рдкреНрд╕ рдкрдмреНрд▓рд┐рдХ рд▓рд╛рдЗрд╕реЗрдВрд╕ рдХреЗ рддрд╣рдд, рд╕реНрдЯреЙрд░реНрдо рдбрд┐рд╕реНрдЯреНрд░реАрдмреНрдпреВрдЯреЗрдб рдХрдВрдкреНрдпреВрдЯрд┐рдВрдЧ рдкреНрд░реЛрдЬреЗрдХреНрдЯред рддреВрдлрд╛рди BackType рдкрд░ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рдерд╛ рдФрд░ рдЦрд░реАрдж рдХреЗ рдмрд╛рдж рдЯреНрд╡рд┐рдЯрд░ рдкрд░ рд╕реНрд╡рд┐рдЪ рдХрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред

рд╕реНрдЯреЙрд░реНрдо рдПрдХ рдкреНрд░рдгрд╛рд▓реА рд╣реИ рдЬреЛ рдЕрдкрд╛рдЪреЗ рд╣рдбреЛрдк рдХреЗ рд╕рдорд╛рди рдмрдбрд╝реЗ рдбреЗрдЯрд╛ рдзрд╛рд░рд╛рдУрдВ рдХреЗ рд╡рд┐рддрд░рд┐рдд рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдкрд░ рдХреЗрдВрджреНрд░рд┐рдд рд╣реИ, рд▓реЗрдХрд┐рди рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рдордп рдореЗрдВред

рддреВрдлрд╛рди рдХреА рдореБрдЦреНрдп рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ:

рдкрд╣рд▓рд╛ рднрд╛рдЧ рд╕реНрдЯреЙрд░реНрдо рд╕рдВрд╕реНрдХрд░рдг 0.8.2 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдмрдирд╛рдиреЗ рдХреА рдореВрд▓ рдЕрд╡рдзрд╛рд░рдгрд╛рдУрдВ рдФрд░ рдмреБрдирд┐рдпрд╛рджреА рдмрд╛рддреЛрдВ рдкрд░ рдЪрд░реНрдЪрд╛ рдХрд░рддрд╛ рд╣реИред

рддреВрдлрд╛рди рдХреЗ рддрддреНрд╡


рдЯрдкрд▓
рдбреЗрдЯрд╛ рдкреНрд░рд╕реНрддреБрддрд┐ рддрддреНрд╡ред рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдЗрд╕рдореЗрдВ рд▓реЙрдиреНрдЧ, рдЗрдВрдЯреЗрдЧрд░, рд╢реЙрд░реНрдЯ, рдмрд╛рдЗрдЯ, рд╕реНрдЯреНрд░рд┐рдВрдЧ, рдбрдмрд▓, рдлреНрд▓реЛрдЯ, рдмреБрд▓рд┐рдпрди рдФрд░ рдмрд╛рдЗрдЯ [] рдХреНрд╖реЗрддреНрд░ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рдЯрдкрд▓ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдХрд╕реНрдЯрдо рдкреНрд░рдХрд╛рд░ рдХреНрд░рдордмрджреНрдз рд╣реЛрдиреЗ рдЪрд╛рд╣рд┐рдПред

рдзрд╛рд░рд╛
рдЯрдкрд▓ рдХреА рдЕрдиреБрдХреНрд░рдоред рдЯрдкрд▓ рдореЗрдВ рдЦреЗрддреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдирд╛рдордХрд░рдг рдпреЛрдЬрдирд╛ рд╢рд╛рдорд┐рд▓ рд╣реИред

рдЯреЛрдВрдЯреА
рд╕реНрдЯреНрд░реАрдо рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛ рдкреНрд░рджрд╛рддрд╛ред рдпрд╣ рдмрд╛рд╣рд░реА рд╕реНрд░реЛрддреЛрдВ рд╕реЗ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ, рдЙрдирд╕реЗ рдПрдХ рдЯрдкрд▓ рдмрдирд╛рддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рд╕реНрдЯреНрд░реАрдо рдореЗрдВ рднреЗрдЬрддрд╛ рд╣реИред Tuple рдХреЛ рдХрдИ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╕реНрдЯреНрд░реАрдо рдореЗрдВ рднреЗрдЬ рд╕рдХрддреЗ рд╣реИрдВред рд▓реЛрдХрдкреНрд░рд┐рдп рдореИрд╕реЗрдЬрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИрдВ: RabbitMQ / AMQP , Kestrel , JMS , Kafka ред

рдкреЗрдВрдЪ
рдбрд╛рдЯрд╛ рд╣реИрдВрдбрд▓рд░ред рдЗрдирдкреБрдЯ рдЯреНрдпреВрдкрд▓ рд╣реИред рдЖрдЙрдЯрдкреБрдЯ рдкрд░ 0 рдпрд╛ рдЕрдзрд┐рдХ рдЯрдкрд▓ рднреЗрдЬрддрд╛ рд╣реИред

рдЯреЛрдкреЛрд▓реЙрдЬреА
рдЙрдирдХреЗ рд╕рдВрдмрдВрдзреЛрдВ рдХреЗ рд╡рд┐рд╡рд░рдг рдХреЗ рд╕рд╛рде рддрддреНрд╡реЛрдВ рдХрд╛ рдПрдХ рд╕рдВрдЧреНрд░рд╣ред Hadoop рдореЗрдВ MapReduce рдЬреЙрдм рдХрд╛ рдПрдХ рдПрдирд╛рд▓реЙрдЧред MapReduce рдЬреЙрдм рдХреЗ рд╡рд┐рдкрд░реАрдд, рдпрд╣ рдЗрдирдкреБрдЯ рдбреЗрдЯрд╛ рд╕реНрдЯреНрд░реАрдо рд╕рдорд╛рдкреНрдд рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж рдмрдВрдж рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред рдЯреЛрдВрдЯреА рдкрд░рд┐рд╡рд╣рди рдХреЛ рдЯреЛрдВрдЯреА рдФрд░ рдмреЛрд▓реНрдЯ рддрддреНрд╡реЛрдВ рдХреЗ рдмреАрдЪ рд▓реЗ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕реЗ рд╕реНрдерд╛рдиреАрдп рд░реВрдк рд╕реЗ рд▓реЙрдиреНрдЪ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдпрд╛ рд╕реНрдЯреЙрд░реНрдо рдХреНрд▓рд╕реНрдЯрд░ рдореЗрдВ рд▓реЛрдб рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ


рдХрд╛рд░реНрдп


рдПрдХ Cdr рдлреЛрди рдХреЙрд▓ рдбреЗрдЯрд╛ рд╕реНрдЯреНрд░реАрдо рд╣реИред рд╕реНрд░реЛрдд рд╕рдВрдЦреНрдпрд╛ рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдХреНрд▓рд╛рдЗрдВрдЯ рдЖрдИрдбреА рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХреА рдЬрд╛рддреА рд╣реИред рдЧрдВрддрд╡реНрдп рд╕рдВрдЦреНрдпрд╛ рдФрд░ рдЧреНрд░рд╛рд╣рдХ рдЖрдИрдбреА рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдЯреИрд░рд┐рдл рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдХреЙрд▓ рдХреА рд▓рд╛рдЧрдд рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдкреНрд░рддреНрдпреЗрдХ рдЪрд░рдг рдХреЛ рдХрдИ рдереНрд░реЗрдбреНрд╕ рдореЗрдВ рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред
рдЗрд╕рдХрд╛ рдЙрджрд╛рд╣рд░рдг рд╕реНрдерд╛рдиреАрдп рдорд╢реАрди рдкрд░ рд╣реЛрдЧрд╛ред

рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди


рдЖрд░рдВрдн рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдмрд╕ BasicApp рдЗрдирдкреБрдЯ рдХрд╛ рдкреНрд░рд┐рдВрдЯ рдЖрдЙрдЯ рд▓реЗрдВ ред

рдПрдХ рдирдИ рдЯреЛрдкреЛрд▓реЙрдЬреА рдмрдирд╛рдПрдВ:
TopologyBuilder builder = new TopologyBuilder(); 

рдПрдХ рд╕реНрдкрд╛рдЙрдЯ CdrSpout рдЬрдирд░реЗрдЯрд┐рдВрдЧ рдЗрдирдкреБрдЯ рдЬреЛрдбрд╝реЗрдВ:
 builder.setSpout("CdrReader", new CdrSpout()); 

рдмреЛрд▓реНрдЯ рдХреЛ рджреЛ рдзрд╛рд░рд╛рдУрдВ рдХреЗ рд╕рд╛рде рдЬреЛрдбрд╝реЗрдВ рдФрд░ рдЗрдВрдЧрд┐рдд рдХрд░реЗрдВ рдХрд┐ рдЖрдЙрдЯрдкреБрдЯ рд╕реНрдЯреНрд░реАрдо CdrReader рд╣реИред shuffleGrouping рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ CdrReader рдХрд╛ рдбреЗрдЯрд╛ рдмреЗрддрд░рддреАрдм рдврдВрдЧ рд╕реЗ рдЪрдпрдирд┐рдд PrintOutBolt рдХреЛ рдЦрд┐рд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
 builder.setBolt("PrintOutBolt", new PrintOutBolt(), 2).shuffleGrouping("CdrReader"); 

рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░реЗрдВ рдФрд░ рд╕реНрдерд╛рдиреАрдп рд╕реНрдЯреЙрд░реНрдо рдХреНрд▓рд╕реНрдЯрд░ рд╢реБрд░реВ рдХрд░реЗрдВ:
 Config config = new Config(); //     config.setDebug(false); LocalCluster cluster = new LocalCluster(); //   Storm  cluster.submitTopology("T1", config, builder.createTopology()); //  Topology Thread.sleep(1000*10); cluster.shutdown(); //   

рдЖрдЙрдЯрдкреБрдЯ рд▓рдЧрднрдЧ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╣реИ:
рдЫрд┐рдкрд╛ рд╣реБрдЖ рдкрд╛рда
 OUT >> [80] Cdr {callSource = '78119990005', callDestination = '8313610698077174239' 
 рдХреЙрд▓ рдЯрд╛рдЗрдо = 7631, рдХреНрд▓рд╛рдЗрдВрдЯрдЖрдИрдбреА = 0, рдореВрд▓реНрдп = 0}
 OUT >> [78] Cdr {callSource = '78119990006', callDestination = '2238707710336895468' 
 callTime = 20738, clientId = 0, рдореВрд▓реНрдп = 0}
 OUT >> [78] Cdr {callSource = '78119990007', callDestination = '579372726495390920' 
 callTime = 31544, clientId = 0, рдореВрд▓реНрдп = 0}
 OUT >> [80] Cdr {callSource = '78119990006', callDestination = '2010724447342634423' 
 рдХреЙрд▓рдЯрд╛рдЗрдо = 10268, рдХреНрд▓рд╛рдЗрдВрдЯрдЖрдИрдб = 0, рдореВрд▓реНрдп = 0}

рд╡рд░реНрдЧ рдХреЛрд╖реНрдардХ рдореЗрдВ рд╕рдВрдЦреНрдпрд╛ рдереНрд░реЗрдб рдЖрдИрдбреА рд╣реИ, рдпрд╣ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рд╕рдорд╛рдирд╛рдВрддрд░ рдореЗрдВ рдЖрдпреЛрдЬрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдЖрдЧреЗ рдХреЗ рдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдХрдИ рд╣реИрдВрдбрд▓рд░ рдХреЗ рдмреАрдЪ рдЗрдирдкреБрдЯ рдбреЗрдЯрд╛ рдХреЗ рд╡рд┐рддрд░рдг рд╕реЗ рдирд┐рдкрдЯрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рдКрдкрд░ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдПрдХ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рд▓реЗрдХрд┐рди рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЙрдкрдпреЛрдЧ рдореЗрдВ, рдмреЛрд▓реНрдЯ рд╢рд╛рдпрдж рдмрд╛рд╣рд░реА рдорджрдж рдкреНрд░рдгрд╛рд▓реА рдФрд░ рдбреЗрдЯрд╛рдмреЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдЧрд╛ред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣ рд╡рд╛рдВрдЫрдиреАрдп рд╣реИ рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдмреЛрд▓реНрдЯ рдЗрдирдкреБрдЯ рдбреЗрдЯрд╛ рдХреЗ рдЕрдкрдиреЗ рд╕рдмрд╕реЗрдЯ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддрд╛ рд╣реИред рддрдм рдмрд╛рд╣рд░реА рдкреНрд░рдгрд╛рд▓рд┐рдпреЛрдВ рд╕реЗ рдбреЗрдЯрд╛ рдХреЗ рдкреНрд░рднрд╛рд╡реА рдХреИрд╢рд┐рдВрдЧ рдХреЛ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛ред

рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рддреВрдлрд╛рди CustomStreamGrouping рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред
CdrGrouper рдХреЛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рдЬреЛрдбрд╝реЗрдВред рдЗрд╕рдХрд╛ рдХрд╛рд░реНрдп рдЯреБрдкрд▓ рдХреЛ рд╕рдорд╛рди рд╕реНрд░реЛрдд рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЗ рд╕рд╛рде рдПрдХ рд╣реА рдмреЛрд▓реНрдЯ рдкрд░ рднреЗрдЬрдирд╛ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, CustomStreamGrouping рджреЛ рдХреЙрд▓ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ:
рддреИрдпрд╛рд░ - рдкрд╣рд▓реЗ рдЙрдкрдпреЛрдЧ рд╕реЗ рдкрд╣рд▓реЗ рдмреБрд▓рд╛рдпрд╛:
 @Override public void prepare(WorkerTopologyContext workerTopologyContext, GlobalStreamId globalStreamId, List<Integer> integers) { tasks = new ArrayList<>(integers); //   Bolts } 

рдФрд░ рдЪреБрдирд┐рдВрджрд╛ рдХрд╛рд░реНрдп - рдЬрд╣рд╛рдВ рдЯреНрдпреВрдкрд▓ рд╕реЗ рдПрдХ рд╕реВрдЪреА рдЗрдирдкреБрдЯ рдХреЛ рдЦрд┐рд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдПрдХ рд╕реВрдЪреА рдЬрд┐рд╕рдореЗрдВ рдЯреБрдкрд▓ рд╕реВрдЪреА рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рд╕реНрдерд┐рддрд┐ рдХреЗ рд▓рд┐рдП рдмреЛрд▓реНрдЯ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЛ рд╢рд╛рдорд┐рд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:
 @Override public List<Integer> chooseTasks(int i, List<Object> objects) { List<Integer> rvalue = new ArrayList<>(objects.size()); for(Object o: objects) { Cdr cdr = (Cdr) o; rvalue.add(tasks.get(Math.abs(cdr.getCallSource().hashCode()) % tasks.size())); } return rvalue; } 

рдмрджрд▓реЗрдВ рд╢реНрд░рдЧрдЧреНрд░реБрдкрд┐рдВрдЧ рдХреЛ CdrGrouper BasicGroupApp рдХреЗ рд╕рд╛рде рдмрджрд▓реЗрдВ:
 builder.setBolt("PrintOutBolt", new PrintOutBolt(), 2). customGrouping("CdrReader", new CdrGrouper()); 

рднрд╛рдЧреЛ рдФрд░ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ рдХрд┐ рдпрд╣ рдЗрд░рд╛рджрд╛ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ:
рдЫрд┐рдкрд╛ рд╣реБрдЖ рдкрд╛рда
 OUT >> [80] Cdr {callSource = '78119990007', callDestination = '3314931472251135073' 
 callTime = 17632, clientId = 0, рдореВрд▓реНрдп = 0}
 OUT >> [80] Cdr {callSource = '78119990007', callDestination = '4182885669941386786' 
 рдХреЙрд▓рдЯрд╛рдЗрдо = 31533, рдХреНрд▓рд╛рдЗрдВрдЯрдЖрдИрдбреА = 0, рдореВрд▓реНрдп = 0}


рдЕрдЧрд▓рд╛, рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ:
ClientIdBolt - рд╕реЛрд░реНрд╕ рдирдВрдмрд░ рджреНрд╡рд╛рд░рд╛ рдХреНрд▓рд╛рдЗрдВрдЯ рдЖрдИрдбреА рдХреА рдкрд╣рдЪрд╛рди рдХрд░рддрд╛ рд╣реИред
ClientIdGrouper - рдХреНрд▓рд╛рдЗрдВрдЯ рдЖрдИрдбреА рджреНрд╡рд╛рд░рд╛ рд╕рдореВрд╣ ред
RaterBolt - рдмрд┐рд▓рд┐рдВрдЧ рдореЗрдВ рд▓рдЧреЗ рд╣реБрдП рд╣реИрдВред
CalcApp рдХрд╛рд░реНрдпрдХреНрд░рдо рдХрд╛ рдЕрдВрддрд┐рдо рд╕рдВрд╕реНрдХрд░рдг рд╣реИред

рдпрджрд┐ рд╡рд┐рд╖рдп рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ, рддреЛ рдЕрдЧрд▓реЗ рднрд╛рдЧ рдореЗрдВ рдореБрдЭреЗ рдбреЗрдЯрд╛ рд╣рд╛рдирд┐ рдХреЗ рдЦрд┐рд▓рд╛рдл рд╕реБрд░рдХреНрд╖рд╛ рддрдВрддреНрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рдиреЗ рдХреА рдЙрдореНрдореАрдж рд╣реИ рдФрд░ рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдХреНрд▓рд╕реНрдЯрд░ рдкрд░ рдЪрд▓ рд░рд╣рд╛ рд╣реИред рдХреЛрдб GitHub рдкрд░ рдЙрдкрд▓рдмреНрдз рд╣реИ ред

рдкреБрдирд╢реНрдЪред рдмреЗрд╢рдХ, рдЖрдкрдиреЗ рдЧреАрдд рд╕реЗ рд╢рдмреНрджреЛрдВ рдХреЛ рдирд╣реАрдВ рдирд┐рдХрд╛рд▓рд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдбреЗрдЯрд╛ рдкреНрд░реЛрд╕реЗрд╕рд░ "рдмреЛрд▓реНрдЯ" рдХрд╛ рдирд╛рдо рдХреБрдЫ рднреНрд░рд╛рдордХ рд╣реИ :)

рдпреБрдкреАрдбреАред рд▓реЗрдЦ рдХрд╛ рджреВрд╕рд░рд╛ рднрд╛рдЧ рдкреНрд░рдХрд╛рд╢рд┐рдд рд╣реБрдЖ рд╣реИред

Source: https://habr.com/ru/post/In186208/


All Articles