Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Redis

การเรียนรู้คิวข้อความด้วย Node.js และ Redis:เพิ่มประสิทธิภาพเว็บแอป

การเรียนรู้คิวข้อความด้วย Node.js และ Redis:เพิ่มประสิทธิภาพเว็บแอป

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

คิวข้อความช่วยแก้ปัญหานี้โดยจัดเตรียมสาขาเพิ่มเติมให้กับเส้นทางการตอบกลับคำขอตามปกติ สาขาเพิ่มเติมนี้ช่วยให้แน่ใจว่าผู้ใช้จะได้รับการตอบสนองทันที และกระบวนการที่ใช้เวลานานสามารถทำได้ที่ด้านข้าง ทุกคนกลับบ้านอย่างมีความสุข

บทความนี้จะเน้นไปที่การอธิบายว่าคิวข้อความคืออะไร และจะเริ่มต้นใช้งานคิวข้อความเหล่านี้ได้อย่างไรโดยการสร้างแอปพลิเคชันที่เรียบง่าย คุณควรคุ้นเคยกับพื้นฐานของ Node.js และคุณควรติดตั้ง Redis ภายในเครื่องหรือบนอินสแตนซ์ระบบคลาวด์ เรียนรู้วิธีติดตั้ง Redis ที่นี่

คิวคืออะไร

คิวคือโครงสร้างข้อมูลที่ช่วยให้คุณจัดเก็บเอนทิตีในคำสั่งซื้อได้ การเข้าคิวใช้หลักการเข้าก่อนออกก่อน (FIFO)

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

ในวิทยาการคอมพิวเตอร์ เมื่อกระบวนการต่างๆ เช่น คำขอ API กำลังทำงานอยู่ และคุณจำเป็นต้องลบงานบางอย่าง (เช่น การส่งอีเมล) ออกจากโฟลว์ปัจจุบัน คุณจะพุชงานนั้นไปที่คิวและดำเนินการกระบวนการต่อไป

แผนภาพด้านล่างแสดงวงจรชีวิตของคิว:

การเรียนรู้คิวข้อความด้วย Node.js และ Redis:เพิ่มประสิทธิภาพเว็บแอป วงจรชีวิตของคิว | https://optimalbits.github.io/bull/

งานคืออะไร?

งานคือชิ้นส่วนของข้อมูลใดๆ ที่ใช้ในคิว ซึ่งโดยปกติจะเป็นออบเจ็กต์ที่มีลักษณะคล้าย JSON

ดังที่แสดงไว้ในภาพหน้าปกของบทความนี้ คุณสามารถนึกถึงงานในฐานะที่แต่ละคนต้องต่อคิวที่สนามบิน แต่ละคนถือกระเป๋าเอกสารที่มีข้อมูลเฉพาะและคำแนะนำอื่นๆ (หนังสือเดินทางและเอกสารทางการแพทย์หากจำเป็น) ซึ่งจะช่วยได้เมื่อถึงตาพวกเขาที่ต้องดูแล

คนใหม่ที่เข้าคิวนี้จะเข้าจากด้านหลัง (เป็นคนสุดท้าย) และคนจะเข้าจากด้านหน้า นั่นคือวิธีการประมวลผลงาน แต่ละงานประกอบด้วยข้อมูลที่จะใช้สำหรับการประมวลผล งานใหม่จะถูกเพิ่มจากด้านหลัง ในขณะที่งานถูกนำออกจากด้านหน้า

ผู้ผลิตงานคืออะไร

ผู้ผลิตงานคือโค้ดใดๆ ที่เพิ่มงานลงในคิว ในชีวิตจริง นี่จะเป็นเจ้าหน้าที่รักษาความปลอดภัยที่สนามบินคอยบอกทิศทางให้ผู้คนทราบว่าต้องเข้าคิวไหนเพื่อจุดประสงค์ที่แตกต่างกัน

ผู้ผลิตงานสามารถดำรงอยู่ได้โดยอิสระจากผู้บริโภคงาน ซึ่งหมายความว่าในการตั้งค่าไมโครเซอร์วิส บริการเฉพาะอาจเกี่ยวข้องกับการเพิ่มงานลงในคิว แต่ไม่ใช่วิธีดำเนินการหลังจากนั้น

พนักงาน (ผู้บริโภคงาน) คืออะไร

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

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

งานที่ล้มเหลวคืออะไร

บ่อยครั้ง งานบางอย่างอาจล้มเหลวในระหว่างการประมวลผล

นี่คือสาเหตุบางประการที่ทำให้งานล้มเหลว:

  • ข้อมูลอินพุตไม่ถูกต้องหรือขาดหายไป:เมื่อข้อมูลที่จำเป็นสำหรับงานที่ประมวลผลหายไป งานจะล้มเหลว ตัวอย่างเช่น งานส่งอีเมลจะล้มเหลวหากไม่มีที่อยู่อีเมลของผู้รับ
  • หมดเวลา:งานอาจล้มเหลวโดยกลไกคิวหากใช้เวลานานกว่าปกติ นี่อาจเป็นเพราะปัญหาเกี่ยวกับการพึ่งพางานหรืออย่างอื่น แต่โดยปกติแล้วคุณไม่ต้องการให้งานเดียวดำเนินไปตลอดกาล
  • ปัญหาเครือข่ายหรือโครงสร้างพื้นฐาน:ปัญหาเหล่านี้เกือบจะอยู่นอกเหนือการควบคุมของคุณ แต่ก็เกิดขึ้นได้ ข้อผิดพลาดในการเชื่อมต่อฐานข้อมูลอาจทำให้งานล้มเหลว
  • ปัญหาการพึ่งพา:บางครั้งงานต้องอาศัยทรัพยากรภายนอกเพื่อให้ทำงานได้ดี เมื่อใดก็ตามที่ทรัพยากรอื่นๆ เหล่านี้ไม่พร้อมใช้งานหรือไม่สำเร็จ งานก็จะล้มเหลว

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

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

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

คิวช่วยหลีกเลี่ยงจุดล้มเหลวเพียงจุดเดียว กระบวนการที่มีความสามารถในการล้มเหลวและสามารถลองใหม่ได้นั้นดีที่สุดในการประมวลผลโดยใช้คิวซึ่งสามารถลองใหม่ได้ในภายหลัง

วิธีสร้างแอปพลิเคชันอย่างง่ายที่ใช้คิว

ในบทความนี้ เราจะสร้างโปรเจ็กต์ง่ายๆ โดยใช้ Node.js และ Redis เราจะใช้ไลบรารี Bull เนื่องจากช่วยลดความซับซ้อนมากมายที่เกี่ยวข้องกับการสร้างระบบคิว โปรเจ็กต์จะมีปลายทางเดียวในการส่งอีเมล

สร้างโครงการ Node.js ใหม่

mkdir nodejs-queue-project
cd nodejs-queue-project
npm init -y

คำสั่งด้านบนจะสร้างโฟลเดอร์ใหม่ชื่อ 09 และ 16 ไฟล์ในนั้น 29 ไฟล์ควรมีลักษณะดังนี้:

{
 "name": "nodejs-queue-project",
 "version": "1.0.0",
 "description": "",
 "main": "index.js",
 "scripts": {
 "test": "echo \"Error: no test specified\" && exit 1"
 },
 "keywords": [],
 "author": "",
 "license": "ISC"
}

ติดตั้งการพึ่งพาที่จำเป็น

npm i express @types/express @types/node body-parser ts-node ts-lint typescript nodemon nodemailer @types/nodemailer

คำสั่งด้านบนจะติดตั้งแพ็คเกจและการขึ้นต่อกันต่าง ๆ ที่จำเป็นสำหรับโปรเจ็กต์

หลังการติดตั้ง คุณสามารถอัพเดต 37 ได้ ส่วนของ 47 ของคุณ ที่จะมี 52 คำสั่ง 60 ทั้งหมดของคุณ ไฟล์ควรมีลักษณะดังนี้:

{
 "name": "nodejs-queue-project",
 "version": "1.0.0",
 "description": "",
 "main": "index.js",
 "scripts": {
 "dev": "nodemon src/app.ts"
 },
 "keywords": [],
 "author": "",
 "license": "ISC",
 "dependencies": {
 "@types/express": "^4.17.17",
 "@types/node": "^20.3.3",
 "@types/nodemailer": "^6.4.8",
 "body-parser": "^1.20.2",
 "express": "^4.18.2",
 "nodemailer": "^6.9.3",
 "nodemon": "^2.0.22",
 "ts-lint": "^4.5.1",
 "ts-node": "^10.9.1",
 "typescript": "^5.1.6"
 }
}

ไฟล์ด้านบนแสดงการอ้างอิงที่ติดตั้งทั้งหมดของคุณ 70 คำสั่งจะทำงานเมื่อคุณใช้ 88 สคริปต์

วิธีสร้างจุดสิ้นสุด

สิ่งแรกที่ต้องทำคือสร้างโฟลเดอร์ใหม่ชื่อ 92 . โฟลเดอร์นี้จะมีไฟล์โค้ดทั้งหมดของคุณ ไฟล์แรกจะมีคือไฟล์รูทของแอปพลิเคชัน — 101 ตามที่กำหนดไว้ใน 116 ไฟล์.

เราจะใช้ 120 ไฟล์เพื่อนำเข้าแพ็คเกจที่จำเป็นและสร้างเซิร์ฟเวอร์อย่างง่ายที่มีจุดสิ้นสุดเดียวเพื่อส่งอีเมลดังที่แสดงด้านล่าง:

import express from "express";
import bodyParser from "body-parser";
import nodemailer from "nodemailer";
const app = express();
app.use(bodyParser.json());
app.post("/send-email", async (req, res) => {
 const { from, to, subject, text } = req.body;
 // Use a test account as this is a tutorial
 const testAccount = await nodemailer.createTestAccount();
 const transporter = nodemailer.createTransport({
 host: "smtp.ethereal.email",
 port: 587,
 secure: false,
 auth: {
 user: testAccount.user,
 pass: testAccount.pass,
 },
 tls: {
 rejectUnauthorized: false,
 },
 });
 console.log("Sending mail to %s", to);
 let info = await transporter.sendMail({
 from,
 to,
 subject,
 text,
 html: `<strong>${text}</strong>`,
 });
 console.log("Message sent: %s", info.messageId);
 console.log("Preview URL: %s", nodemailer.getTestMessageUrl(info));
 res.json({
 message: "Email Sent",
 });
});
app.listen(4300, () => {
 console.log("Server started at http://localhost:4300");
});

ตอนนี้คุณสามารถเริ่มต้นเซิร์ฟเวอร์ของคุณโดยเรียกใช้ 135 ในเทอร์มินัลของคุณ คุณควรเห็นข้อความว่า 146 ในเทอร์มินัลของคุณ

การเรียนรู้คิวข้อความด้วย Node.js และ Redis:เพิ่มประสิทธิภาพเว็บแอป npm เรียกใช้ข้อความ dev

ตอนนี้คุณสามารถทดสอบตำแหน่งข้อมูลโดยใช้เครื่องมือเช่นบุรุษไปรษณีย์:

การเรียนรู้คิวข้อความด้วย Node.js และ Redis:เพิ่มประสิทธิภาพเว็บแอป การทดสอบปลายทางกับบุรุษไปรษณีย์

คำขอใช้เวลาเกือบ 4 วินาทีตามที่แสดงในภาพหน้าจอ ซึ่งช้ามากสำหรับปลายทาง หากคุณดูที่เทอร์มินัลของคุณ คุณจะเห็น URL ที่คุณสามารถดูตัวอย่างอีเมลที่ถูกส่งไปได้ด้วย

การเรียนรู้คิวข้อความด้วย Node.js และ Redis:เพิ่มประสิทธิภาพเว็บแอป

การเปิดลิงก์จะทำให้คุณเห็นว่าอีเมลมีลักษณะอย่างไร

การเรียนรู้คิวข้อความด้วย Node.js และ Redis:เพิ่มประสิทธิภาพเว็บแอป เนื้อหาอีเมล

วิธีสร้างคิว

เพื่อให้กระบวนการรวดเร็วยิ่งขึ้น สามารถจัดคิวอีเมลเพื่อส่งในภายหลังและส่งการตอบกลับไปยังผู้ใช้ได้ทันที

เมื่อต้องการทำเช่นนี้ ให้ติดตั้ง 155 ไลบรารี่และ 167 ไลบรารี่ที่เราจะใช้เพื่อสร้างคิว นั่นคือ:

npm i bull @types/bull

การสร้างคิวใหม่โดยใช้ 178 ง่ายเหมือนกับการสร้างอินสแตนซ์ 181 ใหม่ วัตถุที่มีชื่อสำหรับคิว:

// This goes at the top of your file
import Bull from 'bull';
const emailQueue = new Bull("email");

เมื่อคิวถูกสร้างขึ้นด้วยชื่อคิวเพียงอย่างเดียว คิวจะพยายามใช้ URL การเชื่อมต่อ Redis เริ่มต้น:195 . หากคุณต้องการใช้ URL อื่น เพียงส่งวัตถุที่สองไปที่ 205 คลาสเป็นวัตถุตัวเลือก:

const emailQueue = new Bull("email", {
 redis: "localhost:6379",
});

ณ จุดนี้ คุณสามารถสร้างฟังก์ชันง่ายๆ เพื่อทำหน้าที่เป็นผู้ผลิตงานและเพิ่มงานลงในคิวทุกครั้งที่มีคำขอเข้ามา

type EmailType = {
 from: string;
 to: string;
 subject: string;
 text: string;
};
const sendNewEmail = async (email: EmailType) => {
 emailQueue.add({ ...email });
};

ฟังก์ชันที่สร้างขึ้นใหม่นี้ 217 ยอมรับออบเจ็กต์ที่มีรายละเอียดของอีเมลใหม่ที่จะส่งประเภท 229 . มีที่อยู่อีเมลของผู้ส่ง (238 ) ที่อยู่อีเมลผู้รับ (243 ), 256 ของอีเมล และเนื้อหาของอีเมล (260 ). แล้วมันดันงานใหม่เข้าคิว

คุณสามารถใช้ฟังก์ชันนี้แทนการส่งอีเมลในระหว่างการร้องขอได้ทันที แก้ไขจุดสิ้นสุดเพื่อทำสิ่งนี้:

app.post("/send-email", async (req, res) => {
 const { from, to, subject, text } = req.body;
 await sendNewEmail({ from, to, subject, text });
 console.log("Added to queue");
 res.json({
 message: "Email Sent",
 });
});

ณ จุดนี้ โค้ดจะง่ายกว่าและกระบวนการก็เร็วขึ้น คำขอใช้เวลาประมาณ 40 เมตร — เร็วกว่าเดิมประมาณ 100 เท่า

การเรียนรู้คิวข้อความด้วย Node.js และ Redis:เพิ่มประสิทธิภาพเว็บแอป การทดสอบปลายทางกับบุรุษไปรษณีย์

ณ จุดนี้ อีเมลจะถูกเพิ่มลงในคิว มันจะยังคงอยู่ในคิวจนกว่าจะประมวลผล งานสามารถประมวลผลได้โดยแอปพลิเคชันเดียวกันหรือบริการอื่น (หากอยู่ในการตั้งค่าไมโครเซอร์วิส)

วิธีการประมวลผลงาน

วงจรนี้จะไม่สมบูรณ์และไม่มีประโยชน์หากอีเมลไม่เคยออกจากคิว เราจะสร้างผู้ใช้งานเพื่อประมวลผลงานและล้างคิว

เราสามารถทำได้โดยการสร้างตรรกะสำหรับฟังก์ชันที่ยอมรับ 274 คัดค้านและส่งอีเมล:

const processEmailQueue = async (job: Job) => {
 // Use a test account as this is a tutorial
 const testAccount = await nodemailer.createTestAccount();
 const transporter = nodemailer.createTransport({
 host: "smtp.ethereal.email",
 port: 587,
 secure: false,
 auth: {
 user: testAccount.user,
 pass: testAccount.pass,
 },
 tls: {
 rejectUnauthorized: false,
 },
 });
 const { from, to, subject, text } = job.data;
 console.log("Sending mail to %s", to);
 let info = await transporter.sendMail({
 from,
 to,
 subject,
 text,
 html: `<strong>${text}</strong>`,
 });
 console.log("Message sent: %s", info.messageId);
 console.log("Preview URL: %s", nodemailer.getTestMessageUrl(info));
 return nodemailer.getTestMessageUrl(info);
};

ฟังก์ชั่นด้านบนยอมรับ 288 วัตถุ วัตถุมีคุณสมบัติที่เป็นประโยชน์ที่แสดงสถานะและข้อมูลในงาน ที่นี่เราใช้ 297 ทรัพย์สิน

ณ จุดนี้ ทั้งหมดที่เรามีคือฟังก์ชัน ไม่รับงานโดยอัตโนมัติเพราะไม่รู้ว่าจะทำงานกับคิวไหน

ก่อนที่จะเชื่อมต่อเข้ากับคิว คุณสามารถเพิ่มงานสองสามงานลงในคิวต่อไปได้โดยส่งคำขอบางส่วน คุณสามารถตรวจสอบงานอีเมลที่อยู่ในคิวปัจจุบันได้โดยการรันคำสั่งนี้ใน 305 ของคุณ :

LRANGE bull:email:wait 0 -1

ซึ่งจะตรวจสอบรายการรออีเมล และส่งกลับ 311 ของงานที่รอคอย

การเรียนรู้คิวข้อความด้วย Node.js และ Redis:เพิ่มประสิทธิภาพเว็บแอป Redis CLI

ฉันได้สร้างงานสองสามงานเพียงเพื่อแสดงให้เห็นว่าคนงานทำงานอย่างไร

ตอนนี้ เชื่อมต่อผู้ปฏิบัติงานเข้ากับคิวโดยการเพิ่มบรรทัดโค้ดนี้:

emailQueue.process(processEmailQueue);

นี่คือสิ่งที่ 322 ของคุณ ไฟล์ควรดูแลสิ่งนั้น:

import express from "express";
import bodyParser from "body-parser";
import nodemailer from "nodemailer";
import Bull, { Job } from "bull";
const app = express();
app.use(bodyParser.json());
const emailQueue = new Bull("email", {
 redis: "localhost:6379",
});
type EmailType = {
 from: string;
 to: string;
 subject: string;
 text: string;
};
const sendNewEmail = async (email: EmailType) => {
 emailQueue.add({ ...email });
};
const processEmailQueue = async (job: Job) => {
 // Use a test account as this is a tutorial
 const testAccount = await nodemailer.createTestAccount();
 const transporter = nodemailer.createTransport({
 host: "smtp.ethereal.email",
 port: 587,
 secure: false,
 auth: {
 user: testAccount.user,
 pass: testAccount.pass,
 },
 tls: {
 rejectUnauthorized: false,
 },
 });
 const { from, to, subject, text } = job.data;
 console.log("Sending mail to %s", to);
 let info = await transporter.sendMail({
 from,
 to,
 subject,
 text,
 html: `<strong>${text}</strong>`,
 });
 console.log("Message sent: %s", info.messageId);
 console.log("Preview URL: %s", nodemailer.getTestMessageUrl(info));
};
emailQueue.process(processEmailQueue);
app.post("/send-email", async (req, res) => {
 const { from, to, subject, text } = req.body;
 await sendNewEmail({ from, to, subject, text });
 console.log("Added to queue");
 res.json({
 message: "Email Sent",
 });
});
app.listen(4300, () => {
 console.log("Server started at http://localhost:4300");
});

เมื่อคุณบันทึก คุณจะสังเกตเห็นว่าเซิร์ฟเวอร์รีสตาร์ทและเริ่มส่งอีเมลทันที เนื่องจากผู้ปฏิบัติงานมองเห็นคิวและเริ่มประมวลผลทันที

การเรียนรู้คิวข้อความด้วย Node.js และ Redis:เพิ่มประสิทธิภาพเว็บแอป เซิร์ฟเวอร์ส่งอีเมลที่อยู่ในคิว

ตอนนี้ทั้งผู้ผลิตและคนงานต่างกระตือรือร้นกัน คำขอ API ใหม่ทุกรายการจะถูกส่งไปยังคิว และผู้ปฏิบัติงานจะดำเนินการทันที เว้นแต่จะมีงานที่ค้างอยู่บางส่วนอยู่แล้ว

สรุป

ฉันหวังว่าบทความนี้จะช่วยให้คุณเข้าใจว่าคิวข้อความคืออะไร วิธีเพิ่มงานและสร้างกระบวนการเพื่อเรียกใช้งาน และวิธีที่คุณสามารถใช้เพื่อสร้างแอปพลิเคชันเว็บที่ดีขึ้น คุณสามารถค้นหาไฟล์โค้ดที่ใช้ในบทความนี้ได้ที่ GitHub

หากคุณมีคำถามหรือคำแนะนำที่เกี่ยวข้อง โปรดติดต่อฉันเพื่อแบ่งปัน

หากต้องการอ่านบทความของฉันเพิ่มเติมหรือติดตามผลงานของฉัน คุณสามารถเชื่อมต่อกับฉันได้ทาง LinkedIn, Twitter และ Github รวดเร็ว ง่ายดาย และฟรี!

เรียนรู้การเขียนโค้ดฟรี หลักสูตรโอเพ่นซอร์สของ freeCodeCamp ช่วยให้ผู้คนมากกว่า 40,000 คนได้งานในตำแหน่งนักพัฒนา เริ่มต้น