สถาปัตยกรรม Microservice - SOA แบบ Hands-On

ในบทนี้เราจะพัฒนาแอปพลิเคชันที่ใช้ CRUD ด้วยสถาปัตยกรรม SOA ต่อไปในบทต่อ ๆ ไปเราจะแยกบริการนี้ออกเป็นไมโครเซอร์วิสและเราจะเรียนรู้ความแตกต่างพื้นฐานระหว่างสถาปัตยกรรม SOA และไมโครเซอร์วิส

การกำหนดค่าระบบและการตั้งค่า

ในส่วนนี้เราจะสร้างแอปพลิเคชัน CRUD ตัวอย่างซึ่งจะส่งคืนออบเจ็กต์ JSON เป็นการตอบสนองทุกครั้งที่เราเรียกใช้บริการของเรา เราจะใช้เจอร์ซีกรอบในการพัฒนาเดียวกัน ต่อไปนี้เป็นขั้นตอนในการตั้งค่าสภาพแวดล้อมระบบโลคัลของคุณ

การพัฒนาแอปพลิเคชัน CRUD

Step 1- เราจะใช้ NetBeans เป็น IDE ในการพัฒนา โปรดดาวน์โหลดและติดตั้งเวอร์ชันล่าสุดบนเว็บไซต์ทางการของ NetBeanshttps://netbeans.org/downloads/.

Step 2- เปิด NetBeans IDE ของคุณ ไปที่“ ไฟล์ -> โครงการใหม่” ภาพหน้าจอต่อไปนี้จะปรากฏขึ้น เลือก“ Maven” เป็นหมวดหมู่และเลือก“ Project from ArchType” เป็นโปรเจ็กต์แล้วกด Next

สิ่งนี้จะดาวน์โหลดไฟล์ jar ที่จำเป็นทั้งหมดเพื่อสร้างโปรเจ็กต์ Maven และ RESTful Web Service ครั้งแรกของคุณ

Step 3- ในการกดปุ่ม Next ในขั้นตอนก่อนหน้านี้ภาพหน้าจอต่อไปนี้จะปรากฏขึ้น ที่นี่คุณจะต้องระบุ Maven Archetype

ในช่องค้นหาให้ค้นหา“ Jersey-archType-Webapp (2.16)” แล้วเลือกช่องทำเครื่องหมาย“ Show Older”

Step 4- เมื่อคุณเลือกแบบเดียวกันคุณจะถูกนำไปยังหน้าจอต่อไปนี้ เลือกโถที่ต้องการจากรายการและกด Next เพื่อดำเนินการต่อ

Step 5- ในขั้นตอนนี้คุณต้องระบุชื่อโครงการของคุณและรหัสกลุ่มของคุณรวมถึงรายละเอียดแพ็คเกจ หลังจากให้ข้อมูลทั้งหมดแล้วให้กด Finish เพื่อดำเนินการต่อ

Step 6- คุณตั้งค่าพื้นที่ทำงานเสร็จแล้ว ไดเรกทอรีโครงการจะมีลักษณะดังต่อไปนี้

ตรวจสอบโฟลเดอร์ "Dependencies" ของคุณและคุณจะพบว่า Maven ได้ดาวน์โหลดไฟล์ jar ที่จำเป็นทั้งหมดสำหรับโครงการนี้โดยอัตโนมัติ

Step 7- พื้นที่ทำงานของคุณได้รับการตั้งค่าและคุณสามารถเริ่มต้นด้วยการเขียนโค้ดได้ สร้างคลาสและแพ็กเกจสี่คลาสตามที่ระบุไว้ในภาพหน้าจอต่อไปนี้ คุณจะพบว่า MyResource.java สร้างขึ้นโดย Maven แล้วเนื่องจาก Maven ฉลาดพอที่จะตรวจพบว่าคุณกำลังจะสร้างบริการเว็บของคุณเอง

Step 8 - เมื่อทำตามขั้นตอนข้างต้นเสร็จแล้วเราจะสร้างคลาส POJO ของเราที่เป็น UserProfile.java ดังต่อไปนี้

package com.tutorialspoint.userprofile.Model;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class UserProfile {
   private long ProId;
   private String FName;
   private String LName;
   private String Add;
   public UserProfile(){}
   
   public UserProfile(long Proid, String Fname, String Lname,String Add) {
      this.ProId = Proid;
      this.FName = Fname;
      this.LName = Lname;
      this.Add = Add;
   }
   public long getProId() {
      return ProId;
   }
   public void setProId(long ProId) {
      this.ProId = ProId;
   }
   public String getFName() {
      return FName;
   }
   public void setFName(String FName) {
      this.FName = FName;
   }
   public String getLName() {
      return LName;
   }
   public void setLName(String LName) {
      this.LName = LName;
   }
   public String getAdd() {
      return Add;
   }
   public void setAdd(String Add) {
      this.Add = Add;
   }
}

Step 9- ตอนนี้เราจะสร้างคลาสฐานข้อมูลของเรา เนื่องจากนี่เป็นส่วนหนึ่งของสื่อการเรียนรู้เราจะไม่ใช้ฐานข้อมูลใด ๆ เป็นฐานข้อมูลของเรา เราจะใช้หน่วยความจำ Java ในตัวเพื่อทำงานเป็นหน่วยความจำชั่วคราวของเรา ดังที่คุณเห็นในชุดรหัสต่อไปนี้เราจะใช้ MAP เป็นฐานข้อมูลของเรา การดำเนินการบริการเว็บทั้งหมดที่เราดำเนินการเราจะทำงานบน MAP นี้ที่กำหนดไว้ในคลาส

package com.tutorialspoint.userprofile.DAO;

import com.tutorialspoint.userprofile.Model.UserProfile;

import java.util.HashMap;
import java.util.Map;

public class DatabaseClass {
   private static Map<Long,UserProfile> messages = new HashMap<Long,UserProfile>();
   public static Map<Long,UserProfile> getUsers() {
      return messages; 
      // Each time this method will return entire map as an instance of database
   }
}

Step 10- ตอนนี้ให้เราสร้างคลาสบริการของเรา คัดลอกและวางชุดรหัสต่อไปนี้ในคลาส“ ProfileService.java” นี่คือคลาสที่เราจะประกาศวิธีการบริการเว็บทั้งหมดของเราที่จะเปิดเผยต่อโลกภายนอก เราจำเป็นต้องสร้างการอ้างอิงของ DatabaseClass ของเราเพื่อให้สามารถเข้าถึงฐานข้อมูลชั่วคราวของเราได้ในคลาสนี้

package com.tutorialspoint.userprofile.service;

import com.tutorialspoint.userprofile.DAO.DatabaseClass;
import com.tutorialspoint.userprofile.Model.UserProfile;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class ProfileService {
   private Map<Long,UserProfile> Userprofiles = DatabaseClass.getUsers();
   
   // Creating some predefine profile and populating the same in the map
   public ProfileService() {
      UserProfile m1 = new UserProfile(1L,"Tutorials1","Point1","TutorialsPoint.com");
      UserProfile m2 = new UserProfile(2L,"Tutorials2","Point2","TutorialsPoint.com2");
      UserProfile m3 = new UserProfile(3L,"Tutorials3","Point3","TutorialsPoint.com3");
      UserProfile m4 = new UserProfile(4L,"Tutorials4","Point4","TutorialsPoint.com4");
      
      Userprofiles.put(1L, m1);
      Userprofiles.put(2L, m2);
      Userprofiles.put(1L, m3);
      Userprofiles.put(2L, m4);
   }
   
   //Method to fetch all profile
   public List<UserProfile> getAllProfile() {
      List<UserProfile> list = new ArrayList<UserProfile>(Userprofiles.values());
      return list;
   }  // Method to fetch only one profile depending on the ID provided
   
   public UserProfile getProfile(long id) {
      return Userprofiles.get(id);
   }  //Method to add profile
   
   public UserProfile addProfile(UserProfile UserProfile) {
      UserProfile.setProId(Userprofiles.size()+1);
      Userprofiles.put(UserProfile.getProId(), UserProfile);
      return UserProfile;
   }  //method to update Profile

   public UserProfile UpdateProfile(UserProfile UserProfile) {
      if(UserProfile.getProId()<=0) { 
         return null;
      } else { 
         Userprofiles.put(UserProfile.getProId(), UserProfile);
         return UserProfile;
      }
   } //method to delete profile
   
   public void RemoveProfile(long Id) {
      Userprofiles.remove(Id);
   }
}

Step 11 - ในขั้นตอนนี้เราจะสร้างคลาส Resource ของเราที่จะเชื่อมโยงกับ URL และจะเรียกใช้บริการที่เกี่ยวข้อง

package com.tutorialspoint.userprofile.Resource;

import com.tutorialspoint.userprofile.Model.UserProfile;
import com.tutorialspoint.userprofile.service.ProfileService;

import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/Profile")
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)

public class ProfileResource {
   ProfileService messageService = new ProfileService();
   
   @GET
   public List<UserProfile> getProfile() {
      return messageService.getAllProfile();
   }

   @GET
   @Path("/{ProID}")
   public UserProfile getProfile(@PathParam("ProID")long Id) {
      return messageService.getProfile(Id);
   }

   @POST
   public UserProfile addProfile(UserProfile profile) {
      return messageService.addProfile(profile);
   }

   @PUT
   @Path("/{proID}")
   public UserProfile UpdateProfile(@PathParam("proID")long Id,UserProfile UserProfile) {
      UserProfile.setProId(Id);
      return messageService.UpdateProfile(UserProfile);
   }
   
   @DELETE
   @Path("/{ProID}")
   public void deleteProfile(@PathParam("ProID")long Id) {
      messageService.RemoveProfile(Id);
   }
}

Step 12- ทำความสะอาดสร้างโครงการและเรียกใช้ หากทุกอย่างเป็นไปด้วยดีคุณควรได้รับผลลัพธ์ต่อไปนี้ในเบราว์เซอร์ขณะเข้าถึงhttp://localhost:8080/UserProfile/webapi/Profile” URL

คุณสามารถดูรายการต่างๆที่สร้างขึ้นโดยใช้การแสดง XML

วิธีการต่างๆสามารถทดสอบได้โดยใช้บุรุษไปรษณีย์โดยใช้ URL วิธีการที่เหมาะสม

@GET method - ภาพหน้าจอต่อไปนี้แสดงให้เห็นว่าเราจะได้ผลลัพธ์ที่ต้องการสำหรับคำขอได้อย่างไรซึ่งจะแสดงรายละเอียดผู้ใช้ทั้งหมด

@POST- สามารถใช้คำขอต่อไปนี้เพื่อทดสอบวิธีการโพสต์ของเรา สังเกตว่า proId ถูกสร้างขึ้นโดยอัตโนมัติอย่างไร

@PUT- วิธีนี้จะอัปเดตรายการ ภาพหน้าจอต่อไปนี้แสดงให้เห็นว่า Jersey ใช้ proId จาก URL คำขอและอัปเดตการตอบกลับโปรไฟล์ผู้ใช้เดียวกันได้อย่างไร

ในทำนองเดียวกันคุณสามารถตรวจสอบวิธีการอื่น ๆ ที่มีอยู่ในบริการบนเว็บของคุณ

ในส่วนก่อนหน้านี้เราได้พัฒนาบริการหนึ่งซึ่งจะแสดงฟังก์ชัน CRUD เมื่อใดก็ตามที่เราพยายามใช้บริการนี้ในแอปพลิเคชันของเราเราจำเป็นต้องสร้างไคลเอนต์ของแอปพลิเคชันนี้และแนบเข้ากับแอปพลิเคชันของเรา ในบทนี้เราจะเรียนรู้วิธีการสร้างฟังก์ชันนี้โดยใช้แนวคิดของ Microservice ต่อไปนี้คือการแสดงแผนผังของแอปพลิเคชันของเราที่สร้างขึ้นโดยใช้ขั้นตอนข้างต้น

นักแสดงควรเป็นจุดเริ่มต้นของบริการของเรา ในกรณีนี้“ ProfileResource.java” จะเป็นหน้าที่ของนักแสดง คลาสนี้จะเรียกวิธีการที่แตกต่างกันเพื่อดำเนินการที่แตกต่างกันเช่นเพิ่มอัปเดตและลบ

การสลายตัวของแอปพลิเคชัน CRUD

ตามหลักการสำคัญของ microservice เราจำเป็นต้องมีงานทางธุรกิจเพียงอย่างเดียวสำหรับแต่ละโมดูลดังนั้นนักแสดงคนหนึ่งจึงไม่ควรรับผิดชอบฟังก์ชัน CRUD ทั้งสี่อย่าง ลองพิจารณาตัวอย่างต่อไปนี้ที่เราได้แนะนำบทบาทใหม่บางอย่างเพื่อให้คุณเข้าใจได้อย่างชัดเจนว่า Microservice เป็นตัวแทนทางสถาปัตยกรรมของ SOA

“ ผู้ใช้หลัก” คือผู้ใช้ที่สื่อสารกับ“ Application Controller” เพื่อตอบสนองความต้องการ "ตัวควบคุมแอปพลิเคชัน" คือผู้ที่เรียกว่า "ผู้จัดการทรัพยากร" ที่แตกต่างกันขึ้นอยู่กับคำขอจากผู้ใช้ปลายทาง “ ผู้จัดการทรัพยากร” ทำงานที่จำเป็นต้องทำ มาดูบทบาทต่างๆของหน่วยต่างๆของแอปพลิเคชันกันอย่างรวดเร็ว

  • End User/Main Users - ขอทรัพยากรบางอย่างไปยัง Application Controller

  • Application - รับคำขอและส่งต่อสิ่งเดียวกันกับผู้จัดการทรัพยากรเฉพาะ

  • Resource Manager - งานอัปเดตลบและเพิ่มผู้ใช้จริงหรือไม่

ดูว่าความรับผิดชอบทั้งหมดของชั้นเรียนหนึ่งถูกกระจายไปยังชั้นเรียนอื่น ๆ อย่างไร