Hiển thị các bài đăng có nhãn DONE. Hiển thị tất cả bài đăng
Hiển thị các bài đăng có nhãn DONE. Hiển thị tất cả bài đăng

Thứ Hai, 19 tháng 2, 2024

HTTPS hoạt động như thế nào?

    Ở bài viết cách hoạt động của mạng của Internet, chúng ta đã phần nào hiểu được cách thức giao tiếp giữa trình duyệt trên một máy tính cá nhân tới một máy chủ dựa vào giao thức HTTP và tầm quan trọng của việc có một kết nối an toàn. Có rất nhiều dữ liệu nhạy cảm mà bạn sẽ sử dụng để truy cập các chức năng trên mạng internet như username/password, thông tin thẻ creditcard, các thông tin cá nhân, message, image... Khi website không có https, các dữ liệu này đều có thể bị nghe lén.
    Trong bài viết này chúng ta sẽ đi vào tìm hiểu sâu hơn cách hoạt động của giao thức HTTPS. Làm thế nào để giao thức HTTPS có thể đảm bảo một kết nối an toàn khi truy cập tới một máy chủ.


 HTTPS là gì?

HTTPS viết tắt của Hyper Text Transfer Protocol Secure (Giao thức truyền tải siêu văn bản bảo mật), đây là giao thức cải tiến hơn của HTTP do có thêm layer cho việc bảo mật. Chúng ta cần tới HTTPS bởi 3 lý do:

  • Privacy - sự riêng tư: Khi dữ liệu được truyền tải trên mạng internet, không ai có thể đọc được dữ liệu của bạn trong khi truyền tải.
  • Integrity - Tính toàn vẹn dữ liệu: Dữ liệu từ điểm này tới điểm khác trên mạng internet cần được đảm bảo tính toàn vẹn, không ai có khả năng chỉnh sửa các dữ liệu này trên đường truyền tải mà không bị phát hiện
  • Identification - Định danh: Website mà bạn đang truy cập chính xác là trang web đó, nói cách khác là kết nối đến máy chủ không bị làm giả. HTTPS thông qua chứng chỉ SSL , sẽ đảm bảo bạn đang kết nối đến đúng máy chủ mà bạn mong muốn.
Chứng chỉ SSL này cần hợp lệ và được cấp bởi một số tổ chức Certificate Authority hợp pháp.

HTTPS bảo vệ dữ liệu như thế nào?

    Trong bài viết trước chúng ta cũng đã đề cập đến khái niệm mã hóa dữ liệu và sự khác nhau về nguyên lý của việc mã hóa dữ liệu bằng mã hóa đồng bộ và mã hóa bất đồng bộ. Vậy thực sự thì HTTPS sử dụng SSL certificate mã hóa dữ liệu bất đồng bộ như thế nào?

Theo dõi bài viết trước tại đây//TODO link đến bài how internet work đoạn kết nối an toàn

    Khi sử dụng một trình duyệt để thực hiện request đến một Server chứa website. Private key được lưu trữ ở phía server và Public key được chia sẻ cho trình duyệt. Bất cứ một trong hai phía gửi hoặc nhận dữ liệu sẽ sử dụng key của mình để mã hóa/ giải mã. Nếu trình duyệt gửi message đến server, trình duyệt sử dụng Public key để mã hóa và gửi đi, Server sẽ sử dụng private key để giải mã. Và ngược lại, khi server trả về kết quả cho trình duyệt, server sử dụng private key để mã hóa, và trình duyệt dùng public key của mình để giải mã. Đây là ý tưởng cơ bản của việc sử dụng keys để thực hiện kết nối an toàn sử dụng giao thức HTTPS.

Quá trình kết nối từ trình duyệt tới máy chủ

    Khi bạn sử dụng trình duyệt truy cập tới sunteco.vn , trình duyệt của bạn giao tiếp với máy chủ lưu trữ website và cả hai bên thành lập một kết nối an toàn để trao đổi dữ liệu, nếu việc quá trình thương lượng với nhau thất bại, trình duyệt sẽ báo lỗi hoặc cảnh báo về kết nối không an toàn. Nếu kết nối an toàn được thành lập, trình duyệt sẽ hiển thị hình chiếc khóa trên thanh địa chỉ. Quá trình  này được gọi là handshake. Sau đây là từng bước trình duyệt bắt tay với server:
  • Clien Hello: Trình duyệt gửi tới server một danh sách các phiên bản SSL/TLS và các giải thuật mà trình duyệt đang hỗ trợ(cipher suite)
  • Server Hello: Server lựa chọn một phiên bản SSL/TLS và giải thuật phù hợp sau đó phản hồi với trình duyệt bằng Certificate, trong đó bao gồm cả Public key, nhờ đó mà trình duyệt có thể xác định định danh của máy chủ có đúng hay không (Identification)
  • Client Key exchange: Trình duyệt kiểm tra Certificate để đảm bảo máy chủ hợp lệ. Trình duyệt generate một "pre-master key", key này sẽ được sử dụng để sinh ra một unique key về sau. Trình duyệt mã hóa "pre-master key" bằng Public key và gửi lại cho Server
  • Change Ciper spec: Server sử dụng Private key để giải mã "pre-master key"
  • Test connection: Trình duyệt sử dụng Public key để mã hóa message và gửi tới server, server sử dụng Private key để đọc message.
Đến đây hai bên đã trao đổi cho nhau các key cần thiết để thực hiện kết nối an toàn và bảo mật. Mọi thứ sẽ được bảo mật cho đến khi kết thúc phiên làm việc

Sự khác nhau giữa HTTPS/SSL/TLS

Nãy giờ chúng ta đã nhắc đến HTTPS, SSL/TLS vậy chúng liện quan tới nhau như thế nào? HTTPS là phiên bản bảo mật của HTTP, trình duyệt và máy chủ sử dụng giao thức HTTP để giao tiếp và trao đổi dữ liệu. Trong khi trao đổi dữ liệu, các dữ liệu được mã hóa bởi SSL/TLS nên giao thức này được gọi là HTTPS, S viết tắt của secured.
    Câu chuyện về SSL/TLS sẽ phức tạp hơn một chút. SSL viết tắt của Secure Sockets Layer. Một giao thức được phát triển bởi Netscape. Phiên bản đầu tiên của SSL không được release, nhưng phiên bản thứ 2 đã được release cùng với trình duyệt Netscape 1.1 vào năm 1995. Sau đó một năm Netscape release phiên bản thứ 3 vì bản thứ hai có một số lỗi nghiêm trọng. Cho đến năm 1999, cuộc chiến về trình duyệt giữa Netscape và Microsoft (internet explore) dẫn đến sự cần thiết của các chuẩn cho trình duyệt. Netscape chuyển giao giao thức SSL cho IETF (Internet Engineering Task Force).
    Cuối năm 1999, IETF release TLS version 1.0 (mà thực ra là SSL 3.1). SSL được đổi tên thành TLS-Transport Layer Security. Dẫn đến việc gây lú cho tới ngày nay. TLS 1.0 kết thúc và bản 1.1 release năm 2006. Vài năm sau TLS 1.2 ra đời để giải quyết một số sai sót. Nhưng đến tận 2013, các trình duyệt mới bắt kịp và hỗ trợ cho TLS 1.2
    Để gây lú x3.14, SSL 3.0 chính thức được release năm 2015. TLS 1.3 được chấp thuận vào tháng 3 năm 2018 và trình duyệt của bạn hiện giờ chắc hẳn đã hỗ trợ. TLS 1.3 cải thiện về bảo mật và loại bỏ một số issue .
Bạn có thể check version TLS của trình duyệt tại đây

Certificate Autorities

Certificate Autority là một tổ chức third-party phục vụ 3 mục đích chính:
  • Cấp certificates
  • Confirm định danh của chủ sở hữu certificate
  • Cung cấp bằng chứng rằng certificate là hợp lệ.
    Chúng ta có thể đã nghe đến Symantec, Comodo, Let's Encrypt, GoDaddy... Trở thành CA là một nhiệm vụ rất khó khăn về yêu cầu bảo mật và kiểm tra. Bạn phải được tin tưởng để có thể được chấp nhận truy cập vào Root store. Root store về cơ bản là cơ sở dữ liệu của các CAs, các CAs sẽ chia sẻ chung với nhau cơ sở dữ liệu này.
    Certificate nào mà bạn nên mua? Về cơ bản bạn có 3 loại cert để lựa chọn:
  • Domain validated: Loại certificate này chỉ xác nhận cho tên miền.
  • Organization validate: Loại cert này yêu cầu thẩm định và xác minh tổ chức cần cấp chứng chỉ một cách manual
  • Extended validation: Cert yêu cầu xác minh đầy đủ về doanh nghiệp.
    Kết quả của các chứng chỉ hợp lệ trên trình duyệt là biểu tượng khóa an toàn trên thanh địa chỉ. Extended validation thường hiển thị thêm công ty đi cùng biểu tượng khóa. Nhưng làm sao để một chứng chỉ hợp lệ?
    Khi CA cấp một certificate, họ sẽ kí vào trong certificate một chữ kí điện tử bằng chứng chỉ gốc của họ đã được cài đặt trước trên root store. Thường là sẽ có một intermediate certificate được kí với bằng root certificate. Và chứng chỉ trung gian này lại được dùng để kí cho các chứng chỉ đầu cuối. 
    Cùng đi qua tiến trình xác minh để hiểu một certificate được xác định hợp lệ như thế nào. Trình duyệt của bạn connect tới một trang web bằng HTTPS và download cert. Cert đó không phải là root cert, trình duyệt tiếp tục download cert mà được dùng để ký cho cert trên trang của bạn truy cập, nhưng cert này vẫn không phải là root cert. Trình duyệt download thêm một lần nữa cert sử dụng để kí cho mid cert. Ya! Đây đúng là root cert rồi. Vậy là tất cả các cert này đều được xác mình và tin cậy. Khi certtificate cuối cùng không phải là root cert, chuỗi xác mình này sẽ thất bại và certificate đầu tiên sẽ không hợp lệ. 
    Vậy tại sao phải sử dụng certificate đến từ Certificate Authotity trong khi bạn có thể tự tạo ra certificate của mình? Một self-sign certificate  cung cấp cùng mức độ mã hóa giống như tổ chức có thẩm quyền. Dữ liệu vẫn được bảo mật khi truyền dẫn và bạn không phải mất phí để gen certificate. Nhưng hầu như các trình duyệt sẽ kiểm tra certificate được cấp bởi các tổ chức có thẩm quyền. Các truy cập vào một website mà cert không phải do CA cấp sẽ bị hiển thị cảnh báo connection insecure.


Self-signed certificate có thể hữu ích cho test và nội bộ, nhưng bạn nên tránh sử dụng cho các trang web public. Do các chứng chỉ tự ký này có thể bị làm giả.

Kết

    Hy vọng bài viết đã làm rõ tầm quan trọng của HTTPS và cách mà một Certificate được sinh ra và được sử dụng để tạo ra một kết nối an toàn trên mạng internet. Trong những bài viết sau, chúng ta sẽ tiến hành thực hiện việc gen certificate để tạo ra một kết nối an toàn cho website đang hosting trên máy chủ.


Tham khảo https://howhttps.works/







Chủ Nhật, 18 tháng 2, 2024

Internet hoạt động như thế nào?

     Chúng ta vẫn đang sử dụng mạng Internet hàng ngày, nhưng có bao giờ bạn đặt câu hỏi về việc một mạng thông tin toàn cầu lớn như vậy được tạo nên như thế nào và có ai đang kiểm soát nó hay không?

Bài viết này sẽ giải đáp các vấn đề cốt lõi như: làm cách nào mà Internet được tạo thành và dữ liệu di chuyển trên Internet như thế nào, dữ liệu di chuyển từ máy tính này đến các máy tính khác ở cách đó rất xa mà vẫn đảm bảo tính toàn vẹn và bảo mật dữ liệu.

Internet là gì?

    Internet là một hệ thống rất lớn các networks và kết nối các máy tính trên toàn thế giới. Qua mạng internet, người ta có thể chia sẻ thông tin và giao tiếp từ nơi này đến nơi khác trên thế giới chỉ với kết nối vào mạng Internet. Kết nối này được tuân theo các chuẩn nhất định để bảo vệ dữ liệu của người dùng.

Dữ liệu di chuyển trên mạng internet như thế nào?

   Nói theo một cách khác, Internet là mạng toàn cầu bao gồm cả các cáp vật lý như dây đồng của đường dây điện thoại, cap tivi hoặc cáp quang. Thậm chí gồm cả các kết nối không dây như tín hiệu vệ tinh, wifi và 3G/4G . Khi bạn truy cập một trang web, bạn gửi yêu cầu qua dây cáp đến một server. Server này là nơi lưu trữ website, đây là một máy chủ vậy lý hoạt động tương tự như máy tính cá nhân của bạn nhưng có thể ở cấp độ lớn hơn rất nhiều. Sau đó máy chủ sẽ xử lý request và trả dữ liệu về máy tính của bạn. Nhưng thật kì diệu, quá trình này thường chỉ mất chưa tới một giây, ngay cả khi Server nằm ở đầu kia của trái đất

Các network nói chuyện với nhau bằng cách nào?

    Vậy bây giờ ta đã hiểu về mặt vật lý, vẫn sẽ có những dây dẫn kết nối giữa các thiết bị trên mạng Internet. Vậy về mặt logic, làm sao dữ liệu có thể đi đúng tới máy server và sau đó trả dữ liệu về đúng máy vừa request mà không phải là một máy khác. Lúc này sẽ là việc của IP và DNS. IP có ý nghĩa như địa chỉ duy nhất của một thiết bị trên mạng Internet và nó có dạng của một dãy số xxx.xxx.xxx.xxx . Khi đã biết địa chỉ, các thiết bị sẽ giao tiếp với nhau thông qua việc tuân thủ các Protocol. Protocol là một bộ các quy tắc tiêu chuẩn mà khi các bên đồng ý sử dụng, nó sẽ cho phép họ giao tiếp mà không gặp rắc rối. Nhưng thông thường thì chúng ta sẽ không truy cập trang web bằng địa chỉ IP , nó khá khó nhớ và nhàm chán. Thay vào đó người ta sử dụng các tên miền có nghĩa, đây là các tên đơn giản được cài đặt để đại diện cho các địa chỉ IP. Nhờ vào DNS (Domain Name System) mà các thiết bị có thể biết được địa chỉ IP của máy chủ từ tên miền. DNS hoạt động như một kho lưu trữ các tên miền cùng với các địa chỉ IP mà chúng đại diện, và khi các thiết bị muốn biết IP mà tên miền đại diện, DNS sẽ giải quyết vấn đề này.

Để hiểu thêm về cách thức hoạt động của DNS, xem thêm: DNS hoạt động như thế nào?

Packets, Routing và sự tin cậy


    Khi bạn download dữ liệu, bạn có thể nhìn thấy thanh tiến trình đầy dần cho đến khi tất cả dữ liệu đến được máy tính của bạn. Liệu những dữ liệu này có đến cùng một lúc và di chuyển trên cùng một con đường hay không? Câu trả lời là không. Đây chính là cách truyền tải dữ liệu cơ bản của Internet: dữ liệu gốc được chia nhỏ ra thành các gói tin(Packets) theo các giao thức tin cậy, sau đó được gửi qua mạng internet qua nhiều tuyến đường khác nhau. Giống như cách chúng ta di chuyển giữa các tuyến đường, nếu như biết tuyến đường này bị tắc, ta sẽ chuyển hướng sang một con đường khác, có thể sẽ dài hơn về mặt khoảng cách  nhưng sẽ nhanh hơn về mặt thời gian. Những gói tin này không tự chọn đường đi cho mình, mỗi gói tin sẽ có địa chỉ nơi nó đi và nơi nó cần đến. 
    Một số các máy tính đặc biệt trên mạng internet mang tên định tuyến (Router) đóng vai trò như người điều phối giao thông, đảm bảo các gói tin di chuyển thông suốt trên mạng. Nếu một tuyến đường bị nghẽn, các gói tin đơn lẻ có thể đi đường khác. Mỗi định tuyến sẽ theo dõi nhiều đường dẫn để gửi gói tin và chọn đường dẫn phù hợp, tối ưu nhất cho gói tin dựa trên địa chỉ IP cần đến. Tối ưu ở đây bao gồm cả về chi phí, thời gian, cũng có thể là chính trị hoặc quan hệ giữa các công ty, thậm chí do người quản trị cài đặt điều hướng. 
    Vậy những router này thuộc về ai? Tại mỗi điểm giao nhau giữa các network sẽ có ít nhất một router. Tại những nơi network lớn giao nhau, có rất nhiều router để đảm bảo sự ổn định. Càng nhiều router thì độ ổn định càng cao. Vậy nên router sẽ thuộc về cá nhân/ tổ chức nào quản lý network đó. Ở cấp độ văn phòng hoặc gia đình Router thuộc về chúng ta, tương tự với cấp độ lớn hơn như nhà cung cấp dịch vụ internet (ISP) thì router thuộc về họ, ở cấp độ chính phủ thì router thuộc về chính phủ... 

TCP (Transmission control protocol)

    Các packet bị chia nhỏ và truyền tải phân tán qua mạng internet, vậy làm sao để chắc chắn răng toàn bộ dữ liệu đã được truyền tải và nhận được ở đích đến. It's TCP time! TCP quản lý việc gửi và nhận toàn bộ dữ liệu dưới dạng gói tin. Trách nhiệm của TPC giống như dịch vụ gửi thư đảm bảo. Khi các gói tin đến nơi, TCP sẽ tiến hành kiểm định và confirm đã nhận từng gói tin và ký đã nhận hàng. Nếu một vài gói tin bị thiếu , TCP sẽ không kí hoặc máy chủ chứa dữ liệu sẽ gửi lại các gói tin. Lúc này, máy tính sẽ chấp nhận sử dụng dữ liệu bị thiếu các gói tin (chấp nhận sai sót - fault tolenrance) hoặc đợi cho đến khi máy chủ gửi lại đầy đủ dữ liệu (dự phòng - redundancy). Nhờ những nguyên tắc này mà chúng ta có thể phát triển và mở rộng internet mà không làm gián đoạn dịch vụ của bất kì ai.

HTTP và HTML

    Các trang web và ứng dụng dựa trên nền web vẫn đang là một trong  những hình thức sử dụng internet phổ biến nhất hiện nay. Và để giao tiếp giữa các máy tính cá nhân và các máy chủ chứa website, các máy tính sử dụng giao thức HTTP (Giao thức truyền tải siêu văn bản - Hyper text transfer Protocol), giao thức này cũng dựa trên bộ giao thức TCP/IP. Khi thực hiện yêu cầu một trang web, máy khách  (client) thực hiện một request theo tiêu chuẩn, sau đó máy chủ sẽ nhận request và trả về các mã HTML (Hyper text markup language - Ngôn ngữ siêu văn bản). HTML là một tập hợp các quy tắc mô tả dữ liệu giúp cho phía server và client thống nhất về format dữ liệu hiển thị, sau đó client(trình duyệt) có thể hiển thị trang web dựa trên kết quả trả về. HyperText - Siêu văn bản ở đây nói đến các định dạng dữ liệu hiển thị bao gồm cả text, hình ảnh và video, file...
    Đến đây chúng ta đã hiểu được cách thức truyền tải dữ liệu qua mạng internet cho đến khi được sử dụng bởi một ứng dụng trên máy tính. Nhưng nếu dữ liệu truyền tải chỉ đơn thuần là các gói tin, hacker hoàn toàn có thể đứng ở các đầu router và đọc được các dữ liệu in/out từ network. Vậy làm sao để các gói tin di chuyển trên internet một cách an toàn?

Truyền nhận dữ liệu an toàn (HTTPS/SSL/TLS)

    Để dữ liệu được an toàn trong khi truyền dẫn, cần tuân thủ theo một số giải thuật mã hóa dữ liệu đảm bảo chỉ hai đầu gửi nhận có thể đọc được dữ liệu, các thành phần trung gian trong quá trình truyền tải không thể đọc được những dữ liệu này. Dữ liệu sẽ được được gửi qua một kênh an toàn bằng cách sử dụng Secure Socket Layer (SSL) và Transport Layer Security (TLS). Có thể coi SSL và TLS như một lớp bảo mật bao quanh việc truyền tải thông tin. Dễ nhận thấy nhất là các website đang truy cập có hình một chiếc khóa  ở thanh địa chỉ và tiền tố https (HyperText Markup Language Secure) trước địa chỉ website. Điều này có nghĩa là dữ liệu trang web của bạn đang được bảo vệ.


    Mã hóa dữ liệu sẽ giúp kết nối của chúng ta được an toàn trên Internet. SSL/TLS sử dụng giải thuật Public key/ Private key.

    Đầu tiên ta cần hiểu mục đích của quá trình mã hóa/giải mã (encrypt/decrypt) là gì. Từ hàng trăm năm trước, người ta đã nghĩ ra cách biến đổi nội dung của thư từ trước khi gửi đi, người gửi và người nhận sẽ cùng thống nhất chung với nhau một quy tắc về nội dung. Ví dụ quy tắc này có thể là: mỗi chữ cái được lùi lại 3 kí tự theo thứ tự trong bảng chữ cái: attack => xqqxzh. Nội dung trong thư sẽ là xqqxzh, người đưa tin hoặc quân địch khi phát hiện cũng không thể hiểu được. Chỉ người nhận biết được quy tắc này mới có thể hiểu nội dung.

    Trong khoa học máy tính, bộ quy tắc về mã hóa/giải mã này được gọi là giải thuật, bởi việc nghĩ ra một giải thuật là không hề đơn giản và tăng cường thêm bảo mật, bên cạnh giải thuật người ta còn sử dụng thêm các key. Với cùng một giải thuật nhưng sử dụng kèm các key(salt) khác nhau cũng sẽ cho ra các kết quả khác nhau, dữ liệu của cùng một giải thuật nhưng sử dụng các key khác nhau cũng sẽ được an toàn. Việc sử dụng chung một key để mã hóa/giải mã dữ liệu được gọi là mã hóa đối xứng  (symmetric encryption). Việc này có thể tiện nếu chỉ có hai phía, nhưng trong thế giới internet, các thành phần ở rất xa nhau, không thể nào gặp để thống nhất về giải thuật, ngoài ra với sức mạnh của máy tính hiện nay, việc brute force (thử tất cả key cho đến khi đúng) khiến cho việc mã hóa đối xứng không còn nhiều ưu thế.

    Một hình thức mã hóa khác là bất đối xứng (asymmetric encrytion). Chúng ta sử dụng một cặp Private key - public key để thực hiện mã hóa/ giải mã dữ liệu. Có thể có nhiều Public key hoặc có thể chia sẻ cho bất kỳ ai dùng để mã hóa dữ liệu, còn Private key sẽ được giữ kín để giải mã. Ý tưởng ở đây là chỉ những cặp Private Key/Public key được pair cùng với nhau thì mới có thể thực hiện cùng quá trình mã hóa/ giải mã. Một key dùng để mã hóa thì key còn lại có thể dùng để giải mã. Khi sử dụng một public key không pair với private key phía còn lại, dữ liệu sẽ không thể được giải mã và ngược lại.

    SSL/TLS cũng sử dụng nguyên tắc này để trao đổi dữ liệu. Hiểu một cách đơn giản, khi bạn truy cập một trang web có chứng chỉ hỗ trợ giao thức https, trình duyệt của bạn sẽ nhận được một chứng chỉ SSL (certificate), trình duyệt sử dụng chứng chỉ này như là một Public key để mã hóa/giải mã các dữ liệu khi thực hiện trao đổi với máy chủ. Phía máy chủ cũng giữ một Private key để mã hóa/giải mã các dữ liệu từ client.

Kết

    Hy vọng với bài viết này các bạn đã hiểu cách mà mạng Internet hoạt động, cả về vật lý, tính logic, và khả năng đảm bảo an toàn thông cho dữ liệu khi truyền tải qua mạng Internet. Ở bài viết sau chúng ta sẽ tìm hiểu kĩ hơn cách mà kết nối HTTPS được hình thành và các thành phần khác giúp đảm bảo dữ liệu truyền dẫn được đảm bảo an toàn.


Thứ Ba, 14 tháng 11, 2023

Các thành phần trong kiến trúc Microservices

 

Mở đầu   

 Với kiến trúc microservice chúng ta sẽ triển khai một hệ thống phân tán (distributed system) bao gồm rất nhiều thành phần kĩ thuật xoay quanh các service về business chính. Hệ thống phân tán sẽ có lợi thế về tính linh hoạt giữa các dịch vụ và nhưng sẽ gặp khó khăn khi phân phối các thay đổi. Bài viết này sẽ đi tìm hiểu các thành phần quan trọng của kiến trúc microservice và tầm quan trọng của chúng .

Thành phần trong kiến trúc microservices

Containers và Orschestration

    Container là thành phần compute chính trong kiến microservice, nó có chức năng chạy các ứng dụng tương tự như VM ở các kiến trúc cũ. Sự khác biệt cốt lõi giữa container và VM nằm ở công nghệ ảo hóa: Containerization và Virtualization. Tuy nói Microservice là kiến trúc của ứng dụng, không phân biệt chạy trên Container hay VM, nhưng do giới hạn về khả năng provisioning, scaling và HA nên VM rất ít tương thích với các concept của microservice.
    Container được thiết kế chủ yếu để cách ly các tiến trình hoặc các ứng dụng với nhau và với hệ điều hành. Cài đặt và chạy một ứng dụng trên container rất đơn giản, nhưng sẽ thế nào nếu cần cài đặt những container này cho một hệ thống, lúc này số container sẽ lên tới hàng chục cho tới hàng trăm và hơn nữa. Đi kèm với hệ thống là các cài đặt về mạng, lưu trữ cho database, lưu trữ các biến môi trường, config của ứng dụng, các nhu cầu về scaling tự động, khôi phục tự động... Lúc này sẽ cần một "nhạc trưởng" để quản lý và điều phối(orchestrated) hoạt động của các container và hệ sinh thái đi kèm. Một số container orchestration có thể kể đến như K8S, Google container engine, Amazon ECS.

API gateway

    API gateway là thành phần thiết yếu của kiến trúc microservice. Do trong một hệ thống phân tán có rất nhiều service, hệ thống cần giới hạn lại các entry point để có thể quản lý được các request ra vào hệ thống, đây chính là tác dụng quan trọng nhất của API gateway. Hệ thống microservice thường được tổ chức theo cách chỉ có API gateway được facing ra ngoài internet, còn các dịch vụ bên trong sẽ giao tiếp với nhau qua internal endpoint hoặc messaging system. Do ở vị trí như một cánh cổng trung gian giữa hệ thống, network và system khác, API gateway có thể đảm nhiệm các chức năng:
  • Routing:  API gateway hoạt động bằng cách cấu hình mapping giữa địa chỉ của dịch vụ với một pattern URL của request gọi đến. Lúc này, các hệ thống bên ngoài sẽ chỉ nhìn thấy một endpoint duy nhất của API gateway. Gateway sẽ thực hiện forward request và response của request vào và ra khỏi hệ thống, tới các dịch vụ. Do đó nó cũng có tác dụng che giấu kiến trúc các thành phần bên trong.
  • Quản lý truy cập tập trung: Hệ thống luôn có nhu cầu thực hiện authentication, auditing, logging...tập trung với các request vào hệ thống. API gateway trở thành bộ phận hoàn hảo để đặt các tính năng này.
  • Quản lý quota truy cập: Tính năng này giới hạn tần suất của request đến hệ thống, các yếu tố detect có thể là url, ip, authentication factor, session... Việc này có thể ngăn chặn giúp việc Ddos hệ thống hoặc crawl data.
  • Handle request/response: API gateway có thể được sử dụng để detect các metadata của request hoặc status của response để thực hiện các công việc như custom response hoặc redirect.
  • Caching: Một vài API thường rất ít  khi thay đổi dữ liệu trả về, việc cache lại ở Gateway và response ngay lập tức mà ko phải request vào nguồn dữ liệu sẽ giảm tải cho hệ thống.
  • Load balancing: Chia tải (request) tới các địa chỉ khác nhau để giảm tải cho một instance.
  • Api health monitoring: Nhóm chức năng này giúp gateway có thể detect được trạng thái available của dịch vụ, từ đó có thể chuyển hướng request tới các dịch vụ hoặc thực hiện các kịch bản dự phòng
Một số giải pháp gateway: nginx, spring gateway, kong gateway

Service Discovery 

    Service Discovery giúp quản lý các deployment và phân bố tải giữa các dịch vụ trong quá trình vận hành hệ thống. Trên thực tế, các instance của các dịch vụ được triển khai trên khắp các node của hệ thống, các IP/host của instance có thể bị thay đổi trong khi runtime, start một instance mới hay thay đổi instance khi tăng số instance, service request sẽ không biết được địa chỉ cụ thể của các instance để request đến. Service discovery sẽ giúp giải quyết vấn đề này, nó đóng vai trò như một nhà ga trung tâm, luôn quản lý danh sách các instance đang active. Service Discovery hoạt động với 3 thành phần chính
  • Service provider: Là service cung cấp dịch vụ
  • Service consumer: Là ứng dụng hoặc dịch vụ đang yêu cầu cung cấp địa chỉ của một service để tiến hành request.
  • Service registry: Tồn tại như một database giúp lưu trữ địa chỉ các instance đang available của dịch vụ.
    Các hoạt động của Service Discovery:
  1. Service provider khi được sinh ra sẽ đăng kí dịch vụ với service registry location/address của instance
  2. Service consumer sẽ request đến Server registry để lấy địa chỉ của dịch vụ thông qua tên dịch vụ
  3. Service registry trả về địa chỉ của Service provider đang active
  4. Service consumer sẽ request đến Service provider theo địa chỉ nhận được
Service discovery bao gồm hai pattern chính là server-side và client-side. Client-side hoạt động tương tự cách mô tả ở trên, còn server-side sẽ hoạt động hơi khác một chút, sau bước 2, sau khi đã định vị được địa chỉ của service provider, router sẽ forward request tới service tương ứng.
    Với một số giải pháp microservice tự xây dựng, người dùng sẽ cần cài đặt riêng thành phần service discorvey. Ngoài ra nếu sử dụng các giải pháp container orchestration thì người dùng không cần phải quan tâm đến thành phần này, hầu hết đã được build in trong giải pháp, người dùng chỉ cần quan tâm đến các container phục vụ business.

Service Mesh

    Thuật ngữ Service mesh xuất hiện trong bối cảnh cùng với cloud application, containers và microservice. Trong hệ thống microservice, khi có nhiều dịch vụ và instance runtime được sinh ra, việc kiểm soát communication giữa các dịch vụ trở nên rất khó khăn, nếu không có giải pháp hay công cụ hỗ trợ, nhà phát triển hoàn toàn phải kiểm soát communication này bằng cách thủ công bắt đầu từ việc liệt kê connection giữa các dịch vụ. Các nhu cầu bao gồm kiểm soát connection giữa các dịch vụ, lượng traffic phát sinh, metric và monitoring.. Service mesh sẽ giải quyết vấn đề này, nhà phát triển chỉ cần tập trung vào các vấn đề của business. Layer quản lý connection trong mạng lưới dịch vụ phân tán se trở nên transparent với code business.
    Service mesh sử dụng sidecar pattern, pattern này hoạt động với nguyên lý tạo ra một proxy-container bên cạnh các container instance của dịch vụ, proxy container này sẽ định tuyến traffic tới các proxy-container của dịch vụ khác, nhờ đó handle được các connection mà không can thiệp tới hoạt động của container chính.

Load Balancing

    Số lượng request đến hệ thống có thể thay đổi theo lượng sử dụng của người dùng, ví dụ như: theo các ngày đặc biệt trong năm, chương trình khuyến mãi hay các sự kiện tập trung nhiều truy cập... Lúc này hệ thống có thể lựa chọn phương án tăng thêm tài nguyên CPU/RAM(Vertical scaling) hoặc sẽ tạo ra thêm các instance(horizontal scaling) để đáp ứng tải. Với phương án horizontal- scaling, hệ thống cần một thành phần để điều phối request tới các instance của cùng một dịch vụ. Việc điều phối này cần phải linh hoạt theo nhiều tiêu chí để đáp ứng được các bài toán thực tế chứ không phải chỉ là lần lượt chia đều tải trên số lượng instance. Load balancer chính là thành phần này, nó giúp tối ưu hóa xử lý compute, tăng tính ổn định và tin cậy, giảm độ trễ của hệ thống. Load balancer có thể phân phối tải đều tới tất cả các instance trên các node đang được triển khai. Thuật ngữ load balancing không chỉ ở trong phạm vi công nghệ container mà với công nghệ Virtual Machine cũng tương tự, ở đây thay vì phân phối tải tới các container thì load balancer sẽ phân phối tải tới các máy vm trong cùng một group.

Circuit Break

    Đây là cơ chế giúp ngăn ngừa các lỗi có thể xảy ra khi request gửi đến một instance mà ko có phản hồi hoặc có tín hiệu unavailable. Service client khi request tới một service khác nên gọi qua một proxy có chức năng tương tự như một cầu dao diện(circuit break). Khi số lượng request thất bại liên tục đạt tới một ngưỡng, kết nối sẽ bị ngắt hoàn toàn ngay từ proxy, khi kết nối bị ngắt, các request tới dịch vụ đích sẽ bị từ chối ngay lập tức. Sau một khoảng thời gian, một số lượng request test nhất định được phép đi qua, nếu những request này thành công thì cầu dao sẽ được đóng lại và khôi phục kết nối, còn ngược lại, một chu kì lỗi timeout sẽ tiếp tục diễn ra. Quá trình này giúp tránh những trường hợp như dịch vụ vừa khôi phục đã phải nhận một lượng lớn request, dẫn đến hệ thống tiếp tục bị treo, không thể phục hồi hoàn toàn.
    Pattern này tạo điều kiện cho dịch vụ tự khôi phục và không xảy ra quá nhiều lỗi trên dịch vụ đích. Quá trình hoạt động của circuit break được tóm tắt qua 3 trạng thái: Closed State(Trạng thái ngắt), Open state (Trạng thái mở), Half-Open State (Trạng thái test)

Centralized Logging

    Logging luôn luôn là yêu cầu cần thiết cho bất cứ hệ thống nào, chức năng phục vụ cho tracing dữ liệu, debugging và troubleshooting ứng dụng. Nhưng với sự phức tạp của hệ thống microservice, log đến từ hàng chục đến hàng trăm instance với các định dạng log của các ngôn ngữ khác nhau, debugging trở nên thật sự khó khăn. Nhà phát triển không thể access vào console log của từng ứng dụng và kéo hàng nghìn dòng log để tìm kiếm thứ mình cần. Khó khăn còn đến từ multiple instance của mỗi dịch vụ, người dùng không thể biết exception vừa bắn ra từ hệ thống đến từ instance nào. Việc logging từ ứng dụng container cũng trở nên khó khăn hơn từ vm do nguồn phát sinh log đã trở nên đa dạng và phức tạp hơn rất nhiều. 
    Ý tưởng cho việc logging cần dễ dàng cho việc truy cập, lưu được theo retention dài, da dạng các chỉ số index cho việc tìm  kiếm từ log(xuất phát từ dịch vụ nào, thời gian, nội dung, token, session, url...). Việc lưu trữ và truy xuất cũng cần tập trung thay vì rải rác trên các dịch vụ hoặc thành phần khác nhau. Các công cụ phổ biến như ELK, EFK hay Splunk là ý tưởng cho việc tìm kiếm, lọc và query log. Trước đó còn cần có bước chuẩn hóa định dạng log trước khi đẩy dữ liệu vào các công cụ tìm kiếm.

Monitoring and Alert

         Các thành phần hạ tầng của một hệ thống bao gồm CPU, RAM, Storage và Bandwidth
    Thành phần này thường không được chú trọng trong thời gian đầu phát triển hệ thống, nhưng khi hệ thống đã đi vào hoạt động thì lại thực sự cần thiết. Monitoring là tính năng cho phép quản trị viên và nhà phát triển có thể theo dõi sức khỏe hệ thống realtime hoặc tổng hợp lại theo các khoảng thời gian  (giờ, ngày, tháng, năm), từ đó có thể tracing các issue của hệ thống như bị tấn công, các function chưa tối ưu, thiếu tài nguyên (cpu/ram/storage/bandwidth). 
    Alert sẽ cho phép người dùng cài đặt các mức cảnh báo hoặc các cài đặt về healthcheck sau đó gửi cảnh báo đến người dùng (email, slack, discord...) cho phép người dùng aware được sớm các vấn đề mà hệ thống đang gặp phải, từ đó đưa ra các quyết định thích hợp để giữ hệ thống hoạt động ổn định. Tránh gặp phải các tính trạng như hệ thống bị treo do hết ram/cpu hoặc quá nhiều người truy cập dẫn đến bottle neck hay database lưu trữ hết dung lượng khiến hệ thống gặp lỗi...
Các giải pháp phục vụ cho Monitoring và Alert có thể kể đến: Prometheus, Grafana

Messaging System

    Messaging phục vụ nhu cầu giao tiếp giữa các dịch vụ. Do kiến trúc microservice dựa trên sự phân tán, giao tiếp point to point sẽ gặp một số issue: các request có thể bị mất do lỗi logic code, network latency, service downtime... Bạn có thể đã từng nghe đến Message queue và Message broker. 
Message queue đảm bảo dữ liệu sẽ không bị mất trong các trường hợp kể trên, ngoài ra chức năng cơ bản nhất của message queue là vận chuyển dữ liệu đến các client/consumer đúng thứ tự như khi chúng được ghi vào queue(FIFO). 
    Message broker được thiết kế để duy trì message cho đến khi consumer/subscribe có thể nhận được dữ liệu. Điều đó có nghĩa là Messaging system giúp giảm effort rất nhiều cho nhà phát triển khi không phải xử lý các vấn đề như message translation, message validation, topic/channel ACL, routing message từ producer đến consummer, đảm bảo tính persistence, vận chuyển và streaming dữ liệu... mà chỉ cần tập trung vào code business. Ngay cả với các hệ thống không dựa trên kiến trúc microservice thì Message broker cũng là một thành phần phổ biến và có nhiều tác dụng.
Các giải pháp cho Messaging trong hệ thống microservice: Kakfa, RabbitMP, Active MQ

Single Page Application 

    Single Page Application ít được chú ý nhưng cũng rất phổ biến trong kiến trúc microservice. Đây là thành phần thuộc lớp ứng dụng frontend. Giống như sự tương thích giữa Container với microservice, thì SPA cũng phát triển và phù hợp với hệ sinh thái microservice. Thay vì render tất cả HTML DOM từ phía server như các công nghệ đã có từ lâu (Spring MVC, PHP, Java Servlet, ASP.NET MVC...), SPA chỉ trả về các resource và code logic, hầu hết được đóng gói trong các file js bundle, từ đó kết hợp với các dữ liệu để render ra HTML theo behavior của người dùng ngay trên client browser (client side rendering)
    SPA được xây dựng dựa trên các component, vừa tăng tính tái sử dụng code, từ đó tăng tốc độ phát triển ứng dụng. Đi cùng với SPA thường là Rest API giúp giao tiếp với phía server. Với SPA, người dùng sẽ có trải nghiệm ứng dụng mượt mà, giảm thời gian tải trang giữa các lần truy cập và cũng giảm tải cho phía server. SPA cũng giúp tách riêng việc phát triển UI ứng dụng và xử lý logic backend phía sau, tăng tốc phát triển của dự án.
Các công nghệ SPA phổ biến: Angular, React, Vuejs

Configuration Server

    Một hệ thống microservice chạy trên rất nhiều container, các container này lại cần rất nhiều cấu hình để phục vụ CI/CD hoặc runtime. Configuration server sẽ có tác dụng lưu trữ tập trung các dữ liệu cấu hình và có thể được truy cập từ các service hoặc các thành phần khác của hệ thống. Giải pháp lưu trữ tập trung cấu hình ngoài việc đảm bảo việc dễ dàng truy cập dữ liệu từ các service còn giải quyết những vấn đề xung quanh như ACL, versioning của dữ liệu, grouping by project/environment...

Kết

    Bài viết đã đề cập đến các thành phần quan trọng của kiến trúc Microservice và tầm quan trọng của mỗi thành phần. Nhìn nhận ở một góc độ khác, hầu hết các thành phần của hệ thống phân tán lại có chức năng quản lý tập trung và kết nối các dịch vụ, đây chính là điểm khác biệt giúp bù đắp lại những issue của kiến trúc microservice so với monolithic. Chúng ta sẽ đi sâu vào mỗi thành phần và cách sử dụng các thành phần trên lý thuyết và cả thực tế ở những bài viết sau.

Thứ Ba, 7 tháng 11, 2023

Những lợi ích của microservices

 Mở đầu

    Microservice đã nhanh chóng trở thành kiến trúc phổ biến cho những công ty, tổ chức tân tiến,  Nó là một kiến trúc xây dựng hệ thống phân tán cho phép nhà phát triển xây dựng, triển khai và co giãn các dịch vụ riêng lẻ một cách độc lập. Điều này cho phép dễ dàng quản lý một ứng dụng lớn và thay đổi business nhanh chóng theo các yêu cầu .
 Ở bài viết trước tôi đã nhắc đến những khó khăn và thách thức khi làm việc với microserivce, nhưng như vậy là không công bằng nếu ko nhìn về mặt lợi ích mà microservice mang lại. Bài viết này sẽ là câu trả lời tiếp theo cho câu hỏi Microservice có phải là miền đất hứa? (Link đến bài Microservice có phải là miền đất hứa)






Những lợi ích của microservices

Easy to develop and maintain

Microservice tương đối nhỏ và đơn giản hơn ứng dụng monolithich nên dễ dàng hơn trong việc phát triển và bảo trì. Các dịch vụ được isolate về business và data nên hoạt động và performance của dịch vụ này sẽ ít hoặc không ảnh hưởng đến toàn hệ thống. Với một trường hợp khi một tính năng cao tải, với hệ thống monolithic thì toàn bộ tài nguyên available của hệ thống sẽ bị sử dụng hết, toàn bộ hệ thống có thể downtime, thậm chí phải cần đến reset toàn bộ, trong khi với microservice, issue không ảnh hưởng tới toàn hệ thống và có thể được giải quyết bằng các giải pháp cục bộ.

Highly available

    Tính sẵn sàng cao nói đến việc service của bạn luôn sẵn sàng trong nhiều điều kiện khác nhau(một instance bị crash, cao tải, không phản hồi...). Theo mô hình tiêu chuẩn, một hệ thống microservice thường được triển khai trên các nền tảng ảo hóa, một service được chạy song song trên nhiều runtime instance(Replica), hệ thống Container Orchestration sẽ kiểm tra tính sẵn sàng và điều  phối request đến các instance đang available, và ngăn các request đến các instance có vấn đề cho đến khi chúng phục hồi.

Scalable

    Khả năng có giãn của service mang lại hiệu quả cả về kinh tế và performance cho cả hệ thống. Tưởng tượng khi hệ thống thấp tải hoặc các service không yêu cầu quá nhiều tài nguyên, có thể giảm cấu hình của từng instance hoặc giảm cả về số lượng instance để tối ưu chi phí. Khi hệ thống yêu cầu tài nguyên lớn để xử lý trong các trường hợp đặc biệt, hệ thống lại sẵn sàng tăng cấu hình từng instance hoặc tăng số lượng lớn các instance để đáp ứng tải. 

Resilient

    Khả năng phục hồi: Các nền tảng ảo hóa thường có cơ chế để kiểm tra sức khỏe từng phần hoặc cả hệ thống từ đó đảm bảo tự động khôi phục hoạt động của ứng dụng và hệ thống khi có vấn đề xảy ra, các vấn đề có thể đến từ nội hàm của dịch vụ  như cao tải, crash ứng dụng, do người dùng delete các instance hoặc các vấn đề lớn hơn như máy chủ vật lý gặp lỗi, cần chuyển sang node khác để hoạt động.

Fault-tolerant

    Khả năng chịu lỗi: Khả năng này khá trừu tượng cho những người mới tiếp cận với microservice. Khả năng chịu  có vẻ tương đồng với khả năng phục hồi, nhưng scope của những tính năng này không giống nhau. Khi các instance gặp lỗi, hệ thống cũng cần có khả năng handle được lỗi này. Nhưng không chỉ có vậy, nếu nhìn một cách tổng quát hơn, bất kì vấn đề nào của hệ thống microservice đều có thể dẫn đến khả năng ảnh hưởng đến business và dữ liệu. Mục đích cuối cùng của khả năng chịu lỗi là đảm bảo business ít hoặc không bị ảnh hưởng bởi các lỗi của hệ thống, bảo gồm các lỗi do logic và các lỗi do hạ tầng, kết nối. Các lỗi của hệ thống có thể kể đến như Slow Network, Service downtime, Connection timeout, Cross service transaction...

Increase Release Cycle

    Do các business domain đã được chia nhỏ theo các service nên tốc độ  phát triển có thể được gia tăng bằng cách triển khai nhiều team cùng phát triển các domain của ứng dụng. Nhưng từ bài viết trước chúng ta cũng thấy được microservice khiến việc duplicate các effort lên là khá thường xuyên, nhưng khi đã có giải pháp để tối ưu thì tính linh hoạt của microservice được thể hiện rõ rệt, do các ứng dụng tương đối nhỏ, ít depend với nhau nên khả năng phát triển độc lập được gia tăng. Quá trình CI-CD được tích hợp liên tục mà không làm gián đoạn cả hệ thống trong thời gian dài

Technology combination

    Trước đây chúng ta thường thấy có những stack thường đi cùng với nhau như XAMMP, LAMP, WAMP vs MAMP trong phát triển ứng dụng web hoặc các giải pháp của .Net, C-sharp thường gắn liền với hệ sinh thái của Microsoft. Nhưng giờ đây với sự phát triển của công nghệ nói chung và microservice nói riêng, các stack tương thích với nhau dễ dàng hơn rất nhiều, nhiều chuẩn giao tiếp, protocol được phát triển và được hỗ trợ bởi nhiều ứng dụng như Rest API, gRPC, Messaging... Cả một hệ thống hoặc ứng dụng lớn có thể được triển khai đơn giản trên công nghệ container khi tất cả source code và các dependency đã được đóng gói trong một image duy nhất, rất tiện dụng. Hệ thống có thể kết hợp nhiều công nghệ, đa dạng ngôn ngữ lập trình cho các mục đích phù hợp, tối ưu hóa hệ thống.

Hardware/Resource Optimization

Nhờ công nghệ container mà chúng ta không cần phải triển khai cả một máy chủ ảo để chạy các ứng dụng theo cách truyền thống, các ứng dụng khi được viết bằng các ngôn ngữ phù hợp có thể chạy trên các cấu hình container nhỏ (0.25CPU/ 0.25 Gb RAM) hoặc thậm chí nhỏ hơn nữa, bao gồm cả các ứng dụng phía backend. Quá trình CI-CD trên các dịch vụ nhỏ cũng giúp tăng tốc và tối ưu về tốc độ phát triển. Do có thể chia nhỏ việc phát triển các dịch vụ trên các team/member nhỏ hơn nên việc phát triển cũng tối ưu về nguồn lực, mỗi team/member chịu trách nhiệm trên service của mình, giảm việc phải hiểu và debug cả project lớn và phải hiểu nhiều tech stack, language khác nhau.

Reusability

Khả năng tái sử dụng cao do các service được đóng gói cả code và dependency cùng với nhau, khi có bất cứ nhu cầu về triển khai lại các version code khác nhau, chỉ cần deploy lại image tương ứng, mà không cần build lại từ đầu. Cùng image đó có thể triển khai trên nhiều hạ tầng khác nhau, với chắc chắn cùng một phiên bản code, stable về business. Write once, run everywhere, chỉ cần máy chủ có triển khai công nghệ container thì microservice có thể triển khai trên bất kì hệ điều hành nào bao gồm cả linux và window.

Security

Các service có thể được tách biệt về code và cả data nên có thể che giấu được business phía sau. Đảm bảo bảo mật về mặt dữ liệu và business. Các dịch vụ cũng không access được đến các secret, config của dịch vụ khác, đảm bảo isolate giữa các teams/members.

Kết

Quả cả hai bài viết, chúng ta đã có cái nhìn khá toàn diện về ưu/nhược điểm của kiến trúc microservices. Điều này sẽ giúp nhà phát triển đưa ra được quyết định tốt nhất khi xây dựng kiến trúc hệ thống

Peace! 
Tác giả: Ethanol Tran

Thứ Ba, 31 tháng 10, 2023

Microservice có phải là miền đất hứa?

    Thuật ngữ Microservice đã không còn xa lạ trong việc triển khai các ứng dụng và hệ thống phần mềm trong nhiều năm trở lại đây, Microservice sẽ là lựa chọn hàng đầu của developer khi bắt đầu xây dựng một hệ thống mới. Và cũng là mục tiêu chuyển đổi cho nhiều hệ thống monolithic đang hoạt động kém hiệu quả.

//TODO link đến bài chuyển đổi microservice in action, lick vào chỗ bôi đậm bên trên

    Trong bối cảnh hiện nay, các ứng dụng ngày càng trở nên phức tạp, hệ sinh thái đã trở nên rất đa dạng về thiết bị và các phương thức giao tiếp, developer ngày càng phải xử lý những vấn đề phức tạp và business thay đổi liên tục. Ứng dụng Monolithic khi vừa phát triển có lẽ sẽ không có vấn đề gì, nhưng càng phát triển sẽ càng bộc lộ những nhược điểm mà nếu không được đánh giá để chuyển đổi kịp thời sang microsevice thì đến một thời điểm doanh nghiệp sẽ nhận ra hệ thống hiện tại không thể đáp ứng được business. Nhưng microservice có phải chỉ có những hứa hẹn như cách mà chúng ta vẫn nghe về nó. Bài viết này sẽ đi vào những thách thức mà nhà phát triển sẽ phải đối mặt trước khi có thể đạt được những giá trị mà microservice mang lại. 

Microservice và Monolithic

    Ưu điểm lớn nhất của monolithic là tính dễ triển khai, chi phí thấp, phát triển nhanh khi ở quy mô nhỏ, còn với Microservice ưu điểm sẽ là tính linh hoạt trong việc thay đổi và mở rộng. Nhà phát triển cần bỏ công sức ra nhiều hơn để phát triển, bảo trì và vận hành hệ thống microservice so với một hệ thống monolithic có cùng tính năng. 

    Những giá trị microservice mang đến thật sự đáng giá, ví dụ như khả năng phục hồi, khả năng chịu lỗi, khả năng co giãn đáp ứng tải. Nhưng những điều này không phải tự nhiên mà có. Câu chuyện với Microservice không đơn giản như cài đặt một framework, vì là kiến trúc phần mềm, Microservice được mô tả bằng các pattern, concept và principle. Và để đạt được những giá trị của microservice đòi hỏi nhà phát triển vừa triển khai theo các concept nhưng cũng phải cân đối chi phí cho việc phát triển theo từng giai đoạn.

Lợi ích của Microservice

Cùng điểm qua một số ưu điểm của microservice trước khi đi vào chi phí
  • Những dịch vụ có thể rất đơn giản, tập trung vào một số business nhất định
  • Hệ thống xây dựng theo hướng loosely coupling, xoay quanh business
  • Nhiều nhà phát triển hoặc các team khác nhau có thể đồng thời triển khai các tính năng tương đối độc lập với nhau
  • Phù hợp với nhu cầu delivery liên tục, cho phép release trong khi giữ phần còn lại của hệ thống vẫn ổn định

Chi phí phát triển

Microservice cần rất nhiều chi phí vận hành

   Thông thường một ứng dụng trải qua rất nhiều các phase trước khi được publish hoàn toàn. Mỗi service phải trải qua build, test, deploy and run. Mỗi dịch vụ có thể được viết bằng các ngôn ngữ và chạy trên các môi trường/ hệ điều hành khác nhau, các kịch bản triển khai CICD, và các dependency cũng có thể khác nhau.
    Mỗi ứng dụng lại cần được triển khai theo cụm(clustering) để đáp ứng khả năng chịu lỗi và phục hồi, dẫn đến x2, x3 số lượng runtime instance so với số lượng dịch vụ ban đầu. Nếu hệ thống có 15 service, số lượng runtime instance có thể lên tới 30-50. Cộng thêm với các thành phần Load balancer và Message broker, hệ thống đã trở nên khá lớn nếu so với ứng dụng monolithic cùng chức năng.
    Do hệ thống bị phân tán , việc monitoring và tracing cũng cần được thêm vào để đảm bảo hệ thống hoạt động ổn đinh. Tránh tình trạng deadlock, hết dung lượng lưu trữ, compute bị quá tải...hay làm sao để biết được dịch vụ nào đang bị quá tải hoặc bị ngừng hoạt động để đưa ra quyết định phù hợp, hoặc làm sao để tracing được data/bug khi thực hiện một chức năng cross qua nhiều service và kênh messaging. Để ghi lại và truy vấn được log trong 30-50 instance cần một lượng tài nguyên không hề nhỏ.
    Hiện tại đã có nhiều giải pháp đáp ứng các quá trình phát triển và triển khai các microservice, nhưng thường những ứng dụng này chỉ đáp ứng một phần các công việc cần làm . Gần như nhà phát triển sẽ cần triển khai hệ thống ở một mức độ nhất định trước khi có thể bắt tay vào code business.

Yêu cầu kĩ năng DevOps

Một hệ thống Microservice thường được triển khai qua một Container Engine/ Container Orchestration như Docker, Docker swarm, K8S, Openshift... Những công nghệ này yêu cầu kiến thức về docker, container, hệ điều hành và commandline, chưa kể đến kiến thức về mạng, storage, environment thậm chí các kiến thức nâng cao hơn về ảo hóa, clustering của mỗi công nghệ đặc thù. Hệ thống được tạo nên từ nhiều dịch vụ nhỏ, nên quá trình CICD là không thể thiếu để quá trình triển khai và tích hợp được tự động. Những kiến thức trên khá xa lạ với các developer chuyên về business như Frontend hay Backend, nên hệ thống Microservice yêu cầu kĩ năng về DevOps đáng kể

Interface Giao tiếp giữa các dịch vụ không rõ ràng

Vì hệ thống được chia nhỏ ra thành cách thành phần riêng biệt có thể cả về hướng kĩ thuật hoặc hướng theo domain business, các dịch vụ này cũng có thể được thực hiện bởi những cá nhân hay team khác nhau, dẫn đến việc hợp đồng cùng với nhau để định nghĩa interface giao tiếp giữa các service-service hoặc service-message broker trở nên phức tạp và không ổn định nếu giữa các team/ cá nhân không tuân thủ theo các rule về mặt giao tiếp. Function sẽ bị break nếu một bên thay đổi kiểu dữ liệu hoặc một dữ liệu mandatory không được đáp ứng giữa các service. Một số chuẩn giao tiếp hoặc công nghệ hỗ trợ cho chuẩn hóa format API và giữ liệu như OpenAPI hay Schema registry đã giúp ích rất nhiều cho việc collab giữa các dịch vụ, nhưng về bản chất nhà phát triển cần có các biện pháp để deal với vấn đề này.

Multiply Effort

    Hệ thống microservice có xu hướng triển khai hầu hết các dịch vụ chính trên cùng một công nghệ hoặc ngôn ngữ để giảm effort phát triển, nhưng ngay cả khi đã triển khai trên cùng một công nghệ thì các dịch vụ cũng thường được lưu trữ code hoàn toàn tách biệt về phạm vi project code và dependency.
Nhà phát triển thường xuyên phải đối mặt với vấn đề duplicate các đoạn code hoặc chức năng trên các service khác nhau, thậm chí ngay cả khi bắt đầu một dịch vụ mới, các cấu hình hệ thống, environment cũng thường được sử dụng lại trên các dịch vụ, các function util, secret, apikey... Điều gì sẽ xảy ra khi một đoạn code hay chức năng global cần được update tính năng hoặc fix bug, nhà phát triển cần đi thực hiện thay đổi đó ở tất cả các dịch vụ đang sử dụng. Vì đặc tính loose coupling của microservice nên việc duplicate các model hay code giữa các service là điều không thể tránh khỏi, nhưng cũng cần được tối ưu để giảm chi phí và rủi ro cho việc maintain hệ thống.

Xử lý hệ thống phân tán phức tạp

Microservice triển khai trên một hệ thống phân tán, các service thậm chí còn không cùng nằm trên một server, đây cũng chính là nguyên do dẫn đến rất nhiều vấn đề của microservice mà nếu ở hệ thống monolithic thậm chí chúng ta còn chưa nghe tới. Các vấn đề có thể kể đến như khả năng chịu lỗi, độ trễ của mạng, xử lý bất đồng bộ, transaction cross qua nhiều service, version của ứng dụng, tracing dữ liệu, khả năng tương thích ngược, cấu hình tập trung...
  • Khả năng chịu lỗi: Microservice cần có khả năng chịu lỗi khi có một thành phần trong hệ thống không hoạt động và đảm bảo business không bị ảnh hưởng khi có một dịch vụ bị downtime hoặc xảy ra lỗi trong giao tiếp
  • Độ trễ của network: Với càng nhiều microservice, nguy cơ độ trễ của function càng lớn, vấn đề này rất quan trọng với các ứng dụng yêu cầu tốc độ cao và ổn định như chứng khoán, financial
  • Xử lý bất đồng bộ: Trong hệ thống có thể có những function không thể nào nhận được đáp ứng ngay lập tức, vậy hệ thống lại cần có cơ chế để bên request có thể thực sự nhận biết được kết quả của một request đã được đáp ứng thực sự.
  • Transaction cross qua nhiều dịch vụ: Đây là vấn đề thực sự quan trọng, Data consistency luôn là vấn đề quan trọng trong bất cứ hệ thống nào. Có lỗi trên một ứng dụng monolithic sẽ dễ dàng được giải quyết hơn do các framework hầu hết đã hỗ trợ Transactional trên các function khi thực thi. Nhưng điều này không thể lặp lại trên microservice, do các ứng dụng có nhu cầu gọi đến nhau để thực thi một business function, chưa kể đến các kênh giao tiếp khác Send and forget (messaging), dẫn đến các chức năng hoặc dữ liệu không thể rollback theo cách truyền thống.
  • Version của ứng dụng: Việc collab giữa các team yêu cầu sự thống nhất về mặt interface giao tiếp và chức năng. Làm sao để biết một business function trong release mới đang cần code của những dịch vụ nào, version nào của dịch vụ đó, và nhu cầu rollback cả hệ thống nữa. 
  • Tracing dữ liệu: Việc debug trên hệ thống microservice không đầy đủ là khá khó khăn, nếu một function cross qua nhiều service và mỗi service chạy trên một vài instance. Điều này lại yêu cầu một hệ thống loging tập trung nữa.
  • Khả năng tương thích ngược: Các ứng dụng khi phát triển cần được quản lý các version và thay đổi interface một cách cần trọng, cân nhắc đến khả năng tương thích ngược với các hệ thống hiện tại. Thận trọng trong các thay đổi về request/response hoặc các bussiness code. Bạn có thể phát triển thêm một tính năng những sẽ break business hiện tại.
  • Centralize configuration: Khi hệ thống phân tán mà không có giải pháp cho việc centralize các configuration, nhà phát triển sẽ phải thường xuyên thay đổi các config một các thủ công và trên nhiều dịch vụ. Việc này khá mất effort và không đảm bảo tính chính xác/ ổn định của hệ thống

Những vấn đề này sẽ được đề cập chi tiết hơn trong các bài viết sau.

Khả năng kiểm thử

Do có nhiều dịch vụ nên việc kiểm thử trở nên khó khăn và tốn effort trên cả unit test/ manual test/ auto test/ intergration test. Thậm chí còn trở nên khó khăn hơn nữa với các chức năng sử dụng bất đồng bộ(async/callback) hoặc messaging(publish/subscribe).

Handle multi instance

Nhà phát triển cần chú ý tới khả năng multi instance có ảnh hưởng đến các chức năng vốn có của các dịch vụ hay không. Nếu lúc đầu các dịch vụ luôn chỉ có 1 instance, nhưng không chắc chắn khi tăng số  replica , mọi business sẽ hoạt động ổn định. Lấy ví dụ với các chức năng về cron-job hoặc subscribe messaging thường chỉ có nhu cầu được trigger/execute 1 lần trên cả hệ thống, nhưng với multi instance, các chức năng này cũng sẽ được repeat hoặc chạy song song nếu không thêm vào các kĩ thuật để xử lý. 

Kết

Trên đây là những khó khăn mà tôi đã gặp phải trong quá trình phát triển hệ thống với microservice, các vấn đề sẽ được phân tích và thảo luận hướng giải quyết trong các bài viết tiếp theo. Tuy có nhiều khó khăn, thách thức nhưng những gì Microservice mang lại là rất đáng giá. Với cách tiếp cận đúng đắn khi nhìn vào cả cơ hội và thách thức của Microservice, tôi hi vọng sẽ giúp cho nhà phát triển có cái nhìn toàn diện hơn và tránh được những sai lầm trong quá trình phát triển microservice.

Peace! 
Tác giả: Ethanol Tran

Thứ Ba, 27 tháng 6, 2023

DNS hoạt động như thế nào? 2

 

Mở đầu

Nhiều năm trước đây, khi mới bước chân vào nghề lập trình web, lần đầu tiên chạy được một ứng dụng web trên địa chỉ localhost:8080 và 127.0.0.1:3000, mình đã tự hỏi:

"Máy tính kết nối tới mạng internet qua địa chỉ IP các thứ, rồi bình thường mình vẫn truy cập web bằng tên miền website, vậy sao mà cái tên website kia lại dẫn tới cái máy chứa trang web được? bla bla..".

Trong bài viết này chúng ta cùng đi tìm hiểu IP, Domain, DNS là gì và chúng liên quan đến nhau như thế nào, và làm cách nào mà trình duyệt có thể request đến đúng máy tính chứa nội dung cần truy cập.

IP và Domain

Thiết bị trong một mạng máy tính sử dụng giao thức Internet( Internet Protocol) sẽ được cung cấp một địa chỉ IP, địa chỉ IP tương đương với định danh của thiết bị trong network, giúp phân biệt giữa các máy tính khác nhau. Địa chỉ IP là một dãy số có dạng xxx.xxx.xxx.xxx
 Tương tự như vậy, với mạng Internet toàn cầu, các máy tính cũng được định danh bằng các địa chỉ IP. Nhưng con người làm sao nhớ được các con số vô nghĩa, chưa kể dãy số còn dài thế kia, vậy nên chúng ta sử dụng các từ gợi nhớ có nghĩa. ví dụ:
- dichvucong.gov.vn
- vi.wikipedia.org
- mail.google.com
- dantri.com
- sunteco.vn
Các tên gợi nhớ này được gọi là tên miền(Domain) và được đặt theo một số quy tắc nhất định.

DNS(Domain name system) sẽ gắn kết hai phần này lại với nhau và bằng cách nào đó khi bạn truy cập tên miền bạn sẽ được chuyển đến đúng địa chỉ IP cần đến. Đó là cách mà DNS hoạt động.

Hành trình từ Domain đến IP

Chúng ta vừa hiểu một cách sơ lược cách hoạt động của DNS, thử tham gia hành trình truy cập một trang web xem sao.
23h PM 
--- Browser and OS---
Human: Typing...
Browser: - Ể có request mới nè: zzz.com, cái trang web gì mà khó hiểu, đợi tí bạn ôi, để tôi xem có thông tin về trang này ko, trước khi tôi hỏi OS, lão đấy khó chịu lắm... Haizza, ko có rồi, đợi tí nhé.
- Hi OS, có đấy ko, tui nhờ tí, tôi có thể tìm zzz.com ở đâu
OS: Bruh bruh, System is updating...
Browser: - Giúp tí i
OS: (Checking now...) -ko thấy nhé, nhưng tôi biết phải hỏi ai để tìm. RESOLVERRRR!!!!

Đến đây ta đều thấy Trình duyệt và hệ điều hành đều tìm kiếm trong cache nhưng không thấy, OS sẽ tiếp tục request đến Resolver

--- Resolver and Root server ----
Resolver hay còn gọi là DNS recursive resolver. Resolver thường được cung cấp bởi ISP(Internet Service Provider) - Nhà cung cấp dịch vụ Internet. Tất cả các nhà cung cấp dịch vụ đều biết: Làm sao để tìm được Root serverRoot server lại biết nơi nào để tìm được .COM TLD server. TLD là viết tắt của Top-Level Domain.

...Hộp thư đến có thư mới...loạt soạt
Resolver: Request mới đến, tuyệt vời, zzz.com, ok để xem nào... ko có trong cache rồi. Đi hỏi Root server thôi.
Root server: Người tiếp theo. Tôi giúp gì được cho bạn.
Resolver: Hi root, tôi đang tìm địa chỉ của zzz.com. Bạn có thể giúp tôi ko?
Root server: Sorry nhé, tôi ko biết địa chỉ của zzz.com, nhưng tôi biết .COM Top-level domain server ở đâu đấy!
Resolver: Ok thanks kiu, trước khi đi tiếp, tôi cache lại phát đã.

Root server này là 1 trong 13 máy chủ Root Name. Root server nằm trên đỉnh của hệ thống phân cấp DNS. Chúng được đặt khắp thế giới và được điều hành bởi 12 tổ chức độc lập khác nhau. Chúng được đặt tên theo định dạng [chữ cái].root-servers.net , các chữ cái được đặt từ a đến m. Điều này không có nghĩa là chỉ có 13 máy chủ vật lý để phục vụ cả thế giới, trên thực tế mỗi tổ chức sẽ cung cấp dịch vụ trên nhiều server vật lý phân tán.

--- tại Top-level Domain .COM ---
Resolver: Tôi không ngại đến đây, tôi chỉ cần một lý do thôi.
.com TLD: WHAT tờ hell??? bad joke, dude!
Resolve: Hợ, sorry, tôi đang tìm zzz.com, cho tôi biết nó ở đâu được ko?
.com TLD: huhm, câu hỏi hay đấy!

Sự sắp xếp của hầu hết các top-level domains thuộc về Internet Coporation for Assigned Names and Number (ICANN). .COM TLD là một trong những cái tên được tạo ra đầu tiên năm 1985. Ngày nay nó cũng trở thành TLD lớn nhất. Một vài loại TLD khác có thể kể đến như 
  • Tên quốc gia (.vn, .uk), 
  • TLD viết bằng ngôn ngữ native locallization(tiếng trung, tiếng arap)
  • Những tên phổ biến khác như. net,. org, .edu
  • TLD hạ tầng: .ARPA, hầu hết dùng cho reverse DNS lookups(Tra cứu tên miền từ IP)
Ngày nay có càng nhiều hơn các TLD được tạo ra. Giờ thì quay trở lại với câu hỏi của Resolver 

.com TLD: Cache searching...Tôi sợ là tôi ko biết IP của zzz.com ở đâu, nhưng tôi tìm thấy name server  của zzz.com đấy (Đưa cho mảnh giấy)
Resolver: Tuyệt vời,Cảm ơn nhé, cache phát nữa. Khoan đã, sao .com có thể chỉ mình tới name server nào nhỉ???

Vậy là .Com TLD đã tìm thấy name servers của zzz.com là aleza.cloudflare.com, name server hay còn gọi là authoritative name server. Khi một domain được thanh toán, Domain Registra (Nhà cung cấp tên miền) sẽ lưu trữ tên miền này và thông báo tới TLD về name server có thẩm quyền của mỗi tên miền. Từ đã, Resolve đang đi phân giải tên miền mà lại nhận được một tên miền nữa là sao? Trên thực tế có thêm những thông tin bổ sung đi kèm với name server, Resolve nhận được ít nhất một địa chỉ IP với mỗi name server, vậy nên Resolver có thể tới chính xác được máy chủ của name server.
aleza.cloudflare.com - 197.246.15.51
bzeta.cloudflare.com - 51.32.246.54
--- Last trip, tại name server--------
aleza.cloudflare.com: Người tiếp theo 
Resolver: Thank god, tôi đã đi một chuyến dài, .com nói tôi tới đây, đằng ấy cho tôi biết địa chỉ IP của zzz.com được ko
aleza.cloudflare.com: Bạn tìm đúng người rồi đấy, tôi chính là name server của zzz.com đây, thực ra có một vài người giống tôi nữa cũng có thể cung cấp IP của zzz.com nữa, vd bzeta.cloudflare.com, đề phòng trường hợp 1 trong chúng tôi ko thể phục vụ. Ok giải thích thế đủ rồi, IP của zzz.com đây: 49.53.63.69
Resolver: Hả?
aleza.cloudflare.com: IP của zzz.com đấy gì nữa 49.53.63.69
Resolver: Oh, thanks(Hí hoáy note).
Resolver: Phùuuu, về nhà thôi

--- Tại Homie computer---
OS: Did you finish? Resolver. Tôi đợi ông hơi lâu rồi đấy (5ms)
Resolver: Hi OS, Câu trả lời đây, IP của zzz.com là 49.53.63.69
OS: Được ấy nhể, nói chuyện sau nhé, tôi giải quyết công việc đã.
OS: Hey Browser, đây là IP của zzz.com, làm gì làm đi.
Browser: Ồ, thanks. Finally!

Connecting...to 49.53.63.69
49.53.63.69: Sure, here your website.
Human:  (Cuộn chuột, click, click...)

Kết 

Qúa trình phân giải từ Domain sang IP có thể tóm tắt bằng sơ đồ sau.


Hi vọng với hành trình và câu chuyện của các nhân vật giả tưởng trên đây có thể giúp các bạn hiểu thêm về nguyên lý hoạt động của IP, Domain và DNS.
Thanks for watching!

Thứ Hai, 8 tháng 5, 2023

Thay đổi cấu hình ứng dụng web(Angular/ Reactjs) bằng biến môi trường mà không cần rebuild

Mở đầu

   Process triển khai phổ biến hiện nay của các  Single Page Application (SPA) hiện nay là Code => Build => Package => Deploy. Trong đó Build phase sẽ biên dịch code từ frame work thành code HTML, CSS, JS  mà trình duyệt có thể hiểu được. Package phase đóng gói code đã được biên dịch vào một Web server image(Nginx, Apache) và sau đó Deploy phase sẽ triển khai Image lên các Container Engine Platform(Docker, K8S, Aws ECS, Sun Spinner...).
    Trong phase Build , build command với tham số biến môi trường, các file config chứa biến môi trường tương ứng sẽ được biên dịch cùng với source code. Cách làm truyền thống này đáp ứng được hầu hết các yêu cầu trong quá trình phát triển nhưng vẫn tồn tại một số hạn chế:
  • Tiêu tốn thời gian build không cần thiết: Do mỗi môi trường yêu cầu một phase build khác nhau mặc dù Source code sau khi biên dịch không có gì khác nhau ngoài các biến môi trường. Trên thực tế các dự án mình đã trải qua, quá trình build production của ứng dụng Angular mất khoảng 15 phút, thời gian build của react js thậm chí còn lên tới 30 phút hoặc hơn nữa. Thời gian build có thể thay đổi phụ thuộc khối  lượng source code và cách optimize, nhưng rõ ràng những con số trên đáng để cân nhắc một giải pháp tối ưu hơn cho thời gian triển khai CICD. 
  • Không đủ linh hoạt cho các bài toán Cloud solution, dynamic config: Các bài toán về ứng dụng cloud, multi tenant sẽ không khả thi nếu Source code sau khi build chỉ có thể làm việc với một bộ configuration duy nhất
  • Vấn đề Security: Do dữ liệu cấu hình là một phần của source code, Mỗi thành viên đều có thể truy cập config của tất cả các môi trường, dẫn đến rủi ro về bảo mật và vận hành .

Các ứng dụng backend cũng gặp vấn đề này nhưng được giải quyết đơn giản bằng native Environment của phía server, các biến môi trường có thể được inject qua phase Package nên một source code có thể làm việc với nhiều cấu hình khác nhau.

Cách giải quyết

Vậy giải pháp sẽ là phải làm sao để một bộ source code sau khi build có thể được inject các biến môi trường khác nhau tương tự như cách ứng dụng backend hoạt động. Sau đây là cách giải quyết vấn đề, nguyên lý chung này có thể áp dụng cho các web framework và ngôn ngữ khác nhau.
  1. Chuẩn bị giải pháp cho phép ứng dụng đọc cấu hình từ một nguồn độc lập với source code(File, API)
  2. Chỉnh sửa code của ứng dụng để thay thế các biến môi trường từ nguồn trên
  3. Đảm bảo Cấu hình được load xong trước tiên, làm nguồn cho các render chức năng, giao diện về sau

Thực hành với Angular

Mặc định các file config tồn tại trong thư mục src/environments/ với format environment.<env name>.ts và chỉ dẫn build được đặt trong file angular.json. Với lệnh ng build --configuration=production Angular CLI sẽ thay thế file environment.ts bằng file environmen.prod.ts theo chỉ dẫn fileReplacement 

Và các file logic code sẽ import và sử dụng biến môi trường từ file environment.ts.
Ta sẽ bỏ qua các cài đặt mặc định của Angular để thực hiện giải pháp theo các nguyên lý đã nêu ở trên.
  1. Tạo một file cấu hình JSON có các key giống với file environment.ts trong src folder. Ví dụ env.json

  2. Cấu hình location của file env.json vào phần assets trong angular.json để webpack giữ nguyên file này như một file assets
  3. Tạo một service để đọc cấu hình từ file env.json, lưu ý vị trí tương đối của Service này với file env.json

  4. Đảm bảo dữ liệu config được load đầu tiên khi khởi động ứng dụng
  5. Kết quả 


Vậy là ứng dụng đã đọc được nội dung từ một file hoặc từ một API độc lập. Nhưng từ từ đã, đến đây đã đạt được dự định ban đầu chưa, ta chưa thấy cách inject được giá trị configuration khác. Trên thực tế, sau khi tách file cấu hình ra khỏi phase Build là đã có thể giải quyết được vấn đề. Sau đây là một vài cách để thực hiện việc inject giá trị config.
  1. Inject value vào file env.json trong phase Package của quá trình CICD(thay thế giá trị của file này)
  2. Sử dụng API để lấy cấu hình từ phía backend không cần ghi đè file: Sử dụng API với các param đặc trưng cho phía client như IP, location, hostname... để làm parameter cho việc lấy cấu hình. Ví dụ một api với param /env?hostname=localhost:4200 sẽ trả về env với apiEndpoint là localhost:3000, hostname có thể lấy qua biến window.location  của trình duyệt.
  3. Khi triển khai ứng dụng bằng các Container Engine Platform: các Engine này có hỗ trợ tính năng mount volume, ta chỉ cần cấu hình mount các file chứa biến môi trường tương ứng từ hệ thống quản lý biến môi trường của Container Engine thay thế vào vị trí file env.json bên trong container chứa source code.
Đọc thêm: 

Kết

    Với các thay đổi theo hướng dẫn ở trên, có thể triển khai ứng dụng web với các biến môi trường khác nhau gần như ngay lập tức, các sửa đổi biến môi trường cũng được apply gần như real time. 
    Tham khảo Sunteco Cloud để có thêm nhiều giải pháp cho hệ thống của bạn.

Thứ Năm, 9 tháng 3, 2023

Microservice thực chiến - API as a service P1 - Project requirement and system architect

Mở đầu 

        Hi các bạn, sau khi bài viết trước nhận được khá nhiều sự quan tâm, mình quyết định sẽ tiếp tục việc chia sẻ trải nghiệm của mình với microservice cũng như mong muốn nhận được những góp ý từ phía mọi người. Nếu như bài viết trước cắt ngang vào việc chuyển đổi từ monolith sang microservice thì từ bài viết này mình sẽ bắt đầu một series về xây dựng các dự án từ mức độ ý tưởng/ requirement, thiết kế kiến trúc, coding và deploy xoay quanh kiến trúc micorservice, từ đó nhìn nhận các khó khăn trong quá trình phát triển dự án với kiến trúc microservice và hướng khắc phục. Các dự án có thể là các project cũ bản thân đã từng trải qua trong quá trình làm việc, các business phổ biến trên thị trường, hoặc nếu các bạn muốn mình làm về chủ đề nào thì để lại requirement dưới comment. 

Project Requirement



    Ban đầu ý tưởng của mình là làm một trang thương mại điện tử trên nền microservice, nhưng nghĩ lại thì để full flow với hệ sinh thái đầy đủ từ warehouse, product, order, khuyến mãi, shiping, accounting, shop, supplier ... sẽ là hơi over cho một sự bắt đầu. Vậy nên sau đó mình nghĩ sẽ làm một ứng dụng đơn giản hơn chút. Business của mình sẽ là application dạng API as a service - Cung cấp dịch vụ qua API. Để dễ hiểu hơn thì các bạn có thể thấy các dịch vụ của google dành cho nhà phát triển có rất nhiều dịch vụ dạng API as a service, ví dụ như các dịch vụ về bản đồ, notification, verify phone number. 
    Mô hình kinh doanh của ứng dụng đã có rồi, vậy sẽ phục vụ nhu cầu gì của thị trường bây giờ? Vài năm trước có một người em nhờ mình tư vấn về giải pháp xác định đơn vị hành chính(phường/ xã, quận/ huyện, tỉnh/ thành phố ) dựa trên input là location(longtitude, latitude). Use case ở đây là các thiết bị có hỗ trợ GPS sẽ gửi location về máy chủ, từ đó máy chủ cần detect  được location theo đơn vị hành chính để thực hiện các business tiếp theo. Ví dụ:
- Các thiết bị thông minh/IoT có kết nối wifi/GPS cần gửi các thông số thiết bị về máy chủ để hỗ trợ quá trình chăm sóc khách hàng, bảo hành. Đi kèm với các thông số là data về location, xác định được đơn vị hành chính mới có thể phân phối thông tin đến các bộ phận cskn, bảo hành ở đúng khu vực một cách tự động
- Các doanh nghiệp logistic cũng cần một mapping từ các văn phòng/ kho hàng của họ đến các địa điểm lấy hàng của khách đề điều chuyển resource một cách hợp lý.

Vậy là đã xác định được core business của dự án, cùng điểm qua một số specification:
  • Business cung cấp khả năng xác định đơn vị hành chính(xã/phường- quận/huyện - tỉnh/ thành phố) từ vị trí GPS(*)
  • Mô hình kinh doanh API as a service, khách hàng sẽ trả phí để để có một lượng request nhất định
  • Hệ thống đo được lượng request của khách để giới hạn nếu đã hết quota
  • Dịch vụ có khả năng tích hợp API vào hệ thống của khách hàng.
(*)Trong series bài viết này mình không đi sâu vào phần core function của sản phẩm mà trập trung vào cách triển khai và sự liên kết giữa các phần trong dự án. Phần core function của dự án mình sẽ lướt qua nhé, coi như đã có giải pháp cho phần đó rồi :))

Research

    Cùng lượn qua thị trường một chút trước khi bắt tay vào việc, đợt có làm cái dự án về công nghệ bản đồ nên mình cũng có hiểu biết chút về mảng này. Một vài bên có dịch vụ tương tự mình định làm là Google Map và Mapbox, sang bên đó tham khảo xem dịch vụ họ đang cung cấp như thế nào.

Google Map services


                                                                     Mapbox services

     Về cơ bản thì dịch vụ mình định làm khá giống geocoding của Google và Mapbox. Dịch vụ của họ support convert từ Geo location sang địa chỉ dạng text hoặc ngược lại

Đánh giá dùng thử dịch vụ

    Dữ liệu của google sát hơn với requirement mà mình vừa đề ra ở trên, có các trường dữ liệu rõ ràng phân chia theo level của đơn vị hành chính(level 1 - n). Nhưng vẫn có những nhược điểm như:
- Request 1 điểm mà kết quả dữ liệu trả về 1 mảng,
- Mỗi kết quả trong mảng lại có các level về đơn vị hành chính không đồng nhất(có kết quả có phường-quận- thành phố, nhưng cũng có những kết quả chỉ có quận- thành phố...)
- Không có loại đơn vị hành chính mà chỉ có level
- Giới hạn request free trial rất thấp cho khu vực Việt Nam(3-4 request/day)


Pricing

Pricing của mỗi bên, khảo sát qua tí để đưa ra mức giá phù hợp :))
    Google geocoding pricing

Mapbox geocoding pricing

Brainstorming

    Từ các spec chính đã nêu ở trên, cùng đi chi tiết hơn một chút. Nhìn từ góc độ khách hàng và hệ thống  để xem mỗi bên sẽ ứng xử như thế nào để yêu cầu và đáp ứng được dịch vụ.
  • Khách hàng tiếp cận dịch vụ như thế nào?
  • Làm sao để dùng thử được dịch vụ trước khi quyết định mua hàng?
  • Làm sao để giới hạn số lượng request của khách.
  • Làm sao để khách hàng trên toàn thế giới có thể thanh toán tiền cho hệ thống?
  • Trang portal của khách sẽ có những tính năng gì?
User flows:
  • User sử dụng thử chức năng geo location to administrative location trên trang example
  • User đăng ký tài khoản và verify account.
  • User xem hướng dẫn sử dụng dịch vụ
  • User tạo api key
  • User tích hợp API vào hệ thống
  • User nhận được mail báo lượng request usage và thanh toán cho hệ thống
System flow:
  • Hệ thống đếm và lưu lại số lần request của khách hàng
  • Hệ thống verify request của khách hàng
  • Hệ thống xử lý request và trả về kết quả
  • Hệ thống tính lượng request của khách để đưa ra bill thanh toán theo chu kỳ
  • Hệ thống gửi mail thanh toán đến email của khách hàng
  • Hệ thống theo dõi tình trạng hóa đơn của khách hàng để đưa ra quyết định
    Phần feature sẽ có thể rất rộng, ở đây mình chỉ hình dung các flow chính để thiết kế hệ thống cho phù hợp.

System architect

    Vậy là đã tạm đủ dữ liệu để hình dung ra bước tranh tổng thể của dự án này rồi. Giờ là lúc lên kiến trúc cho dự án

Logical




Microservices responsibility

  • Admin site:  Trang quản trị hệ thống
  • Client site: Trang portal chính mà khách hàng sẽ tương tác
  • Backend gateway: Gateway cho hệ thống backend phía sau
  • User authentication: Service xác thực định danh của khách hàng 
  • Billing service: Service thực hiện việc thanh toán, các nghiệp vụ liên quan đến charge tiền khách hàng,
  • CRM service: Quản lý khách hàng, Subscription, Controller chính của hệ thống backend
  • Report service: Chứa log, phân tích số liệu request của hệ khách hàng
  • Geo service: Core service thực hiện các functional liên quan đến geo-location
  • Integration API gateway: Gateway cho Geo-service, vì đặc trưng của hệ thống là API as a service nên phải có gateway riêng cho các API dịch vụ expose ra cho khách hàng sử dụng
  • API key authentication: Service riêng authenticate các API dịch vụ và trigger request event để limit số lượng request của khách hàng
  • Message queue: Hệ thống microservice không thể thiếu được thành phần này, đóng vai trò là kênh giao tiếp bất đồng bộ và xử lý các nghiệp vụ bắt buộc dùng queue
  • Notification: Các chức năng liên quan đến gửi thông báo, email...
    Một product đưa ra kinh doanh còn phải kể đến các trang static content như branding site, documentation site, nhưng vì không giao tiếp trực tiếp với các thành phần còn lại nên mình sẽ không đề cập.

Tech stack

    Architect bao gồm các thành phần Frontend, Backend, Message Queue, API Gateway, Database. Các bạn có thể lựa chọn stack phù hợp với bản thân:
  • Backend Services: Java Spring
  • Frontend: Angular
  • Message queue: Kafka
  • API gateway: Spring gateway
  • Database: Mysql
    Database nên triển khai theo mô hình Database per service, lúc đầu có thể thấy phiền phức vì nhiều DB phải maintain, nhưng sẽ không gặp phải tình trạng bottle neck nếu một service nào đó sử dụng nhiều tài nguyên database, chưa kể đến khả năng phát triển độc lập các service, security.

Kết

   Project này thể hiện được một phần các thành phần của kiến trúc micorservice, với project khác có thể triển khai kết hợp với nhiều stack, concept hơn nữa. Các service  cũng có thể được tách nhỏ hơn nữa tùy điều kiện.
    Bài viết sau mình sẽ triển khai break chi tiết một vài requirement để làm story và đưa vào triển khai trên phạm vi team.

Powered by Sunteco Cloud
    

API as a service P1 - Project requirement and system architect
API as a service P2 - Break story and development strategy
API as a service P3 - Setup environment and develop flow
API as a service P4 - Coding
API as a service P5 - Các vấn đề thường gặp khi triển khai microservice
API as a service P6 - Release production

Maturity Model - Biết mình đang ở đâu và đích đến tiếp theo

Maturity Model - Biết mình đang ở đâu và đích đến tiếp theo Maturity Model là gì? Đoạn dẫn: Maturity Model (mô hình trưởng thành) là một các...