Twitter đã deploy widgets JavaScript của họ như thế nào
Bài đăng này đã không được cập nhật trong 3 năm
Bài viết này được dịch từ nguồn https://blog.twitter.com/engineering mà mình mới đọc, để mô tả một công việc tưởng chừng như đơn giản mà lại không hề dễ chút nào.
Deploy là 1 công việc khó và dễ làm nản lòng bất kỳ người nào phải làm nó. Rất nhiều bugs có thể xuất hiện trong quá trình deploy, nhất là khi bạn có một số lượng lớn các dòng code thay đổi. Đặc biệt hơn nữa là khi với mỗi phiên bản release được deploy sẽ tới tay hàng triệu người dùng, mũi tên đã bắn không bao giờ quay trở lại (orz), bạn cứ tưởng tượng xem sẽ tồi tệ thế nào nếu sản phẩm có bug bị hàng triệu người dùng phàn nàn 1 lúc =)) Dưới đây là câu chuyện về việc Twitter đã làm thế nào để công việc deploy diễn ra một cách an toàn và dễ dàng.
Các nhà xuất bản web, người viết blog (gọi chung là Publishers) sử dụng 1 file JavaScript, widgets.js
, để nhúng nội dung Twitter vào website của họ. Link file: https://platform.twitter.com/widgets.js cùng hướng dẫn sử dụng tại đây.
Chẳng hạn ta có thể nhúng vào website nội dung twitter của ai đó:
Dù chỉ dùng 1 file Javascript widgets.js
này nhưng lại có thể nhúng Tweets, Timelines, và Tweet buttons, một công việc quá đơn giản và dễ dàng để các web publishers có thể tích hợp ** Twitter widgets** vào website của họ. Cùng với đó, để cải thiện chất lượng dịch vụ, chúng tôi cập nhật code cho file widgets.js
hàng tuần để fix bug, thêm tính năng mới mà không làm ảnh hưởng cũng như yêu cầu các publishers phải làm thêm bất cứ công việc nào để nhận được các update mới này.
Nhưng để đảm bảo người sử dụng không mất công mà vẫn làm mọi việc đơn giản, thì công việc của nhà cung cấp sẽ trở nên phức tạp. Cụ thể, khi nhìn vào đường dẫn https://platform.twitter.com/widgets.js chắc hẳn chúng ta cũng đoán được phần nào việc phải làm. Bạn cần deploy:
- 1 file duy nhất
- Unversioned (Không có kiểu v1, v2, hoặc các mã hash phức tạp kèm theo)
- Well-known
Để các publishers có thể tin tưởng mà sử dụng trên website của họ. Theo như ước tính, widgets.js
code được thực thi khoảng 300.000 lần mỗi giây trôi qua, bởi hơn một tỷ người truy cập mỗi tháng. Điều này làm chúng tôi hiểu rằng: đây là một trách nhiệm lớn đối với chúng tôi và đó là lý do tại sao gần đây chúng tôi đã đầu tư nâng cấp quá trình deploy widgets.js
để bắt bug sớm, đồng thời tránh các ảnh hưởng xấu tới người dùng.
A safe deploy
Chúng tôi bắt đầu project này bằng mối liên kết giữa những tiêu chuẩn deploy lý tưởng. Cụ thể, chúng tôi xác định 3 tính chất của một safe deploy mà chúng tôi đang theo đuổi:
- Reversibility (Tính thuận nghịch): ‘Rollback first, debug later’ là phương châm của chúng tôi. Rollback cần phải nhanh, dễ dàng và đơn giản. Lý tưởng nhất là một button màu đỏ khổng lồ làm giảm nhịp tim của chúng ta xuống mỗi lần deploy
- Icremental release (Cộng dồn phát hành): Tất cả các đoạn code có bugs và deloy cũng có 1 cách tương ứng để đối mặt với điều đó. Đó là lý do tại sao chúng tôi cần khả năng release các đoạn code mới hơn trong giai đoạn này.
- Visibility (Tính minh bạch): Chúng tôi cần phải có 1 đồ thị để hiển thị xem cả hai phiên bản của
widgets.js
đang thực hiện gì ở tất cả các thời điểm. Hơn nữa chúng tôi cũng cần khả năng đi sâu vào theo quốc gia, loại trình duyệt, loại widget. Đồ thì này phải là real time để chúng ta có thể nhanh chóng biết quá trình deploy đang đi tới đâu và có hành động nếu cần thiết.
Đây là những mục tiêu chúng tôi đặt ra cho mình. Bây giờ, chúng ta hãy đi sâu vào chi tiết về cách chúng tôi thực hiện chúng.
How the deploy works
Bởi vì widgets.js
là một well-known asset (Một tập tin được biết tới bởi nhiều người dùng: platform.twitter.com/widgets.js), nó không chứa version trong tên file, do đó việc kiểm soát tiến độ deploy của nó trở nên khó khăn hơn. Cách chúng tôi đã quyết định để kiểm soát việc phát hành một phiên bản mới của file này là kiểm soát domain của chúng tôi, platform.twitter.com được phân giải ở DNS level. Bằng cách này, chúng ta có thể thiết lập quy tắc để phân giải các file vào một trong hai phiên bản mới hoặc cũ, trong quá trình deploy.
Deploy architecture
Để thực hiện kiểm soát như DNS nêu trên, chúng tôi đã phải cấu hình ba thành phần:
- DNS Management service (Dịch vụ quản lý DNS): Đây là một service cho phép chúng ta kiểm soát cách platform.twitter.com được phân giải đến một địa chỉ IP. Chúng tôi sử dụng các khu vực địa lý (geographic regions) để kiểm soát việc triển khai, dựa trên ba nguyên tắc sau đây, tương ứng với mỗi giai đoạn của quá trình deploy:
- Giai đoạn 1: 5% traffic (lưu lượng truy cập) từ khu vực A nhận IP2 và những người khác nhận IP1.
- Giai đoạn 2: 100% traffic từ khu vực A nhận IP2 và những người khác nhận IP1. Lặp lại cho các khu vực lớn hơn.
- Giai đoạn 3: 100% traffic đều nhận được IP2. Điều này bao gồm cả TOR traffic và bất kỳ requests nào mà chúng tôi không thể xác định được nó tới từ khu vực địa lý nào.
- CDN (Content Delivery Network): Đây là một service giúp phân phối tài nguyên tĩnh (static assets) một cách hiệu quả hơn. Chúng tôi cấu hình để nếu một request sinh ra qua IP1 nó sẽ serve các asset từ ORIGIN 1, ngược lại là ORIGIN 2 .
- Origin: Một storage service, giống như Amazon S3, nơi mà
widgets.js
được tải lên. CDN sẽ yêu cầu origin trả lại phiên bản mới nhất củawidgets.js
phục vụ cho các tác vụ xử lý.
Trạng thái mặc định là tất cả các request được xử lý bởi các asset từ ORIGIN 1. Quá trình deploy bắt đầu với việc tải lên một phiên bản mới của widgets.js
tại ORIGIN 2. Sau đó chúng tôi bắt đầu di chuyển traffic đến ORIGIN 2 bằng việc thực hiện các giai đoạn từ 1-3, như mô tả ở trên. Nếu deploy thành công, chúng tôi lại copy assets từ ORIGIN 2 sang ORIGIN 1 và reset toàn bộ traffic thành ORIGIN 1.
Scoring the new deploy process
Mục tiêu của chúng ta là có 1 safe deploy, vì thế chúng ta cần đánh giá những gì chúng ta đa làm. Bằng cách có 2 origins, chúng tôi đã có thể rollback tức thời – Một rollback ở đây là di chuyển toàn bộ traffic quay trở lại về ORIGIN 1, nơi chúng tôi có version trước đó của file widgets.js
. Geography-based deploy (Deploy dựa trên khu vực địa lý) đã cho chúng tôi một cách để từng bước triển khai một phiên bản mới và chỉ tiếp tục thực hiện nếu nó là an toàn để làm. Cuối cùng, sử dụng client code logs (chương trình lưu lại log) ghi lại các phiên bản phát hành, vì vậy chúng tôi đã có thể xây dựng các đồ thị thời gian thực (real-time graphs) thể hiện với chúng tôi rằng việc deploy thành công hay không.
Một deploy thành công sẽ giống như sau:
Sự thay đổi traffic của version cũ và mới trong suốt quá trình deploy thành công
Chúng tôi đã sử dụng quá trình deploy này trong gần một năm nay, và phát hiện ra lỗi sớm hơn trước đó. Ví dụ, gần đây chúng tôi đã có một bug trong code của chúng tôi, mà ở đó việc lazy loaded
JavaScript file được thực hiện không chính xác, kết quả là widgets không được render hoàn toàn. Nhưng nhờ quá trình deploy này, chúng tôi nhanh chóng nhận ra tác động và đã có thể giải quyết nó trước khi nó ảnh hưởng rộng đến nhiều client.
Next steps
Chúng tôi có những ý tưởng lớn để áp dụng các cải thiện cho phiên bản kế tiếp. Một điều chúng tôi đã học được là DNS rules của chúng tôi có thể được làm tốt hơn. Chúng tôi cấu hình giai đoạn 1 là một số lượng nhỏ người dùng (5%) nhưng có thể cho chúng ta cái nhìn sâu sắc nhanh chóng về các lỗi và nguy cơ tiềm ẩn có thể xảy ra . Trong giai đoạn 2, chúng tôi muốn có một mẫu lớn người sử dụng hơn để bắt các bug tinh vi, khó nhận ra hơn. Để có thể thực hiện các giai đoạn này mà vẫn đảm bảo giữ vững mục tiêu, đòi hỏi phải có một số điều chỉnh của DNS rules, một lĩnh vực mà chúng tôi muốn đầu tư trong tương lai.
Một lĩnh vực khác chúng tôi muốn cải thiện là tổng thời gian deploy. Với rất nhiều phần phải di chuyển, thời gian deploy của chúng tôi đã tăng từ vài phút đến vài giờ, và điều này chủ yếu là bởi vì chúng ta phải chờ đợi cho tất cả các intermediate cache (cache trung gian) mất hiệu lực mỗi khí chúng tôi di chuyển traffic từ một giai đoạn sang giai đoạn khác.
Chúng tôi cũng muốn thêm số liệu hiệu suất trong tương lai, vì vậy chúng tôi có thể mở rộng release verification từ successes/failures đến những hiểu biết sâu sắc về hiệu suất hơn như render times ở các locations khác nhau trên thế giới.
Chúng tôi sử dụng các nhà cung dịch vụ CDN cũng như quản lý DNS và tất cả các cấu hình mà tôi mô tả ở đây về việc sử dụng DNS đều công khai API tại đây, bạn có thể sử dụng những kiến thức này cho việc deploy. Nhìn chung, chúng tôi cảm thấy rất hạnh phúc với việc những gì mà quá trình deploy mới đã làm được cho chúng tôi ngày hôm nay vì nó đã khuyến khích chúng tôi cập nhật thường xuyên hơn widget trong khi vẫn giữ những điều đơn giản nhất tới các nhà xuất bản (publishers).
All rights reserved