рд╣реЗ рд╣рдмрд░ред
рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рдореИрдВ рдорд╛рдЗрдХреНрд░реЛрд╕рд░реНрд╡рд┐рд╕реЗрдЬ рдХреЗ рд╕рд╛рде рдкреНрд░рдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реАрдЦрдиреЗ рдХрд╛ рдорд╛рд╣реМрд▓ рдмрдирд╛рдиреЗ рдХреЗ рдЕрдкрдиреЗ рдЕрдиреБрднрд╡ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред рдЬрдм рдореИрдВрдиреЗ рдкреНрд░рддреНрдпреЗрдХ рдирдП рдЯреВрд▓ рдХреЛ рд╕реАрдЦрд╛, рддреЛ рдореИрдВ рд╣рдореЗрд╢рд╛ рдЗрд╕реЗ рди рдХреЗрд╡рд▓ рд╕реНрдерд╛рдиреАрдп рдорд╢реАрди рдкрд░, рдмрд▓реНрдХрд┐ рдЕрдзрд┐рдХ рдпрдерд╛рд░реНрдерд╡рд╛рджреА рдкрд░рд┐рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдореЗрдВ рднреА рдЖрдЬрд╝рдорд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ред рдЗрд╕рд▓рд┐рдП, рдореИрдВрдиреЗ рдПрдХ рд╕рд░рд▓реАрдХреГрдд рдорд╛рдЗрдХреНрд░реЛрд╕рд░реНрд╡рд┐рд╕ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдмрдирд╛рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛, рдЬрд┐рд╕реЗ рдмрд╛рдж рдореЗрдВ рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреА рджрд┐рд▓рдЪрд╕реНрдк рддрдХрдиреАрдХреЛрдВ рдХреЗ рд╕рд╛рде "рдХрд╡рд░" рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рд▓рд┐рдП рдореБрдЦреНрдп рдЖрд╡рд╢реНрдпрдХрддрд╛ рдЗрд╕рдХреА рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкреНрд░рдгрд╛рд▓реА рд╕реЗ рдЕрдзрд┐рдХрддрдо рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдирд┐рдХрдЯрддрд╛ рд╣реИред
рдкреНрд░рд╛рд░рдВрдн рдореЗрдВ, рдореИрдВрдиреЗ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЛ рдХрдИ рдЪрд░рдгреЛрдВ рдореЗрдВ рддреЛрдбрд╝рд╛:
-
рджреЛ рд╕реЗрд╡рд╛рдПрдВ рдмрдирд╛рдПрдВ - 'рдмреИрдХрдПрдВрдб' (рдмреИрдХрдПрдВрдб) рдФрд░ 'рдЧреЗрдЯрд╡реЗ' (рдЧреЗрдЯрд╡реЗ), рдЙрдиреНрд╣реЗрдВ рдбреЙрдХрд░ рдЗрдореЗрдЬ рдореЗрдВ рдкреИрдХ рдХрд░реЗрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдПрдХ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реЗрдЯ рдХрд░реЗрдВ
рдХреАрд╡рд░реНрдб: рдЬрд╛рд╡рд╛ 11, рд╕реНрдкреНрд░рд┐рдВрдЧ рдмреВрдЯ, рдбреЙрдХрд░, рдЫрд╡рд┐ рдЕрдиреБрдХреВрд▓рди
-
рдХреАрд╡рд░реНрдб: рдХреБрдмреЗрд░рдиреЗрдЯреНрд╕, рдЬреАрдХреЗрдИ, рд╕рдВрд╕рд╛рдзрди рдкреНрд░рдмрдВрдзрди, рдСрдЯреЛрд╕реНрдХреЗрд▓рд┐рдВрдЧ, рд░рд╣рд╕реНрдп
-
рдмреЗрд╣рддрд░ рдХреНрд▓рд╕реНрдЯрд░ рдкреНрд░рдмрдВрдзрди рдХреЗ рд▓рд┐рдП рд╣реЗрд▓реНрдо 3 рдХреЗ рд╕рд╛рде рдЪрд╛рд░реНрдЯ рдмрдирд╛рдирд╛
рдЯреИрдЧ: рдкрддрд╡рд╛рд░ 3, рдЪрд╛рд░реНрдЯ рдкрд░рд┐рдирд┐рдпреЛрдЬрди
-
рдХреНрд▓рд╕реНрдЯрд░ рдХреЛ рдХреЛрдб рдХреА рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдбрд┐рд▓реАрд╡рд░реА рдХреЗ рд▓рд┐рдП рдЬреЗрдирдХреАрдВрд╕ рдФрд░ рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдХреА рд╕реНрдерд╛рдкрдирд╛
рдХреАрд╡рд░реНрдб: рдЬреЗрдирдХрд┐рдВрд╕ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди, рдкреНрд▓рдЧрдЗрдиреНрд╕, рдЕрд▓рдЧ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА
рдореИрдВ рдкреНрд░рддреНрдпреЗрдХ рдЪрд░рдг рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд▓рдЧ рд▓реЗрдЦ рд╕рдорд░реНрдкрд┐рдд рдХрд░рдиреЗ рдХреА рдпреЛрдЬрдирд╛ рдмрдирд╛ рд░рд╣рд╛ рд╣реВрдВред
рд▓реЗрдЦреЛрдВ рдХреА рдЗрд╕ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХрд╛ рдлреЛрдХрд╕ рдпрд╣ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдорд╛рдЗрдХреНрд░реЛрд╕рд░реНрд╡рд┐рд╕реЗрдЬ рдХреЛ рдХреИрд╕реЗ рд▓рд┐рдЦрд╛ рдЬрд╛рдП, рдмрд▓реНрдХрд┐ рдпрд╣ рд╣реИ рдХрд┐ рдЙрдиреНрд╣реЗрдВ рдПрдХ рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рдХреИрд╕реЗ рдХрд╛рдо рдХрд┐рдпрд╛ рдЬрд╛рдПред рд╣рд╛рд▓рд╛рдБрдХрд┐ рдпреЗ рд╕рднреА рдЪреАрдЬреЗрдВ рдЖрдорддреМрд░ рдкрд░ рдбреЗрд╡рд▓рдкрд░ рдХреА рдЬрд┐рдореНрдореЗрджрд╛рд░реА рд╕реЗ рдмрд╛рд╣рд░ рд╣реЛрддреА рд╣реИрдВ, рдлрд┐рд░ рднреА рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдХрдо рд╕реЗ рдХрдо 20% (рдЬреЛ, рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ, рдкрд░рд┐рдгрд╛рдо рдХрд╛ 80% рджреЗрддреЗ рд╣реИрдВ) рдЕрднреА рднреА рдЙрдирд╕реЗ рдкрд░рд┐рдЪрд┐рдд рд╣реЛрдирд╛ рдЙрдкрдпреЛрдЧреА рд╣реИред рд╕реБрд░рдХреНрд╖рд╛ рдЬреИрд╕реЗ рдХреБрдЫ рдмрд┐рдирд╛ рд╢рд░реНрдд рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╡рд┐рд╖рдпреЛрдВ рдХреЛ рдЗрд╕ рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╕реЗ рдмрд╛рд╣рд░ рд░рдЦрд╛ рдЬрд╛рдПрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рд▓реЗрдЦрдХ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╣реБрдд рдХрдо рд╕рдордЭрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдкреНрд░рдгрд╛рд▓реА рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╡реНрдпрдХреНрддрд┐рдЧрдд рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдмрдирд╛рдИ рдЧрдИ рд╣реИред рдореИрдВ рдХрд┐рд╕реА рднреА рд░рд╛рдп рдФрд░ рд░рдЪрдирд╛рддреНрдордХ рдЖрд▓реЛрдЪрдирд╛ рдХрд╛ рд╕реНрд╡рд╛рдЧрдд рдХрд░рддрд╛ рд╣реВрдВред
рдорд╛рдЗрдХреНрд░реЛрд╕рд░реНрд╡рд┐рд╕реЗрдЬ рдмрдирд╛рдирд╛
рд╕реЗрд╡рд╛ рдЬрд╛рд╡рд╛ 11 рдореЗрдВ рд╕реНрдкреНрд░рд┐рдВрдЧ рдмреВрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд▓рд┐рдЦреА рдЧрдИ рдереАред рдЗрдВрдЯрд░рд╕рд░реНрд╡рд┐рд╕ рдЗрдВрдЯрд░реИрдХреНрд╢рди REST рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЖрдпреЛрдЬрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдиреНрдпреВрдирддрдо рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рд╢рд╛рдорд┐рд▓ рд╣реЛрдВрдЧреЗ (рддрд╛рдХрд┐ рдмрд╛рдж рдореЗрдВ рдЬреЗрдирдХреАрдВрд╕ рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рд╣реЛ)ред рд╕реЗрд╡рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рд╕реНрд░реЛрдд рдХреЛрдб GitHub рдкрд░ рдЙрдкрд▓рдмреНрдз рд╣реИ:
рдкреНрд░рддреНрдпреЗрдХ рд╕реЗрд╡рд╛ рдХреА рд╕реНрдерд┐рддрд┐ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП, рдЙрдирдХреА рдирд┐рд░реНрднрд░рддрд╛ рдореЗрдВ рдПрдХ рд╕реНрдкреНрд░рд┐рдВрдЧ рдПрдХреНрдЯреНрдпреВрдПрдЯрд░ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рд╣реИред рдпрд╣ рдПрдХ/рдПрдХреНрдЯреНрдпреВрдПрдЯрд░/рд╕реНрд╡рд╛рд╕реНрдереНрдп рд╕рдорд╛рдкрди рдмрд┐рдВрджреБ рдмрдирд╛рдПрдЧрд╛ рдФрд░ рдпрджрд┐ рд╕реЗрд╡рд╛ рдЯреНрд░реИрдлрд╝рд┐рдХ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИ, рдпрд╛ рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рд╣реЛрдиреЗ рдкрд░ 200 рд╕реНрдерд┐рддрд┐ рд▓реМрдЯрд╛рдПрдЧрд╛ред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣ рдПрдХ рдХрд╛рд▓реНрдкрдирд┐рдХ рдЬрд╛рдВрдЪ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╕реЗрд╡рд╛рдПрдВ рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИрдВ, рдФрд░ рдХреБрдЫ рдЕрдкреНрд░рддреНрдпрд╛рд╢рд┐рдд рдШрдЯрдирд╛рдУрдВ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╡реЗ рдЖрдВрд╢рд┐рдХ рд░реВрдк рд╕реЗ рдЪрд╛рд▓реВ рд░рд╣рдиреЗ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрдиреБрдкрд▓рдмреНрдз рд╣реЛрдиреЗ рдХреА рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рд░рдЦрддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкреНрд░рдгрд╛рд▓рд┐рдпреЛрдВ рдореЗрдВ, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬреВрдЭрдирд╛ рд╢реБрд░реВ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдПрдХреНрдЪреБрдПрдЯрд░ рдХрд┐рд╕реА рд╕рдорд╕реНрдпрд╛ рдХрд╛ рдирд┐рджрд╛рди рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рдбреЗрдЯрд╛рдмреЗрд╕ рддрдХ рдкрд╣реБрдБрдЪрдиреЗ рдореЗрдВ рд╕рдорд╕реНрдпрд╛рдПрдБ рд╣реИрдВ, рддреЛ рд╣рдо рдЯреВрдЯреЗ рд╣реБрдП рд╕реЗрд╡рд╛ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд░реЛрдХрдХрд░ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдЗрд╕рдХрд╛ рдЬрд╡рд╛рдм рджреЗ рд╕рдХрддреЗ рд╣реИрдВред
рдмреИрдХ рдПрдВрдб рд╕рд░реНрд╡рд┐рд╕
рдмреИрдХрдПрдВрдб рд╕реЗрд╡рд╛ рдХреЗрд╡рд▓ рд╕реНрд╡реАрдХреГрдд рдЕрдиреБрд░реЛрдзреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреА рдЧрдгрдирд╛ рдФрд░ рд╡рд╛рдкрд╕реА рдХрд░реЗрдЧреАред
рдирд┐рдпрдВрддреНрд░рдХ рдХреЛрдб:
@RestController
public class RequestsCounterController {
private final AtomicLong counter = new AtomicLong();
@GetMapping("/requests")
public Long getRequestsCount() {
return counter.incrementAndGet();
}
}
рдирд┐рдпрдВрддреНрд░рдХ рдкрд░реАрдХреНрд╖рдг:
@WebMvcTest(RequestsCounterController.class)
public class RequestsCounterControllerTests {
@Autowired
private MockMvc mockMvc;
@Test
public void firstRequest_one() throws Exception {
mockMvc.perform(get("/requests"))
.andExpect(status().isOk())
.andExpect(MockMvcResultMatchers.content().string("1"));
}
}
рд╕рд░реНрд╡рд┐рд╕ рдЧреЗрдЯрд╡реЗ
рдЧреЗрдЯрд╡реЗ рдмреИрдХрдПрдВрдб рд╕реЗрд╡рд╛ рдХреЗ рд▓рд┐рдП рдЕрдиреБрд░реЛрдз рдХреЛ рдЕрдЧреНрд░реЗрд╖рд┐рдд рдХрд░реЗрдЧрд╛, рдЗрд╕реЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд╕рд╛рде рдкреВрд░рдХ рдХрд░реЗрдЧрд╛:
- рдЧреЗрдЯрд╡реЗ рдЖрдИрдбреАред рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рддрд╛рдХрд┐ рд╕рд░реНрд╡рд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рджреНрд╡рд╛рд░рд╛ рдЧреЗрдЯрд╡реЗ рдХреЗ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЛ рджреВрд╕рд░реЗ рд╕реЗ рдЕрд▓рдЧ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛ рд╕рдХреЗ
- рдХреБрдЫ "рдЧреБрдкреНрдд" рдЬреЛ рдПрдХ рдмрд╣реБрдд рд╣реА рдорд╣рддреНрд╡рдкреВрд░реНрдг рдкрд╛рд╕рд╡рд░реНрдб рдХреА рднреВрдорд┐рдХрд╛ рдирд┐рднрд╛рдПрдВрдЧреЗ (рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдХреБрдХреА рдХреА рдПрдиреНрдХреНрд░рд┐рдкреНрд╢рди рдХреБрдВрдЬреА рдХреА рд╕рдВрдЦреНрдпрд╛)
application.properties рдореЗрдВ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди:
backend.url=http://localhost:8081
instance.id=${random.int}
secret="default-secret"
рдмреИрдХрдПрдВрдб рдПрдбреЗрдкреНрдЯрд░:
@Service
public class BackendAdapter {
private static final String REQUESTS_ENDPOINT = "/requests";
private final RestTemplate restTemplate;
@Value("${backend.url}")
private String backendUrl;
public BackendAdapter(RestTemplateBuilder builder) {
restTemplate = builder.build();
}
public String getRequests() {
ResponseEntity<String> response = restTemplate.getForEntity(
backendUrl + REQUESTS_ENDPOINT, String.class);
return response.getBody();
}
}
рдирд┐рдпрдВрддреНрд░рдХ:
@RestController
@RequiredArgsConstructor
public class EndpointController {
private final BackendAdapter backendAdapter;
@Value("${instance.id}")
private int instanceId;
@Value("${secret}")
private String secret;
@GetMapping("/")
public String getRequestsCount() {
return String.format("Number of requests %s (gateway %d, secret %s)", backendAdapter.getRequests(), instanceId, secret);
}
}
рд╢реБрд░реВ рдХрд░рдирд╛:
рд╣рдо рдмреИрдХрдПрдВрдб рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ:
./mvnw package -DskipTests
java -Dserver.port=8081 -jar target/microservices-backend-1.0.0.jar
рдЧреЗрдЯрд╡реЗ рд╢реБрд░реВ рдХрд░рдирд╛:
./mvnw package -DskipTests
java -jar target/microservices-gateway-1.0.0.jar
рд╣рдо рдЬрд╛рдБрдЪ:
$ curl http://localhost:8080/
Number of requests 1 (gateway 38560358, secret "default-secret")
рд╕рдм рдХреБрдЫ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реИред рдПрдХ рдЪреМрдХрд╕ рдкрд╛рдардХ рдзреНрдпрд╛рди рджреЗрдЧрд╛ рдХрд┐ рдЧреЗрдЯрд╡реЗ рдХреЛ рдмрд╛рдпрдкрд╛рд╕ рдХрд░рддреЗ рд╣реБрдП рд╕реАрдзреЗ рдмреИрдХрдПрдВрдб рддрдХ рдкрд╣реБрдБрдЪрдиреЗ рд╕реЗ рд╣рдореЗрдВ рдХреБрдЫ рднреА рдирд╣реАрдВ рд░реЛрдХрддрд╛ рд╣реИ (
рд╕рд╛рде рд╣реА, рджреЛрдиреЛрдВ рд╕реЗрд╡рд╛рдПрдВ рдПрдХ рдлрд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо рд╕рд╛рдЭрд╛ рдХрд░рддреА рд╣реИрдВ, рдзрд╛рд░рд╛рдПрдВ рдЙрддреНрдкрдиреНрди рдХрд░рддреА рд╣реИрдВ рдФрд░ рдПрдХ рдХреНрд╖рдг рдореЗрдВ рдПрдХ рджреВрд╕рд░реЗ рдХреЗ рд╕рд╛рде рд╣рд╕реНрддрдХреНрд╖реЗрдк рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рд╕рдХрддреА рд╣реИрдВред рд╣рдорд╛рд░реА рдорд╛рдЗрдХреНрд░реЛрд╕рд░реНрд╡рд┐рд╕реЗрдЬ рдХреЛ рдЕрд▓рдЧ рдХрд░рдирд╛ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ред рдпрд╣ рд╡рд░реНрдЪреБрдЕрд▓ рдорд╢реАрдиреЛрдВ (рд╕рдВрд╕рд╛рдзрди рдЧрд╣рди, рд▓рдВрдмреЗ рд╕реНрдЯрд╛рд░реНрдЯрдЕрдк) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдпрд╛ рдХрдВрдЯреЗрдирд░реАрдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╡рд┐рднрд┐рдиреНрди рдорд╢реАрдиреЛрдВ (рдмрд╣реБрдд рд╕рд╛рд░рд╛ рдкреИрд╕рд╛, рдХрдард┐рди) рдкрд░ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЛ рд╡рд┐рддрд░рд┐рдд рдХрд░рдХреЗ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЬреИрд╕рд╛ рдХрд┐ рдЕрдкреЗрдХреНрд╖рд┐рдд рдерд╛, рд╣рдо рддреАрд╕рд░рд╛ рд╡рд┐рдХрд▓реНрдк рдЪреБрдирддреЗ рд╣реИрдВ рдФрд░
рдбрд╛рдХ рдореЗрдВ рдХрд╛рдо рдХрд░рдиреЗрд╡рд╛рд▓рд╛ рдордЬрд╝рджреВрд░
рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ, рдбреЙрдХрдЯрд░ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдХрдВрдЯреЗрдирд░ рдмрдирд╛рддрд╛ рд╣реИ, рдкреНрд░рддрд┐ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдПрдХред рдбреЙрдХрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдбреЙрдХрд░рдлрд╛рдЗрд▓ рд▓рд┐рдЦрдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ - рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдмрдирд╛рдиреЗ рдФрд░ рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рд░реНрджреЗрд╢ред рдЗрд╕рдХреЗ рдмрд╛рдж, рдЖрдк рдЗрдореЗрдЬ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕реЗ рдЗрдореЗрдЬ рд░рдЬрд┐рд╕реНрдЯреНрд░реА рдореЗрдВ рдЕрдкрд▓реЛрдб рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рдирдВрдмрд░ XNUMX.
Dockerfile
рдПрдХ рдЫрд╡рд┐ рдХреА рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдЗрд╕рдХрд╛ рдЖрдХрд╛рд░ рд╣реИред рдПрдХ рдХреЙрдореНрдкреИрдХреНрдЯ рдЫрд╡рд┐ рджреВрд░рд╕реНрде рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рд╕реЗ рддреЗрдЬреА рд╕реЗ рдбрд╛рдЙрдирд▓реЛрдб рд╣реЛрдЧреА, рдХрдо рдЬрдЧрд╣ рд▓реЗрдЧреА, рдФрд░ рдЖрдкрдХреА рд╕реЗрд╡рд╛ рддреЗрдЬреА рд╕реЗ рд╢реБрд░реВ рд╣реЛ рдЬрд╛рдПрдЧреАред рдХреЛрдИ рднреА рдЫрд╡рд┐ рдЖрдзрд╛рд░ рдЫрд╡рд┐ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдмрдирд╛рдИ рдЧрдИ рд╣реИ, рдФрд░ рдпрд╣ рд╕рдмрд╕реЗ рдиреНрдпреВрдирддрд░ рд╡рд┐рдХрд▓реНрдк рдЪреБрдирдиреЗ рдХреА рд╕рд┐рдлрд╛рд░рд┐рд╢ рдХреА рдЬрд╛рддреА рд╣реИред рдЕрд▓реНрдкрд╛рдЗрди рдПрдХ рдЕрдЪреНрдЫрд╛ рд╡рд┐рдХрд▓реНрдк рд╣реИ, рдиреНрдпреВрдирддрдо рдкреИрдХреЗрдЬ рдХреЗ рд╕рд╛рде рдПрдХ рдкреВрд░реНрдг рд▓рд┐рдирдХреНрд╕ рд╡рд┐рддрд░рдгред
рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдЗрдП "рдорд╛рдереЗ рдкрд░" рдбреЙрдХрд░рдлрд╛рдЗрд▓ рд▓рд┐рдЦрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВ (рдореИрдВ рддреБрд░рдВрдд рдХрд╣реВрдВрдЧрд╛ рдХрд┐ рдпрд╣ рдПрдХ рдмреБрд░рд╛ рддрд░реАрдХрд╛ рд╣реИ, рдРрд╕рд╛ рдордд рдХрд░реЛ):
FROM adoptopenjdk/openjdk11:jdk-11.0.5_10-alpine
ADD . /src
WORKDIR /src
RUN ./mvnw package -DskipTests
EXPOSE 8080
ENTRYPOINT ["java","-jar","target/microservices-gateway-1.0.0.jar"]
рдпрд╣рд╛рдВ рд╣рдо рдЕрдкрдиреА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЗ рд▓рд┐рдП рдкрд╣рд▓реЗ рд╕реЗ рд╕реНрдерд╛рдкрд┐рдд JDK рдХреЗ рд╕рд╛рде рдПрдХ рдЕрд▓реНрдкрд╛рдЗрди рдЖрдзрд╛рд░рд┐рдд рдЖрдзрд╛рд░ рдЫрд╡рд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВред ADD рдХрдорд╛рдВрдб рдХреЗ рд╕рд╛рде, рд╣рдо рд╡рд░реНрддрдорд╛рди src рдбрд╛рдпрд░реЗрдХреНрдЯрд░реА рдХреЛ рдЗрдореЗрдЬ рдореЗрдВ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рдЗрд╕реЗ рд╡рд░реНрдХрд┐рдВрдЧ (WORKDIR) рдХреЗ рд░реВрдк рдореЗрдВ рдЪрд┐рд╣реНрдирд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдмрд┐рд▓реНрдб рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред EXPOSE 8080 рдХрдорд╛рдВрдб рдбреЙрдХрдЯрд░ рдХреЛ рд╕рдВрдХреЗрдд рджреЗрддрд╛ рд╣реИ рдХрд┐ рдХрдВрдЯреЗрдирд░ рдореЗрдВ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЕрдкрдиреЗ рдкреЛрд░реНрдЯ 8080 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдЧрд╛ (рдпрд╣ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдмрд╛рд╣рд░ рд╕реЗ рдПрдХреНрд╕реЗрд╕ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдирд╣реАрдВ рдмрдирд╛рдПрдЧрд╛, рд▓реЗрдХрд┐рди рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдПрдХреНрд╕реЗрд╕ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЙрд╕реА рдбреЙрдХрдЯрд░ рдиреЗрдЯрд╡рд░реНрдХ рдкрд░ рдХрд┐рд╕реА рдЕрдиреНрдп рдХрдВрдЯреЗрдирд░ рд╕реЗ ).
рд╕реЗрд╡рд╛рдУрдВ рдХреЛ рдЫрд╡рд┐рдпреЛрдВ рдореЗрдВ рдкреИрдХреЗрдЬ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреА рдЬрдбрд╝ рд╕реЗ рдЖрджреЗрд╢ рдЪрд▓рд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:
docker image build . -t msvc-backend:1.0.0
рдирддреАрдЬрд╛ 456 рдПрдордмреА рдЫрд╡рд┐ рд╣реИ (рдЬрд┐рд╕рдореЗрдВ рд╕реЗ рдЖрдзрд╛рд░ рдЬреЗрдбреАрдХреЗ рдЫрд╡рд┐ 340 рдПрдордмреА рдкрд░ рдХрдмреНрдЬрд╛ рдХрд░ рд▓реЗрддреА рд╣реИ)ред рдФрд░ рд╕рдм рдЗрд╕ рддрдереНрдп рдХреЗ рдмрд╛рд╡рдЬреВрдж рдХрд┐ рд╣рдорд╛рд░реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдХрдХреНрд╖рд╛рдУрдВ рдХреЛ рдПрдХ рдЙрдВрдЧрд▓реА рдкрд░ рдЧрд┐рдирд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд╣рдорд╛рд░реА рдЫрд╡рд┐ рдХреЗ рдЖрдХрд╛рд░ рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП:
- рд╣рдо рдорд▓реНрдЯреА-рд╕реНрдЯреЗрдк рдЕрд╕реЗрдВрдмрд▓реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рдкрд╣рд▓реЗ рдЪрд░рдг рдореЗрдВ рд╣рдо рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░реЗрдВрдЧреЗ, рджреВрд╕рд░реЗ рдЪрд░рдг рдореЗрдВ рд╣рдо рдЬреЗрдЖрд░рдИ рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВрдЧреЗ, рдФрд░ рддреАрд╕рд░реЗ рдЪрд░рдг рдореЗрдВ рд╣рдо рдЗрд╕реЗ рдПрдХ рдирдИ рд╕реНрд╡рдЪреНрдЫ рдЕрд▓реНрдкрд╛рдЗрди рдЫрд╡рд┐ рдореЗрдВ рдХреЙрдкреА рдХрд░реЗрдВрдЧреЗред рдХреБрд▓ рдорд┐рд▓рд╛рдХрд░, рдЕрдВрддрд┐рдо рдЫрд╡рд┐ рдореЗрдВ рдХреЗрд╡рд▓ рдЖрд╡рд╢реНрдпрдХ рдШрдЯрдХ рд╣реЛрдВрдЧреЗред
- рдЖрдЗрдП рдЬрд╛рд╡рд╛ рдХреЗ рдореЙрдбреНрдпреВрд▓рд░рд▓рд╛рдЗрдЬреЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред Java 9 рд╕реЗ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реБрдП, рдЖрдк jlink рдЯреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╕рд┐рд░реНрдл рдЕрдкрдиреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдореЙрдбреНрдпреВрд▓ рд╕реЗ JRE рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ
рдЬрд┐рдЬреНрдЮрд╛рд╕реБрдУрдВ рдХреЗ рд▓рд┐рдП, рдпрд╣рд╛рдВ рдЗрдореЗрдЬ рд░рд┐рдбрдХреНрд╢рди рдПрдкреНрд░реЛрдЪ рдкрд░ рдПрдХ рдЕрдЪреНрдЫрд╛ рд▓реЗрдЦ рд╣реИред
рдЕрдВрддрд┐рдо рдбреЙрдХрд░рдлрд╛рдЗрд▓:
FROM adoptopenjdk/openjdk11:jdk-11.0.5_10-alpine as builder
ADD . /src
WORKDIR /src
RUN ./mvnw package -DskipTests
FROM alpine:3.10.3 as packager
RUN apk --no-cache add openjdk11-jdk openjdk11-jmods
ENV JAVA_MINIMAL="/opt/java-minimal"
RUN /usr/lib/jvm/java-11-openjdk/bin/jlink
--verbose
--add-modules
java.base,java.sql,java.naming,java.desktop,java.management,java.security.jgss,java.instrument
--compress 2 --strip-debug --no-header-files --no-man-pages
--release-info="add:IMPLEMENTOR=radistao:IMPLEMENTOR_VERSION=radistao_JRE"
--output "$JAVA_MINIMAL"
FROM alpine:3.10.3
LABEL maintainer="Anton Shelenkov [email protected]"
ENV JAVA_HOME=/opt/java-minimal
ENV PATH="$PATH:$JAVA_HOME/bin"
COPY --from=packager "$JAVA_HOME" "$JAVA_HOME"
COPY --from=builder /src/target/microservices-backend-*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]
рд╣рдордиреЗ рдЫрд╡рд┐ рдХреЛ рдлрд┐рд░ рд╕реЗ рдмрдирд╛рдпрд╛, рдФрд░ рдЗрд╕рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рдЗрд╕рдХрд╛ рд╡рдЬрди 6 рдЧреБрдирд╛ рдХрдо рд╣реЛ рдЧрдпрд╛, рдЬрд┐рд╕рдХреА рдорд╛рддреНрд░рд╛ 77 рдПрдордмреА рдереАред рдЗрддрдирд╛ рдЦрд░рд╛рдм рднреА рдирд╣реАрдВред рдЙрд╕рдХреЗ рдмрд╛рдж, рддреИрдпрд╛рд░ рдЫрд╡рд┐рдпреЛрдВ рдХреЛ рдЫрд╡рд┐ рд░рдЬрд┐рд╕реНрдЯреНрд░реА рдореЗрдВ рдЕрдкрд▓реЛрдб рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рддрд╛рдХрд┐ рдЖрдкрдХреА рдЫрд╡рд┐рдпрд╛рдВ рдЗрдВрдЯрд░рдиреЗрдЯ рд╕реЗ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрд▓рдмреНрдз рд╣реЛрдВред
рдбреЙрдХрд░ рдореЗрдВ рд╕рд╣-рдЪрд▓ рд░рд╣реА рд╕реЗрд╡рд╛рдПрдВ
рдЖрд░рдВрдн рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реА рд╕реЗрд╡рд╛рдПрдВ рдПрдХ рд╣реА рдиреЗрдЯрд╡рд░реНрдХ рдкрд░ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдПред рдбреЙрдХрдЯрд░ рдореЗрдВ рдХрдИ рдкреНрд░рдХрд╛рд░ рдХреЗ рдиреЗрдЯрд╡рд░реНрдХ рд╣реИрдВ, рдФрд░ рд╣рдо рдЙрдирдореЗрдВ рд╕реЗ рд╕рдмрд╕реЗ рдЖрджрд┐рдо - рдмреНрд░рд┐рдЬ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ рдЖрдкрдХреЛ рдПрдХ рд╣реА рд╣реЛрд╕реНрдЯ рдкрд░ рдЪрд▓рдиреЗ рд╡рд╛рд▓реЗ рдиреЗрдЯрд╡рд░реНрдХ рдХрдВрдЯреЗрдирд░реЛрдВ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдирд┐рдореНрди рдЖрджреЗрд╢ рдХреЗ рд╕рд╛рде рдПрдХ рдиреЗрдЯрд╡рд░реНрдХ рдмрдирд╛рдПрдБ:
docker network create msvc-network
рдЗрд╕рдХреЗ рдмрд╛рдж, 'рдмреИрдХрдПрдВрдб' рдирд╛рдо рдХреЗ рдмреИрдХрдПрдВрдб рдХрдВрдЯреЗрдирд░ рдХреЛ рдорд╛рдЗрдХреНрд░реЛрд╕рд░реНрд╡рд┐рд╕реЗрдЬ-рдмреИрдХрдПрдВрдб:1.0.0 рдЗрдореЗрдЬ рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░реЗрдВ:
docker run -dit --name backend --network msvc-net microservices-backend:1.0.0
рдпрд╣ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдХрд┐ рдмреНрд░рд┐рдЬ рдиреЗрдЯрд╡рд░реНрдХ рдХрдВрдЯреЗрдирд░реЛрдВ рдХреЗ рд▓рд┐рдП рдЙрдирдХреЗ рдирд╛рдо рд╕реЗ рдЖрдЙрдЯ рдСрдл рдж рдмреЙрдХреНрд╕ рд╕рд░реНрд╡рд┐рд╕ рдбрд┐рд╕реНрдХрд╡рд░реА рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рдпрд╛рдиреА рдмреИрдХрдПрдВрдб рд╕рд░реНрд╡рд┐рд╕ docker network рдХреЗ рдЕрдВрджрд░ at рдкрд░ рдЙрдкрд▓рдмреНрдз рд╣реЛрдЧреА
рдЧреЗрдЯрд╡реЗ рд╢реБрд░реВ рдХрд░рдирд╛:
docker run -dit -p 80:8080 --env secret=my-real-secret --env BACKEND_URL=http://backend:8080/ --name gateway --network msvc-net microservices-gateway:1.0.0
рдЗрд╕ рдЖрджреЗрд╢ рдореЗрдВ, рд╣рдо рдЗрдВрдЧрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рд╣рдо рдЕрдкрдиреЗ рд╣реЛрд╕реНрдЯ рдХреЗ рдкреЛрд░реНрдЯ 80 рдХреЛ рдХрдВрдЯреЗрдирд░ рдХреЗ рдкреЛрд░реНрдЯ 8080 рдкрд░ рдЕрдЧреНрд░реЗрд╖рд┐рдд рдХрд░ рд░рд╣реЗ рд╣реИрдВред рд╣рдо рдкрд░реНрдпрд╛рд╡рд░рдг рдЪрд░ рд╕реЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП env рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рд╡рд╕рдВрдд рджреНрд╡рд╛рд░рд╛ рдкрдврд╝реЗ рдЬрд╛рдПрдВрдЧреЗ рдФрд░ application.properties рд╕реЗ рдЧреБрдгреЛрдВ рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░реЗрдВрдЧреЗред
рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ
рдирд┐рд╖реНрдХрд░реНрд╖
рдирддреАрдЬрддрди, рд╣рдордиреЗ рджреЛ рд╕рд░рд▓ рдорд╛рдЗрдХреНрд░реЛрд╕рд░реНрд╡рд┐рд╕реЗрдЬ рдмрдирд╛рдП, рдЙрдиреНрд╣реЗрдВ рдбреЙрдХрдЯрд░ рдХрдВрдЯреЗрдирд░реЛрдВ рдореЗрдВ рдкреИрдХ рдХрд┐рдпрд╛ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдПрдХ рд╣реА рдорд╢реАрди рдкрд░ рдПрдХ рд╕рд╛рде рд▓реЙрдиреНрдЪ рдХрд┐рдпрд╛ред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдкрд░рд┐рдгрд╛рдореА рдкреНрд░рдгрд╛рд▓реА рдХреЗ рдХрдИ рдиреБрдХрд╕рд╛рди рд╣реИрдВ:
- рдЦрд░рд╛рдм рджреЛрд╖ рд╕рд╣рд┐рд╖реНрдгреБрддрд╛ - рд╣рдорд╛рд░реЗ рд▓рд┐рдП рд╕рдм рдХреБрдЫ рдПрдХ рд╕рд░реНрд╡рд░ рдкрд░ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ
- рдЦрд░рд╛рдм рдЕрдиреБрдорд╛рдкрдиреАрдпрддрд╛ - рдЬрдм рд▓реЛрдб рдмрдврд╝рддрд╛ рд╣реИ, рддреЛ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдХрд┐ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдЕрддрд┐рд░рд┐рдХреНрдд рд╕реЗрд╡рд╛ рдЗрдВрд╕реНрдЯреЗрдВрд╕ рдХреЛ рддреИрдирд╛рдд рдХрд┐рдпрд╛ рдЬрд╛рдП рдФрд░ рдЙрдирдХреЗ рдмреАрдЪ рд▓реЛрдб рдХреЛ рд╕рдВрддреБрд▓рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдП
- рд▓реЙрдиреНрдЪ рдХреА рдЬрдЯрд┐рд▓рддрд╛ - рд╣рдореЗрдВ рдХрдо рд╕реЗ рдХрдо 3 рдХрдорд╛рдВрдб рджрд░реНрдЬ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдереА, рдФрд░ рдХреБрдЫ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде (рдпрд╣ рдХреЗрд╡рд▓ 2 рд╕реЗрд╡рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рд╣реИ)
рдЙрдкрд░реЛрдХреНрдд рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рдареАрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдХрдИ рд╕рдорд╛рдзрд╛рди рд╣реИрдВ рдЬреИрд╕реЗ рдбреЙрдХрд░ рдЭреБрдВрдб, рдШреБрдордВрддреВ, рдХреБрдмреЗрд░рдиреЗрдЯреНрд╕ рдпрд╛ рдУрдкрдирд╢рд┐рдлреНрдЯред рдпрджрд┐ рдкреВрд░рд╛ рд╕рд┐рд╕реНрдЯрдо рдЬрд╛рд╡рд╛ рдореЗрдВ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ, рддреЛ рдЖрдк рд╕реНрдкреНрд░рд┐рдВрдЧ рдХреНрд▓рд╛рдЙрдб рдХреА рдУрд░ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ (
╨Т
рд╕реНрд░реЛрдд: www.habr.com