สถาปัตยกรรมไมโครเซอร์วิสคืออะไร
สถาปัตยกรรมไมโครเซอร์วิสเป็นรูปแบบการออกแบบซอฟต์แวร์ที่เราเขียนแอปพลิเคชันโดยการรวมโปรแกรมขนาดเล็กหลายโปรแกรมเข้าด้วยกัน โปรแกรมเหล่านี้ ซึ่งเรียกว่าไมโครเซอร์วิส ทำงานร่วมกันเพื่อเป้าหมายร่วมกัน สำหรับบางทีม อาจใช้เวลาและความพยายามในการเขียนแอปพลิเคชันขนาดเล็กหลายๆ แอปพลิเคชันน้อยกว่าแอปพลิเคชันขนาดใหญ่เพียงแอปพลิเคชันเดียว
โปรเจ็กต์ที่เน้นไมโครเซอร์วิสประกอบด้วยกลุ่มของแอพพลิเคชั่นขนาดเล็ก โดยแต่ละโปรเจ็กต์ทำหน้าที่ของมัน ทำงานในกระบวนการที่แยกจากกัน และสื่อสารกับส่วนที่เหลือผ่านอินเทอร์เฟซมาตรฐาน วิธีนี้ช่วยให้ทีมสามารถเลือกเครื่องมือที่ดีที่สุดสำหรับแต่ละปัญหาโดยไม่ต้องผูกมัดกับภาษาหรือเฟรมเวิร์กเดียว นอกจากนี้ยังช่วยให้เราแบ่งงานระหว่างกลุ่มที่เชี่ยวชาญอีกด้วย
จากโมโนลิธสู่ไมโครเซอร์วิส
ในส่วนแรกของชุดนี้ เราได้พูดถึงเสาหิน เสาหินสามารถเริ่มต้นได้ง่าย อย่างไรก็ตาม อัตราการก้าวของการพัฒนานั้นไม่ค่อยดีนัก สาเหตุหลักมาจากทุกอย่างเชื่อมโยงกันอย่างแน่นแฟ้น แม้แต่การเปลี่ยนแปลงโค้ดเพียงเล็กน้อยก็บังคับให้เราต้องสร้างใหม่และทดสอบทั้งโปรเจ็กต์ ซึ่งนำไปสู่รอบการเปิดตัวที่ยาวนานอย่างน่าผิดหวัง
เราจะเปลี่ยนจาก monolith เป็น microservice ได้อย่างไร? ใช้กรณีของอเมซอน ไม่นานมานี้ พวกเขาเริ่มเป็นเสาหินและเปลี่ยนไปใช้ไมโครเซอร์วิสเมื่อเวลาผ่านไป การออกแบบเริ่มต้นของพวกเขาอาจมีลักษณะดังนี้:
แน่นอน ฉันพูดง่ายเกินไปที่นี่ แต่ฉันเชื่อว่าฉันครอบคลุมพื้นฐานส่วนใหญ่แล้ว จะเกิดอะไรขึ้นหากพวกเขาเลือกปฏิบัติตามรูปแบบไมโครเซอร์วิสตั้งแต่เริ่มต้น? พวกเขาจะแยกแอปพลิเคชันตามฟังก์ชัน โดยให้แต่ละองค์ประกอบมุ่งเน้นไปที่ปัญหาเดียว
พวกเขายังต้องกำหนดอินเทอร์เฟซและโปรโตคอลสำหรับการสื่อสารระหว่างบริการ ซึ่งโดยทั่วไปแล้วจะมีกลไกที่ไม่ซับซ้อน เช่น RESTful API
เนมสเปซคืออะไร
การออกแบบไมโครเซอร์วิสมีชุดของความท้าทายที่ไม่เหมือนใคร ประเด็นหลักอาจเป็นเครื่องมือวัดและการรายงานข้อผิดพลาด ลองคิดดู เรากำลังตรวจสอบส่วนประกอบนับสิบหรือหลายร้อยรายการซึ่งกระจายอยู่ในแพลตฟอร์มและภาษาต่างๆ และเราต้องจับตาดูพวกเขาทั้งหมด และในขณะเดียวกันก็อย่าสูญเสียภาพรวม เนมสเปซสามารถช่วยเราโฟกัสกลุ่มไมโครเซอร์วิสที่เชื่อมต่อกันอย่างหลวมๆ ให้เป็นภาพที่เชื่อมโยงกัน
ใน AppSignal เนมสเปซคือคอนเทนเนอร์สำหรับเมตริกที่รวบรวม AppSignal ใช้เนมสเปซสามรายการโดยค่าเริ่มต้น (web
, background
และ frontend
) แต่เราสามารถสร้างโค้ดของเราเองได้โดยการเพิ่มโค้ดสองสามบรรทัด เรามาดูกันว่ามันทำงานอย่างไรต่อไป
แอปพลิเคชั่นเดียวที่จะควบคุมพวกเขาทั้งหมด
เมื่อตั้งค่าคอมโพเนนต์ไมโครเซอร์วิส สิ่งแรกที่ต้องทำคือกำหนดค่าชื่อและสภาพแวดล้อมของแอปพลิเคชันทั่วไป ดังนั้น AppSignal จะแสดงเมตริกและการแจ้งเตือนที่รวบรวมไว้ทั้งหมดบนแดชบอร์ดเดียวกัน
รายละเอียดเฉพาะของการกำหนดค่าค่าเหล่านี้ขึ้นอยู่กับภาษาและการผสานรวม ตัวอย่างเช่น ในการกำหนดค่าแอปพลิเคชัน Ruby on Rails ให้ใช้ชื่อ “Nozama”:
# config/appsignal.yml
production:
active: true
push_api_key: "YOUR APPSIGNAL API KEY"
name: "Nozama"
ซึ่งคล้ายกับที่เรากำหนดค่าการรวม Elixir:
# config/config.exs
config :appsignal, :config,
active: true,
name: "Nozama",
push_api_key: "YOUR APPSIGNAL API KEY",
env: "production"
ใน Node.js เราใช้:
const { Appsignal } = require("@appsignal/nodejs");
const appsignal = new Appsignal({
active: true,
name: "Nozama",
apiKey: "YOUR APPSIGNAL API KEY",
});
สำหรับการผสานรวม JavaScript ส่วนหน้า เราใช้ @appsignal/javascript
แทน:
import Appsignal from "@appsignal/javascript";
export default new Appsignal({
name: "Nozama",
key: "YOUR FRONTEND API KEY",
});
คุณสามารถค้นหาข้อมูลเกี่ยวกับการติดตั้งและกำหนดค่า AppSignal ได้ที่นี่:
- การเพิ่มแอปพลิเคชันใหม่
- การกำหนดค่าแอปพลิเคชัน
การใช้เนมสเปซในไมโครเซอร์วิส
เรามาดูกันว่าเราจะเขียนโค้ดแต่ละไมโครเซอร์วิสอย่างไร เริ่มจากระบบการเรียกเก็บเงิน เราจะใช้ Elixir และ Phoenix ในส่วนนี้
เมื่อเราปฏิบัติตามการตั้งค่าการรวม Phoenix เราสามารถเริ่มทำงานกับคอนโทรลเลอร์ได้ ตัวอย่างต่อไปนี้ตั้งค่าเนมสเปซเป็น billing
:
# in a Phoenix controller, we use plug to run the namespace initialization
defmodule BillingPageController.PageController do
use BillingPageController, :controller
plug :set_appsignal_namespace
defp set_appsignal_namespace(conn, _params) do
# Sets all actions in this controller to report in the "billing" namespace
Appsignal.Transaction.set_namespace(:billing)
conn
end
# rest of the controller ...
end
ข้อมูลควรเริ่มปรากฏในแดชบอร์ดเมื่อไมโครเซอร์วิสทำงานและคอนโทรลเลอร์เห็นกิจกรรมบางอย่าง
แน่นอน การเรียกเก็บเงินจะไม่ทำให้เราห่างไกลเว้นแต่จะมีคนซื้อของบางอย่าง นี่เป็นปัญหาที่เราสามารถแก้ไขได้ในไมโครเซอร์วิสที่แยกจากกัน ตามรูปแบบเดียวกัน เราจะเขียนแอปพลิเคชัน Phoenix ใหม่ล่าสุดด้วย PayButtonController
คอนโทรลเลอร์ที่ขึ้นต้นดังนี้:
defmodule PayButtonController.PageController do
use PayButtonController, :controller
plug :set_appsignal_namespace
defp set_appsignal_namespace(conn, _params) do
Appsignal.Span.set_namespace(Appsignal.Tracer.root_span(), "pay_button")
conn
end
# rest of the controller ...
end
ตอนนี้เรามีเนมสเปซสองรายการในแดชบอร์ด การใช้ชื่อและสภาพแวดล้อมเดียวกันทำให้มั่นใจได้ว่าข้อมูลจาก PayButtonController
แสดงพร้อมกับ BillingPageController
แม้ว่าจะเป็นแอปพลิเคชันแยกต่างหากที่ทำงานบนเครื่องต่างๆ ก็ตาม
ส่วนประกอบต่อไปคือเอ็นจิ้นการแนะนำ เราจะใช้ปลายทาง API ที่แสดงคำแนะนำผลิตภัณฑ์ด้วย Express เราตั้งค่าเนมสเปซใน Node.js ดังที่แสดง:
app.get("/", (req, res) => {
const tracer = appsignal.tracer();
tracer.withSpan(
tracer.createSpan({ namespace: "recommendations" }),
(span) => {
// code to measure goes here
span.close();
}
);
});
ตอนนี้เรามีเนมสเปซถึงสามเนมสเปซ
ทีมมือถือและส่วนหน้าอาจต้องการบันทึกข้อผิดพลาดในแดชบอร์ด การรวม JavaScript ของ AppSignal จะกำหนดข้อมูลขาเข้าโดยอัตโนมัติด้วย frontend
เนมสเปซ แต่เราเปลี่ยนได้ดังนี้:
try {
// code that might fail
} catch (error) {
// handle the error
// send error to AppSignal
appsignal.sendError(error, {}, "Mobile");
}
อีกสักครู่ข้อมูลจะเริ่มปรากฏใน Mobile
เนมสเปซ
ตัวอย่างแสดง JavaScript ธรรมดา แต่อาจมีขั้นตอนการตั้งค่าเพิ่มเติมหากคุณใช้เฟรมเวิร์กส่วนหน้า เช่น React หรือ Angular
สำหรับเว็บไซต์ มาลองใช้ Ruby on Rails ซึ่งเป็นเฟรมเวิร์ก MVC ที่รู้จักกันดีซึ่ง AppSignal ผสานการทำงานกับอุปกรณ์ที่พร้อมใช้งานทันที เราจะเริ่มตัวควบคุม Rails ด้วยข้อมูลโค้ดต่อไปนี้เพื่อตั้งค่าเนมสเปซเป็น homepage
:
# in Rails we use before_action callback to change
# the namespace before the request starts
class HomepageController < ApplicationController
before_action :set_appsignal_namespace
def set_appsignal_namespace
Appsignal.set_namespace("homepage")
end
# controller actions ...
end
ต่อไป เราสามารถใช้ปลายทาง API เพื่อให้บริการข้อมูลไปยังเว็บไซต์และแอปพลิเคชันมือถือ สำหรับสิ่งนี้ เราสามารถใช้ Grape ซึ่งเป็นเฟรมเวิร์ก REST API ที่มีน้ำหนักเบาสำหรับ Ruby คราวนี้ การกำหนดค่า AppSignal ต้องใช้เวลาอีกเล็กน้อย
หลังจากกำหนดค่าการรวม Ruby ใน ´config/appsignal.yml´ แล้ว คุณสามารถเริ่มบันทึกเหตุการณ์และเมตริกด้วย:
Appsignal.start_logger
Appsignal.start
จากนั้น แทรกมิดเดิลแวร์ AppSignal ในกลุ่มตัวจัดการข้อผิดพลาด:
require "appsignal"
require "appsignal/integrations/grape"
class API < Grape::API
insert_before Grape::Middleware::Error, Appsignal::Grape::Middleware
resource :search do
desc 'return a product search'
before do
Appsignal.set_namespace("search")
end
get :product do
# product search logic
end
end
end
สำหรับตัวอย่างเพิ่มเติม โปรดดูเอกสารการรวม Grape
เพื่อให้ภาพสมบูรณ์ เราจะปิดท้ายด้วยงานพื้นหลังของ Sidekiq Sidekiq เป็นตัวประมวลผลงานยอดนิยมสำหรับ Ruby และนี่คือวิธีที่เราสามารถเริ่มต้นมันในโหมดสแตนด์อโลนหลังจากกำหนดค่า ´config/appsignal.yml´:
# config.ru
require 'appsignal'
Sidekiq.on(:startup) do
Appsignal.start
end
Sidekiq.on(:shutdown) do
Appsignal.stop('Sidekiq shutdown')
end
AppSignal กำหนดข้อมูลจากงานโดยอัตโนมัติไปยัง background
เนมสเปซ เราอาจต้องการเปลี่ยนเป็นเนมสเปซที่เฉพาะเจาะจงมากขึ้น
require 'sidekiq'
require 'appsignal'
class PlainOldRuby
include Sidekiq::Worker
def perform()
Appsignal.set_namespace("urgent_background")
# job logic
end
end
การรวบรวมเมตริกด้วยตัวแทนแบบสแตนด์อโลน
เอเจนต์แบบสแตนด์อโลนจะรวบรวมเมตริกการใช้ทรัพยากรจากเครื่อง Ubuntu, RedHat หรือ CentOS เราสามารถใช้เอเจนต์เพื่อตรวจสอบเซิร์ฟเวอร์ดาวเทียมที่อำนวยความสะดวก เช่น ฐานข้อมูล เกตเวย์ หรือตัวรับส่งข้อความไปยังแอปพลิเคชันไมโครเซอร์วิส
ใน AppSignal เราใช้เอเจนต์เพื่อตรวจสอบเซิร์ฟเวอร์ Kafka ของเราเอง เอเจนต์ยังมีประโยชน์สำหรับการสร้างเครื่องมือแบบกำหนดเองในภาษาและเฟรมเวิร์กที่ไม่รองรับโดยตรง
ในการเริ่มต้นใช้งานเอเจนต์ ให้ดาวน์โหลดและติดตั้งโดยทำตามคำแนะนำในการติดตั้ง
เมื่อเริ่มทำงานแล้ว เราจะต้องแก้ไขไฟล์การกำหนดค่าเพื่อตั้งค่าคีย์ API ชื่อแอปพลิเคชัน และสภาพแวดล้อม ใช้ค่าเดียวกับที่ใช้ในไมโครเซอร์วิสที่เหลือเพื่อรวมทุกอย่างไว้ในแดชบอร์ดเดียว
# /etc/appsignal-agent.conf
push_api_key = "YOUR APPSIGNAL API KEY"
app_name = "Nozama"
environment = "production"
บทสรุป
เนมสเปซเป็นวิธีที่ยอดเยี่ยมในการจัดระเบียบข้อมูลที่กระจายไปยังหลายระบบ นอกจากนี้ยังช่วยให้เราสามารถกำหนดค่าการแจ้งเตือนและปรับแต่งการจัดการการแจ้งเตือน หากต้องการดูวิธีการทำงาน โปรดดูส่วนแรกของชุดนี้
อ่านเพิ่มเติม:
- คุณสามารถทำอะไรกับเนมสเปซได้
- การตรวจสอบระบบใดๆ ด้วย StatsD และตัวแทนแบบสแตนด์อโลนของ AppSignal
- ปรับปรุงเมตริกและการแจ้งเตือนของโฮสต์