simple, bit: nhỏ xinh, cho những giấc mơ dài
webservice
4
C/C++
6
White

dungcoi viết ngày 25/10/2015

simplehttp à một source viết bởi bitly : https://github.com/bitly/simplehttp
Như các bạn thấy các từ simple, bit : đơn giản và nhỏ bé thôi, đừng to tát, đừng vĩ mô, mình sợ :fearful:

bitly là một dịch vụ rút gọn URL nổi tiếng, bit- nhỏ, rất nhỏ. Tương tự Microsoft, micro: nhỏ, siêu nhỏ. Mình rất thích cách đặt tên này, nho nhỏ và dễ thương :heart_eyes:
simplehttp : Một http server cơ bản, được xây dựng trên nền của thư viện đã rất quen thuộc với những ai làm về network programming: libevent
Trên nền tảng là simplehttp, bộ source này đã xây dựng các các công cụ nhỏ, mô tả các kỹ thuật thường dùng trong web service, tất cả đều thông qua các http request.

Đây là một trong các source thú vị nhất mình từng đọc, bởi 2 điểm:

  • Rất nhiều vấn đề kỹ thuật trong bộ source này
  • Đây đều là các kỹ thuật thông dụng, sử dụng rất nhiều trong web service. Các kỹ thuật đều được giải quyết một cách căn bản nhất, rất tốt để tìm hiểu

Về bài này, mình nghĩ có thể tiếp cận theo 2 hướng:

  1. Đọc thẳng code C++, để tìm hiểu bên trong các kỹ thuật làm gì.
  2. Nếu không quen đọc, bạn nên bỏ chút thời gian tìm hiểu các keyword mình đưa ra, mình có search sẵn link cho mọi người tiện tra cứu.

Với anh em đã hiểu về các thứ này thì chắc không cần thiết .

Bài viết sẽ trình bày các thành phần quan trọng của bộ source này, đi kèm là tên kỹ thuật của thành phần sử dụng, đại diện tương tự …

simplehttp

Trên nền tảng libevent xây dựng sẵn async_simplehttp, hỗ trợ sẵn cơ chế connection pool.
Xây dựng một http web server theo cơ chế lập trình hướng sự kiện (event-driven).
Hầu hết ai lập trình network chắc chắn đều biết về socket đồng bộ (synchronous - blocking) và bất đồng bộ (asynchronous - non blocking), event-driven liên quan tới 2 thứ này nên mình sẽ nhắc lại chút.

Mình mô tả quá trình 1 socket làm việc của client và server cho dễ hình dung sự khác nhau giữa 2 loại này.

Chuyện kể rằng, có 1 thằng chủ nợ (client) và thằng con nợ (server).
Hồi 1: Chủ nợ tìm nhà con nợ: Xác định địa chỉ - hàm gethostname, và các hàm tương tự
Chủ nợ tìm cách lấy thông tin nhà thằng con nợ (IP), rồi lại phải tìm cửa vào nhà (port).

Hồi 2: Chủ nợ tới nhà: Hàm connect
Chúng ta bỏ qua các yếu tố khác như đi xe đò, xe ôm, máy bay, bơi ếch, bơi chó ... các kiểu, coi như chủ nợ dùng cách cửa thần kỳ của Doreamon tới thẳng nhà thằng con nợ. Mô tả vậy cho nhanh.

Hồi 3: Tính sổ
Chủ nợ: Trả tao tiền :triumph: -> hàm recv
Con nợ: Em hông có tiền :cry:

Giờ chủ nợ có 2 phương án lựa chọn:

  1. Ở lỳ đó, đưa cái mặt hầm hầm, tới khi nào nó trả tiền hay phá sản thì thôi: Đó gọi là socket đồng bộ synchronous. Tức là cố đấm ăn xôi, cố sống cố chết lấy được tiền về.
  2. Đi về nhà, nhưng vẫn giữ liên lạc (connect), lâu lâu lại tới nhà thằng kia hỏi lại 1 câu: “trả tao tiền”. Đó gọi là socket bất đồng bộ asynchronous. Tức là lâu lâu nhớ ra lại hỏi 1 phát, rất thong thả.

Chúng ta thấy một sự khác biệt về tinh thần của 2 bên.

Synchronous socket thường là đủ tốt cho số lượng socket nhỏ nhưng với số lớn kết nối là tắt thở, vấn đề C10K thuở xưa là tại em nó.
Kiến trúc server cho dạng synchronous là mỗi thread giữ một connection. Sẽ là thảm họa với 1 lượng vài nghìn connection cùng lúc.

Asynchronous socket đem lại cho ta giải pháp cho vấn đề này, tuy nhiên cũng như trong vụ đòi nợ, không thể ngày nào cũng phải gõ cửa hỏi nó có tiền về chưa. Nên tốt hơn là có 1 cái gì đó báo cho chúng ta biết là con nợ đã có tiền trả, sau đó chúng ta thoải mái tới lấy.
Đó chính là ý tưởng cho event-driven, một giải pháp giúp chúng ta biết connection đã xuất hiện event mà chúng ta đã đăng ký hay chưa.
Các giải pháp được cài đặt vấn đề này trong *nix: select, poll, epoll, kqueue, và trong Windows là IOCP.

Và libevent là thư viện wrapper mớ API bên trên, giúp đơn giản hóa việc dùng các API này, giúp dễ dàng cross platform. Hiện trở thành phần trong rất nhiều hệ thống lớn (và kể cả Chrome nếu bạn đang xài nó).

pubsub

Kỹ thuật Publish-subscribe.
Kỹ thuật thông dụng được sử dụng rất nhiều các web service hiện đại, nhất là với các chức năng realtime như:

  • notifier facebook
  • chat room ...
  • message queue cũng là một giải pháp sử dụng kỹ thuật này

Ngoài ra còn hỗ trợ chức năng xem stat connection hiện tại.
Trong bộ source còn 2 thành phần sử dụng pubsub nữa là:

  • ps_to_file : chức năng nhận request rồi ghi xuống file, rất hay để lưu log hệ thống
  • ps_to_http : tương đương chức năng một proxy thu nhỏ, dùng cơ chế connection pool

profiler_stats

Thống kê các hàm, service trong hệ thống làm việc, dùng để quản lý hiệu suất, kiểm soát các vấn đề phát sinh trong làm việc của các service, hàm ... cái này rất quan trọng trong hệ thống lớn

simplequeue

Kỹ thuật message queue
Là thành phần message queue server, một thành phần quan trọng trong các hệ thống service đòi hỏi phân tán và ổn định, các công việc sẽ giải quyết một cách bất đồng bộ, thông qua các worker.
Hỗ trợ đầy đủ get, put, multi_get, multi_put, dump data
Các đại diện cho kỹ thuật:

  • gearman
  • ZeroMQ
  • RabbitMQ
  • Kafka

queuereader

Thành phần client trong message queue mà bên trên đã đề cập.
Liên lạc qua json. Chức năng là một worker lấy job về thực hiện, rồi trả lại kết quả cho phía server.
Hỗ trợ chức năng khi push job trở lại khi thực hiện thất bại
Cấu trúc dữ liệu lưu trữ job gọn, hỗ trợ đủ trường dữ liệu để hỗ trợ: retry, expired time

  • data : job data
  • tries : số lần thử thực hiện
  • retry_on : lần cuối thực hiện
  • started : job create time

simpledb

Các thành phần simpleattributes, simpleleveldb, simplememdb, simpletokyo, sortdb
Quản lý các tác vụ cơ bản với các nền tảng NoSQL thông qua http request: tokyodb, leveldb.
Đáng chú ý là sortdb : một key/value db only read, siêu nhỏ tự chế.

Vấn đề đồng bộ hóa dữ liệu trong simplehttp

Vấn đề đồng bộ hóa dữ liệu để liên lạc giữa các ngôn ngữ, service khác nhau (cụ thể trong simplehttp là vấn đề liên lạc giữa client với server), giữa các thành phần gọi là data serialization formats.
Các đại diện tiêu biểu cho kỹ thuật này:

  • thrift
  • protobuff

Trong simplehttp sử dụng giao thức http, với data được đóng gói trên json. Điều này giúp có thể dễ dàng code các client từ các ngôn ngữ khác mà không cần wrapper (lên lib viết bằng C) hay parse protocol.

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

dungcoi

4 bài viết.
99 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
50 14
HTTP/1 Năm 1989, Tim BernersLee phát minh ra HTTP. Năm 1996, HTTP 1.0 được tổ chức RFC thông qua trở thành một chuẩn, HTTP 1.1 cũng hình thành cùn...
dungcoi viết gần 3 năm trước
50 14
White
20 4
Trong note này bạn sẽ thấy sự xuất hiện các node.js , socket.io, redis ... hay đủ thứ khác, nhưng nội dung của note chỉ luẩn quẩn quanh khái niệm s...
dungcoi viết hơn 2 năm trước
20 4
White
15 2
(Link) là một phần mềm load balancing thông dụng được phát triển trên ngôn ngữ C, có tốc độ xử lý và độ ổn định rất cao, các lý do thì hầu hết đã đ...
dungcoi viết gần 3 năm trước
15 2
Bài viết liên quan
Male avatar
11 6
P/s: Tài liệu này được mình viết bằng Japanese Version cách đây 6 tháng nên có 1 số hình ảnh có lẽ là chưa giống với hiện tại nhưng mà mình cũng ng...
Chu Chu viết gần 3 năm trước
11 6
White
8 2
Khái niệm macro và ví dụ Macro một cái tên nghe khá hổ báo, được dùng để chỉ những hàm được viết ở phần Preprocessor, thay vì đặt nó vào trong phầ...
Võ Phi Hùng viết gần 3 năm trước
8 2
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
4 bài viết.
99 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!