рдЬрд╛рд╡рд╛ рдкреНрд░реМрджреНрдпреЛрдЧрд┐рдХрд┐рдпреЛрдВ рдХреЗ рдПрдХ рдЖрдзреБрдирд┐рдХ рдвреЗрд░ рдкрд░ рдорд╛рдЗрдХреНрд░реЛрд╕рд┐рд╕реНрдЯрд╡рд░реНрдХ рд╡рд╛рд╕реНрддреБрдХрд▓рд╛

рд╣рдорд╛рд░реЗ рдкрд╛рд╕ JDK 11, рдХреЛрдЯрд▓рд┐рди, рд╕реНрдкреНрд░рд┐рдВрдЧ 5 рдФрд░ рд╕реНрдкреНрд░рд┐рдВрдЧ рдмреВрдЯ 2, рдЧреНрд░реИрдбрд▓ 5 рдкреНрд░реЛрдбрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рдХреЛрдЯрд▓рд┐рди DSL, JUnit 5 рдФрд░ рд╕рд░реНрд╡рд┐рд╕ рдбрд┐рд╕реНрдХрд╡рд░реА рдХреЗ рд▓рд┐рдП рдПрдХ рджрд░реНрдЬрди рд╕реНрдкреНрд░рд┐рдВрдЧ рдХреНрд▓рд╛рдЙрдб рд╕реНрдЯреИрдХ рд▓рд╛рдЗрдмреНрд░реЗрд░реА, рдЧреЗрдЯрд╡реЗ рдПрдкреАрдЖрдИ, рдХреНрд▓рд╛рдЗрдВрдЯ рдмреИрд▓реЗрдВрд╕рд┐рдВрдЧ, рдФрд░ рд╕рд░реНрдХрд┐рдЯ рдмреНрд░реЗрдХрд░ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдерд╛ред рдШреЛрд╖рдгрд╛рддреНрдордХ HTTP рдХреНрд▓рд╛рдЗрдВрдЯ рд▓рд┐рдЦрдирд╛, рдЯреНрд░реЗрд╕рд┐рдВрдЧ рд╡рд┐рддрд░рд┐рдд рдХрд░рдирд╛ рдФрд░ рд╡рд╣ рд╕рдмред рдРрд╕рд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рд╕рдм рдПрдХ microservice рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдерд╛ - рдХреЗрд╡рд▓ рдордиреЛрд░рдВрдЬрди рдХреЗ рд▓рд┐рдП ...

рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐


рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рдЖрдк рдЬрд╛рд╡рд╛ рджреБрдирд┐рдпрд╛ рдореЗрдВ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рддрдХрдиреАрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рдорд╛рдЗрдХреНрд░реЛрд╕реИрд╕ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рджреЗрдЦреЗрдВрдЧреЗ, рдЬрд┐рдирдореЗрдВ рд╕реЗ рдореБрдЦреНрдп рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рд╣реИрдВ (рдпреЗ рд╕рдВрд╕реНрдХрд░рдг рдкреНрд░рдХрд╛рд╢рди рдХреЗ рд╕рдордп рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ):
рддрдХрдиреАрдХ рдХрд╛ рдкреНрд░рдХрд╛рд░рдирд╛рдорд╕рдВрд╕реНрдХрд░рдг
рдордВрдЪJDK11.0.1
рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛Kotlin1.3.10
рдЖрд╡реЗрджрди рдХреА рд░реВрдкрд░реЗрдЦрд╛рд╡рд╕рдВрдд рдХреА рд░реВрдкрд░реЗрдЦрд╛5.0.9
рд╡рд╕рдВрдд рдХрд╛ рдмреВрдЯ2.0.5
рд╕рд┐рд╕реНрдЯрдо рдмрдирд╛рдПрдВGradle5.0
рдЧреНрд░реЗрдбрд▓ рдХреЛрдЯрд▓рд┐рди рдбреА.рдПрд╕.рдПрд▓.1.0.4
рдпреВрдирд┐рдЯ рдЯреЗрд╕реНрдЯрд┐рдВрдЧ рдлреНрд░реЗрдорд╡рд░реНрдХJUnit5.1.1
рд╡рд╕рдВрдд рдХрд╛ рдмрд╛рджрд▓
рд╕рд┐рдВрдЧрд▓ рдПрдХреНрд╕реЗрд╕ рдкреНрд╡рд╛рдЗрдВрдЯ (рдПрдкреАрдЖрдИ рдЧреЗрдЯрд╡реЗ)рд╕реНрдкреНрд░рд┐рдВрдЧ рдХреНрд▓рд╛рдЙрдб рдЧреЗрдЯрд╡реЗрд░рд┐рд▓реАрдЬрд╝ рдЯреНрд░реЗрди рдлрд┐рдВрдЪрд▓реА SR2 рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд╕реНрдкреНрд░рд┐рдВрдЧ рдХреНрд▓рд╛рдЙрдб рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реИ
рдХреЗрдВрджреНрд░реАрдХреГрдд рд╡рд┐рдиреНрдпрд╛рд╕рд╕реНрдкреНрд░рд┐рдВрдЧ рдХреНрд▓рд╛рдЙрдб рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди
рдЕрдиреБрд░реЛрдз рдЕрдиреБрд░реЗрдЦрдг (рд╡рд┐рддрд░рд┐рдд рдЕрдиреБрд░реЗрдЦрдг)рдмрд╕рдВрдд рдореЗрдШ рдмрд╛рджрд╢рд╛рд╣
рдШреЛрд╖рдгрд╛рддреНрдордХ HTTP рдХреНрд▓рд╛рдЗрдВрдЯрд╕реНрдкреНрд░рд┐рдВрдЧ рдХреНрд▓рд╛рдЙрдб рдУрдкрдирдлрд╛рдЗрди
рд╕реЗрд╡рд╛ рдЦреЛрдЬрд╕реНрдкреНрд░рд┐рдВрдЧ рдХреНрд▓рд╛рдЙрдб рдиреЗрдЯрдлреНрд▓рд┐рдХреНрд╕ рдпреВрд░реЗрдХрд╛
рд╕рд░реНрдХрд┐рдЯ рдмреНрд░реЗрдХрд░рд╕реНрдкреНрд░рд┐рдВрдЧ рдХреНрд▓рд╛рдЙрдб рдиреЗрдЯрдлреНрд▓рд┐рдХреНрд╕ рд╣рд┐рд╕реНрдЯреНрд░рд┐рдХреНрд╕
рдХреНрд▓рд╛рдЗрдВрдЯ-рд╕рд╛рдЗрдб рд▓реЛрдб рд╕рдВрддреБрд▓рдирд╕реНрдкреНрд░рд┐рдВрдЧ рдХреНрд▓рд╛рдЙрдб рдиреЗрдЯрдлреНрд▓рд┐рдХреНрд╕ рд░рд┐рдмрди

рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ 5 рдорд╛рдЗрдХреНрд░реЛрд╕рд░реНрд╡рд┐рд╕реЗрдЬ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ: 3 рдЕрд╡рд╕рдВрд░рдЪрдирд╛ (рдХреЙрдиреНрдлрд┐рдЧрд░ рд╕рд░реНрд╡рд░, рд╕рд░реНрд╡рд┐рд╕ рдбрд┐рд╕реНрдХрд╡рд░реА рд╕рд░реНрд╡рд░, рдпреВрдЖрдИ рдЧреЗрдЯрд╡реЗ) рдФрд░ рдлреНрд░рдВрдЯ-рдПрдВрдб (рдпреВрдЖрдИ) рдФрд░ рдмреИрдХ-рдПрдВрдб (рдЖрдЗрдЯрдо рд╕реЗрд╡рд╛) рдХреЗ рдЙрджрд╛рд╣рд░рдг:


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

рддреНрдпрд╛рдЧ


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

рд╕рд░реНрд╡рд░ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░реЗрдВ


рд╕реНрдкреНрд░рд┐рдВрдЧ рдХреНрд▓рд╛рдЙрдб рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЗ рдХреЗрдВрджреНрд░реАрдХреГрдд рднрдВрдбрд╛рд░ рдХреЛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдХрдиреНрдлрд╝рд┐рдЧреНрд╕ рдХреЛ рд╡рд┐рднрд┐рдиреНрди рд╕реНрд░реЛрддреЛрдВ рд╕реЗ рдкрдврд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рдЕрд▓рдЧ рдЧрд┐рдЯ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА; рдЗрд╕ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ, рд╕рд░рд▓рддрд╛ рдФрд░ рд╕реНрдкрд╖реНрдЯрддрд╛ рдХреЗ рд▓рд┐рдП, рд╡реЗ рдЖрд╡реЗрджрди рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдореЗрдВ рд╣реИрдВ:


рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдХреЙрдиреНрдлрд╝рд┐рдЧ рд╕рд░реНрд╡рд░ (Application.yml) рдХрд╛ рд╡рд┐рдиреНрдпрд╛рд╕ рд╕реНрд╡рдпрдВ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:

 spring: profiles: active: native cloud: config: server: native: search-locations: classpath:/config server: port: 8888 

рдкреЛрд░реНрдЯ 8888 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рд╕рд░реНрд╡рд░ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рдЙрдирдХреЗ bootstrap.yml рдореЗрдВ рдЕрдкрдиреЗ рдкреЛрд░реНрдЯ рдХреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирд╣реАрдВ рдХрд░рдиреЗ рджреЗрддрд╛ рд╣реИред рд╕реНрдЯрд╛рд░реНрдЯрдЕрдк рдкрд░, рд╡реЗ HTTP API рдХреЙрдиреНрдлрд╝рд┐рдЧ рд╕рд░реНрд╡рд░ рдкрд░ GET рдЕрдиреБрд░реЛрдз рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдХреЗ рдЕрдкрдирд╛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдЕрдкрд▓реЛрдб рдХрд░рддреЗ рд╣реИрдВред

рдЗрд╕ microservice рдХреЗ рд▓рд┐рдП рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛрдб рдореЗрдВ рдХреЗрд╡рд▓ рдПрдХ рдлрд╝рд╛рдЗрд▓ рд╣реЛрддреА рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреНрд▓рд╛рд╕ рдХреА рдШреЛрд╖рдгрд╛ рдФрд░ рдореБрдЦреНрдп рд╡рд┐рдзрд┐ рд╢рд╛рдорд┐рд▓ рд╣реЛрддреА рд╣реИ, рдЬреЛ рд╕рдордХрдХреНрд╖ рдЬрд╛рд╡рд╛ рдХреЛрдб рдХреЗ рд╡рд┐рдкрд░реАрдд рдПрдХ рд╢реАрд░реНрд╖-рд╕реНрддрд░реАрдп рдлрд╝рдВрдХреНрд╢рди рд╣реИ:

 @SpringBootApplication @EnableConfigServer class ConfigServerApplication fun main(args: Array<String>) { runApplication<ConfigServerApplication>(*args) } 

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

рд╕реЗрд╡рд╛ рдЦреЛрдЬ рд╕рд░реНрд╡рд░


рд╕реЗрд╡рд╛ рдХреА рдЦреЛрдЬ рдПрдХ рдорд╛рдЗрдХреНрд░реЛрд╕реИрд╕ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдкреИрдЯрд░реНрди рд╣реИ рдЬреЛ рдЖрдкрдХреЛ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рдмреАрдЪ рдЙрдирдХреЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдФрд░ рдиреЗрдЯрд╡рд░реНрдХ рд╕реНрдерд╛рди рдХреА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рд╕рдВрднрд╛рд╡рд┐рдд рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рдЪреЗрд╣рд░реЗ рдкрд░ рдмрд╛рддрдЪреАрдд рдХреЛ рдЖрд╕рд╛рди рдмрдирд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдореЗрдВ рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдШрдЯрдХ рд╕реЗрд╡рд╛ рд░рдЬрд┐рд╕реНрдЯреНрд░реА рд╣реИ - рдорд╛рдЗрдХреНрд░реЛрд╕рд┐рд╕реНрдЯрд░реНрд╕ рдХрд╛ рдПрдХ рдбреЗрдЯрд╛рдмреЗрд╕, рдЙрдирдХреЗ рдЙрджрд╛рд╣рд░рдг рдФрд░ рдиреЗрдЯрд╡рд░реНрдХ рд╕реНрдерд╛рди ( рдпрд╣рд╛рдВ рдЕрдзрд┐рдХ рд╡рд┐рд╡рд░рдг)ред

рдЗрд╕ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ, рд╕реЗрд╡рд╛ рдХреА рдЦреЛрдЬ рдиреЗрдЯрдлреНрд▓рд┐рдХреНрд╕ рдпреВрд░реЗрдХрд╛ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИ, рдЬреЛ рдХреНрд▓рд╛рдЗрдВрдЯ-рд╕рд╛рдЗрдб рд╕рд░реНрд╡рд┐рд╕ рдбрд┐рд╕реНрдХрд╡рд░реА рд╣реИ : рдпреВрд░реЗрдХрд╛ рд╕рд░реНрд╡рд░ рд╕реЗрд╡рд╛ рд░рдЬрд┐рд╕реНрдЯреНрд░реА рдХрд╛ рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдпреВрд░реЗрдХрд╛ рдХреНрд▓рд╛рдЗрдВрдЯ, рдХрд┐рд╕реА рднреА рдорд╛рдЗрдХреНрд░реЛрд╕реЗрд╡рдХ рдХреЗ рд▓рд┐рдП рдЕрдиреБрд░реЛрдз рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдпреВрд░реЗрдХрд╛ рд╕рд░реНрд╡рд░ рдХреЛ рдХреЙрд▓ рдХрд┐рдП рдЧрдП рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреА рд╕реВрдЪреА рдХреЗ рд▓рд┐рдП рд╕рдВрдкрд░реНрдХ рдХрд░рддрд╛ рд╣реИ рдФрд░ рд╕реНрд╡рддрдВрддреНрд░ рд░реВрдк рд╕реЗ рд╕рдВрддреБрд▓рди рд╕рд╛рдзрддрд╛ рд╣реИред рд▓реЛрдб (рдиреЗрдЯрдлреНрд▓рд┐рдХреНрд╕ рд░рд┐рдмрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ)ред рдиреЗрдЯрдлреНрд▓рд┐рдХреНрд╕ рдпреВрд░реЗрдХрд╛, рдХреБрдЫ рдЕрдиреНрдп рдиреЗрдЯрдлреНрд▓рд┐рдХреНрд╕ рдУрдПрд╕рдПрд╕ рд╕реНрдЯреИрдХ рдШрдЯрдХреЛрдВ (рдЬреИрд╕реЗ рдХрд┐ рд╣рд┐рд╕реНрдЯреНрд░рд┐рдХреНрд╕ рдФрд░ рд░рд┐рдмрди) рдХреА рддрд░рд╣ рд╕реНрдкреНрд░рд┐рдВрдЧ рдХреНрд▓рд╛рдЙрдб рдиреЗрдЯрдлреНрд▓рд┐рдХреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕реНрдкреНрд░рд┐рдВрдЧ рдмреВрдЯ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХреАрдХреГрдд рдХрд░рддрд╛ рд╣реИред

рдЕрдкрдиреЗ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдореЗрдВ рд╕реНрдерд┐рдд рд╕реЗрд╡рд╛ рдЦреЛрдЬ рд╕рд░реНрд╡рд░ рдХреЙрдиреНрдлрд┐рдЧрд░ ( bootstrap.yml ) рдореЗрдВ, рдХреЗрд╡рд▓ рдирд╛рдо рдХрд╛ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдФрд░ рдкреИрд░рд╛рдореАрдЯрд░ рдпрд╣ рджрд░реНрд╢рд╛рддрд╛ рд╣реИ рдХрд┐ рдпрджрд┐ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╕рд░реНрд╡рд░ рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░рдирд╛ рдЕрд╕рдВрднрд╡ рд╣реИ, рддреЛ рдорд╛рдЗрдХреНрд░реЛрд╕реИрд╕ рд╕рд░реНрд╡рд┐рд╕ рдХреА рд╢реБрд░реБрдЖрдд рдмрд╛рдзрд┐рдд рд╣реЛ рдЬрд╛рдПрдЧреАред

 spring: application: name: eureka-server cloud: config: fail-fast: true 

рд╢реЗрд╖ рдПрдкреНрд▓рд┐рдХреЗрд╢рди eureka-server.yml рд╡рд┐рдиреНрдпрд╛рд╕ рд╕рд░реНрд╡рд░ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдореЗрдВ eureka-server.yml рдореЗрдВ рд╕реНрдерд┐рдд рд╣реИ:

 server: port: 8761 eureka: client: register-with-eureka: true fetch-registry: false 

рдпреВрд░реЗрдХрд╛ рд╕рд░реНрд╡рд░ рдкреЛрд░реНрдЯ 8761 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рд╕рднреА рдпреВрд░реЗрдХрд╛ рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХреЛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕реЗ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирд╣реАрдВ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред register-with-eureka рдХрд╛ рдорд╛рди (рд╕реНрдкрд╖реНрдЯрддрд╛ рдХреЗ рд▓рд┐рдП рд╕рдВрдХреЗрдд рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, register-with-eureka рдпрд╣ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рднреА рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ) рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдЕрдиреНрдп рдорд╛рдЗрдХреНрд░реЛрд╕реЗрд░реЛ рдХреА рддрд░рд╣ рд╣реА рдПрдкреНрд▓рд┐рдХреЗрд╢рди рднреА рдпреВрд░реЗрдХрд╛ рд╕рд░реНрд╡рд░ рдореЗрдВ рдкрдВрдЬреАрдХреГрдд рд╣реЛрдЧрд╛ред fetch-registry рдкреИрд░рд╛рдореАрдЯрд░ рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдпреВрд░реЗрдХрд╛ рдХреНрд▓рд╛рдЗрдВрдЯ рд╕реЗрд╡рд╛ рд░рдЬрд┐рд╕реНрдЯреНрд░реА рд╕реЗ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдЧрд╛ред

рдкрдВрдЬреАрдХреГрдд рдЖрд╡реЗрджрдиреЛрдВ рдФрд░ рдЕрдиреНрдп рд╕реВрдЪрдирд╛рдУрдВ рдХреА рдПрдХ рд╕реВрдЪреА http://localhost:8761/ : рдкрд░ рдЙрдкрд▓рдмреНрдз рд╣реИред


рд╕реЗрд╡рд╛ рдХреА рдЦреЛрдЬ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рдХрд▓реНрдк рд╣реИрдВ рдХрдВрд╕рд▓, рдЬрд╝реБрдХреАрдкрд░ рдФрд░ рдЕрдиреНрдпред

рдЖрдЗрдЯрдо рд╕реЗрд╡рд╛


рдпрд╣ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдПрдХ рдмреИрдХ-рдПрдВрдб рдХрд╛ рдЙрджрд╛рд╣рд░рдг рд╣реИ, рдЬреЛ рд╡реЗрдм 5 рдлреНрд▓реЛ рдореЗрдВ рджрд┐рдЦрд╛рдИ рджреЗрдиреЗ рд╡рд╛рд▓реЗ рд╡реЗрдмрдлреНрд▓рдХреНрд╕ рдлреНрд░реЗрдорд╡рд░реНрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ (рдЗрд╕рдХреЗ рд▓рд┐рдП рдкреНрд░рд▓реЗрдЦрди рдпрд╣рд╛рдБ рд╣реИ ), рдпрд╛ рдЗрд╕рдХреЗ рд▓рд┐рдП рдХреЛрдЯрд▓рд┐рди рдбреАрдПрд╕рдПрд▓:

 @Bean fun itemsRouter(handler: ItemHandler) = router { path("/items").nest { GET("/", handler::getAll) POST("/", handler::add) GET("/{id}", handler::getOne) PUT("/{id}", handler::update) } } 

HTTP рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЛ ItemHandler рд╡рд░реНрдЧ ItemHandler рдХреЛ рд╕реМрдВрдкрд╛ рдЧрдпрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХреБрдЫ рдЗрдХрд╛рдИ рдХреА рд╡рд╕реНрддреБрдУрдВ рдХреА рд╕реВрдЪреА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рдзрд┐ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ:

 fun getAll(request: ServerRequest) = ServerResponse.ok() .contentType(APPLICATION_JSON_UTF8) .body(fromObject(itemRepository.findAll())) 

spring-cloud-starter-netflix-eureka-client рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдХреЗ рдХрд╛рд░рдг, рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдпреВрд░реЗрдХрд╛ рд╕рд░реНрд╡рд░ рдХреНрд▓рд╛рдЗрдВрдЯ рдмрди рдЬрд╛рддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рдд, рдпрд╣ рдкрдВрдЬреАрдХреГрдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рд╕реЗрд╡рд╛ рд░рдЬрд┐рд╕реНрдЯреНрд░реА рд╕реЗ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИред рдкрдВрдЬреАрдХрд░рдг рдХреЗ рдмрд╛рдж, рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдЖрд╡реГрддреНрддрд┐ рдХреЗ рд╕рд╛рде рдпреВрд░реЗрдХрд╛ рд╕рд░реНрд╡рд░ рдХреЛ рд╣рд╛рд░реНрдЯрдмрд┐рдЯреНрд╕ рднреЗрдЬрддрд╛ рд╣реИ, рдФрд░ рдпрджрд┐ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдЕрд╡рдзрд┐ рдХреЗ рд▓рд┐рдП рдпреВрд░реЗрдХрд╛ рд╕рд░реНрд╡рд░ рджреНрд╡рд╛рд░рд╛ рдЕрдзрд┐рдХрддрдо рд╕рдВрднрд╡ рдореВрд▓реНрдп рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рдкреНрд░рд╛рдкреНрдд рд╣рд╛рд░реНрдЯрдмрд┐рдЯреНрд╕ рдХрд╛ рдкреНрд░рддрд┐рд╢рдд рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╕реАрдорд╛ рд╕реЗ рдХрдо рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╕реЗрд╡рд╛ рд░рдЬрд┐рд╕реНрдЯреНрд░реА рд╕реЗ рд╣рдЯрд╛ рджреА рдЬрд╛рдПрдЧреАред

рдпреВрд░реЗрдХрд╛ рд╕рд░реНрд╡рд░ рдкрд░ рдЕрддрд┐рд░рд┐рдХреНрдд рдореЗрдЯрд╛рдбреЗрдЯрд╛ рднреЗрдЬрдиреЗ рдХреЗ рддрд░реАрдХреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ:

 @PostConstruct private fun addMetadata() = aim.registerAppMetadata(mapOf("description" to "Some description")) 

рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ рдХрд┐ рдпрд╣ рдбреЗрдЯрд╛ рдпреВрд░реЗрдХрд╛ рд╕рд░реНрд╡рд░ рджреНрд╡рд╛рд░рд╛ http://localhost:8761/eureka/apps/items-service рдкреЛрд╕реНрдЯрдореИрди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЬрд╛рдХрд░ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:



рдЖрдЗрдЯрдо рдпреВрдЖрдИ


рдпрд╣ microservice, UI рдЧреЗрдЯрд╡реЗ (рдЕрдЧрд▓реЗ рднрд╛рдЧ рдореЗрдВ рджрд┐рдЦрд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛) рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХрд╛ рдкреНрд░рджрд░реНрд╢рди рдХрд░рдиреЗ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЖрдЗрдЯрдо рд╕реЗрд╡рд╛ рдХреЗ рд▓рд┐рдП рдлреНрд░рдВрдЯ-рдПрдВрдб рдлрд╝рдВрдХреНрд╢рди рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдХрдИ рддрд░реАрдХреЛрдВ рд╕реЗ REST API рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ:

  1. OpenFeign рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рдПрдкреАрдЖрдИ рдХреЗ рд▓рд┐рдП рдЧреНрд░рд╛рд╣рдХ:

     @FeignClient("items-service", fallbackFactory = ItemsServiceFeignClient.ItemsServiceFeignClientFallbackFactory::class) interface ItemsServiceFeignClient { @GetMapping("/items/{id}") fun getItem(@PathVariable("id") id: Long): String @GetMapping("/not-existing-path") fun testHystrixFallback(): String @Component class ItemsServiceFeignClientFallbackFactory : FallbackFactory<ItemsServiceFeignClient> { private val log = LoggerFactory.getLogger(this::class.java) override fun create(cause: Throwable) = object : ItemsServiceFeignClient { override fun getItem(id: Long): String { log.error("Cannot get item with id=$id") throw ItemsUiException(cause) } override fun testHystrixFallback(): String { log.error("This is expected error") return "{\"error\" : \"Some error\"}" } } } } 
  2. RestTemplate рдмреАрди
    рдЬрд╛рд╡рд╛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдореЗрдВ рдПрдХ рдмрд┐рди рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:

     @Bean @LoadBalanced fun restTemplate() = RestTemplate() 

    рдФрд░ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛:

     fun requestWithRestTemplate(id: Long): String = restTemplate.getForEntity("http://items-service/items/$id", String::class.java).body ?: "No result" 
  3. WebClient рд╡рд░реНрдЧ WebClient (WebFlux рдврд╛рдВрдЪреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╡рд┐рдзрд┐)
    рдЬрд╛рд╡рд╛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдореЗрдВ рдПрдХ рдмрд┐рди рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:

     @Bean fun webClient(loadBalancerClient: LoadBalancerClient) = WebClient.builder() .filter(LoadBalancerExchangeFilterFunction(loadBalancerClient)) .build() 

    рдФрд░ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛:

     fun requestWithWebClient(id: Long): Mono<String> = webClient.get().uri("http://items-service/items/$id").retrieve().bodyToMono(String::class.java) 

рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ рд╕рднреА рддреАрди рддрд░реАрдХреЗ рдПрдХ рд╣реА рдкрд░рд┐рдгрд╛рдо рд▓реМрдЯрд╛рддреЗ рд╣реИрдВ http://localhost:8081/example рдЬрд╛рдХрд░ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:


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

 itemsServiceFeignClient.getItem(1) 

рдпрджрд┐ рдХрд┐рд╕реА рдХрд╛рд░рдг рд╕реЗ рдЕрдиреБрд░реЛрдз рд╡рд┐рдлрд▓ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ FallbackFactory рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рд╡рд╛рд▓реА рдХрдХреНрд╖рд╛ рдХреА рд╕рдВрдмрдВрдзрд┐рдд рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдЬрд┐рд╕рдореЗрдВ рдЖрдкрдХреЛ рддреНрд░реБрдЯрд┐ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдФрд░ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ (рдпрд╛ рдПрдХ рдЕрдкрд╡рд╛рдж рдХреЛ рдЖрдЧреЗ рдлреЗрдВрдХрдиреЗ) рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЗрд╕ рдШрдЯрдирд╛ рдореЗрдВ рдХрд┐ рдирд┐рд╢реНрдЪрд┐рдд рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рд▓рдЧрд╛рддрд╛рд░ рдХреЙрд▓ рд╡рд┐рдлрд▓ рд╣реЛ рдЬрд╛рддреА рд╣реИрдВ, рдлреНрдпреВрдЬ рд╕рд░реНрдХрд┐рдЯ рдХреЛ рдЦреЛрд▓реЗрдЧрд╛ (рд╕рд░реНрдХрд┐рдЯ рдмреНрд░реЗрдХрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдпрд╣рд╛рдВ рдФрд░ рдпрд╣рд╛рдВ ), рдЧрд┐рд░реЗ рд╣реБрдП рдорд╛рдЗрдХреНрд░реЛрд╕рд░реНрд╡рд┐рд╕ рдХреЛ рдкреБрдирд░реНрдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рд╕рдордп рджреЗ рд░рд╣рд╛ рд╣реИред

Feign рдХреНрд▓рд╛рдЗрдВрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ @EnableFeignClients рдПрдкреНрд▓рд┐рдХреЗрд╢рди @EnableFeignClients рдХреЛ рдПрдиреЛрдЯреЗрдЯ рдХрд░рдирд╛ @EnableFeignClients :

 @SpringBootApplication @EnableFeignClients(clients = [ItemsServiceFeignClient::class]) class ItemsUiApplication 

рдлрд╝рд┐рд╢ рдХреНрд▓рд╛рдЗрдВрдЯ рдореЗрдВ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рд┐рд╕реНрдЯреНрд░рд┐рдХреНрд╕ рдХрдордмреИрдХ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рдореНрди рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛:

 feign: hystrix: enabled: true 

рдлрд╝рд┐рдЧреНрдиреЗрдВрдЯ рдХреНрд▓рд╛рдЗрдВрдЯ рдореЗрдВ рд╣рд┐рд╕реНрдЯреНрд░рд┐рдХреНрд╕ рдлрд╝реЙрд▓рдмреИрдХ рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдмрд╕ http://localhost:8081/hystrix-fallback ред Feign рдХреНрд▓рд╛рдЗрдВрдЯ рдЙрд╕ рдкрде рдкрд░ рдЕрдиреБрд░реЛрдз рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдЧрд╛ рдЬреЛ рдЖрдЗрдЯрдо рд╕реЗрд╡рд╛ рдореЗрдВ рдореМрдЬреВрдж рдирд╣реАрдВ рд╣реИ, рдЬреЛ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреА рдУрд░ рд▓реЗ рдЬрд╛рдПрдЧрд╛:

 {"error" : "Some error"} 

рдпреВрдЖрдИ рдЧреЗрдЯрд╡реЗ


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

рдЗрд╕ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ, рдЕрдзрд┐рдХ рд╕реНрдкрд╖реНрдЯрддрд╛ рдХреЗ рд▓рд┐рдП, рдПрдХ рдпреВрдЖрдИ рдЧреЗрдЯрд╡реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рдд, рд╡рд┐рднрд┐рдиреНрди рдпреВрдЖрдИ рдХреЗ рд▓рд┐рдП рдПрдХ рдПрдХрд▓ рдкреНрд░рд╡реЗрд╢ рдмрд┐рдВрджреБ; рдЬрд╛рд╣рд┐рд░ рд╣реИ, рдЧреЗрдЯрд╡реЗ рдПрдкреАрдЖрдИ рдХреЛ рдЗрд╕реА рддрд░рд╣ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдорд╛рдЗрдХреНрд░реЛрд╕реЗрд╡рд╕ рд╕реНрдкреНрд░рд┐рдВрдЧ рдХреНрд▓рд╛рдЙрдб рдЧреЗрдЯрд╡реЗ рдврд╛рдВрдЪреЗ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдПрдХ рд╡рд┐рдХрд▓реНрдк рд╣реИ рдиреЗрдЯрдлреНрд▓рд┐рдХреНрд╕ рдЬрд╝реВрд▓, рдиреЗрдЯрдлреНрд▓рд┐рдХреНрд╕ рдУрдПрд╕рдПрд╕ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рдФрд░ рд╕реНрдкреНрд░рд┐рдВрдЧ рдХреНрд▓рд╛рдЙрдб рдиреЗрдЯрдлреНрд▓рд┐рдХреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕реНрдкреНрд░рд┐рдВрдЧ рдмреВрдЯ рдХреЗ рд╕рд╛рде рдПрдХреАрдХреГрддред
рдпреВрдЖрдИ рдЧреЗрдЯрд╡реЗ рдЬреЗрдирд░реЗрдЯ рдПрд╕рдПрд╕рдПрд▓ рд╕рд░реНрдЯрд┐рдлрд┐рдХреЗрдЯ (рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рд╕реНрдерд┐рдд) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреЛрд░реНрдЯ 443 рдкрд░ рдЪрд▓рддрд╛ рд╣реИред SSL рдФрд░ HTTPS рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдП рдЧрдП рд╣реИрдВ:

 server: port: 443 ssl: key-store: classpath:keystore.p12 key-store-password: qwerty key-alias: test_key key-store-type: PKCS12 

рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд▓реЙрдЧрд┐рди рдФрд░ рдкрд╛рд╕рд╡рд░реНрдб WebFlux-specific ReactiveUserDetailsService рдорд╛рдирдЪрд┐рддреНрд░-рдЖрдзрд╛рд░рд┐рдд рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реИрдВ:

 @Bean fun reactiveUserDetailsService(): ReactiveUserDetailsService { val user = User.withDefaultPasswordEncoder() .username("john_doe").password("qwerty").roles("USER") .build() val admin = User.withDefaultPasswordEncoder() .username("admin").password("admin").roles("ADMIN") .build() return MapReactiveUserDetailsService(user, admin) } 

рд╕реБрд░рдХреНрд╖рд╛ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХреА рдЧрдИ рд╣реИрдВ:

 @Bean fun springWebFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain = http .formLogin().loginPage("/login") .and() .authorizeExchange() .pathMatchers("/login").permitAll() .pathMatchers("/static/**").permitAll() .pathMatchers("/favicon.ico").permitAll() .pathMatchers("/webjars/**").permitAll() .pathMatchers("/actuator/**").permitAll() .anyExchange().authenticated() .and() .csrf().disable() .build() 

рджрд┐рдП рдЧрдП рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рд╡реЗрдм-рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╕реНрдЯреИрдЯрд┐рдХреНрд╕) рд╕рднреА рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдЙрдкрд▓рдмреНрдз рд╣реИ, рдЬрд┐рдирдореЗрдВ рд╡реЗ рднреА рдкреНрд░рдорд╛рдгрд┐рдд рдирд╣реАрдВ рд╣реИрдВ, рдФрд░ рдмрд╛рдХреА рд╕рдм ( .anyExchange() ) рдХреЗрд╡рд▓ рдкреНрд░рдорд╛рдгрд┐рдд рд╣реИред рдпрджрд┐ рдЖрдк рдПрдХ URL рджрд░реНрдЬ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рд╕рдореЗрдВ рдкреНрд░рдорд╛рдгреАрдХрд░рдг рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рддреЛ рдЗрд╕реЗ рд▓реЙрдЧрд┐рди рдкреГрд╖реНрда ( https://localhost/login ) рдкрд░ рдкреБрдирдГ рдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛:


рдпрд╣ рдкреГрд╖реНрда рдмреВрдЯрд╕реНрдЯреНрд░реИрдк рдврд╛рдВрдЪреЗ рдХреЗ рдФрдЬрд╛рд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рд╡реЗрдмрдЬрд╛рд░ рдХреЗ рдЙрдкрдпреЛрдЧ рд╕реЗ рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╕реЗ рдЬреБрдбрд╝рд╛ рд╣реИ, рдЬреЛ рдХреНрд▓рд╛рдЗрдВрдЯ-рд╕рд╛рдЗрдб рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛ рдирд┐рдпрдорд┐рдд рдирд┐рд░реНрднрд░рддрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рдмрдВрдзрд┐рдд рдХрд░рдирд╛ рд╕рдВрднрд╡ рдмрдирд╛рддрд╛ рд╣реИред Thymeleaf рдХрд╛ рдЙрдкрдпреЛрдЧ HTML рдкреЗрдЬ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд▓реЙрдЧрд┐рди рдкреЗрдЬ рддрдХ рдкрд╣реБрдВрдЪ WebFlux рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:

 @Bean fun routes() = router { GET("/login") { ServerResponse.ok().contentType(MediaType.TEXT_HTML).render("login") } } 

рд╕реНрдкреНрд░рд┐рдВрдЧ рдХреНрд▓рд╛рдЙрдб рдЧреЗрдЯрд╡реЗ рд░реВрдЯрд┐рдВрдЧ рдХреЛ рдПрдХ YAML рдпрд╛ рдЬрд╛рд╡рд╛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдореЗрдВ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдорд╛рдЗрдХреНрд░реЛрд╕рд░реНрд╡рд┐рд╕реЗрдЬ рдХреЛ рд░реВрдЯ рдпрд╛ рддреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдЕрд╕рд╛рдЗрди рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ рдпрд╛ рд╕рд░реНрд╡рд┐рд╕ рд░рдЬрд┐рд╕реНрдЯреНрд░реА рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдбреЗрдЯрд╛ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдмрдирд╛рдП рдЬрд╛рддреЗ рд╣реИрдВред рдПрдХ рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ UI рдХреЗ рд╕рд╛рде, рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рд░реВрдЯрд┐рдВрдЧ рдЖрд╡рд╢реНрдпрдХ рд╣реИ, рд╕реЗрд╡рд╛ рд░рдЬрд┐рд╕реНрдЯреНрд░реА рдХреЗ рд╕рд╛рде рдПрдХреАрдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реЛрдЧрд╛:

 spring: cloud: gateway: discovery: locator: enabled: true lower-case-service-id: true include-expression: serviceId.endsWith('-UI') url-expression: "'lb:http://'+serviceId" 

include-expression рдкреИрд░рд╛рдореАрдЯрд░ рдХрд╛ рдорд╛рди рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рд░реВрдЯ рдХреЗрд╡рд▓ рдЙрди рдорд╛рдЗрдХреНрд░реЛ-рд╕реЗрд╡рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдмрдирд╛рдП рдЬрд╛рдПрдВрдЧреЗ рдЬрд┐рдирдХреЗ рдирд╛рдо рдЕрдВрдд рдореЗрдВ -рдпреВрдЖрдИ рд╣реИрдВ , рдФрд░ url-expression рдкреИрд░рд╛рдореАрдЯрд░ рдХрд╛ рдореВрд▓реНрдп рдпрд╣ рд╣реИ рдХрд┐ рд╡реЗ рдПрдЪрдЯреАрдЯреАрдкреАрдПрд╕ рдкрд░ рдЪрд▓рдиреЗ рд╡рд╛рд▓реЗ рдпреВрдЖрдИ рдЧреЗрдЯрд╡реЗ рдХреЗ рд╡рд┐рдкрд░реАрдд, рдФрд░ рдПрдХреНрд╕реЗрд╕ рдХрд┐рдП рдЬрд╛рдиреЗ рдкрд░ HTTP рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкрд╣реБрдВрдЪ рдпреЛрдЧреНрдп рд╣реИрдВред рд╡реЗ рдХреНрд▓рд╛рдЗрдВрдЯ рд▓реЛрдб рдмреИрд▓реЗрдВрд╕рд┐рдВрдЧ (рдиреЗрдЯрдлреНрд▓рд┐рдХреНрд╕ рд░рд┐рдмрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред

рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдЬрд╛рд╡рд╛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдореЗрдВ рдорд╛рд░реНрдЧ рдмрдирд╛рдиреЗ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ (рд╕реЗрд╡рд╛ рд░рдЬрд┐рд╕реНрдЯреНрд░реА рдХреЗ рд╕рд╛рде рдПрдХреАрдХрд░рдг рдХреЗ рдмрд┐рдирд╛):

 @Bean fun routeLocator(builder: RouteLocatorBuilder) = builder.routes { route("eureka-gui") { path("/eureka") filters { rewritePath("/eureka", "/") } uri("lb:http://eureka-server") } route("eureka-internals") { path("/eureka/**") uri("lb:http://eureka-server") } } 

рдкрд╣рд▓реЗ рджрд┐рдЦрд╛рдП рдЧрдП рдпреВрд░реЗрдХрд╛ рд╕рд░реНрд╡рд░ рд╣реЛрдо рдкреЗрдЬ рдкрд░ рдкрд╣рд▓рд╛ рд░реВрдЯ рд░реВрдЯ ( http://localhost:8761 ) рд╣реИ, рджреВрд╕рд░реЗ рдХреЛ рдЗрд╕ рдкреЗрдЬ рдкрд░ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЛ рд▓реЛрдб рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рдПрдкреНрд▓рд┐рдХреЗрд╢рди рджреНрд╡рд╛рд░рд╛ рдмрдирд╛рдП рдЧрдП рд╕рднреА рдорд╛рд░реНрдЧ https://localhost/actuator/gateway/routes ред

рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд microservices рдореЗрдВ, рдпреВрдЖрдИ рдЧреЗрдЯрд╡реЗ рдореЗрдВ рдкреНрд░рдорд╛рдгрд┐рдд рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рд▓реЙрдЧрд┐рди рдФрд░ / рдпрд╛ рднреВрдорд┐рдХрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рдПрдХ рдлрд╝рд┐рд▓реНрдЯрд░ рдмрдирд╛рдпрд╛ рдЬреЛ рдЕрдиреБрд░реЛрдз рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рд╣реЗрдбрд░ рдЬреЛрдбрд╝рддрд╛ рд╣реИ:

 @Component class AddCredentialsGlobalFilter : GlobalFilter { private val loggedInUserHeader = "logged-in-user" private val loggedInUserRolesHeader = "logged-in-user-roles" override fun filter(exchange: ServerWebExchange, chain: GatewayFilterChain) = exchange.getPrincipal<Principal>() .flatMap { val request = exchange.request.mutate() .header(loggedInUserHeader, it.name) .header(loggedInUserRolesHeader, (it as Authentication).authorities?.joinToString(";") ?: "") .build() chain.filter(exchange.mutate().request(request).build()) } } 

рдЕрдм рдпреВрдЖрдИ рдЧреЗрдЯрд╡реЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЖрдЗрдЯрдо рдпреВрдЖрдИ рдХреА рдУрд░ рд░реБрдЦ рдХрд░рддреЗ рд╣реИрдВ - https://localhost/items-ui/greeting , рд╕рд╣реА рдорд╛рди рд▓реЗрдВ рдХрд┐ рдЖрдЗрдЯрдо рдпреВрдЖрдИ рдореЗрдВ рдЗрди рд╣реЗрдбрд░реЛрдВ рдХрд╛ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдкрд╣рд▓реЗ рд╣реА рд▓рд╛рдЧреВ рд╣реЛ рдЪреБрдХрд╛ рд╣реИ:


рд╕реНрдкреНрд░рд┐рдВрдЧ рдХреНрд▓рд╛рдЙрдб рд╕реНрд▓реАрде рдПрдХ рд╡рд┐рддрд░рд┐рдд рдкреНрд░рдгрд╛рд▓реА рдореЗрдВ рдХреНрд╡реЗрд░реА рдЯреНрд░реЗрд╕рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдорд╛рдзрд╛рди рд╣реИред рдЯреНрд░реЗрд╕ рдЖрдИрдбреА (рдкрд╛рд╕-рдереНрд░реВ рдЖрдЗрдбреЗрдВрдЯрд┐рдлрд╝рд╛рдпрд░) рдФрд░ рд╕реНрдкреИрди рдЖрдИрдбреА (рд╡рд░реНрдХ рдЖрдЗрдбреЗрдВрдЯрд┐рдлрд╝рд╛рдпрд░ рдХреА рдпреВрдирд┐рдЯ) рдХреЛ рдХрдИ рдорд╛рдЗрдХреНрд░реЛрд╕реЗрдХреНрд╢рдВрд╕ рд╕реЗ рдЧреБрдЬрд░рдиреЗ рдХреЗ рдЕрдиреБрд░реЛрдз рдХреЗ рд╣реЗрдбрд░ рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ (рдЖрд╕рд╛рди рд╕рдордЭ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рд╕реНрдХреАрдо рдХреЛ рд╕рд░рд▓ рдмрдирд╛рдпрд╛; рдпрд╣рд╛рдБ рдПрдХ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддреГрдд рд╡рд┐рд╡рд░рдг рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ):


рдпрд╣ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдмрд╕ spring-cloud-starter-sleuth рдЬреЛрдбрд╝рдХрд░ рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рд╣реИред

рдЙрдкрдпреБрдХреНрдд рд▓реЙрдЧрд┐рдВрдЧ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдХреЗ, рд╕рдВрдмрдВрдзрд┐рдд рдорд╛рдЗрдХреНрд░реЛрд╕рд░реНрд╡рд┐рд╕ рдХреЗ рдХрдВрд╕реЛрд▓ рдореЗрдВ рдЖрдк рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ (рдЯреНрд░реЗрд╕ рдЖрдИрдбреА рдФрд░ рд╕реНрдкреИрди рдЖрдИрдбреА рдХреЛ рдорд╛рдЗрдХреНрд░реЛрд╕рд░реНрд╡рд┐рд╕ рдХреЗ рдирд╛рдо рдХреЗ рдмрд╛рдж рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ):

 DEBUG [ui-gateway,009b085bfab5d0f2,009b085bfab5d0f2,false] oscghRoutePredicateHandlerMapping : Route matched: CompositeDiscoveryClient_ITEMS-UI DEBUG [items-ui,009b085bfab5d0f2,947bff0ce8d184f4,false] oswrfunction.server.RouterFunctions : Predicate "(GET && /example)" matches against "GET /example" DEBUG [items-service,009b085bfab5d0f2,dd3fa674cd994b01,false] oswrfunction.server.RouterFunctions : Predicate "(GET && /{id})" matches against "GET /1" 

рд╡рд┐рддрд░рд┐рдд рдЕрдиреБрд░реЗрдЦрдг рдХреЗ рдПрдХ рдЧреНрд░рд╛рдлрд┐рдХрд▓ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХреЗ рд▓рд┐рдП, рдЖрдк рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЬрд┐рдкрдХрд┐рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рдПрдХ рд╕рд░реНрд╡рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рд░реНрдп рдХрд░реЗрдЧрд╛ рдЬреЛ рдЕрдиреНрдп рдорд╛рдЗрдХреНрд░реЛрд╕рд░реНрд╡рд┐рд╕ рд╕реЗ HTTP рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдПрдХрддреНрд░ рдХрд░рддрд╛ рд╣реИ (рдЕрдзрд┐рдХ рд╡рд┐рд╡рд░рдг рдпрд╣рд╛рдВ )ред

рд╕рднрд╛


OS рдХреЗ рдЖрдзрд╛рд░ рдкрд░, gradlew clean build рдпрд╛ ./gradlew clean build ред

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

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

рд▓рд╛рдВрдЪ


рдореИрдВ рдЗрд╕ рдЖрд▓реЗрдЦ рдореЗрдВ рд╡рд░реНрдгрд┐рдд рдХреНрд░рдо рдореЗрдВ рдЖрд╡реЗрджрди рд╢реБрд░реВ рдХрд░рдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВред рдпрджрд┐ рдЖрдк Intellij IDEA рдХрд╛ рдЙрдкрдпреЛрдЧ рд░рди рдбреИрд╢рдмреЛрд░реНрдб рд╕рдХреНрд╖рдо рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдирд┐рдореНрди рдЬреИрд╕рд╛ рдХреБрдЫ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП:


рдирд┐рд╖реНрдХрд░реНрд╖


рд▓реЗрдЦ рдиреЗ рдЬрд╛рд╡рд╛ рджреБрдирд┐рдпрд╛ рдореЗрдВ рд╡рд░реНрддрдорд╛рди рдкреНрд░реМрджреНрдпреЛрдЧрд┐рдХреА рд╕реНрдЯреИрдХ, рдЗрд╕рдХреЗ рдореБрдЦреНрдп рдШрдЯрдХреЛрдВ рдФрд░ рдХреБрдЫ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдкрд░ рдорд╛рдЗрдХреНрд░реЛрд╕реИрд╕ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдХреА рдЬрд╛рдВрдЪ рдХреАред рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдХрд┐рд╕реА рдХреЗ рд▓рд┐рдП рд╕рд╛рдордЧреНрд░реА рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧреАред рдЖрдкрдХрд╛ рдзреНрдпрд╛рди рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж!

рд╕рдВрджрд░реНрдн


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


All Articles