Sinau carane masang layanan mikro. Part 1. Spring Boot lan Docker
Hey Habr.
Ing artikel iki, aku pengin ngomong babagan pengalaman nggawe lingkungan sinau kanggo eksperimen karo layanan mikro. Nalika aku sinau saben alat anyar, Aku tansah wanted kanggo nyoba ora mung ing mesin lokal, nanging uga ing kahanan luwih nyata. Mulane, aku mutusake kanggo nggawe aplikasi microservice sing disederhanakake, sing mengko bisa "ditutupi" karo kabeh jinis teknologi sing menarik. Syarat utama kanggo proyek kasebut yaiku jarak fungsional maksimal menyang sistem nyata.
Kaping pisanan, aku nyuwil nggawe proyek dadi sawetara langkah:
Gawe rong layanan - 'backend' (backend) lan 'gateway' (gateway), bungkus menyang gambar docker lan atur supaya bisa digunakake bebarengan
Kata Kunci: Java 11, Spring Boot, Docker, image optimization
Kata Kunci: Kubernetes, GKE, manajemen sumber daya, autoscaling, rahasia
Nggawe grafik nganggo Helm 3 kanggo manajemen kluster sing luwih apik
Tags: Helm 3, penyebaran grafik
Nyetel Jenkins lan pipeline kanggo pangiriman otomatis kode kanggo kluster
Kata Kunci: konfigurasi Jenkins, plugins, repositori konfigurasi sing kapisah
Aku rencana kanggo nyawisake artikel kapisah kanggo saben langkah.
Fokus saka seri artikel iki dudu carane nulis layanan mikro, nanging kepiye carane bisa digunakake ing siji sistem. Senajan kabeh iki biasane njaba tanggung jawab pangembang, Aku isih migunani kanggo menowo karo wong-wong mau ing paling 20% ββ(sing, sing ngerti, menehi 80% saka asil). Sawetara topik tanpa syarat penting, kayata keamanan, bakal ditinggalake saka proyek iki, amarga penulis ora ngerti babagan sistem iki mung digawe kanggo panggunaan pribadi. Aku nampani panemu lan kritik sing mbangun.
Nggawe microservices
Layanan kasebut ditulis ing Java 11 nggunakake Spring Boot. Interaksi antar layanan diatur nggunakake REST. Proyèk bakal kalebu jumlah minimal saka tes (supaya mengko ana soko kanggo nyoba ing Jenkins). Kode sumber kanggo layanan kasedhiya ing GitHub: mburi и Gerbang.
Kanggo bisa mriksa status saben layanan, Spring Actuator wis ditambahake menyang dependensi. Iku bakal nggawe / actuator / endpoint kesehatan lan bali status 200 yen layanan siap kanggo nampa lalu lintas, utawa 504 yen ana masalah. Ing kasus iki, iki mriksa rada fiktif, amarga layanan banget prasaja, lan ing cilik saka sawetara force majeure, padha luwih kamungkinan kanggo dadi rampung ora kasedhiya saka tetep sebagian operasional. Nanging ing sistem nyata, Actuator bisa mbantu diagnosa masalah sadurunge pangguna miwiti perang. Contone, yen ana masalah ngakses database, kita bisa kanthi otomatis nanggapi iki kanthi mungkasi panjalukan pangolahan karo conto layanan rusak.
Layanan mburi mburi
Layanan backend mung bakal ngetung lan ngasilake jumlah panjaluk sing ditampa.
Kode pengontrol:
@RestController
public class RequestsCounterController {
private final AtomicLong counter = new AtomicLong();
@GetMapping("/requests")
public Long getRequestsCount() {
return counter.incrementAndGet();
}
}
Tes kontrol:
@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"));
}
}
Gerbang Layanan
Gerbang kasebut bakal nerusake panjalukan menyang layanan backend, ditambah karo informasi ing ngisor iki:
id gateway Perlu supaya bisa mbedakake siji conto gateway saka liyane kanthi respon server
Sawetara "rahasia" sing bakal dadi sandhi sing penting banget (nomer kunci enkripsi cookie penting)
$ curl http://localhost:8080/
Number of requests 1 (gateway 38560358, secret "default-secret")
Kabeh mlaku. Sing maca sing ati-ati bakal nyathet yen ora ana sing ngalangi kita ngakses backend langsung, ngliwati gateway (http://localhost:8081/requests). Kanggo ndandani iki, layanan kasebut kudu digabung dadi siji jaringan, lan mung gateway sing kudu "metu" ing njaba.
Kajaba iku, loro layanan nuduhake siji sistem file, ngasilake stream lan ing wayahe bisa mulai ngganggu siji liyane. Luwih becik ngisolasi layanan mikro kita. Iki bisa digayuh kanthi nyebarake aplikasi ing mesin sing beda-beda (dhuwit akeh, angel), nggunakake mesin virtual (intensif sumber daya, wiwitan dawa), utawa nggunakake containerization. Kaya samesthine, kita milih pilihan katelu lan docker minangka alat kanggo containerization.
docker
Ing cendhak, docker nggawe wadhah sing terisolasi, siji saben aplikasi. Kanggo nggunakake docker, sampeyan kudu nulis Dockerfile - instruksi kanggo mbangun lan mbukak aplikasi. Sabanjure, sampeyan bisa mbangun gambar, upload menyang registri gambar (No. Dockerhub) lan masang microservice ing sembarang lingkungan dockerized ing siji printah.
file docker
Salah sawijining ciri sing paling penting saka gambar yaiku ukurane. Gambar sing kompak bakal diundhuh luwih cepet saka repositori remot, njupuk papan sing luwih sithik, lan layanan sampeyan bakal luwih cepet. Sembarang gambar dibangun kanthi basis gambar dhasar, lan dianjurake kanggo milih pilihan sing paling minimalis. Pilihan sing apik yaiku Alpine, distribusi Linux lengkap kanthi paket minimal.
Pisanan, ayo nyoba nulis Dockerfile "ing bathuk" (aku bakal langsung ngomong yen iki cara sing ala, aja nglakoni):
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"]
Ing kene kita nggunakake gambar basis Alpine kanthi JDK sing wis diinstal kanggo mbangun proyek kita. Kanthi printah ADD, kita nambah direktori src saiki kanggo gambar, tandha minangka digunakake (WORKDIR) lan miwiti mbangun. Printah EXPOSE 8080 menehi sinyal menyang docker yen aplikasi ing wadhah bakal nggunakake port 8080 (iki ora bakal nggawe aplikasi bisa diakses saka njaba, nanging ngidini aplikasi bisa diakses, contone, saka wadhah liyane ing jaringan docker sing padha. ).
Kanggo paket layanan menyang gambar, sampeyan kudu mbukak printah saka ROOT saben project:
docker image build . -t msvc-backend:1.0.0
Asil punika 456 MB gambar (kang basis JDK gambar dikuwasani 340 MB). Lan kabeh senadyan kasunyatane yen kelas ing proyek kita bisa diitung nganggo driji. Kanggo nyuda ukuran gambar kita:
Kita nggunakake perakitan multi-langkah. Ing langkah pisanan kita bakal mbangun proyek, ing langkah kapindho kita bakal nginstal JRE, lan ing langkah katelu kita bakal nyalin kabeh menyang gambar Alpine resik anyar. Secara total, mung komponen sing dibutuhake bakal ana ing gambar pungkasan.
Ayo nggunakake modularization of java. Miwiti karo Java 9, sampeyan bisa nggunakake alat jlink kanggo nggawe JRE mung saka modul sing dibutuhake
Kanggo miwiti, layanan kita kudu ing jaringan sing padha. Ana sawetara jinis jaringan ing docker, lan kita nggunakake paling primitif saka wong-wong mau - bridge, sing ngijini sampeyan kanggo jaringan kontaner mlaku ing inang padha. Gawe jaringan kanthi printah ing ngisor iki:
docker network create msvc-network
Sabanjure, miwiti wadhah backend jenenge 'backend' karo microservices-backend:1.0.0 gambar:
docker run -dit --name backend --network msvc-net microservices-backend:1.0.0
Wigati dicathet yen jaringan jembatan nyedhiyakake panemuan layanan out of the box kanggo wadhah kanthi jenenge. Yaiku, layanan backend bakal kasedhiya ing jaringan docker ing http://backend:8080.
Ing printah iki, kita nuduhake yen kita nerusake port 80 saka host menyang port 8080 saka wadhah kasebut. Kita nggunakake opsi env kanggo nyetel variabel lingkungan sing bakal diwaca kanthi otomatis dening spring lan override sifat saka application.properties.
Sawise miwiti, kita nelpon http://localhost/ lan priksa manawa kabeh bisa digunakake, kaya ing kasus sadurunge.
toleransi fault miskin - kabeh bisa kanggo kita ing siji server
Skalabilitas sing ora apik - nalika beban mundhak, luwih becik masang conto layanan tambahan kanthi otomatis lan ngimbangi beban ing antarane.
Kerumitan peluncuran - kita kudu ngetik paling ora 3 printah, lan kanthi paramèter tartamtu (iki mung kanggo 2 layanan)
Kanggo ndandani masalah ing ndhuwur, ana sawetara solusi kayata Docker Swarm, Nomad, Kubernetes utawa OpenShift. Yen kabeh sistem ditulis ing Jawa, sampeyan bisa ndeleng menyang Spring Cloud (artikel apik).
Π bagean sabanjure Aku bakal ngomong babagan carane nyiyapake Kubernetes lan nyebarake proyek kasebut menyang Google Kubernetes Engine.