12 điều răn

The Twelve Factors

I. Codebase
One codebase tracked in revision control, many deploys
Quản lý source code bằng Git, Git Flow,…
II. Dependencies
Explicitly declare and isolate dependencies
Quản lý thư viện mà ứng dụng phụ thuộc bằng khai báo ra file cụ thể (kiểu như package.json trong Node.js).
III. Config
Store config in the environment
Lưu cấu hình vào biến môi trường để dễ dàng thay đổi mà không thay đổi code.
IV. Backing services
Treat backing services as attached resources
Coi dịch vụ CSDL, Message Queue phía sau là tài nguyên có thêm / bớt dễ dàng. Ứng dụng tuyệt đối không nên gắn chặt sống còn vào một tài nguyên cụ thể nào vì điều này khiến hệ thống khó mở rộng.
V. Build, release, run
Strictly separate build, release and run stages
Tách bạch hoàn toàn 3 stages: build – release – run.
VI. Processes
Execute the app as one or more stateless processes
Vận hành ứng dụng bằng nhiều tiến trình không lưu giữ trạng thái (stateless process). Stateless process sẽ giúp hệ thống mở rộng tốt hơn, dễ hơn, ít lỗi hơn so với state process.
VII. Port binding
Export services via port binding
Cung cấp dịch vụ qua các port khác nhau – sử dụng port binding. Đây là mô hình API Gateway trong microservice.
VIII. Concurrency
Scale out via the process model
Mở rộng bằng thêm nhiều dịch vụ độc lập chứ không bằng cách tăng sức mạnh phần cứng.
IX. Disposability
Maximize robustness with fast startup and graceful shutdown
Khởi động nhanh – thu hồi sạch sẽ tốt hơn khởi động chậm, khi thoát không giải phóng hết bộ nhớ.
X. Dev/prod parity
Keep development, staging, and production as similar as possible
Môi trường DEV, SIT, UAT, PRD nên càng giống nhau càng tốt giúp dễ gỡ rối và chuyển từ môi trường DEV lên PRD mới nhanh và liên tục được.
XI. Logs
Treat logs as event streams
Coi log là một chuỗi sự kiện thời sự để xử lý thời gian thực.
XII. Admin processes
Run admin/management tasks as one-off processes
Quản trị hệ thống nên là một tiến trình độc lập, có thể gắn – hoặc tách ra khỏi ứng dụng đang chạy.

NodeJS kết nối database MS SQL Server

Chuẩn bị đồ nghề

Chạy lệnh sau để tạo một webapp hello-mssql :

$mkdir helloworld && cd hello-mssql && npm init -y && npm install express && touch index.js

Copy đoạn code sau vào file index.js

const express = require('express')
const app = express()
const port = 3000
app.get('/', (req, res) => res.send('Hello MS SQL!'))
app.listen(port, () => console.log(`Example app listening on port ${port}!`))

Run $node index.js

Chi tiết có thể xem thêm ở đây.

Bắt đầu nấu nướng

Chuẩn bị một database SQL Server: trong bài này mình sử dụng SQL Server 2014 với sample database AdventureWorks2014. Các bạn có thể download sample ở đây.

Cài đặt thư viện mssql vào ứng dụng. Thư viện này dùng để kết nối và query thông tin trong database SQL Server:

npm install mssql --save

Ghi đè nội dụng sau vào file index.js

const express = require('express')
const app = express()
const port = 3000
var sql = require('mssql');

app.listen(port, () => console.log(`Example app listening on port ${port}!`))


app.get('/', (req, res) => {
  var config = {
    user: 'sa',
    password: 'xxxxx',
    server: '192.168.1.100', 
    port:1433,
    database: 'AdventureWorks2014',
    options: {
      trustedConnection: true,
      encrypt: false
    } 
  }
  
  sql.connect(config, function (err) {

    if (err) console.log(err);
  
    // create Request object
    var request = new sql.Request();
  
    // query to the database and get the records
    request.query('SELECT TOP 10 [Name],[ProductNumber] FROM [Production].[Product]', function (err, recordset) {
      sql.close()

      if (err) {
        res.send(err)
      }
        
      res.send(JSON.stringify (recordset))
    })
  })
})

Save and run $node index.js

Vào Chrome chạy và test thử http://localhost:3000

Gender Detection API

Gender Detection API là gì?

Gender Detection API là một rest API để xác định giới tính dựa vào tên của người Việt. API này giúp tạo ta những form tự động điền giới tính. Thử tưởng tượng khi bạn lập trình một form nhập liệu, trong đó có trường “Họ và tên” và “Giới tính”. Nếu có một công cụ nào đó khi khách hàng của bạn chỉ cần nhập họ và tên, hệ thống tự detect ra giới tính tương ưng, việc này giúp giảm thiểu thời gian cho khách hàng của bạn rất nhiều, giúp tăng cường UI/UX ứng dụng của bạn.

Link

http://khangle.tech

Cách sử dụng

  • Sử dụng lệnh Curl
    $ curl -X POST "http://khangle.tech/gender" -H "accept: */*" -H "Content-Type: application/json" -d "{\"fullName\":\"Trương Thị Thanh Bình\"}"
  • Sử dụng Postman

Docker with Vultr

Vultr là gì?

Vultr là nhà cung cấp dịch vụ VPS Server, Cloud Server với 100% phần cứng SSD, 15 datacenter location trải dài trên khắp thế giới. Ưu điểm của Vultr là giá rẻ, hiệu năng cao và cài đặt dễ dàng, nhanh chóng. Chỉ cần 1 ly trà sữa/1 tháng là có thể có 1 server để cho bạn vọc vạch. Đăng ký Vultr ở đây.

Vultr Logo

Tạo một Docker trên Vultr

Đăng nhập vào Vultr

Sau khi đã đăng ký Vultr và kích hoạt thành công, bạn sẽ truy cập vào trang quản trị tài khoản bằng địa chỉ https://my.vultr.com/.

Nếu đăng nhập lần đầu và chưa có server nào được tạo bạn sẽ nhìn thấy màn hình tạo Server ngay. Nếu bạn đã tạo server bạn sẽ thấy màn hình như sau:

Bây giờ bạn hãy bấm vào nút dấu cộng (+) để tạo server mới:

  • Vultr có rất nhiều vị trí đặt server trải dài từ châu Mỹ, châu Âu, châu Úc và châu Á. Tùy thuộc vào đối tượng khách truy cập bạn muốn hướng tới mà chọn vị trí phù hợp. Ví dụ bạn ưu tiên đối tượng ở Việt Nam thì nên chọn vị trí là Singapore hoặc Tokyo cho gần Việt Nam.
  • Chọn tab Application, chọn Docker, có 2 option lựa chọn là Ubuntu hay CentOS. Tuỳ bạn rành về OS nào thì chọn OS đó. Ở đây mình chọn CentOS.
  • Chon Server Size. Tuỳ nhu cầu mà mình lựa chọn size phù hợp. Nếu chỉ để test thì nên chọn gói thấp nhất 5USD/tháng.
  • Sau đó nhấn nút Deploy Now
  • Quá trình cài đặt có thể mất ít phút. Sau khi cài đặt xong bạn sẽ có được IP và tài khoản root để đăng nhập qua SSH.
  • Mở Terminal gõ $ssh root@<IP address> để vào server này.
  • Sau khi login gõ docker --version để kiểm tra version của Docker

Deploy một app lên Vultr

Để deploy một image lên Docker, có 2 cách:

  • Cách 1: deploy 1 image từ local Docker lên Vultr:
    • Lưu image tử local Docker thành file zip: $docker save <image-name> | gzip > <image-name>.tar.gz
    • Copy file zip này lên server Vultr: $scp <image-name>.tar.gz root@<IP adress>:/root/image_zips/
    • SSH vào server Vultr, deploy image này lên Docker: $docker import <path-of-image-name>
    • Chạy lệnh $docker images để kiểm tra xem image đã import thành công hay chưa
    • Chạy lệnh docker run --rm -d -p <HOST_PORT>:<CONTAINER_PORT> <image-name>:latest để start app
  • Cách 2: copy source-code từ local lên server Vultr bằng lệnh scp. Sau đó tiến hành tạo deploy như local. Xem ở đây

ExpressJS trên Docker

Cài đặt Docker

Xem cách cài đặt Docker ở đây

Tạo một NodeJS App

Xem cách tạo ứng dụng helloworld với ExpressJS ở đây

Tạo một image Docker

Trước hết ta tạo một file Dockerfile trống bằng câu lệnh

$touch Dockerfile

Copy nội dung sau vào file này:

FROM node:8.12.0-jessie
# Create app directory
WORKDIR /usr/src/app
# Bundle app src
COPY . .
# Install app dependencies
RUN npm install
EXPOSE 3000
CMD [ "node", "index.js" ]

Ý nghĩa:

  • Dòng FROM node:8.12.0-jessie chỉ ra rằng chúng ta muốn build từ image nào, ở đây mình dùng image 8.12.0-jessie có NodeJS version 8.12.0 LTS. Khi mình chạy lệnh build nó sẽ vào Docker Hub để lấy image này về để cho chúng ta thêm phần của mình vào .
  • Dòng WORKDIR /usr/src/app là nơi chứa code của chúng ta trong image.
  • Dòng COPY . . copy toàn bộ source của project vào trong image.
  • Dòng RUN npm install download các dependencies.
  • Dòng EXPOSE 3000 vì helloworld listen ở cổng 3000 nên ta sẽ EXPOSE ra tại cổng 3000.
  • Dòng cuối cùng CMD [ "node", "index.js" ] dùng CMD để chạy app.

Build image

Sử dụng câu lệnh sau

$docker build --rm -f Dockerfile -t helloworld:latest .

Nhớ có dấu . sau cùng nhen! Dấu . ở đây ám chỉ Dockerfile đang nằm trong thư mục hiện tại.

Sau khi nhấn ENTER, nó vào Internet pull image gốc về như hình

Sau khi chạy xong chạy lệnh kiểm tra xem nó đã tạo ra image chưa

$docker images

Run image

$docker run --rm -d -p 3000:3000 helloworld:latest

Rồi kiểm tra process bằng $docker ps

Vào Chrome chạy và test thử http://localhost:3000

Nếu màn hình xuất hiện chữ “Hello World!” là done. Congratulation!

Setup Docker trên Mac

Để cài đặt được Docker trên Mac, bạn chỉ cần truy cập trang sau:

https://docs.docker.com/docker-for-mac/install/#download-docker-for-mac

Để download phải đăng ký account trước. Account này không chỉ để dùng để download Docker mà còn dùng để download hay tạo các image sau này.

Sau khi đăng ký xong thì sẽ được tải về file docker.dmg rồi double click file để cài đặt. Đơn giản, bạn chỉ cần kéo thả biểu tượng con cá voi sang bên biểu tượng Application:

Sau khi setup xong thì biểu tượng cá voi xuất hiện trên thanh status bar. Click vào nó và đăng nhập với account đã tạo.

Whale in menu bar

Mở Terminal, chạy 2 lệnh sau xem quá trình cài đặt có OK không?

$docker version để kiểm tra version

$docker run hello-world để kiểm tra xem Docker có kéo image về như mong đợi hay không.

Nếu thành công. Xin chúc mừng đến với thế giới của Docker.

Tạo webapp Helloworld với ExpressJS

Yêu cầu đầu tiên cần phải setup NodeJS. Xem ở đây

Tếp theo là phải nghỉ ra cái tên cho webapp của mình. Ở đây mình đặt tên là helloworld.

Mở Terminal (giao diện dòng lệnh) ra gõ những dòng lệnh sau:

$mkdir helloworld
$cd helloworld

Chạy lệnh npm init để tạo ra file package.json trong folder helloworld. Xem thêm đặc tả package.json

$npm init

Khi chạy lệnh này nó sẽ hỏi một vài câu hỏi những câu trả lời của bạn sẽ được ghi vào nội dung của package.json. Đơn giản là cứ nhấn Enter. Mình còn có cơ hội chỉnh sữa lại sau.

Tiếp đến là install Express, chạy lệnh sau:

$npm install express --save

Đợi một vài phút để npm kéo module về.

Chạy lệnh sau để tạo file index.js

$touch index.js

Copy nội dung sau vào file index.js. Để tiện lập trình trong NodeJS, các bạn nên dùng một editor, mình dùng Visual Code của Microsoft, download ở đây.

const express = require('express')
const app = express()
const port = 3000

app.get('/', (req, res) => res.send('Hello World!'))

app.listen(port, () => console.log(`Example app listening on port ${port}!`))

Cuối cùng, chạy lệnh sau để start cái web của bạn

$node index.js

Nếu thành công thì nó sẽ báo Example app listening on port 3000!

Mở browser vào địa chỉ http://localhost:3000/ Nếu nó xuất hiện chữ “Hello World” chúc mừng bạn đã thành công.

Tất cả các lệnh trên, các bạn có thể gom thành một lệnh duy nhất như sau:

$mkdir helloworld && cd helloworld && npm init -y && npm install express && touch index.js

Đây là cách cơ bản nhất, ngoài ra còn nhiều cách khác nữa. Thế giới NodeJS muôn hình vạn trạng!!!

Lịch sử hình thành Docker

Traditional Deployment

Xưa thật là xưa, mô hình máy chủ thường là máy chủ vật lý + hệ điều hành(OS) + application

Vấn đề gặp phải ở đây là lãng phí tài nguyên, một máy chủ chỉ cài được một OS, cho dù có ổ cứng khủng, ram khủng thì cũng không tận dụng hết lợi thế. Nếu để nhiều ứng dụng lên để tận dụng tài nguyên thì lúc đó lại phát sinh vấn đề về tương thích version library, runtime, version của OS…Không lẽ mỗi ứng dụng mua một server? chưa nói đến tiền, chỗ đâu để đặt server…? Vậy là cái khó ló cái khôn, thế giới công nghệ tiến hoá qua một thời kỳ mới “ảo hoá” (vitualization)

Virtualized Deployment

Cũng là xưa nhưng chưa xưa lắm, công nghệ ảo hoá ra đời, với công nghệ này, trên một máy chủ vật lý mình có thể tạo được nhiều máy ảo, các máy ảo này chạy độc lập, có thể cài đặt nhiều hệ điều hành khác nhau trên cùng một máy vật lý, tận dụng tài nguyên đã tốt hơn, giải quyết được những vấn đề nan giải của mô hình Traditional Deployment nhưng lúc này lại nảy sinh những yêu cầu mới để kịp với thời đại mới: tận dụng tài nguyên tốt hơn nữa, triển khai nhanh hơn…

  • Khi chạy máy ảo, bạn phải cung cấp “cứng” ổ cứng cũng như ram cho máy ảo đó, bật máy ảo lên để đó không làm gì thì máy thật cũng phải phân phát tài nguyên.
  • Việc khởi động, shutdown khá lâu, có thể lên tới hàng phút.

Những tên tuổi đại diện cho mô hình này: Vitualbox, VMware, Virtual Server. Nổi bật nhất là VMware trong lĩnh vực này.

  • Nếu ai đã từng khi triển khai một dự án run dưới local chạy demo thì ngon vãi nhưng khi deploy lên server thì sập vỡ mặt thì đã đến lúc nghỉ đến một bước tiến hoá mới containerization.
  • Nếu ai đã từng phải mất hàng ngày trời để setup môi trường DEV, SIT, UAT, PRD thì cũng đã đến lúc nghỉ đến một bước tiến hoá mới containerization.

Container Deployment

Ngày nảy ngày nay, người ta sinh ra công nghệ containerlization. Ở bước tiến hóa này, trên một máy chủ vật lý, ta sẽ sinh ra được nhiều “máy con” (giống với công nghệ ảo hóa vitualization), nhưng tốt hơn ở chỗ là các “máy con” này đều dùng chung phần nhân (OS kernel) của máy mẹ (host OS) và chia sẻ với nhau tài nguyên máy mẹ. Bên cạnh đó, nó giúp:

  • Tạo ra một môi trường chứa “mọi thứ” mà application cần để có thể chạy được.
  • Không bị các yếu tố liên quan đến môi trường hệ thống làm ảnh hưởng tới.
  • Cũng như không làm ảnh hưởng tới các phần còn lại của hệ thống.

Những tên tuổi đại diện cho mô hình này: Docker, rkt, RXD,… Nổi bật nhất là Docker trong lĩnh vực này.

Quá trình tiến hoá