[Microservice] Dựng Microservice internet bằng Spring Boot và Eureka [Phần 1]

Microservices là 1 giải pháp cho phép chia 1 hệ thống lớn thành 1 vài những element độc lập về phát triển thành, check và deploy.

Spring Cloud là 1 dự án con trong họ nhà Spring, được dùng để phát triển thành những ứng dụng phân tán. 1 ứng dụng được gọi là phần tán (Distributed software) lúc những phần của nó có thể được phát triển thành trên những ngôn ngữ khác nhau và được triển khai trên những máy chủ khác nhau. Như vậy, Spring Cloud sinh ra là để khiến những hệ thống microservice. Mọi những dự sán Spring Cloud nên được tạo từ Spring Boot để giảm thiểu những cấu hình phức tạp và dễ cài đặt hơn.

Trong sequence này, chúng ta sẽ cùng tìm hiểu phương pháp xây dựng 1 hệ thống microservice bằng Spring Boot và Eureka (1 dự án trong Spring Cloud). Phần trước tiên là tạo những microservice và gateway.

img_1

1. Tổng quan

Nhìn vào sơ đồ những thành phần của hệ thống trên trên, chúng ta cần tạo những service registry, picture, gallery và 1 gateway. Gallery service sẽ dùng những bức ảnh lấy từ Picture service và sắp xếp chúng thành 1 album ảnh.

Phiên bản Spring Boot mà chúng ta sẽ dùng trong serries này là sentayho.com.vnASE.

<father or mother> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <model>2.0.0.RELEASE</model> <relativePath/> </father or mother> 2. Eureka Server

Đây là 1 máy chủ dùng để quản lý, đặt tên cho những service, hay còn gọi là service registry. Nhưng tại sao chúng ta lại cần 1 server để đặt tên cho từng service. Nguyên nhân:

  • Chúng ta ko muốn hardcode liên hệ IP của từng microservice. Bạn chẳng bao giờ dùng liên hệ 64.233.181.99 để truy cập vào trang sentayho.com.vn, đúng chứ?
  • Lúc mà những service của chúng ta dùng IP động, nó sẽ tự động động cập nhật, chúng ta ko cần thay đổi đổi code.

Vậy là từng service sẽ được đăng ký sở hữu Eureka và sẽ ping cho Eureka để đảm bảo chúng vẫn hoạt động. Giả dụ Eureka server ko nhận được bất kỳ thông tin nào từ service thì service đấy sẽ bị gỡ khỏi Eureka 1 phương pháp tự động động.

Okay, để tạo Eureka server, chúng ta sẽ dùng Maven để quản lý những dependencies. Lưu ý khác sở hữu kiến trúc monolithic, từng element trong microservice được dựng 1 phương pháp độc lập. Do đấy chúng ta sẽ tạo new 1 challenge Spring Boot và khai báo file sentayho.com.vn có những dependencies Net, Eureka Server và DevTools (tùy thuộc} chọn):

<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>check</scope> </dependency> </dependencies>

Tiếp theo, trong file sentayho.com.vnerties, chúng ta cần cấu hình 1 số thứ như sau:

# Give a reputation lớn the eureka server sentayho.com.vn=eureka-server # default port for eureka server sentayho.com.vn=8761 # eureka by default will register itself as a consumer. So, we’d like lớn set it lớn false. # What’s a consumer server? See different microservices (picture, gallery, auth, and many others). sentayho.com.vnster-with-eureka=false sentayho.com.vnh-registry=false

Cuối cùng, trong class principal của challenge, chúng ta sẽ khai báo đây là 1 Eureka server bằng annotation @EnableEurekaServer:

package deal sentayho.com.vner; import sentayho.com.vnngApplication; import sentayho.com.vnngBootApplication; import sentayho.com.vnleEurekaServer; @SpringBootApplication @EnableEurekaServer public class ServerApplication { public static void principal(String[] args) { sentayho.com.vn(ServerApplication.class, args); } }

Xem Thêm  Tú lơ khơ là gì? Nắm bắt rõ phương pháp chơi bài tú lơ khơ hiệu quả

Đơn giản thế thôi, đi tiếp tới những service về nghiệp vụ nào 😄

3. Picture Service

Những Eureka consumer service là 1 service độc lập trong kiến trúc microservice. Từng consumer service chỉ thực hành duy nhất 1 nghiệp vụ nào đấy trong hệ thống như tính sổ, account, thông tin, xác thực, cấu hình,… Chúng ta sẽ xây dựng picture service như 1 nguồn để chứa và phân phối những bức ảnh, từng bức ảnh sẽ có id, title và liên hệ url. Chỉ đơn giản như vậy thôi.

Okay, cũng như Eureka Server, chúng ta sẽ tạo 1 challenge Spring Boot new nhưng dùng Eureka Shopper trong file sentayho.com.vn:

<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-rest</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>check</scope> </dependency> </dependencies>

Trong file sentayho.com.vnerties chúng ta sẽ ghi lại liên hệ của Eureka server:

# serivce title sentayho.com.vn=image-service # port sentayho.com.vn=8200 # eureka server url sentayho.com.vnult-zone=http://localhost:8761/eureka

Tiếp tục để chỉ cho Spring Boot biết đây là 1 Eureka consumer, chúng ta dùng annotation @EnableEurekaClient trong class principal:

package deal sentayho.com.vne; import sentayho.com.vnngApplication; import sentayho.com.vnngBootApplication; import sentayho.com.vnleEurekaClient; @SpringBootApplication @EnableEurekaClient public class ImageApplication { public static void principal(String[] args) { sentayho.com.vn(ImageApplication.class, args); } }

Trên sự thật} để picture service có thể expose information ra bên cạnh, chúng ta cần có những endpoint đúng ko? Tương tự động 1 RESTful internet service, chúng ta sẽ tạo 1 entity định nghĩa cấu trúc chuỗi JSON và 1 controller điều hướng:

  • Picture.java

package deal sentayho.com.vnty; public class Picture { non-public Integer id; non-public String title; non-public String url; public Picture(Integer id, String title, String url) { sentayho.com.vn = id; sentayho.com.vn = title; sentayho.com.vn = url; } public Integer getId() { return id; } public void setId(Integer id) { sentayho.com.vn = id; } public String getTitle() { return title; } public void setTitle(String title) { sentayho.com.vn = title; } public String getUrl() { return url; } public void setUrl(String url) { sentayho.com.vn = url; } }

  • HomeController.java

package deal sentayho.com.vnroller; import sentayho.com.vne; import sentayho.com.vnwired; import sentayho.com.vnronment; import sentayho.com.vnestMapping; import sentayho.com.vnController; import sentayho.com.vnys; import sentayho.com.vn; @RestController @RequestMapping(“/”) public class HomeController { @Autowired non-public Atmosphere env; @RequestMapping(“/”) public String dwelling() { // That is helpful for debugging // When having a number of occasion of picture service working at totally different ports. // We load steadiness amongst them, and show which occasion obtained the request. return “Hiya from Picture Service working at port: ” + sentayho.com.vnroperty(“native.server.port”); } @RequestMapping(“/pictures”) public Record<Picture> getImages() { Record<Picture> pictures = sentayho.com.vnst( new Picture(1, “Treehouse of Horror V”, “https://www.imdb.com/title/tt0096697/mediaviewer/rm3842005760”), new Picture(2, “The City”, “https://www.imdb.com/title/tt0096697/mediaviewer/rm3698134272”), new Picture(3, “The Final Traction Hero”, “https://www.imdb.com/title/tt0096697/mediaviewer/rm1445594112”)); return pictures; } } 4. Gallery Service

Những Eureka consumer service có thể là 1 REST consumer dùng để phân phối information cho 1 service khác (REST API service). Do đấy, trong hệ thống của chúng ta, gallery service sẽ gọi tới picture service thông qua những endpoint mà chúng ta đã tạo ra trên trên, và từ đấy sẽ get ra 1 checklist ảnh để tạo ra 1 album. Để gọi tới 1 service từ 1 REST consumer, chúng ta có thể dùng:

  1. RestTemplate: Đây là 1 object cho phép gửi request tới 1 REST API service.
  2. FeignClient: hoạt động như 1 proxy, phân phối những giải pháp khác cho RestTemplate.

Và cả 2 phương pháp thì cân bằng tải đều có thể ứng dụng.

Cân bằng tải (Load balancing) là gì? Giả dụ như có nhiều hơn 1 occasion của 1 service chạy trên những port khác nhau thì chúng ta cần cân bằng những request giữa đa số những occasion đấy. Trong điều kiện hoàn hảo thì cân bằng tải sẽ giúp những port nhận số lượng request tương đương nhau.

Tương tự động Picture service, chúng ta khai báo file sentayho.com.vn cho Gallery service. Và trong sentayho.com.vnerties, port dùng sẽ khác sở hữu Picture service:

Xem Thêm  888 On line casino – Reside On line casino km tới 3tr888

sentayho.com.vn=gallery-service sentayho.com.vn=8100 sentayho.com.vnult-zone=http://localhost:8761/eureka

Trong class principal, ngoài annotation @EnableEurekaClient, chúng ta sẽ cần tạo thêm 1 bean cho RestTemplate dùng để gọi tới picture service.

package deal sentayho.com.vnery; import sentayho.com.vnngApplication; import sentayho.com.vnngBootApplication; import sentayho.com.vnBalanced; import sentayho.com.vnleEurekaClient; import sentayho.com.vn; import sentayho.com.vniguration; import sentayho.com.vnTemplate; @SpringBootApplication @EnableEurekaClient public class GalleryServiceApplication { public static void principal(String[] args) { sentayho.com.vn(GalleryServiceApplication.class, args); } } @Configuration class RestTemplateConfig { // Create a bean for restTemplate lớn name providers @Bean @LoadBalanced // Load steadiness between service cases working at totally different ports. public RestTemplate restTemplate() { return new RestTemplate(); } }

Đừng quên entity và controller:

  • Gallery.java

package deal sentayho.com.vnty; import sentayho.com.vn; public class Gallery { non-public Integer id; non-public Record<Object> pictures; public Gallery(Integer id, Record<Object> pictures) { sentayho.com.vn = id; sentayho.com.vn = pictures; } public Gallery() { } public Integer getId() { return id; } public void setId(Integer id) { sentayho.com.vn = id; } public Record<Object> getImages() { return pictures; } public void setImages(Record<Object> pictures) { sentayho.com.vn = pictures; } }

  • HomeController.java

package deal sentayho.com.vnroller; import sentayho.com.vnery; import sentayho.com.vnwired; import sentayho.com.vnronment; import sentayho.com.vnVariable; import sentayho.com.vnestMapping; import sentayho.com.vnController; import sentayho.com.vnTemplate; import sentayho.com.vn; @RestController @RequestMapping(“/”) public class HomeController { @Autowired non-public RestTemplate restTemplate; @Autowired non-public Atmosphere env; @RequestMapping(“/”) public String dwelling() { // That is helpful for debugging // When having a number of occasion of gallery service working at totally different ports. // We load steadiness amongst them, and show which occasion obtained the request. return “Hiya from Gallery Service working at port: ” + sentayho.com.vnroperty(“native.server.port”); } @RequestMapping(“/{id}”) public Gallery getGallery(@PathVariable remaining int id) { // create gallery object Gallery gallery = new Gallery(); sentayho.com.vnd(id); // get checklist of accessible pictures Record<Object> pictures = sentayho.com.vnorObject(“http://image-service/pictures/”, sentayho.com.vns); sentayho.com.vnmages(pictures); return gallery; } // – Admin Space – // This technique ought to solely be accessed by customers with function of ‘admin’ // We’ll add the logic of function based mostly auth later @RequestMapping(“/admin”) public String homeAdmin() { return “That is the admin space of Gallery service working at port: ” + sentayho.com.vnroperty(“native.server.port”); } }

Okay, tới đây chúng ta cần chú ý lúc dùng restTemplate thì trong Eureka Server đã đặt tên cho những service nên chúng ta sẽ dùng tên của chúng (image-service thay đổi vì localhost:port) nhằm phần đích dùng cân bằng tải.

5. Gateway – Zuul

Lúc chúng ta gọi tới bất kỳ service nào từ browser, chúng ta ko thể gọi quản lý bằng tên của chúng như trên trên Gallery server đã khiến bởi vì những tên service như vậy buộc phải được bí mật và chỉ dùng trong nội bộ những service sở hữu nhau.

Giả dụ chúng ta có nhiều occasion của 1 service, từng occasion lại dùng 1 port khác nhau. Vậy khiến thế nào chúng ta có thể gọi đa số những service từ browser và phân tán những request tới những occasion đấy thông qua những cổng khác nhau? Câu trả lời là dùng 1 Gateway.

1 gateway là 1 entry level đơn trong hệ thống, được dùng để deal with những request bằng phương pháp định tuyến chúng tới những service tương ứng. Nó cũng có thể được dùng để xác thực, giám sát và khiến nhiều việc khác.

Xem Thêm  TTR Là Gì? Bật Mí Quy Trình 5 Bước Thanh Toán Quốc Tế

Zuul là gì?

Nó là 1 proxy, gateway và 1 lớp trung gian giữa person và những service của bạn. Eureka server đã giải quyết vấn đề đặt tên cho từng service thay đổi vì dùng liên hệ IP của chúng. Tuy nhiên 1 service vẫn có thể có nhiều occasion và chúng sẽ chạy trên những cổng khác nhau nên nhiệm vụ của Zuul sẽ là:

  • Map giữa 1 prefix path (/gallery/**) và 1 service (gallery-service). Nó dùng Euraka server để định tuyến những service được request.
  • Nó giúp cân bằng tải giữa những occasion của 1 service.
  • Còn gì nữa? Chúng ta có thể dùng nó để filter request, thêm xác thực,…

Trong file sentayho.com.vn của challenge Zuul, chúng ta sẽ có những dependencies: Net, Eureka Shopper và Zuul:

<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>check</scope> </dependency> </dependencies>

Điều đáng nói là Zuul hoạt động như 1 Eureka consumer. Vì vậy chúng ta có thể đặt tên cho nó, chỉ định port và đường dẫn tới Eureka server như những consumer trước đấy.

sentayho.com.vn=8762 sentayho.com.vn=zuul-server sentayho.com.vnult-zone=http://localhost:8761/eureka/ # A prefix that may added lớn starting of all requests. #zuul.prefix=/api # Disable accessing providers utilizing service title (i.e. gallery-service). # They need to be solely accessed by way of the trail outlined under. sentayho.com.vnred-services=* # Map paths lớn providers sentayho.com.vn=/gallery/** sentayho.com.vnice-id=gallery-service

Cuối cùng là thêm những annotation để thông tin đây là Zuul và Eureka consumer:

package deal sentayho.com.vnserver; import sentayho.com.vnngApplication; import sentayho.com.vnngBootApplication; import sentayho.com.vnleEurekaClient; import sentayho.com.vnleZuulProxy; @SpringBootApplication @EnableEurekaClient // It acts as a eureka consumer @EnableZuulProxy // Allow Zuul public class ZuulServerApplication { public static void principal(String[] args) { sentayho.com.vn(ZuulServerApplication.class, args); } } 6. Testing

Okay, như vậy là chúng ta đã dựng xong bộ khuôn cho hệ thống microservice. Chúng ta đã có 1 service discovery (Eureka server), 2 service (Picture và Gallery), 1 cổng gateway (Zuul) và giờ chỉ cần begin chúng lên.

Để chạy nhiều occasion thì trong Eclipse, bạn vào Run -> Configurations/Arguments -> VM choices và thêm sentayho.com.vn=8300

Để đánh giá ứng dụng của chúng ta, hãy truy cập vào localhost:8761, đây là cổng của Eureka Server. Và bạn sẽ thấy những server đang chạy như sau: img_3 Tiếp tục hãy gọi tiếp tới gallery service bằng đường dẫn localhost:8762/gallery. Chúng ta sẽ nhận được message như sau: >Hiya from Gallery Service working at port: 8100

Giả dụ dùng a number of occasion, bạn sẽ nhận được 2 dòng như trên sở hữu 2 cổng khác nhau.

Tiếp theo chúng ta gọi tới service Picture thông qua Gallery bằng đường dẫn localhost:8762/gallery/1. Kết quả nhận được sẽ là:

// 20181218230927 // http://localhost:8762/gallery/1 { “id”: 1, “pictures”: [ { “id”: 1, “title”: “Treehouse of Horror V”, “url”: “https://www.imdb.com/title/tt0096697/mediaviewer/rm3842005760” }, { “id”: 2, “title”: “The Town”, “url”: “https://www.imdb.com/title/tt0096697/mediaviewer/rm3698134272” }, { “id”: 3, “title”: “The Last Traction Hero”, “url”: “https://www.imdb.com/title/tt0096697/mediaviewer/rm1445594112” } ] }

Kết thúc phần trước tiên trên đây, trên phần tiếp theo chúng ta sẽ tìm hiểu phương pháp để xác thực person bằng JWT.

Nguồn bài viết Supply code