วันพฤหัสบดีที่ 6 กรกฎาคม พ.ศ. 2560

วิธีการ Parse JSON ขนาดใหญ่ใน Android

วิธีการ Parse JSON ขนาดใหญ่ใน Android

ยามเช้าในวันที่อากาศไม่ค่อยจะสดใสวันหนึ่ง ผมได้รับแจ้งจาก User ผู้ใช้งานแอป miimai ว่าเกิดปัญหาในการใช้งานบางอย่างขึ้น และได้ Report ข้อผิดพลาดมาให้ผมเรียบร้อยแล้ว ผมก็เลยรีบไปเปิดดูข้อมูลในทันใดและพบว่าเป็น OutOfMemoryError ตอนที่เห็นทีแรกยังค่อยข้างงงอยู่บ้างว่ามันเป็นไปได้ยังไง ปกติแล้วแอปแทบจะไม่ใช้ Memory เลยด้วยซ้ำ
ผมค่อยๆ ไล่ดูบรรทัดที่เกิดปัญหาและพบว่ามันมาจากบรรทัดนี้

1
new JSONObject(resposeStr)
Constructor ของ JSON จะทำการรับข้อมูล JSON ที่อยู่ในรูปของ String (ผมแปลงเป็น String ก่อนที่จะส่งข้อมูลมา) มาแปลงให้อยู่ในรูปของ Object แบบ JSON ซึ่งดูผ่านๆ ก็ไม่ได้มีปัญหาอะไรตรงไหน
ปัญหาที่ผมเจอมันอยู่ตรงที่ว่า เครื่องของ User เป็นเครื่องเก่าและ Memory ต่ำพอสมควร ประกอบกับข้อมูลที่ผมส่งไปเป็นข้อมูลหนังสือประมาณ 20,000 กว่าเล่ม (รวมๆ แล้วก็หลาย MB อยู่) ซึ่งการแปลง String ให้เป็น Object นี้จะแปลง String ทั้งหมดเลย และใช้ Memory สูงมาก (หลายคนบอกว่าน่าจะประมาณ 3–5 เท่าของขนาดเดิม)
โอเคครับ รับทราบปัญหากันเป็นที่เรียบร้อยแล้ว คำถามถัดไปที่ควรจะถามคือ จะแก้ยังไงดี
ผมลองหาข้อมูลดู ก็มีบางคนบอกว่า จริงๆ แล้ว JSON Protocol เนี่ยไม่ควรนำมาใช้ในการส่งข้อมูลจำนวนมากๆ (เพราะมัน Parse แล้ว Memory บวมอย่างที่เห็น) ควรจะใช้วิธีการอื่นมากกว่า
ซึ่งก็ดูมีเหตุผลนะ แต่ในเมื่อแอปมันออกแบบมาแบบนี้แล้ว ถ้าแก้ทีนี่ยาวเลยนะ มีวิธีไหนมั้ยที่ยังใช้ JSON อยู่ แต่ไม่ให้มันใช้หน่วยความจำเกินแบบนี้อีก ซึ่งพอลองหาๆ ไปก็เจอว่าวิธีการคือค่อยๆ Parse ทีละส่วน (หลายที่เรียกมันว่า Streaming) มันก็จะลดการใช้หน่วยความจำจำนวนมากในคราวเดียวได้ โดยไลบลาลีที่สามารถนำมาใช้ได้ก็อย่างเช่น Jackson และ GSON
ด้วยอคติส่วนตัว ผมจึงลองเลือก GSON มาใช้อย่างไม่มีเหตุผลใดๆ
วิธีการใช้หลักๆ ก็คือเราต้องเขียนให้มัน Parse ข้อมูลเอาเองว่าจะมีข้อมูลอะไรยังไงบ้าง เช่นสมมติว่าข้อมูลของผมเป็นหนังสือหลายๆ เล่มแล้วกัน
?
1
2
3
4
5
6
7
8
9
10
11
[
  {
    id: 20,
    name: "Dragon Ball",
    author: "TORIYAMA Akira"
  },
  {
    ...
  },
  ...
]
ก็ให้สร้างฟังก์ชันสำหรับ Parse ตัวข้อมูลหนังสือขึ้นมาก่อน โดยมีพารามิเตอร์เป็น JsonReader
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public Book readBook(JsonReader reader) throws IOException {
    Book book = new Book();
 
    reader.beginObject();
    while (reader.hasNext()) {
        String name = reader.nextName();
        switch (name) {
            case "id":
                book.setId(reader.nextInt()); break;
            case "name":
                book.setName(reader.nextString()); break;
            case "author":
                book.setAuthor(reader.nextString()); break;
            default:
                reader.skipValue();
        }
    }
    reader.endObject();
    return book;
}
ฟังก์ชันนี้ก็จะมีหน้าที่สำหรับ Parse ข้อมูลหนังสือแต่ละเล่มโดยเฉพาะ จากนั้นก็สร้างอีกฟังก์ชันสำหรับ Parse ข้อมูลอาร์เรย์ของหนังสือ
?
1
2
3
4
5
6
7
8
9
10
11
public List<book> readBookArray(JsonReader reader) throws  IOException {
    List<book> books = new ArrayList<>();
 
    reader.beginArray();
    while (reader.hasNext()) {
        books.add(readBook(reader));
    }
    reader.endArray();
    return books;
}
</book></book>
อารมณ์ก็ง่ายๆ ประมาณนี้แหละครับ เหลือแค่แปลง String ให้เป็น JsonReader แล้วก็ส่งเข้ามาเท่านั้นเอง
1
2
InputStream stream = new ByteArrayInputStream(response.getBytes(Charset.forName("UTF-8")));
JsonReader reader = new JsonReader(new InputStreamReader(in, "UTF-8"));
เท่านี้ก็เป็นอันเรียบร้อยครับ ผมก็เลยลองเทสดูด้วยว่ามันใช้ Memory ต่างกันจริงๆ รึเปล่า เริ่มจากวิธีแรก
วิธีนี้คือใช้ JSONObject แบบตรงๆ เลย ถ้าดูก็จะเห็นว่ามันกิน Memory เยอะอยู่แป๊ปเดียวก็จริง แต่ก็เพียงพอให้ Error แล้วครับ ช่วงพีคสุดคือกินไป 50 กว่าๆ MB
ทีนี้ผมลองใช้ GSON แล้ว Parse แบบเองดู
กินสูงสุดเหลือแค่ 30 กว่า MB เอง ใช้ได้เลยแฮะ
ถ้าอยากลองใช้กันดู ก็ไปดูรายละเอียดที่ https://github.com/google/gson เลยนะครับ น่าจะละเอียดกว่าผมอธิบายแน่ๆ

แนะนำ C++11 - มีอะไรใหม่ มีอะไรดี

แนะนำ C++11 - มีอะไรใหม่ มีอะไรดี
ก่อนอื่นหลายคนอาจจะมีคำถามที่ว่าแล้ว C++11 คืออะไร? ต่างจาก C++ ธรรมดายังไง? คำตอบก็คือว่า C++11 เป็นมาตรฐานของ C++ ตัวใหม่ครับ ซึ่งเป็นมาตรฐานที่ออกมาในปี 2011 คือหมายถึงเถียงกันเสร็จเรียบร้อยแล้วว่าจะให้มีหรือไม่มีอะไรบ้าง อย่างไร ซึ่งถ้าย้อนกลับไปตอนแรกเหมือนมาตรฐานนี้จะใช้ชื่อแบบลำลองว่า C++0x นั่นไม่แน่ใจว่าจะเสร็จในปีไหนแต่คงมี 200x นี่แหละ ซึ่งพอเอาเข้าจริงก็ลากยากมาถึงปี 2011 เลยทีเดียว ถึงขนาดมีคนเล่นมุกว่า 0x ที่ว่าคือ 0B (เลขฐาน 16) นั่นเอง (ฮา)

ตอนที่กำลังเขียนอยู่นี่ก็ต้นปี 2016 เข้าไปแล้ว จริงๆแล้วมันก็มีมาตรฐานใหม่ออกมาเพิ่มอีกแหละครับคือ C++14 กับ C++17 แต่ว่าคราวนี้เรามาดูกันก่อนว่าไอ้เจ้า C++11 นี่มันมีอะไรต่างจากเดิมมั่ง มันเจ๋งขึ้นจริงๆ รึเปล่า?

ก่อนที่จะใช้ C++11 เนี่ยก็จำเป็นที่จะต้องใช้ตัวคอมไพเลอร์ที่ Implement ฟีเจอร์ต่างๆของ C++11 ได้ทั้งหมดแล้ว ซึ่งหาไม่ยากเลยครับ g++, clang ตัวใหม่ หรือจะเป็นคอมไพเลอร์ของ Intel และ Microsoft ก็ใช้ได้หมดแล้ว สามารถดูรายละเอียดว่ามีตัวไหนใช้อะไรได้บ้างที่ C++ compiler support เลยครับ

ทีนี้เรามาดูกันเลยดีกว่าว่ามันมีอะไรที่ทำให้ชีวิตดีขึ้นบ้าง
1. auto

มันคือการที่เราสามารถกำหนดชนิดตัวแปรเป็น auto แล้วให้คอมไพเลอร์ไปหาเองว่ามันควรจะเป็นชนิดอะไรครับ พูดแล้วเห็นภาพยาก ลองดูตัวอย่างดีกว่า
auto x = 20;
auto y = 4.5;
auto z = 'A';

จากตัวอย่างบรรทัดแรกคือ เราไม่ต้องประกาศตัวแปร x เป็นชนิด int ให้เห็นแต่ว่า ใช้ auto ไปเลย คอมไพลเอร์จะเดาชนิดให้เองจาก ชนิดของด้านขวามือ ซึ่งก็คือ int เพราะมันเห็นว่า 20 เป็น int ครับ ตัวแปร y ก็จะหลายเป็น double และ z ก็จะเป็น char แน่นอนว่าคีย์เวิร์ด auto ก็มีข้อจำกัดอยู่ เช่นถ้าเราไม่มีการกำหนดค่ามันก็จะเดาชนิดให้ไม่ออกครับ เช่นประกาศ auto s; แบบนี้ไม่ได้แน่นอนเพราะไม่มีชนิดในมันอ้างอิง (ยังไงตัวแปรใน C++ ก็ต้องกำหนดชนิดข้อมูล เหมือนเดิมครับ เพียงแต่ว่าเราแค่ปล่อยให้มันไปหาเองได้ว่าควรจะเป็นชนิดอะไร)

ตัวอย่างเมื่อกี้เป็นแค่ตัวอย่างให้เห็นภาพครับ ยังไม่ใช่ประโยชน์ที่แท้จริงเท่าไหร่ เพราะมันดูไม่ช่วยอะไรเท่าไหร่ มันจะช่วยได้มากในกรณีต่อไปนี้ครับ
vector<int> v;
/* คำสั่งอื่นๆ */
vector<int>::iterator it = v.begin();

vector< map<int,string> > mapv;
/* คำสั่งอื่นๆ */
map<int,string> m = mapv[5];

การประกาศชนิดของ iterator หรือว่าชนิดที่เป็น template ทั้งหลายจะสูญเสียพลังงานในการพิมพ์มาก เราก็จะเปลี่ยนเป็นใช้ auto แทน ซึ่งเสียเวลาพิมพ์น้อยกว่า โค้ดก็อ่านง่ายสบายตากว่าเดิมเยอะ เช่นแบบนี้ครับ 
vectorint v;
/* คำสั่งอื่นๆ */
auto = v.begin();

vector< map<int,string> > mapv;
/* คำสั่งอื่นๆ */
auto m = mapv[5];

 2. แก้ไขการ parse <>

อันนี้นึกไม่ออกว่าจะเรียกมันว่าอะไร แต่ C++ มีข้อจำกัดที่โคตรจะน่ารำคาญอย่างนึงคือเวลาเขียนชนิดที่เป็น template ซ้อนกันจะต้องเว้นวรรคระหว่าง > อย่างน้อย 1 ทีครับ เช่น ถ้าเราอยากจะสร้าง matrix ขึ้นมาอันนึงเราอาจจะใช้ vector<vector<int>> mat; แต่ว่าเขียนแบบนี้ถือว่าผิด เพราะคอมไพเลอร์จะเข้าใจว่าไอ้ >> ติดกันนี่คือโอเปอเรเตอร์ >> ซึ่งถ้าจะให้ถูกจะต้องเขียนว่า vector< vector<int> > mat; เพื่อกันมันสับสน

แต่ว่า C++11 ไม่โง่แล้วครับ เขียนไปได้เลย vector<vector<int>> มันไม่มึนแล้ว ชีวิตสดใสขึ้นเยอะเลย

 3. ลูป for แบบ range

ภาษาสมัยใหม่มันก็มีกันหมดแล้วล่ะ ก็เลยเป็นอีก 1 ฟีเจอร์ที่ขาดไปไม่ได้ จากที่แต่ก่อนเราอาจจะต้องวนลูปตัวอาร์เรย์หรือ containner ต่างๆ แล้วค่อย get ค่ามาจากการใช้ index แบบนี้

vector<int> v;
for (int i = 0; i < v.size(); ++i) {
    int x = v[i];
    /* เอาค่า x ไปทำอะไรซักอย่าง */
}

for (vector<int>::iterator it = v.begin();
     it != v.end(); ++it) {
    int x = *it;
    /* เอาค่า x ไปทำอะไรซักอย่าง */
}

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

for (int x : v) {
    /* เอาค่า x ไปทำอะไรซักอย่าง */
}

หรือจะเอา auto มาใช้ก็ได้ เกิดถ้าชนิดของ element ใน container มันยาว

vector< map<int,string> > mapv;
for (auto m : mapv) {
    /* เอาค่า m ไปทำอะไรซักอย่าง */
}

 4. List initialization

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

int a[5] = {1,2,3,4,5}; /* ทำได้ */
vector<int> v = {1,2,3,4,5}; /* ทำไม่ได้ */

/* ถ้าจะได้ต้องเอาอาร์เรย์มากำหนดให้มันอีกต่อนึงแบบนี้ */
vector<int> v(a,a+5);

ปัญหาก็ประมาณนี้แหละครับ คือมันกำหนดค่าเริ่มต้นยากมาก ดังนั้นใน C++11 ก็เลยยอมให้ทำได้เรียบร้อยแล้ว  
vector<int> v = {1,2,3,4,5}; /* ทำได้ใน C++11 */
vector<int> v2{1,2,3,4,5}; /* แบบนี้ก็ได้ (C++11) */

/* กำหนดค่าไปแล้วอยากเปลี่ยนกลางอากาศก็ทำได้ สุดยอด!! */
v = {100,200,300};

ผมก็สุดยอดไปงั้นแหละครับ พวกภาษาสมัยใหม่มันเขียนได้อยู่แล้ว แต่ C++ มันทำไม่ได้มาอย่างนาน พอได้แล้วมันก็ต้องดีใจบ้าง (ฮา) นอกจากนี้ยังกำหนดค่าแบบ nested ได้ด้วยนะ อย่างเช่นพวก map

   
map<int,string> m = {
    {1, "one"},
    {2, "two"},
    {3, "three"}
};



5. Lambda functions

Labmda functions ถ้ามองผ่านก็คือฟังก์ชันที่ไม่มีชื่ออันนึง แต่จริงๆแล้วมันมีอะไรมากกว่าฟังก์ชันธรรมดาครับ มันมีส่วนที่เรียกว่า capture ซึ่งสามารถนำ context ภายนอก เช่นตัวแปรต่างๆเข้าไปใช้ในฟังก์ชันที่สร้างขึ้นได้ ซึ่งขอไม่ลงลึกนะครับ ไปดูตัวอย่างการใช้แบบง่ายๆกันก่อนดีกว่า

   
bool moreThan10(int x) { return x>10; }

vector<int> v = {6,5,10,13,25,1,25,23,13,5,8,90};
int c = count_if(v.begin(), v.end(), moreThan10);

ฟังก์ชัน count_if ใน <algorithm> ใช้สำหรับนับว่าใน container มีข้อมูลกี่ตัวที่ตรงกับเงื่อนไขที่กำหนดให้ ซึ่งเราจะต้องส่งฟังก์ชันสำหรับกำหนดเงื่อนไขเข้าไปตัวนึง ทีนี้ Lambdas จะมีประโยชน์ตรงนี้แหละครับ คือมันสามารถสร้างฟังก์ชันที่ไม่มีชื่อแล้วส่งเข้าไปตรงนั้นได้เลย

   
vector<int> v = {6,5,10,13,25,1,25,23,13,5,8,90};
int c = count_if(v.begin(), v.end(), [](int x){return x>10;});

ซึ่งมันจะเหมาะมากกับฟังก์ชันแบบที่ใช้ครั้งเดียวแล้วก็เลิกลากันไป ไม่ต้องมาประกาศให้กวนใจกันอีกครับ

ตรง [] คือส่วนของ capture ที่บอกว่าจะเอาตัวแปรอะไรเข้าไปใช้ในฟังก์ชันบ้าง ซึ่งในที่นี้เป็นว่างเพราะเราไม่เอาอะไรเข้าไปเลย (int x) อันนี้ก็พารามิเตอร์ของฟังก์ชันเฉยๆ

สมมติว่าอยากให้เช็คว่ามีกี่ตัวบ้างที่มีค่ามากกว่า q

   
vector<int> v = {6,5,10,13,25,1,25,23,13,5,8,90};
int q = 8;
int c = count_if(v.begin(), v.end(), [q](int x){return x>q;});

ตรง capture ก็ใส่ตัวแปร q เข้าไป เพื่อบอกว่าให้เอาตัวแปร q ไปใช้ในฟังก์ชันด้วย ซึ่งความหมายของคำสั่งดังกล่าวคือนับจำนวนของข้อมูลใน vector v ที่มากกว่า q (ซึ่งมีค่าเท่ากับ 8)

จาก concept ของ lambdas ทำให้ประกาศตัวแปรฟังก์ชันใน C++11 ได้ง่ายขึ้นมากครับ (เมื่อก่อนมันก็ทำได้แต่ลำบาก) เช่นจากตัวอย่างแรกสุด เราก็จะได้โปรแกรมใหม่หน้าตาแบบนี้ ใช้ชนิดเป็น auto ไปได้เลยครับ
   
auto moreThan10 = [](int x){return x>10;};
int c = count_if(v.begin(), v.end(), moreThan10);

 อื่นๆ

    เพิ่มฟังก์ชันที่เกี่ยวกับ Regular Expression ใน <regex>
    เพิ่มฟังก์ชันที่เกี่ยวกับการสุ่มใน <random>
    Raw string literals ที่เขียน string literal แบบหลายบรรทัดได้ง่ายขึ้น
    คีย์เวิร์ด override ที่เอาไว้บอกว่าฟังก์ชันนี้เป็นการ overriding และคีย์เวิร์ด final ที่ทำให้ฟังก์ชันไม่สามารถ overriding ต่อได้ (หรือกำหนดให้ class ไม่สามารถ inherite ต่อได้) 
    มีฟังก์ชันใหม่ๆอีกมากมาย, smart pointer, enum แบบใหม่, tuple, การจัดการ thread, atomic operator และอื่นๆอีกมากมายครับ

สรุปง่ายๆคือถ้าใช้ C++ อยู่ ลองมาใช้ C++11 กันดูครับ มันสะดวกขึ้นเยอะเลย

MinGW

MinGW คอมไพเลอร์คืออะไร?

  • MinGW เป็น GNU Minimalist สำหรับ Windows
  • คอมไพเลอร์นี้จะใช้ในการพัฒนาแอพลิเคชัน
  • มันถูกพัฒนาโดยโคลินปีเตอร์ส
  • มันเริ่มต้นมา realease มันปี 1988

เปรียบเทียบกับ Cygwin

MinGW เป็นที่เรียบง่าย GNU จะไม่ให้สภาพแวดล้อมรันไทม์ POSIX สำหรับ
การพัฒนาโปรแกรมประยุกต์บน Windows POSIX
POSIX (แบบพกพาระบบปฏิบัติการ Interface) เป็นมาตรฐานซึ่งมีการทำงานร่วมกัน
ระหว่างระบบปฏิบัติการ
Cygwin ให้การใช้งานโปรแกรม POSIX

การติดตั้ง

สำหรับการตั้งค่าสภาพแวดล้อม MinGW และใช้โปรแกรมผมใช้ต่อไปนี้:
  • ระบบปฏิบัติการ Windows 7
  • คอมไพเลอร์ MinGW
  • แก้ไขข้อความเช่น Notepad
ตอนนี้ติดตั้ง MinGW จากลิงค์ต่อไปนี้: ดาวน์โหลด
ในขณะที่ดาวน์โหลดคุณจะเจอหน้าจอเหล่านี้:

ขั้นตอน:

ตอนนี้ขั้นตอนต่อไปแสดงวิธีการเรียกใช้โปรแกรมครั้งแรกของคุณใน MinGW คอมไพเลอร์:
  • เปิดเปลือก MinGW จากลิงค์ต่อไปนี้ (สมมติว่าคุณติดตั้งไว้ใน C: ไดรฟ์):
  •  C: \ MinGW \ MSYS \ 1.0 
  • ตอนนี้หลังจากที่เปิดเปลือก MinGW ถึงสถานที่แห่งนี้โดยทำตามขั้นตอนที่แสดงด้านล่างภายใต้ภาพ:

    • สร้างไฟล์ TXT ใหม่ในไดเร็กทอรี "bin" และบันทึกเป็น "amitprogram1.c" เขียนรหัสที่ง่ายต่อไปนี้เพื่อเพิ่มตัวเลขสอง (แสดงโปรแกรมนี้เพื่อประโยชน์ของความเรียบง่าย):

  • ตอนนี้ป้อนคำสั่งต่อไปนี้:
    GCC amitprogram1.c -o amitprogram.exe
    -o แสดงในคำสั่งกำหนดชื่อของไฟล์ที่ส่งออกที่สร้างขึ้น คำสั่งดังกล่าวจะรวบรวมและประสบความสำเร็จไฟล์ exe จะสร้าง:
  • ตอนนี้ทำงานได้ประสบความสำเร็จโดยการป้อน "amitprogram1" เอาท์พุทสามารถมองเห็นได้ที่นี่:
  • สุดท้ายคุณก็ประสบความสำเร็จจะรันโปรแกรมครั้งแรกของคุณใน MinGW คอมไพเลอร์
    สำหรับการดำเนินการ C ++ โปรแกรมของคุณเพียงแค่เปลี่ยน "GCC" กับ "G ++" คือ
     G ++ amitprogram1.c -o amitprogram.exe 
ด้วยวิธีนี้คุณสามารถเรียกใช้โปรแกรมแรกใน MinGW คอมไพเลอร์

วันเสาร์ที่ 1 กรกฎาคม พ.ศ. 2560

VMware ESXi ระบบปฏิบัติการสำหรับ VPS Hosting


แรกเริ่มเดิมที VMware มีแต่ ESX และเมื่อ ESX ติดตลาดและทำตัวเปรียบเสมือนระบบปฏิบัติการตัวหนึ่งจึงนำไปจำหน่ายพ่วงกับ เซิร์ฟเวอร์หลายค่าย บางทีถูกโหลดไว้ในฮาร์ดดิสก์ บางทีมาเป็นไดร์ฟ USB แล้วแต่ว่าค่ายไหนจะรังสรรค์ผลงานออกมายังไง ส่วน VMware ESX ที่จำหน่ายพร้อมกับเซิร์ฟเวอร์นี้จึงได้ชื่อเป็น ESXi โดย i ก็คือ Integrated จะจำหน่ายมาพร้อมกับเซิร์ฟเวอร์เท่านั้น ช่วงเวลาหลัง คิดว่าน่าจะเป็นที่ ESXi แบบเดิม รองรับเซิร์ฟเวอร์ได้ในวงจำกัด และการขายผ่านเซิร์ฟเวอร์ลูกค้าไม่สามารถทดลองก่อนได้ เจ้า ESXi แบบมากับเซิร์ฟเวอร์จึงได้ชื่อใหม่เป็น ESXi Embedded โดยวีเอ็มแวร์ออก ESXi Installable มาอีกหนึ่งตัว ESXi Installable สามารถดาวน์โหลดมาติดตั้งได้โดยง่ายไม่ต้องรอซื้อพ่วงกับเซิร์ฟเวอร์ สรุปแล้วปัจจุบัน ESX มีด้วยกัน 2 รูปแบบ คือ
vmware_infrastructure
ESX (เสียเงิน)
ESXi (ฟรี) โดยมีอีก 2 แบบย่อยคือ ESXi Embedded จำหน่ายพร้อมเซิร์ฟเวอร์ และ ESXi Installable ฟรี สามารถดาวน์โหลด และติดตั้งเองได้
แน่นอนว่าหากสนใจใช้ฟรีไม่มีทางหนีพ้นไปจาก VMware ESXi แต่หากต้องการใช้งานกับโครงสร้าง VMware Infrastructure (VI) เราสามารถเลือกได้ว่าจะใช้ VMware ESX หรือ VMware ESXi
สำหรับทาง Host4PRO ได้เลือกใช้ระบบปฏิบัติการ VMWare ESXi ซึ่งทำงานแบบ Bare Metal Hypervisor ที่มีความสามารถสูงในการจัดการทรัพยากรภายในเครื่อง เพื่อไม่ให้เกิดการแย่งทรัพยากรกันเองภายในเครื่อง (ถ้าเป็น Software Virtual Machine ยังไม่สามารถจัดการได้ดีเท่าไหร่นัก) และ Dell PowerEdge R210 , CISCO C200 ทำให้คุณมั่นใจได้ว่า Linux VPS ของเรา แรง เร็ว กว่าใคร โดยลูกค้าสามารถเลือก OS ได้ เช่น CentOs Debia , Slackware Fedora Gentoo Ubuntu FreeBSD หรือ Windows Server และเรายังแถม Control Panel จาก DirectAdmin ทำให้คุณเริ่มต้นใช้งานได้ทันที

จัดเตรียม IP และ Subnet และ VMware ESXi เพื่อตอบโจทย์

2. จัดเตรียม IP และ Subnet และ VMware ESXi เพื่อตอบโจทย์

จากโพสต์ที่แล้ว  โจทย์ที่ได้รับ ติดตั้ง Active Directory ที่ผมต้องทำ

เรามาต่อกันที่ จัดเตรียมระบบโดย VMware ESXi ตามโจทย์ที่ได้รับมา คือ

โจทย์ที่ 1 ทำ 1 VM Kernal (สำหรับทำให้  VM Network ทั้ง 3 Route หากันได้)

โจทย์ที่ 2 ทำ 3 VM Network เพื่อ แยก Server ใน Guest OS ให้อยูคนละ Subnet

โจทย์ที่ 3 ทำ 3 VM Guest OS ก็คือ ทำ Windows Server สำหรับทำ Active Directory

แยกข้อสอบออกเป็นส่วนๆ ดังนี้
โจทย์ที่ 1 ทำ 1 VM Kernal (สำหรับทำให้  VM Network ทั้ง 3 Route หากันได้)

- Windows Server ทั้ง 3 Guest OS มี IP และ Subnet ต่างกัน ทำอย่างไรให้ทั้งหมดสามารถมองเห็นกัน หรือสามารถรวมกันเป็น Network เดียวกัน (เครื่องมอที่ใช้ คือ เว็บ subnet-calculator.com เพื่อช่วยคำนวณ Subnet)
สำนักงานใหญ่ ต่อ Net โดยตั้ง IP ภายใน สำหรับ Server ดังนี้
IP = 10.10.10.0 / 21 หมายถึง สามารถใช้ IP ได้ 2046 IP Address
IP Address ที่ใช้ได้ คือ 10.10.8.1 - 10.10.15-255
10.10.8.x สำหรับ PC
10.10.9.x สำหรับ Device ต่างๆ
10.10.10.x สำหรับ Server หรือ อุปกรณ์เกี่ยวกับ Server
....
Subnet = 255.255.248.0
สาขา ต่อ Net โดยตั้ง IP ภายใน สำหรับ Server ดังนี้
IP = 10.10.20.0 / 21 หมายถึง สามารถใช้ IP ได้ 2046 IP Address
IP Address ที่ใช้ได้ คือ 10.10.16.1 - 10.10.23.255
10.10.16.x สำหรับ PC
10.10.19.x สำหรับ Device ต่างๆ
10.10.20.x สำหรับ Server หรือ อุปกรณ์เกี่ยวกับ Server
....
Subnet = 255.255.248.0
บริษัทลูก ต่อ Net โดยตั้ง IP ภายใน สำหรับ Server ดังนี้
IP = 10.10.30.0 / 21 หมายถึง สามารถใช้ IP ได้ 2046 IP Address
IP Address ที่ใช้ได้ คือ 10.10.24.1 - 10.10.31.255
10.10.24.x สำหรับ PC
10.10.25.x สำหรับ Device ต่างๆ
10.10.30.x สำหรับ Server หรือ อุปกรณ์เกี่ยวกับ Server
....
Subnet = 255.255.248.0
ฉะนั้นจะต้องทำการสร้าง VM Kernel ให้รองรับทั้ง 3 Subnet สามารถ ทำการ Route หากันได้
ดังนี้
IP และ Subnet ที่ต้องการคือ
IP = 10.10.0.0 / 19
Subnet = 255.255.224.0
เริ่มกันที่สร้าง VM Kernel
เรียกโปรแแกรม VMware vSphere Client ขึ้นมา 
เลือกแทบ Configuration
เลือก Networking
เลือก Add Networking...
 เลือก VMkernel กด Next
 เลือก Use vSwitch0 กด Next
 ช่อง Network Label สามารถตั้งชื่อเองได้
ถ้าไม่ กด Next
 เลือก Use the following IP settings
ใส่ค่า IP Address ที่คำนวณ ไว้ สำหรับการ Route Network ทั้งสามวง
IP = 10.10.0.0
Subnet = 255.255.224.0
กด Next
กดปุ่ม Finish
ต่อไปเป็นการสร้าง VM Network
ที่หน้า Configuration
 เลือก Add Networking..
 เลือก Virtual Machine
 เลือก Use vSwitch0
 ช่อง Network Label ตั้งชื่อตามต้องการ กด Next
 กดปุ่ม Finish
เรียบร้อยแล้วให้ทำการเพิ่ม VM Neywork เพิ่ม ให้ครบ 3 VM Network
ต่อไปจะเป็นการสร้าง VM Guest OS เพื่อติดตั้ง Windows Server 2012 เพื่อทำ AD ตามโจทย์ครับ

VMware ESXi

1. โจทย์ที่ได้รับ ติดตั้ง Active Directory ที่ผมต้องทำ

Windows Server 2012 Active Directory

ได้รับโจทย์มาดังนี้
? บริษัท มีสำงานใหญ่ 1 แห่ง สาขา 1 แห่ง และ บริษัทลูก อีก 1 แห่ง
? ทั้งหมดมี Server AD ของตัวเอง
? สำนักงานใหญ่สามารถเพิ่ม-ลบ User จากสำนักงานใหญ่ได้
? สาขา ไม่มี IT ต้องทำการเพิ่ม-ลบ จากสำนักงานใหญ่ได้ เท่านั้น กรณีมี IT ประจำ จึงจะสามารถเพิ่ม-ลบ ได้เอง
? เครื่อง PC หรือ  NB สามารถ Logon โดย User เดียวกันได้จากทุกที่ หรือเฉพาะที่กำหนด

วางแผนจำลองระบบต่างๆ ได้ดังนี้
 HO เป็น Root Domain
สาขา เป็น RODC
บริษัทลูก เป็น Child Domain

ทั้งหมด เชื่อมต่อกันผ่าน Internet ทำ Routing สามารถมองเห็นกันได้


โจทย์ ที่ได้รับต้องทำการจำลองระบบ ทำโดย VMware ESXi ค่าที่ต้องการมีดังนี้

1 VM Kernal (Route 3 VM Network)
3 VM Network
3 VM Guest OS


การติดตั้งระบบ VMware ESXi ในบทความนี้ใช้ ESXi 5.5 Download from VMware
ติดตั้ง ESXi
boot ESXi
 หน้าจอขณะ boot ESXi
 หน้าจอขณะ boot ESXi 
  หน้าจอขณะ boot ESXi
 กด Enter ติดตั้ง ESXi
 กด F11 ยอมรับ
 เลือกที่่ติดตั้ง ESXi กด Enter
 เลือก ภาษาของ Keyboard กด Enter
 พิมพ์รหัสผ่านตามต้องการ กด Enter
 กด F11 ยืนยันการติดตั้ง
  หน้าจอขณะ ติดตั้ง ESXi
 ทำการติดตั้ง เรียบร้อย กด Enter

 หลังจาก Reboot เครื่องมาแล้ว จะได้หน้าจอนี้
 กด F2 เพื่อเข้าไปกำหนดค่าต่างๆ 
 เลือก Configure Network Management เพื่อกำหนดค่า IP Address ให้ ESXi
 เลือก IP Configuration
 กำหนดค่า IP Address สำหรับ ESXi Server
 กด Y เพื่อยืนยันการตั้งค่า IP Address
Free Hosting

ทดสอบ ESXi Server ทำงานตาม IP Address ที่ตั้งไว้ ใช้ Browser เข้าไปที่่ IP ที่ตั้งไว้
ทำการดาวน์โหลดโปรแกรม vSphere Client สำหรับการควบคุม ESXi Server ในแบบ GUI โดยคลิกที่
Download vSphere Client
แล้วทำการติดตั้งโปรแกรมให้เรียบร้อย
 เรียกโปรแกรม VMware vSphere Client ใส่ IP Address ของ ESXi Server
User name = root
Password = (รหัสในครั้งแรกที่ติดตั้ง ESXi)
 (กด Ignore)
 เมื่อโปรแกรม vSphere แสดงผลขึ้นมาจะเห็นหน้าจอโปรแกรมแจ้งว่า ESXi Server ที่ติดตั้งไว้ยังเป็นแบบทดลองใช้งาน 60 วัน
กรณีที่ลงทะเบียนขอใช้งาน Free ที่ VMware สามารถเอา License ที่มีอยู่มาใช้ได้ครับ

หน้าจอโปรแกรม VMware vSphere Client สำหรับควบคุมการทำงาน ESXi Server ซึ่งตัวโปรแกรมเองมีความสามารถในการเพิ่มลดการตั้งค่าต่างๆ ตามที่ต้องการได้ เช่น การทำ VM Guest OS หรือ การจำลองเครื่อง PC เพื่อติดตั้ง OS ต่างๆ การจำลอง Network เป็นต้น
ในส่วนของการใช้งาน VMware vSphere Client จะอยู่ในบทความต่อๆไปนะครับ
ต่อไปจะเป็นการติดตั้ง Guest OS Windows Server 2012 เพื่อทำตามโจทย์ที่ได้รับมาครับ

ติด WindowsXP บน Ubuntu โดยใช้ QEMU

QEMU เป็น processor emulator ที่มีากรทำงานที่รวดเร็ว เล็ก และง่ายในการย้าย ไปยังเครื่องใหม่ QEMU สามารถทำงานได้กับ guest OS หลายตัวได้ และยังสามารถทำงานได้คล้ายกับ VMware Workstation และ Microsoft Vitual PC สำหรับการจำลอง CPU สามารถจำลองได้หลายสถาปัตยกรรม รวมทั้ง IA-32 PC, AMD64, MIPS R4000, Sun SPARC sun4u, ARM development board, SH4 SHIX board, PowerPC, ETRAX CRIS และ MicroBlaze เอ้ามาดูว่าเราจะติดตั้ง Windows XP กันยังไงดีกว่าครับ
อันดับแรก ติดตั้ง QEMU กันก่อน
$ apti-get install qemu
สร้าง image สำหรับติดตั้ง Windows XP เมื่อติดตั้ง Windows XP ไปแล้วจะใช้เนื้อที่อย่างน้อย 1.2 GB หรือมากกว่านั้น เราจะใช้ qcow สร้าง image ขึ้นมาแต่ขนาดของ image ไม่ได้ใหญ่เท่ากับ 1.2GB สร้าง image โดยใช้คำสั่งดังนี้
$ qemu-img create -f qcow /path/to/xp.cow 1300M
จากนั้นใส่แผ่น Windows XP ลงใน CDROM แล้วเริ่มติดตั้ง Windows XP ใน QEMU Image ดังนี้
$ qemu -hda /path/to/xp.cow -boot d -cdrom /dev/cdrom -m 384 -localtime
และรอจนติดตั้งเสร็จ เทื่อติดตั้งเสร็จให้ shutdown QEMU เอาแผ่น CD WindowsXP ออก แล้วเริ่ม Windows XP image ใหม่โดยใช้คำสั่ง
$ qemu -hda /path/to/xp.cow -boot c -m 384 -localtime -usb
แค่นี้เราก็ได้ Windows XP ใช้ใน Ubuntu แล้ว ;)

Laravel

  Laravel Framework คือ PHP Framework ตัวหนึ่งที่ถูกออกแบบมาเพื่อพัฒนาเว็บแอพพลิเคชั่นต่างๆ ในรูปแบบ MVC (Model Views Controller) ซึ่งมีการแ...