Thực thi javascript trên máy chủ IIS

từtăngngăn xếp . Được dịch với sự cho phép của người giữ bản quyền.

Trong chương này, tôi sẽ hướng dẫn bạn cách khởi động một máy chủ HTTP đơn giản trong Node.js và bắt đầu xử lý các yêu cầu.

mô-đun http cho máy chủ Node.js của bạn

Khi bạn bắt đầu xây dựng các ứng dụng HTTP trong Node.js, các mô-đun http/https tích hợp sẵn là những gì bạn sẽ tương tác.

Hãy tạo máy chủ HTTP đầu tiên của bạn bằng Node.js! Chúng tôi sẽ cần kết nối mô-đun http và liên kết máy chủ của chúng tôi với cổng 3000.

// nội dung index.js
const http = yêu cầu ("http")
cổng const = 3000 const requestHandler = (yêu cầu, phản hồi) => (
console.log(request.url)
reply.end("Xin chào máy chủ Node.js!")
) const server = http.createServer(requestHandler) server.listen(port, (err) => (
nếu (err) (

})

Sau đó chúng tôi chạy tập lệnh này:

$nodeindex.js

Những điều cần lưu ý ở đây:

  • requestHandler: Hàm này sẽ được gọi mỗi khi có yêu cầu đến máy chủ. Nếu bạn mở localhost:3000 trong trình duyệt của mình, hai thông báo sẽ xuất hiện trong bảng điều khiển: một cho / và một cho favicon.ico .
  • if (err): xử lý lỗi: nếu cổng đã bận hoặc có một số lý do khác khiến máy chủ không thể khởi động được, chúng ta sẽ nhận được thông báo về việc này.

Mô-đun http có mức độ cực kỳ thấp: việc tạo một ứng dụng web phức tạp bằng đoạn mã trên tốn rất nhiều công sức. Chính vì lý do này mà chúng tôi thường chọn các framework để thực hiện các dự án của mình. Có rất nhiều framework, đây là những framework phổ biến nhất:

  • thể hiện
  • hapi
  • koa
  • phục hồi

Trong chương này và các chương tiếp theo, chúng ta sẽ sử dụng Express, vì đó là thứ bạn có thể tìm thấy rất nhiều mô-đun trong NPM.

Thể hiện

Khung web tối giản, linh hoạt, nhanh chóng dành cho Node.js —http://expressjs.com/

Thêm Express vào dự án của bạn là một cài đặt đơn giản thông qua NPM:

$ npm cài đặt nhanh --save

Khi bạn đã cài đặt Express, hãy xem cách tạo một ứng dụng tương tự như những gì chúng tôi đã viết trước đó:


ứng dụng const = express()
cổng const = 3000 app.get('/', (yêu cầu, phản hồi) => (
reply.send("Xin chào từ Express!")
)) app.listen(port, (err) => (
nếu (err) (
return console.log("có chuyện gì đó không ổn đã xảy ra", err)
) console.log(`máy chủ đang lắng nghe trên $(port)`)
})

Sự khác biệt lớn nhất mà bạn có thể nhận thấy ở đây là Express cung cấp cho bạn bộ định tuyến theo mặc định. Bạn không cần phải phân tích cú pháp URL theo cách thủ công để quyết định việc cần làm, thay vào đó, bạn xác định định tuyến của ứng dụng bằng app.get , app.post , app.put, v.v. và những điều này đã được dịch sang các yêu cầu HTTP thích hợp.

Một trong những khái niệm mạnh mẽ nhất mà Express triển khai là mẫu Middleware.

Middleware — bộ xử lý trung gian

Bạn có thể coi phần mềm trung gian như các đường dẫn Unix, nhưng dành cho các yêu cầu HTTP.

Trong sơ đồ, bạn có thể thấy yêu cầu được thực hiện như thế nào trong ứng dụng Express có điều kiện. Nó đi qua ba bộ xử lý trung gian. Mỗi trình xử lý có thể sửa đổi yêu cầu này và sau đó, dựa trên logic nghiệp vụ của bạn, phần mềm trung gian thứ ba sẽ gửi phản hồi hoặc yêu cầu sẽ chuyển đến trình xử lý tuyến đường tương ứng.

Trong thực tế bạn có thể làm điều đó như thế này:

Const express = require("express")
const app = express() app.use((request, reply, next) => (
console.log(request.headers)
Kế tiếp()
)) app.use((request, reply, next) => (
request.chance = Math.random()
Kế tiếp()
)) app.get("/", (yêu cầu, phản hồi) => (
phản hồi.json((
cơ hội: yêu cầu.cơ hội
})
)) ứng dụng.listen(3000)

Những điều cần lưu ý ở đây:

  • app.use: Đây là cách bạn có thể mô tả phần mềm trung gian. Phương thức này nhận một hàm có ba tham số, tham số đầu tiên là yêu cầu, tham số thứ hai là phản hồi và tham số thứ ba là lệnh gọi lại tiếp theo. Gọi các tín hiệu tiếp theo Thể hiện rằng nó có thể chuyển sang phần mềm trung gian tiếp theo.
  • Phần mềm trung gian đầu tiên chỉ ghi lại các tiêu đề và gọi ngay phần tiếp theo.
  • Cái thứ hai thêm thuộc tính bổ sung vào yêu cầu — đây là một trong những tính năng mạnh mẽ nhất của mẫu phần mềm trung gian. Phần mềm trung gian của bạn có thể thêm dữ liệu bổ sung vào đối tượng yêu cầu. Phần mềm trung gian bên dưới có thể đọc/sửa đổi dữ liệu này.

Xử lý lỗi

Như với tất cả các khung công tác, việc xử lý lỗi thích hợp là rất quan trọng. Trong Express, bạn phải tạo một phần mềm trung gian đặc biệt với bốn tham số đầu vào:

Const express = require('express')
const app = express() app.get('/', (yêu cầu, phản hồi) => (
ném Lỗi mới ('oops')
)) app.use((err, request, reply, next) => (
// ghi lại lỗi, bây giờ chỉ console.log
console.log(err)
reply.status(500).send('Đã xảy ra sự cố!')
)) ứng dụng.listen(3000)

Những điều cần lưu ý ở đây:

  • Trình xử lý lỗi phải là chức năng cuối cùngđược thêm bằng app.use .
  • Trình xử lý lỗi chấp nhận cuộc gọi lại tiếp theo. Nó có thể được sử dụng để kết hợp nhiều trình xử lý lỗi.

Kết xuất HTML

Trước đây, chúng ta đã xem xét cách gửi phản hồi JSON. Đã đến lúc tìm hiểu cách hiển thị HTML một cách đơn giản. Để làm điều này, chúng ta sẽ sử dụng gói tay lái với trình bao bọc tay lái nhanh.

Đầu tiên, hãy tạo cấu trúc thư mục sau:

├──index.js
└──lượt xem
├──home.hbs
└── bố cục
└── main.hbs

Sau đó, điền vào index.js đoạn mã sau:

//index.js
const path = require("path")
const express = require("express")
const exphbs = require("tay lái nhanh")
const app = express() app.engine(".hbs", exphbs((
defaultLayout: "chính",
tên mở rộng: ".hbs",
bố cụcDir: path.join(__dirname, "lượt xem/bố cục")
}))
app.set("xem công cụ", ".hbs")
app.set("lượt xem", path.join(__dirname, "lượt xem"))
ứng dụng.listen(3000)

Đoạn mã trên khởi tạo công cụ điều khiển và đặt thư mục mẫu thành lượt xem/bố cục. Đây là thư mục nơi các mẫu của bạn sẽ được lưu trữ.

Sau khi hoàn tất thiết lập này, bạn có thể đặt html ban đầu của mình vào main.hbs . Để làm cho mọi việc dễ dàng hơn, hãy đi thẳng vào vấn đề:



Tay lái tốc hành


(((thân hình)))

Bạn có thể nhận thấy nhãn (((body))) — nội dung của bạn sẽ được đăng ở đây. Hãy tạo home.hbs!

Xin chào ((tên))

Điều cuối cùng chúng ta cần làm để thực hiện tất cả điều này là thêm trình xử lý tuyến đường vào ứng dụng Express của chúng ta:

App.get("/", (yêu cầu, phản hồi) => (
reply.render("home", (
tên: "John"
})
})

Phương thức kết xuất có hai tham số:

  • Đầu tiên là tên mẫu.
  • Thứ hai là dữ liệu cần thiết để hiển thị.

Khi bạn thực hiện yêu cầu đến địa chỉ này, bạn sẽ nhận được một cái gì đó như thế này:



Tay lái tốc hành


chào John



Đây chỉ là đỉnh của tảng băng trôi. Để tìm hiểu cách thêm nhiều mẫu hơn (và thậm chí cả một phần), vui lòng tham khảo tài liệu chính thức về tay lái nhanh.

Gỡ lỗi nhanh

Trong một số trường hợp, bạn có thể cần tìm hiểu điều gì đang xảy ra với Express trong khi ứng dụng đang chạy. Để thực hiện việc này, bạn có thể chuyển biến môi trường sau sang Express: DEBUG=express* .

Bạn nên khởi động máy chủ HTTP Node.js của mình bằng cách sử dụng:

$ DEBUG=express* nút index.js

Bản tóm tắt

Đây là cách bạn có thể thiết lập máy chủ HTTP Node.js đầu tiên của mình từ đầu. Tôi khuyên bạn nên bắt đầu với Express và sau đó thử nghiệm.

Hình 2.1 Kiến trúc của môi trường ứng dụng client-server trong JavaScript

Ba lớp là:

  • Máy khách WWW (chẳng hạn như máy khách Netscape Navigator): Lớp này cung cấp cho ứng dụng giao diện người dùng cuối đa nền tảng. Lớp này cũng có thể chứa một số logic ứng dụng, chẳng hạn như các quy tắc xác thực dữ liệu được triển khai trong JavaScript phía máy khách. Khách hàng có thể ở bên trong hoặc bên ngoài proxy mạng công ty.
  • Máy chủ Netscape WWW/máy khách DB: Lớp này bao gồm một máy chủ Netscape có kích hoạt JavaScript. Nó chứa logic ứng dụng, xử lý bảo mật và kiểm soát quyền truy cập vào ứng dụng cho nhiều người dùng bằng cách sử dụng JavaScript phía máy chủ. Lớp này cho phép các máy khách cả trong và ngoài phạm vi của proxy truy cập vào ứng dụng. Máy chủ WWW cũng hoạt động như một máy khách với bất kỳ máy chủ đã cài đặtĐB.
  • Máy chủ cơ sở dữ liệu: Lớp này bao gồm các máy chủ cơ sở dữ liệu SQL, thường chạy trên các máy trạm hiệu suất cao. Nó chứa mọi thứ dữ liệu cơ sở dữ liệu, siêu dữ liệu và các quy tắc toàn vẹn tham chiếu cần thiết để ứng dụng hoạt động. Lớp này thường nằm trong tầm phủ của máy chủ proxy mạng công ty và có thể cung cấp lớp bảo mật ngoài lớp bảo mật của máy chủ WWW. Netscape Enterprise Server hỗ trợ sử dụng các máy chủ cơ sở dữ liệu: ODBC, DB2, Informix, Oracle và Sybase. Netscape FastTrack Server chỉ hỗ trợ ODBC. Để biết thêm thông tin về Dịch vụ cơ sở dữ liệu LiveWire, hãy xem Phần 3, "Dịch vụ cơ sở dữ liệu LiveWire".

Môi trường máy khách JavaScript chạy như một phần của máy khách WWW và môi trường máy chủ JavaScript chạy như một phần của máy chủ web Netscape có quyền truy cập vào một hoặc nhiều máy chủ cơ sở dữ liệu. trình bày chi tiết hơn về cách khung máy chủ JavaScript và các ứng dụng được xây dựng cho nó được tích hợp vào máy chủ web Netscape.

Yêu cầu hệ thống

Phát triển Ứng dụng JavaScript, tận dụng cả JavaScript phía máy khách và phía máy chủ, bạn cần có môi trường phù hợp để phát triển và xuất bản. Nói chung, nên phát triển ứng dụng trên một hệ thống tách biệt với máy chủ xuất bản vì việc phát triển tiêu tốn nhiều tài nguyên (cổng kết nối, băng thông, thời gian CPU và bộ nhớ). Quá trình phát triển cũng có thể làm gián đoạn các ứng dụng của người dùng cuối đã được xuất bản.

Môi trường phát triển JavaScript bao gồm:

  • Tiện íchđể ủy quyền và biên dịch các ứng dụng JavaScript. Những tiện ích này thường nằm trên máy của nhà phát triển.
  • Máy phát triển có máy chủ webđể chạy các ứng dụng JavaScript đang được phát triển.
  • Máy xuất bản với máy chủ webđể xuất bản các ứng dụng đã phát triển. Người dùng cuối truy cập các ứng dụng nằm trên máy chủ này.

Tiện ích cần thiết:

  • Một trình duyệt có thể chạy JavaScript, chẳng hạn như Netscape Navigator, đi kèm với Netscape Communicator.
  • Trình biên dịch ứng dụng JavaScript, chẳng hạn như trình biên dịch máy chủ web Netscape.
  • Một trình soạn thảo như Emacs hoặc Notepad.

Máy xuất bản và xuất bản yêu cầu phần mềm sau:

  • Máy chủ web;
  • Các công cụ thực thi JavaScript, chẳng hạn như công cụ máy chủ web Netscape.
  • Khả năng định cấu hình máy chủ của bạn để chạy các ứng dụng JavaScript, như được thực hiện trong Trình quản lý ứng dụng JavaScript đi kèm với máy chủ web Netscape.

Ngoài ra, nếu ứng dụng của bạn sử dụng Dịch vụ cơ sở dữ liệu JavaScript LiveWire, bạn sẽ cần:

  • Chương trình này là một máy chủ cơ sở dữ liệu quan hệ trên máy chủ cơ sở dữ liệu của bạn. Xem tài liệu máy chủ cơ sở dữ liệu của bạn. Trong một số trường hợp, bạn sẽ cần cài đặt máy chủ web và máy chủ cơ sở dữ liệu trên cùng một máy. Để biết các yêu cầu cụ thể về JavaScript phía máy chủ, hãy xem Chương 10, "Cấu hình cơ sở dữ liệu".
  • Cơ sở dữ liệu máy khách và phần mềm mạng trên máy chủ web của bạn. Nếu bạn đang sử dụng cùng một máy làm cả máy chủ cơ sở dữ liệu và máy chủ web thì phần mềm máy khách cơ sở dữ liệu thông thường thường đã được cài đặt sẵn khi bạn cài đặt máy chủ cơ sở dữ liệu. Mặt khác, bạn cần đảm bảo rằng máy khách cơ sở dữ liệu được cài đặt trên cùng một máy với máy chủ web để bạn có thể truy cập cơ sở dữ liệu với tư cách máy khách. Đối với các yêu cầu phần mềm máy khách, hãy xem tài liệu bổ sung từ nhà cung cấp cơ sở dữ liệu.

Thông tin cấu hình

Phần này bao gồm thông tin cấu hình để sử dụng JavaScript phía máy chủ. Để biết thêm thông tin về cách thiết lập cơ sở dữ liệu để hoạt động với Dịch vụ cơ sở dữ liệu LiveWire, hãy xem Chương 10, “Cấu hình cơ sở dữ liệu”.

Kết nối máy chủ JavaScript

Để chạy các ứng dụng JavaScript trên máy chủ của mình, bạn phải bật công cụ thực thi JavaScript trong Trình quản lý máy chủ bằng cách nhấp vào Chương trình rồi chọn JavaScript máy chủ. Sau khi xuất hiện dấu nhắc "Kích hoạt môi trường ứng dụng JavaScript" chọn Có và nhấp vào OK. Bạn cũng sẽ được hỏi về việc hạn chế quyền truy cập vào Trình quản lý ứng dụng. Để biết thêm chi tiết xem

GHI CHÚ: Nếu bạn không kích hoạt công cụ thực thi JavaScript, các ứng dụng JavaScript sẽ không thể chạy trên máy chủ này.

Để sử dụng cả servlet và LiveWire, bạn cần bật JavaScript phía máy chủ trước khi kết nối Java. Cả hai đều có thể được kích hoạt thông qua menu chương trình của Máy chủ quản trị. Nếu bạn sửa đổi đường dẫn lớp trong obj.conf, các thay đổi của bạn sẽ bị mất nếu bạn bật/tắt JavaScript hoặc Java phía máy chủ từ menu chương trình của Máy chủ quản trị. Một cách khác để chỉnh sửa chỉ thị đường dẫn lớp trong obj.conf là đặt biến môi trường CLASSPATH trên Unix hoặc đặt biến CLASSPATH trong cài đặt Hệ thống trên Windows NT. Nếu bạn cần chỉnh sửa trực tiếp obj.conf, hãy lưu tệp gốc để đề phòng. Trong Enterprise Server 4.0, bạn phải thêm thông tin CLASSPATH vào các tệp cấu hình JVM (jvm12.conf cho Solaris và NT) thông qua giao diện Máy chủ quản trị doanh nghiệp.

Sau khi kích hoạt môi trường ứng dụng JavaScript, bạn phải dừng và khởi động lại máy chủ web của mình để các biến môi trường liên quan có hiệu lực. Nếu bạn không làm điều này, các ứng dụng JavaScript sử dụng Dịch vụ cơ sở dữ liệu LiveWire sẽ không hoạt động.

Bảo vệ Trình quản lý ứng dụng

Trình quản lý ứng dụng cung cấp quyền kiểm soát các ứng dụng JavaScript. Do khả năng đặc biệt của nó, bạn phải bảo vệ nó khỏi sự truy cập trái phép. Nếu bạn không hạn chế quyền truy cập vào Trình quản lý ứng dụng, bất kỳ ai cũng có thể thêm, xóa, thay đổi, khởi động và dừng ứng dụng trên máy chủ của bạn.

Bạn (nhà phát triển ứng dụng JavaScript) phải có quyền truy cập để sử dụng Trình quản lý ứng dụng trên máy chủ của nhà phát triển vì bạn sử dụng nó để làm việc với ứng dụng trong quá trình phát triển. Tuy nhiên, quản trị viên máy chủ web của bạn có thể không cấp cho bạn các quyền đó trên máy chủ của nhà phát triển. .

Nếu bạn bật công cụ thực thi JavaScript trong Trình quản lý Máy chủ, lời nhắc sẽ hỏi bạn có hạn chế quyền truy cập vào Trình quản lý Ứng dụng hay không. Chọn Có và nhấp vào OK. (Có là mặc định.) Bất kỳ ai cố gắng truy cập Trình quản lý ứng dụng sau đó sẽ được yêu cầu nhập tên người dùng và mật khẩu Trình quản lý máy chủ để có thể sử dụng Trình quản lý ứng dụng và ứng dụng mẫu dbadmin. Để biết thêm thông tin, hãy xem hướng dẫn dành cho quản trị viên dành cho máy chủ web của bạn.

Nếu máy chủ của bạn không sử dụng Lớp cổng bảo mật (SSL), tên người dùng và mật khẩu Trình quản lý ứng dụng sẽ được gửi không được mã hóa qua mạng. Bằng cách chặn dữ liệu này, bạn có thể có quyền truy cập vào Trình quản lý ứng dụng. Nếu bạn sử dụng cùng một mật khẩu cho máy chủ quản trị của mình, tin tặc cũng sẽ giành được quyền kiểm soát máy chủ đó. Do đó, bạn không nên sử dụng Trình quản lý ứng dụng bên ngoài proxy trừ khi bạn đang sử dụng SSL. Để biết thông tin về cách kết nối SSL với máy chủ, hãy xem hướng dẫn dành cho quản trị viên dành cho máy chủ web của bạn.

Andrey Sumin: Chào buổi chiều, tên tôi là Andrey Sumin, tôi làm việc tại Mail.Ru. Có thêm một chút thời gian nên tôi đã chuẩn bị một phần thưởng nhỏ - chỉ trong hai mươi phút còn lại. Tôi sẽ cho bạn thấy các khả năng của công cụ tạo mẫu mà chúng tôi đã tạo ra để đạt được những con số chúng tôi cần.

Trước đó, chúng tôi có một công cụ tạo mẫu hoàn toàn bằng C. Anh ấy khá độc đáo. Vì vậy, chúng tôi thực sự muốn có những thiết kế như thế này, nơi chúng tôi có thể sử dụng JavaScript.

Dưới đây bạn có thể thấy json.name biến thành gì trên máy chủ.

Tôi sẽ không tập trung vào điều này bây giờ. Trong phần chính của báo cáo, tôi sẽ nói về những gì chúng tôi biên soạn, tại sao và tại sao. Chỉ là bây giờ tôi đang đưa ra các cấu trúc cơ bản có thể được sử dụng để lấy giá trị từ hàm băm. Bạn có thể giải trí bằng cách "thoát" giá trị này.

An toàn = đúng. Dưới đây bạn có thể xem mã được biên dịch. Bằng “safe=true”, bạn có thể thấy ngay điều đó, chẳng hạn như “thử bắt” đã biến mất.

Cấu trúc mà bất kỳ công cụ tạo mẫu nào cũng cần là “nếu” và theo đó là “chọn”. Nhưng thông thường biểu mẫu “if else” được sử dụng, điều này rất cần thiết đối với nhà phát triển. Nhưng nếu bạn muốn XML hợp lệ thì thật không may, cách duy nhất là "chọn".

Đây là mã nó biên dịch thành.

Đương nhiên, các vòng lặp được sử dụng. Chúng ta sẽ ở đâu nếu không có chu kỳ? Lặp qua một mảng, lặp qua hàm băm.

Theo mặc định, công cụ tạo mẫu của chúng tôi cũng “cắt bớt” mọi thứ giữa các thẻ.

Tôi e rằng ở đây có thể có những người không quen với những điều này. Nhưng ở không gian html là một biểu tượng có ý nghĩa. Vì vậy, nên cho biết rằng bạn muốn có một không gian ở nơi này. Vâng, có những điều cụ thể như vậy.

Fest:script là cần thiết để chúng ta có thể thực thi một số mã JavaScript ngay giữa công cụ tạo mẫu.

Bây giờ tôi sẽ cố gắng thực hiện những minh chứng nhỏ để bạn có thể thấy điều này dẫn đến điều gì. Đây, tôi có sự chuẩn bị của ngày hôm qua. Đây là máy chủ HTTP thông thường trên Node.js.

(Người nói trình bày phần trình diễn.)

Nó khởi động một số máy chủ. Đây là nơi chúng tôi lấy mẫu. Đương nhiên, tôi sẽ cho bạn xem mẫu. Tôi có một số bản demo được nhận xét ở đây. Chúng ta lấy một mẫu, nó sẽ biến thành một "mẫu" hàm JavaScript. Ở đây chúng tôi sử dụng mẫu này hàng nghìn lần. Vì chủ đề chính của báo cáo của tôi là những con số nên chúng tôi quan tâm đến việc đo lường hiệu quả của nó trong một số tình huống căng thẳng. Dưới đây, theo đó, chúng tôi hiển thị kết quả cho mẫu này.

Chúng ta hãy xem xét kỹ hơn. Mẫu đầu tiên là một vòng lặp gồm mười nghìn lần lặp.

Hãy đặt nó ở đây html tốt hơn, nó sẽ thú vị hơn. Nó tạo ra một khoảng, trong đó chúng tôi xuất giá trị "xin chào" từ hàm băm của đầu vào vào mẫu và thực hiện nối với ngay hiện tại. Nối chuỗi là một hoạt động khá tốn kém. Tất cả điều này sẽ xảy ra mười ngàn lần. Ngoài ra, tôi cũng muốn cho bạn thấy rằng bản thân mẫu đó sẽ được thực thi hàng nghìn lần.

Hãy thử khởi động...

Bây giờ sẽ có những con số dựa trên Node.js. V8 được Node.js sử dụng. Chúng tôi thấy mười ngàn cách nối như vậy. Đừng lo lắng, tôi chỉ xuất những cái mới nhất ra trình duyệt, nếu không tôi sẽ gặp vấn đề về bộ nhớ trong trình duyệt. 10 nghìn phép nối được thực hiện một nghìn lần. Họ cho chúng tôi năm giây. Điều này có nghĩa là có 10 nghìn kết nối cùng một lúc và chúng tôi mất 5 mili giây trên Node.js trên máy chủ.

Chúng tôi có thể xem trình duyệt mất bao lâu (nếu chúng tôi gửi trực tiếp cùng một mẫu tới trình duyệt).

Con số hơi khác một chút. Trên thực tế, chúng ta vẫn có thể xem xét một trình duyệt khác. Chúng tôi quan tâm đến công cụ mẫu JavaScript. Nói chung, bạn đã có thể thấy điều gì sẽ xảy ra. Đây là Opera. Điều này có nghĩa là nó phải có những thứ giống nhau trên máy khách và trên máy chủ. Theo tôi, có gần một phút - 40 giây. Trong mọi trường hợp, ngay cả khi nó sẽ rất con số lớn, nó phải được chia cho một nghìn.

Của bạn đây. 39 giây. Rõ ràng, anh ấy đã dành thời gian còn lại để hiển thị trên chính trình duyệt. Ngay cả khi chúng tôi nhận được các số trong các trình duyệt khác nhau khác nhau nhiều lần (thậm chí có thể là một bậc độ lớn) - bạn vẫn tính đến việc tất cả những số này phải được chia cho một nghìn. Điều này có nghĩa là một lần truyền mất 39 mili giây.

Để tạo mẫu, chúng tôi sử dụng công cụ tạo mẫu này trên máy khách cho các dự án được sử dụng - đây có thể là phiên bản di động dự án dành cho các phiên bản Android cũ hơn và chúng tôi không gặp bất kỳ vấn đề nào về hiệu suất. Thật không may, bây giờ tôi không thể hiển thị nó trong IE vì tôi vẫn có máy Mac. Nhưng có một số sắc thái thú vị.

Chúng tôi có công cụ tạo mẫu mặc định đã bật tính năng "thoát". Điều này sẽ được thảo luận trong phần chính của báo cáo. Nếu chúng tôi biết rằng dữ liệu của chúng tôi chắc chắn không được người dùng nhập thì có thể tắt tính năng "thoát".

Hãy xem điều gì xảy ra với những con số. Bây giờ nó ở trên máy chủ. Đây là V8 trên máy chủ thông qua Node.js.

Vì vậy, rõ ràng là tôi đã phạm sai lầm ở đâu đó. Đây là "lưu đúng". Điều này không có tác dụng gì. Ồ, tất nhiên là có - máy chủ cần được khởi động lại. Tôi vẫn quen làm việc với khách hàng bằng cách nhấn Ctrl+S+F5.

Trên thực tế, đây là sự khác biệt.

"thoát html" mất rất nhiều thời gian. Tôi lấy điều này để chứng minh thứ tự của các vấn đề mà một người phải đối mặt.

Về "lưu", trong trang trình bày trước, mọi biểu thức JS mà trình thiết kế bố cục tạo ra đều được gói trong "thử bắt" theo mặc định.

Nó thực sự không đắt lắm, ít nhất là ở động cơ V8.

Không có nhiều sự khác biệt. Mặc dù, trên thực tế, "thử bắt", như bạn hiểu, có từ một nghìn đến mười nghìn. Nói chung, có rất nhiều hoạt động - 10 triệu. TRONG trình duyệt hiện đạiđiều này được thực hiện rất nhanh chóng và trong các động cơ hiện đại cũng vậy.

Nếu bạn có bất kỳ đề xuất nào về việc nên tải nó bằng gì, bạn có thể bày tỏ nó. Hãy thử. Có lẽ chúng ta thậm chí sẽ tìm thấy thứ gì đó có thể được cải thiện.

Bây giờ là cái thứ hai ví dụ thú vị, thiếu nó chúng ta không thể sống được. Nó không phải là mới. Chúng tôi đã mượn nó dưới một hình thức nào đó từ XSLT. Tôi cũng sẽ nói về điều này. Bây giờ - một cuộc biểu tình. Tuy nhiên, có lẽ ai đó sẽ đến phần đầu của báo cáo.

Chúng tôi có một mẫu riêng tạo ra một khoảng. Trong khoảng này, chúng tôi có một lệnh gọi (ở đây, tôi đã đánh dấu nó) - fest:get. Có nghĩa là hiển thị một khối có tên "word" ở nơi này. Và bên dưới là định nghĩa đây là nội dung của khối đó tương ứng và bằng từ “word”.

Đây. Chúng tôi hiển thị nội dung của khối này. Bạn có thể thấy từ mẫu rằng nó chỉ được bao gồm trong tệp này, có nghĩa là hiển thị một khoảng với khối này. Không có gì khác xảy ra vì "if" của chúng ta trả về sai (ít nhất là các điều kiện trong "if" trả về sai).

Có rõ ràng những gì đã thay đổi? Đây là một ví dụ cho thấy trên thực tế, trong trình duyệt, những mẫu giống nhau này được xử lý theo cùng một cách. Đây là tính kế thừa tương tự được tìm thấy trong tất cả các công cụ tạo mẫu hiện đại (và không quá hiện đại). Theo ý kiến ​​​​của tôi, rất gần với “Django” - nó gần giống nhau.

Tôi muốn nói rằng cú pháp XML này là “cú pháp cú pháp” dành cho các nhà thiết kế bố cục. Một số người quen với XSL của chúng tôi khi nhìn thấy cú pháp này đã bắt đầu viết nó như ngôn ngữ mẹ đẻ của họ. Nhưng điều này đã dẫn đến nhiều vấn đề. Ở đây, chúng tôi có “giá trị lễ hội” mà tôi hiển thị ở đây. Giả sử đây là - “giá trị lễ hội”.

Họ đến và hỏi liệu nó có thuộc tính “định dạng” hay không để họ có thể định dạng ngay lập tức bằng cách nào đó trong “giá trị lễ hội”. Tôi đã trả lời: “Tại thời điểm cụ thể này, hãy quên XSL đi. Bạn có JavaScript bên trong.” Bao gồm cả cú pháp tương tự này. Nó được thiết kế chỉ để đảm bảo rằng các công việc thông thường dẫn đến rất nhiều giải pháp nhanh chóng bằng tốc độ. Vì vậy, không có “chuông và còi” đặc biệt nào ở đó. Nếu có chuông và còi thì đó phải là một quyết định có ý thức nhà phát triển cụ thể. Nó phải được thể hiện bằng JavaScript.

Đây là một nhiệm vụ thú vị hơn. Giả sử chúng ta có một thư viện JavaScript... Hàm này có thể biến cách các từ. Ở đầu vào, nó nhận được một số và một mảng từ cần từ chối. Chúng tôi kết nối nó trong dòng này. Điều này có nghĩa là tại thời điểm này, JavaScript này sẽ được thực thi trên máy chủ và sẽ tạo ra chức năng này.

Chúng tôi tạo ra một loạt các từ. Đây là một mảng nhỏ sẽ xuất ra kết quả từ 0 đến 9, hàm này sẽ hoạt động như thế nào với các tham số đầu vào như vậy.

Đây là chức năng của từ bị từ chối.

Bản thân điều này không thú vị lắm, nếu không có ví dụ sau.

Bây giờ nó là một mẫu tạo html cho trình duyệt. Chú ý: đây không còn là “bao gồm lễ hội” mà là “chèn lễ hội”. Tại thời điểm này, chúng tôi chèn JavaScript này. Trình duyệt sẽ nhận nó chính xác như một chương trình JavaScript.

Ở đây chúng tôi nhận được chính xác ví dụ tương tự. Ở đây, chức năng của chúng tôi đã có trên máy khách và chúng tôi có thể sử dụng nó trên máy khách.

Phần thưởng lớn nhất mà chúng tôi đã đấu tranh là có thể sử dụng cùng các thư viện, mẫu và chương trình JavaScript trên máy khách và máy chủ. Trước đây, điều này là không thể vì nó chậm và khó hiểu. Trong trường hợp bất kỳ ai còn nhớ những lần thử đầu tiên sử dụng JavaScript trên máy chủ - theo ý kiến ​​​​của tôi, đó là một loại IDE nào đó. Jagser, tôi nghĩ nó được gọi như vậy.

Bản sao từ hội trường: Đây có phải là Aptana không?

Andrey Sumin: Vâng, Aptana. Tất nhiên, đó là một thất bại hoàn toàn. Tôi đã cố gắng một cách thành thật, tôi đã cố gắng một cách thành thật, nhưng tôi đã bỏ cuộc. Với sự ra đời của động cơ riêng biệt từ các trình duyệt khác nhau, với sự xuất hiện của sự cạnh tranh nơi họ cạnh tranh với nhau về hiệu suất, chúng tôi có khả năng sử dụng JavaScript trên máy chủ.

Bạn có thắc mắc về ví dụ của tôi?

Bản sao từ hội trường: Tôi có thể xem mã được biên dịch không?

Andrey Sumin: Đúng. Chúng ta có thể nhìn vào mã được biên dịch. Đây là mã mẫu được biên dịch. Tất nhiên, ở đây một số chức năng dịch vụ được ưu tiên hàng đầu. Như tôi đã nói, trốn thoát là cần thiết.

Ví dụ, đây là chu kỳ của chúng tôi. Vì vậy tôi đã nhấn mạnh nó. Hãy thử đưa nó lại gần hơn. Đây là cùng một lời chào + Ngày. Như tôi đã hứa, theo mặc định, chúng tôi có mọi thứ trong chế độ “thử bắt”. Vì vậy, nếu bạn bất ngờ gặp một nhà thiết kế bố cục không thực sự hiểu JavaScript, thì ít nhất anh ta sẽ không mang lại điều gì cho bạn. Thoát html - trung thực, không gian lận.

Bản sao từ hội trường: Trong nhóm của bạn có ai hiểu JavaScript không?

Andrey Sumin: Đúng. Tôi có hơn ba hoặc bốn (thậm chí có thể là năm) người trong nhóm của tôi biết cách “nấu” tập lệnh java. Họ hiểu nó là gì và cách “nấu” nó. Một mối nguy hiểm lớn hơn nhiều là "chấn thương" kiến ​​trúc của JavaScript - cái gọi là từ "var". Nếu bạn chưa khai báo, bạn sẽ gặp vấn đề. Trên máy chủ, đây thực sự là một rò rỉ bộ nhớ, vì theo mặc định, biến sẽ nằm trong danh sách chung và vẫn ở đó, ít nhất là cho đến khi ngữ cảnh được tải lại.

Nhưng chúng tôi có chế độ Thẳng, không cho phép điều này. Công cụ tạo mẫu hiện tại hoạt động với chế độ Thẳng theo mặc định. Tôi đã cố gây rò rỉ bộ nhớ - nó không hoạt động.

Hãy bắt đầu câu chuyện về việc chạy JavaScript trên máy chủ.

Tại sao điều này là cần thiết?

Đương nhiên, câu hỏi đầu tiên nảy sinh khi chúng ta nói về JavaScript trên máy chủ là câu hỏi “tại sao?”. Tôi đã lập trình rất nhiều bằng JavaScript, tôi rất thích nó. Nhưng điều này là không đủ. Chúng ta vẫn cần phải bận rộn.

Ở các công ty lớn (tôi đã làm việc ở một số công ty lớn) có đặc điểm như vậy. Chúng tôi có rất nhiều nhà phát triển phụ trợ mạnh mẽ. Họ biết cách viết mã và biết nhiều về máy chủ. Do đó, hãy để họ viết một công cụ tạo mẫu cho các nhà thiết kế bố cục (trừ khi họ cần sử dụng một công cụ đặc biệt). Điều này gây ra rất nhiều vấn đề. Những nhà phát triển này có vấn đề riêng, ông chủ riêng của họ, họ cần phải làm gì đó. Khi họ đến gặp họ với những yêu cầu như “chúng ta hãy hoàn thành việc gì đó đi, chúng ta đang thiếu thứ gì đó”, tôi thực sự không thích điều đó.

Đồng thời, có một tính năng thứ hai đặc biệt phù hợp hiện nay. Có rất nhiều người biết JavaScript. Cụ thể là tôi có rất nhiều người biết đến JavaScript. Và công cụ tạo mẫu hiện tại của tôi ở dạng C, nhưng tôi không có một người nào dưới quyền của tôi biết C.

Tất nhiên, như tôi đã nói, việc tạo khuôn mẫu được thực hiện trên máy khách. Chúng tôi đã nghĩ về tất cả những điều này, bắt đầu với dự án “Thư”. Dự án Thư không thể thực hiện nếu không có mẫu ở phía máy chủ vì cần phải bắt đầu nhanh. Các đối thủ không ngủ. Không thể thực hiện được nếu không tạo khuôn mẫu ở phía máy khách, vì Ajax được sử dụng nên mọi thứ ở đây cũng phải nhanh. Người dùng phải hài lòng vì rất dễ chuyển sang đối thủ cạnh tranh.

Đồng thời, chúng tôi đã gặp phải tình huống là chúng tôi tạo khuôn mẫu trên máy khách và tạo khuôn mẫu trên máy chủ, logic giống nhau nhưng các mẫu thì khác nhau. Sao chép mã, rất nhiều vấn đề. Không rõ phải làm gì về nó. Thực sự có rất nhiều sai sót.

Chúng tôi đã muốn gì?

Như tôi đã nói, ngoài JavaScript, tôi còn viết rất nhiều bằng XSL. Đây cũng là một công cụ tạo mẫu rất tốt, có lẽ là mạnh mẽ nhất. Nhưng cũng không phải không có “chấn thương khi sinh”. Mặc dù một số khả năng của nó là cần thiết.

Ngoài ra, nếu chúng ta có XSL, một trong những nhược điểm của nó là nó không có bất kỳ loại ngôn ngữ hoàn chỉnh về mặt thuật toán nào được tích hợp trong đó. Khi chúng ta muốn sắp xếp lại mảng ở đó, đây vẫn là một vấn đề có thể giải quyết được. Nhưng khi chúng tôi muốn đến đó “thường xuyên” thì trong XSL thì đó thực sự là địa ngục.

Vì vậy, chúng tôi muốn điều tốt nhất của hai điều này?

Đây là ví dụ tôi đã chỉ cho bạn, nó rất giống với "Django". Chúng tôi tuyên bố một số khối. Ở đây chúng ta có "tiêu đề". Nội dung của nó được xác định ngay lập tức - đó là “Mail.ru”. Nếu chúng tôi kết nối mẫu này như trên trang, thì chúng tôi sẽ hiển thị “tiêu đề” với tiêu đề “Mail.ru”. Tất cả các dự án trên Mail.ru đều có thể kết nối nó và có một tiêu đề duy nhất.

Nhưng chúng tôi có dự án “Thư”. Đương nhiên, chúng tôi muốn mọi thứ giống như trong các dự án khác, chỉ có tiêu đề là khác. Đừng viết một mẫu khác vì điều này! Tôi chỉ muốn xác định lại một phần của nó.

Bản thân JavaScript.

Chúng tôi thực sự muốn có thể làm việc với dữ liệu đầu vào bằng ngôn ngữ hoàn chỉnh về mặt thuật toán. Có một cách xây dựng như "kịch bản lễ hội". Bạn có thể làm điều gì đó cụ thể trong đó bằng JavaScript và bên dưới, thông qua “giá trị lễ hội”, trên thực tế, bạn có thể hiểu được điều đó.

Mẫu này sẽ hiển thị trong Mail.ru.

Bản thân công cụ mẫu.

Trên thực tế, chúng tôi đã tranh luận rất nhiều về cú pháp XML. Cú pháp XML là dư thừa - thật ngu ngốc khi tranh luận với điều đó. Tuy nhiên, nhiệm vụ chính của chúng tôi là tìm hiểu cách “nấu” JavaScript trên máy chủ. Vì vậy, tôi không muốn giải quyết đồng thời các vấn đề “hãy nghĩ ra cú pháp trong đó”, “hãy nghĩ ra cách thoát trong đó”, “hãy viết tất cả các loại plugin cho IDE trong đó”. Tôi không muốn giải quyết chuyện này. Do đó, chúng tôi đã sử dụng XML và đưa ra sự hỗ trợ ngắn gọn cho IDE.

Bất kỳ IDE tự trọng nào cũng sẽ cho bạn biết mà không cần bất kỳ cài đặt nào rằng XML của bạn không hợp lệ. Và tính hợp lệ của các mẫu XML tự động cung cấp cho chúng tôi tính hợp lệ của html đầu ra. Đây là xác nhận ra khỏi hộp.

Ngoài ra, tất cả các IDE đều có tính năng đánh dấu và lập bảng tự động. Tôi không muốn làm phiền.

XML cũng có cái này theo mặc định một điêu tôt, giống như không gian tên. Đây là khả năng mở rộng.

Chúng tôi có một công cụ tạo mẫu nhưng nó không thể làm được gì nhiều. Bạn có những dự án thực tế. Đột nhiên bạn cần đa ngôn ngữ. Việc “may” nó vào mẫu lễ hội mặc định có phần kỳ lạ. Nó sẽ "sưng lên" và trở nên không thể chịu đựng được. Và nếu bạn khai báo không gian tên của dự án, thì bạn có thể “chặn” sự kiện này trong trình biên dịch và xử lý nó theo cách riêng của bạn. Giả sử bạn có thể có các không gian tên cụ thể và Mail.ru.

Qua nhiều năm, chúng tôi đã có rất nhiều công cụ để làm việc với XML. Khi tôi biên dịch từ mẫu lễ hội sang XML, tôi có nhiều lựa chọn về những gì sẽ sử dụng. Do đó, tôi đã sử dụng trình phân tích cú pháp SAX, nhưng thực tế không phải là tôi sẽ dừng ở đó.

Chuyển đổi XML sang XML

Một lần nữa, tôi đã đề cập rằng chuỗi đầu ra của chúng tôi không đơn giản lắm. XML là một ngôn ngữ khá lỏng lẻo. Vì vậy, tôi thực sự không muốn tham gia vào việc “bỏ trốn”. Khi bạn có các cấu trúc điều khiển giống như trong XSL, gần như tất cả các vấn đề "thoát" của bạn đều biến mất. Ngoài ra còn có những thứ bổ sung như CDATA cho phép bạn “thoát”.

Thực hiện

Khi chúng tôi quyết định mẫu sẽ trông như thế nào (chúng tôi đã hiểu đại khái những gì chúng tôi cần cho băng ghế thử nghiệm, để nó bắt đầu hoạt động), chúng tôi bắt đầu triển khai chính trình biên dịch XML thành JavaScript.

Đây là một trải nghiệm lập trình cặp khá bất thường đối với tôi. Tôi thậm chí còn chắc chắn rằng lập trình cặp cho kết quả rất tốt, tốt hơn nhiều so với lập trình đơn lẻ.

Nhưng cụ thể về vấn đề này thì điều ngược lại đã xảy ra. Chúng tôi lấy mẫu, hiểu kết quả mà chúng tôi mong muốn và bắt đầu biên dịch. Tôi đã làm phiên bản của mình và Kostya đã làm phiên bản của anh ấy. Chúng tôi gặp nhau mỗi tuần một lần và nói một cách đại khái là đo lường các con số. Đúng là con số của anh ấy luôn nhanh hơn một chút.

Cấu trúc và chức năng

Chúng tôi đã chọn hai về nguyên tắc phương pháp tiếp cận khác nhau. Tôi quyết định biên dịch XML thành một cấu trúc. Và Kostya đã biên dịch nó thành một hàm. Lúc đầu, nó có vẻ không an toàn lắm đối với tôi.

Để bạn hiểu, việc biên dịch thành một cấu trúc giống như mảng này.

Băm có nghĩa là một hành động và các chuỗi có thể được xuất trực tiếp đến máy khách hoặc có thể thực hiện điều gì đó với chúng.

Để làm rõ. Giá trị băm đầu tiên - "action">template" có nghĩa là mẫu bắt đầu. Bạn không cần phải làm gì với dòng thứ hai; nó có thể được xuất trực tiếp tới máy khách. Dòng thứ ba có nghĩa là dòng thứ tư phải được chuyển qua giá trị, và kết quả giá trịđã mang nó đến cho khách hàng.

Hoặc, ví dụ (có thể sẽ rõ ràng hơn), hãy xem xét tùy chọn với “nếu”.

Dòng đầu tiên và dòng thứ hai giống như trên slide trước. Dòng thứ ba có nghĩa là biểu thức sau phải được thực thi. Nếu nó đúng, thì theo đó, bạn cần xuất ra "true". Nếu sai thì kết quả sẽ là "false".

Trên thực tế, điều này được lấy cảm hứng từ một kỹ thuật khá nổi tiếng được sử dụng trong hầu hết các máy tính - đây là ký hiệu người dùng đảo ngược. Tôi muốn chơi với cô ấy bằng cách nào đó, nhưng tất cả những điều này hóa ra là không cần thiết. Các mẫu thực sự hóa ra đơn giản hơn nhiều.

Mọi thứ đều rõ ràng với việc triển khai thành một hàm. Chỉ là, do một số điều kiện, biến ban đầu, được đặt thành một chuỗi trống, bắt đầu được nối.

Đây là kết quả mà chúng tôi mong muốn.

Đây là một trong những dự án chính của chúng tôi. Đương nhiên, khi nghĩ về một công cụ tạo mẫu, tôi phải nghĩ đến dự án này. Một danh sách các chữ cái có đủ số lượng thư mục.

Thành thật mà nói: lần triển khai đầu tiên tôi thực hiện đã giải quyết được vấn đề này trong 200 mili giây.

Theo tôi, Kostya và tôi đã đối đầu nhau trong một tháng hoặc một tháng rưỡi. Họ đến sau cuối tuần và một người nói: "Và tôi có 180!" Người thứ hai trả lời: “Và tôi có 150!” Vân vân và vân vân. Trên thực tế, có lúc tôi đã bỏ cuộc vì nhận ra rằng mình sẽ không thể theo kịp. Chúng tôi bắt đầu triển khai một hàm và nó đã thành công. Cuối cùng, khi chúng tôi “liếm” mọi thứ đến cùng, chúng tôi phải mất 3 mili giây để hoàn thành nhiệm vụ này.

Danh sách các chữ cái được rút ra trong 3 mili giây. Việc chuyển đổi giống như thế này, nó càng gần với các cấu trúc JavaScript đơn giản nhất càng tốt. "For" - thành "for", "if" - thành "if". Chọn là "if() khác".

Chúng tôi đã phải vật lộn một chút với fest:set, vì tôi nhận ra rằng chúng tôi không thể tiếp tục sống nếu không có sự ghi đè này. Nó cũng không khó lắm để làm. Khi chúng ta thực thi hàm mẫu lần đầu tiên, đối tượng “set” sẽ được tạo lần đầu tiên. Khi nó đi qua các khối "bộ" XML, nó sẽ viết lại hàm, trên thực tế, hàm này xác định lại nội dung của khối này.

Do đó, nếu có nhiều "bộ", thì khi thực thi một mẫu trả về XML, chỉ bộ cuối cùng trong số chúng sẽ được thực thi chứ không phải tất cả. Điều này cũng mang lại một sự gia tăng nhỏ.

Sau đây đã cho một hiệu ứng rất thú vị. Chúng tôi không bận tâm quá nhiều với lần triển khai đầu tiên. Nhìn chung, khi nó ở mức 200 mili giây, chúng tôi không thấy điều này. Nhưng trước tiên chúng tôi đã biên dịch nó thành cấu trúc này. Chúng ta có nguồn HTML, được biên dịch đơn giản thành cách nối từng dòng một.

Khi chúng tôi đạt đến mức ba mili giây, chúng tôi đã sử dụng một dòng “thông thường” đơn giản trong mẫu đã biên dịch để thay thế những “giá trị cộng bằng” này bằng một dòng - chúng tôi thực sự đã có được một con số khá - cộng thêm 30% hiệu suất.

Hãy nói về sự an toàn một lần nữa.

Sự an toàn

Về bảo mật, ý tôi là không chỉ XSS: chúng tôi chắc chắn cần công cụ tạo mẫu để giảm thiểu nó ngay lập tức. Hơn nữa, tôi hy vọng rằng anh ấy sẽ loại chúng ra khỏi hộp. Nhưng cần phải “thử bắt” nếu đột nhiên một nhà thiết kế bố cục bất cẩn lấy đi các thuộc tính không có định nghĩa (tiếng Anh: undefined).

Do đó, theo mặc định, mọi thứ đều ở trạng thái thử bắt. Hơn nữa, theo thử nghiệm của chúng tôi, nó là “miễn phí”.

Đây là một lối thoát. Ngoài ra còn có thoát JavaScript, thoát HTML. Dữ liệu người dùng để không có quyền truy cập.

Một lần nữa, như chúng ta đã thấy, đây là hoạt động “đắt” nhất trong công cụ tạo mẫu của chúng ta.

Tất nhiên, chúng tôi sử dụng "chế độ nghiêm ngặt" để tránh rò rỉ bộ nhớ.

Nếu một nhà thiết kế bố cục đột nhiên nhìn thấy điều gì đó, anh ta sẽ ngay lập tức nhận ra trong quá trình phát triển rằng mình đã làm sai điều gì đó. Và trong quá trình sản xuất, chúng tôi sẽ bắt đầu khởi động lại máy chủ và giữa các lần khởi động lại, chúng tôi sẽ tìm hiểu điều gì đã thực sự xảy ra.

Như tôi đã nói, trình biên dịch mặc định chỉ là "thử bắt" cộng với "thoát".


Hội nhập

Chúng tôi đã có được con số như mong muốn. Hoặc, ít nhất, họ đã có được một số con số kha khá mà không có gì đáng xấu hổ.

Điểm thú vị tiếp theo. Ở công ty của chúng tôi, ít nhất chúng tôi có những ngôn ngữ này. Tôi chắc chắn còn nhiều hơn nữa. Nhưng đây là những người tôi đã gặp phải.

Đây là “C” - chúng tôi có một máy chủ HTTP ở “C” và rất nhiều logic được viết trong đó. Perl: Hầu hết thư được viết bằng Perl. Một số dự án được viết bằng Python. Chúng tôi không có Node.js trong sản xuất, nhưng chúng tôi cũng sử dụng nó trong quá trình phát triển, một cách tự nhiên, chúng tôi phải sống chung với nó.

Có vẻ như khi bổ sung thêm động cơ V8 cho loại xe này, chúng ta sẽ chỉ khiến mọi việc trở nên tồi tệ hơn. Nhưng khi trong một số dự án, chúng tôi đã thêm động cơ V8 vào tất cả các công nghệ này... Trên thực tế, việc này không khó. Cần một chiếc V8 (có một cái ở đó) API Google) đã loại bỏ ba chức năng này để ghi nhật ký.

V8 chỉ là một thư viện; bản thân nó không thể làm được gì. Đây là một thư viện lấy thứ gì đó làm đầu vào và cung cấp thứ gì đó làm đầu ra. Đương nhiên, khi điều gì đó xảy ra bên trong bạn, bạn muốn truyền đạt nó ra thế giới bên ngoài. Chính fest_log này là do công nghệ quyết định. Anh ta có thể báo cáo với bảng điều khiển hoặc trình duyệt hoặc bằng thư hoặc SMS cho quản trị viên hệ thống rằng có lỗi bên trong V8. Và V8 nhận chức năng này từ bên trong và bằng cách nào đó có thể tương tác với nó và thông qua nó với thế giới bên ngoài.

Tất nhiên, Fest_file được tạo khuôn mẫu. Nó hoạt động trên các tập tin, "bao gồm", "chèn", v.v. Vì vậy, khi V8 thu thập và biên dịch tệp, nó cần xử lý "bao gồm" và "chèn". Vì vậy, môi trường bên ngoài phải cung cấp cho V8 khả năng đọc tệp.

Dirname là một điều nhỏ nhặt. Khi bạn muốn đọc một tập tin, bạn cần một cái gì đó để dựa vào. Đây là thư mục của tệp JavaScript hiện có thể thực thi được. Ba thiết kế này đủ để động cơ V8 hoạt động.

Điều sau đây đã xảy ra. Chúng tôi có cả một kho công nghệ trên máy chủ phụ trợ của mình. Nhưng có một dự án sử dụng lễ hội trên máy chủ. Có một dự án sử dụng lễ hội trên máy khách. Có một dự án sử dụng lễ hội trên máy khách và máy chủ. Cú pháp giống nhau ở mọi nơi và các nhà thiết kế bố cục di chuyển giữa các dự án, không có vấn đề gì với điều này. Tất nhiên, chúng tôi đã tích hợp trình duyệt ngay lập tức.

Fest biên dịch thành các cấu trúc JavaScript nguyên thủy, (tôi chắc chắn) được chấp nhận ngay cả bởi Explorer 5. Rất tiếc, không có nơi nào để thử nó.

Làm việc với người dùng thực

Vì vậy, chúng tôi đã triển khai và chúng tôi vẫn muốn tiếp cận người dùng, tìm hiểu xem mọi thứ sẽ hoạt động như thế nào đối với họ. Tôi đã đến gặp Igor để trình bày việc triển khai này và nói rằng quá trình tải thử nghiệm của chúng tôi diễn ra trong vòng ba mili giây. Anh ấy trả lời: "Hãy nhảy theo ý bạn - và sau đó bằng bốn chân."

Bạn phải hiểu rằng quá trình sản xuất, ngoài việc chuyển đổi, còn cần phải thu thập một số dữ liệu khác và thực hiện công việc gì đó với nó. Và 4 mili giây là tất cả.

Nhà bếp nội bộ của chúng tôi đã được sử dụng ở đây; không chắc có ai có cái này không. Nhưng thật không may, hóa ra nó lại rất quan trọng để bỏ lỡ.

Máy chủ HTTP của chúng tôi được viết bằng C, chúng tôi gọi nó là Light. Khi nhận được dữ liệu từ máy chủ phụ trợ, nó sẽ lưu trữ dữ liệu đó dưới dạng hàm băm phẳng. Trong thực tế, đây là một lựa chọn nguyên thủy. Nó phải dễ đọc. Để đề phòng, hãy để tôi làm rõ rằng đây là danh sách các chữ cái. Dòng đầu tiên có nghĩa là độ dài của nó là năm, dòng thứ hai có nghĩa là chữ cái đầu tiên có tiêu đề là "bức thư" và dòng thứ ba có nghĩa là nó chưa được đọc.

Đương nhiên, khi nói về JavaScript, chúng ta muốn thấy V8 như thế này bên trong nó.

Bằng cách nào đó chúng ta cần đưa thứ này vào bên trong động cơ V8. Chúng tôi đã thử rất nhiều lựa chọn. Chúng tôi đã xem xét tất cả các loại Binding, PerlOuI và các giải pháp của chúng tôi - theo ý kiến ​​​​của tôi, tôi đã phải chịu đựng trong khoảng hai tuần. Đây là tùy chọn mà chúng tôi chắc chắn đã thử - đây là giải pháp cho vấn đề thông qua API V8.

Tôi đã thử, nhưng thật không may, không thể cung cấp mã bằng C. Thực sự có rất nhiều nó. Tôi sẽ cố gắng giải thích bằng lời.

Thông qua API V8, bạn có thể thực hiện điều này: nếu bạn viết JSON bằng JavaScript, tại thời điểm đó V8 sẽ truy cập mã C của bạn. Mã C tại thời điểm này có thể trả về những gì nó cho là cần thiết. Nó có thể viết JSON.name. Điều này sẽ có hai cách tiếp cận - lần đầu tiên nó sẽ truy cập JSON và lần thứ hai nó sẽ truy cập vào tên. Nó dài quá.

Tùy chọn thứ hai là JSON.parse. Khi bạn nâng cao ngữ cảnh V8, thì trong “C”, bạn thu thập một dòng giống hệt JSON. Bạn gửi nó đến ngữ cảnh và trực tiếp trong ngữ cảnh bạn phủ V8 JSON.parse lên nó ngay lập tức. Theo đó, trong ngữ cảnh bạn có một hàm băm có thể được gửi đến mẫu. Điều này hóa ra cũng chậm.

Hầu hết tùy chọn nhanh- đây chỉ là lựa chọn thứ ba. Tôi sẽ cố gắng cho bạn xem một đoạn mã C của anh ấy.

Ở đây bạn có dòng thứ hai. Đây chỉ là một mẫu. Ta hàm JavaScript, trong đó lễ hội được tổng hợp. Nó mong đợi JSON làm đầu vào. Bạn thu thập một dòng như vậy, một lệnh gọi hàm này và đối số đầu tiên và duy nhất của nó là JSON cần được sử dụng. Ra lệnh thực hiện điều đó.

Những con số không được tốt lắm. Với giới hạn bốn mili giây, hai trong số đó là sự biến đổi. Chúng tôi đo chúng một cách riêng biệt. Phải mất bốn giây để chuẩn bị dữ liệu.

Bây giờ bạn đang nhìn: có vẻ như sẽ mất khoảng bốn mili giây để chuẩn bị dữ liệu - vậy thì sao? Và đây là 67% của sự chuyển đổi.

67% thời gian của chúng tôi dành cho việc chuẩn bị dữ liệu để tạo html này. Chúng tôi có nhiệm vụ đáp ứng năng lực tương tự như hiện tại. 6 mili giây thay vì 4, gần bằng rồi. Nhưng đó vẫn là một sự xấu hổ. Trên thực tế, tại thời điểm này, chúng tôi gần như đã từ bỏ ý định đó.

Nhưng tôi vẫn tìm thấy sức mạnh để lấy hàm băm mà bạn nhớ. Tôi lấy nó ở dạng văn bản và trở về nhà. Thành thật mà nói, bây giờ tôi không nhớ mã. Nhưng tôi đến từ dạng văn bản bằng cách nào đó nó đã được Node.js chuyển thành JSON.

Tôi đến gặp Igor với những con số này và mong đợi được nghe từ anh ấy: “Tất nhiên, bạn rất tuyệt. Node.js cũng rất tuyệt. Chúng tôi sẽ không viết về Node.js nữa. Nhưng tôi nghe hoàn toàn ngược lại. Nếu điều đó có thể có trong Node.js thì tại sao chúng ta không thể sử dụng nó? Vào lúc đó tôi nhận ra rằng chúng tôi sẽ giải quyết được vấn đề này.

Chúng ta đã làm gì? Hãy quay lại dữ liệu chúng ta có trong máy chủ HTTP.

Trên thực tế, chúng tôi đã có tất cả dữ liệu trong máy chủ HTTP. Vì vậy, chúng tôi đã thực hiện thủ thuật sau. Thay vì chuyển đổi dữ liệu, V8 “chuyển tiếp” một chức năng có thể truy xuất dữ liệu này bằng một phím.

Chúng tôi ngay lập tức loại bỏ mọi chuyển đổi khiến chúng tôi mất 4 mili giây. Vẫn còn thời gian để chuyển tiếp. Nhưng hóa ra thời gian này là 1 mili giây. Với giới hạn 4 mili giây... Tôi xin nhắc bạn rằng đây là danh sách các chữ cái. Chúng tôi đã nhận được mili giây mà chúng tôi đang tìm kiếm. Người dùng thực sự được phép làm điều này. Không phải là họ đã nhìn thấy nó, nhưng tình hình là bình thường.

Chúng tôi đã lấy một trong các máy chủ và tắt tính năng cân bằng của nó. Họ đã cài đặt toàn bộ cơ sở hạ tầng ở đó, được sử dụng để vẽ danh sách các chữ cái. Chúng tôi đã "nghiên cứu" một số yêu cầu thực của người dùng thực bằng dữ liệu thực và danh sách các chữ cái thực. Họ vừa gửi dữ liệu đến máy chủ này (trùng lặp). Chúng tôi có ở đây kết quả của các bài kiểm tra tải trong 30 giờ.

Có, nhân tiện, những kết quả này được hiển thị bởi một lõi chứ không phải máy chủ, tôi muốn lưu ý. Máy chủ xử lý 10 triệu lượt truy cập trong 30 giờ. Thời gian chuyển đổi trung bình là 1,6 mili giây. Không phải là máy chủ nhanh hơn. Chỉ là người dùng thực có các cài đặt khác nhau... Chúng tôi đã thử nghiệm mọi thứ trên 25 chữ cái và ở một số nơi đơn giản là có ít người dùng thực hơn. Ví dụ, hình dưới đây chỉ cho thấy rằng nửa phần trăm thực sự vừa với mười mili giây. Tuy nhiên, rõ ràng là họ chỉ có 200 chữ cái trong phần cài đặt.

Tôi nghĩ không cần thiết phải giải thích trực tiếp những con số. Ở đây bạn có thể thấy rằng phần lớn chỉ có ít hơn hai mili giây. 90% yêu cầu có thời lượng dưới hai mili giây.

Tuy nhiên, chúng ta cần tiếp cận những người dùng thực, những người thực, để họ có thể tận mắt nhìn thấy, dù họ không quan tâm.

Khi Igor và tôi đến Ermkov với những con số chúng tôi nhận được (lúc đó anh ấy là phó giám đốc kĩ thuật), tôi nói: “Các bài kiểm tra tải đều tốt, con số tốt, nhiệm vụ là có thật. Chúng tôi muốn triển khai tính năng này trên người dùng”. Giống như bất kỳ công ty lớn nào, chúng tôi có một số dự án đang chờ xử lý. Có vẻ như bạn nên làm chúng, nhưng có vẻ như bạn không nên làm. Tôi nói: “Hãy thực hiện một trong những dự án này trên V8 tại lễ hội. Nếu có vấn đề gì xảy ra thì không sao cả, hãy quên dự án này đi giống như chúng ta đã quên. Năm ngoái. Nhưng nếu mọi việc suôn sẻ, chúng ta sẽ có được một thứ hoạt động được mà chúng ta có thể dựa vào đó.”

Igor nhìn tôi, nhìn những con số và nói: “Những con số này tốt đấy. Nhưng bạn có thực sự muốn có một chiếc V8 được sản xuất không?” Tôi nói: “Tôi muốn.” Anh ấy trả lời: “Vậy hãy bắt đầu từ trang chính, nếu không, những chiếc “nước mũi” này sẽ tiếp tục bị bôi bẩn.” Đó là một trang. Bố trí mất ba ngày. Chúng tôi lại phân bổ một trong các máy chủ ngoại vi và khởi chạy một nửa tải bình thường ở đó. Chúng tôi đã nhận được mức tiêu thụ tài nguyên bộ xử lý lớn hơn ba lần so với giao diện người dùng lân cận hiện đang hoạt động cho người dùng.

Nó trông giống như một sự thất bại hoàn toàn. Trên thực tế, chúng tôi đã phạm phải một sai lầm rất lớn (tôi sẽ chỉ cho bạn sai lầm đó sau). Nhưng điều này đã giúp chúng tôi tối ưu hóa nhiều hơn. Mọi thứ đều rất buồn, vì chúng tôi quá đắm chìm trong nhiệm vụ này đến nỗi trong đầu tôi có tất cả mã template engine. Tôi có thể sắp xếp nó trong đầu mà không cần chuyển sang IDE. Tôi không hiểu chúng tôi có thể mất nhiều thời gian như vậy ở đâu, bởi vì trong tất cả các bài kiểm tra trước đó, mọi thứ đều ổn.

Chúng tôi đã thua sáu lần so với máy chủ hiện tại.

Không phải lần đầu tiên, như họ nói. Họ bắt đầu xem. Trang chính chiếm 165 kilobyte. Trong số này, V8 tạo ra 65 kilobyte. Còn lại 100 kilobyte. Chúng tôi có công nghệ RB bên trong. Để bạn hiểu, trang chính vẫn là nơi giới thiệu các dự án khác. Vì vậy, RB là phương tiện đưa dữ liệu từ các dự án này lên trang chính. Nói chung, RB được gửi đến máy chủ HTTP ở dạng html. Không cần phải tạo mẫu cho nó. Nếu cần thiết thì RB sẽ thực hiện việc này trong nội bộ. Vì vậy điều sau đây xảy ra.

Chúng tôi có công nghệ RB. Nó “nói chuyện” với HTTP server, HTTP server trả kết quả về V8. V8 nối dữ liệu này với dữ liệu của nó và gửi lại. Thêm một lưu ý nữa cho những ai chưa đọc gì về động cơ V8. Anh ấy giữ mọi thứ bên trong mình bằng utf-16. Điều này có nghĩa là chúng tôi... Và tất nhiên, của chúng tôi là từ utf-8. Utf-8 utf-16 trở lại utf8.

Đây là mã được biên dịch ban đầu ở dạng rất đơn giản.

Chúng tôi có một số chuỗi. Kết quả công việc của RB được nối với chuỗi này, sau đó nó được nối với hàng tiếp theo V8.

Câu hỏi đặt ra: nếu chúng ta không làm gì với RB, tại sao lại đưa nó cho động cơ V8 và tiêu tốn tài nguyên cho nó? Vì vậy, chúng tôi đã thực hiện một hack nhỏ. Hai chức năng nữa đã được chuyển tiếp từ C. Đây là một chức năng đẩy. May mắn thay, trang chủ của chúng tôi rất ổn định. Vì vậy, không cần phải khổ sở với “set” và “get”.

Đừng tập trung vào điều này. Nếu ai đó tìm hiểu kỹ thì bạn sẽ hiểu điều tôi đang nói. Ở đó, sự tạo hình diễn ra liên tục, hay đúng hơn là tuyến tính. Khi mẫu đã hoàn thành một “mảnh”, chúng tôi biết chắc rằng nó có thể được trao cho người dùng.

Điều sau đây đã xảy ra với chúng tôi: thư viện V8 đã tạo một phần của chuỗi theo logic của nó và gửi trực tiếp đến máy chủ HTTP. Anh ta có thể đưa nó ngay cho khách hàng. Tiếp theo, theo logic, bạn cần đưa ra một mảnh từ RB. Chúng tôi thậm chí không có được mảnh này. Chúng tôi ngay lập tức nói với máy chủ HTTP: “Hãy lấy phần này và đưa trực tiếp cho khách hàng - chúng tôi không cần bất cứ thứ gì từ anh ấy”. Chúng tôi nhận được thêm 30%. Nhưng trên thực tế, mức lỗ vẫn gấp bốn lần.

Tôi nghi ngờ có điều gì đó không ổn. Tôi đã tải lượng truy cập này, số lần truy cập mà chúng tôi gửi đến máy chủ thử nghiệm. Tôi đã nhân nó với số lượng máy chủ mà chúng tôi hiện đã “gây dựng” và tôi nhận được số lượt truy cập này mỗi ngày.

440 000 000

Và theo tất cả các quầy TNS, chúng tôi có nhiều lượt truy cập mỗi ngày.

110 000 000

Chúng tôi bắt đầu xem xét nhật ký và phát hiện ra một điều buồn cười: đối với mỗi yêu cầu hữu ích, chúng tôi có bốn yêu cầu đưa nội dung nào đó vào nhật ký. Chúng tôi rất vui mừng vì đã có được chính xác nguồn lực mà chúng tôi cần. Hình ảnh này chứng minh điều này.

Đã có trên một máy chủ đang chạy, đôi khi chúng tôi có cơ hội chuyển đổi giữa các công cụ tạo mẫu. Biểu đồ trên cùng là bộ nhớ. Tất nhiên, bộ nhớ V8 cần nhiều hơn một chút. Lỗi bộ nhớ chỉ là việc chuyển sang công cụ tạo mẫu cũ. Biểu đồ phía dưới chỉ là một “hòn đá”. Không có thay đổi nào đối với nó. Chúng tôi đã đưa ra tất cả cho người dùng.

Bây giờ toàn bộ trang chính của Mail.ru được phục vụ thông qua V8.

V8 hiện tạo ra 65 kilobyte dữ liệu. Có lẽ hôm nay nhiều hơn một chút - tôi vẫn dành hai tuần để chuẩn bị báo cáo. Thời gian thư viện cần để tạo ra dữ liệu này là một phần nghìn giây. Cộng thêm 40 megabyte cho mỗi ngữ cảnh, tính đến số lõi trên máy chủ lên tới 8, tôi không biết hoặc 16. Về nguyên tắc, điều này không gây khó chịu lắm, không có vấn đề gì với nó.

Đó gần như là một câu chuyện thành công. Igor Sysoev có mặt ở đây. Tất nhiên, bất kỳ ai đã từng nghĩ về V8 trên máy chủ đều nên đọc bài viết của anh ấy về các vấn đề của V8.

Nếu tôi sai, tôi hy vọng anh ấy sẽ sửa tôi. Theo như tôi nhớ thì đó là nội dung của nó. Đầu tiên, ở V8, bối cảnh không được nâng lên ngay lập tức. Nếu chúng ta nói về các dự án thực tế, thì bối cảnh của chúng ta sẽ tăng lên khi ra mắt máy chủ HTTP và chỉ một lần. Quá trình này mất khoảng 2 mili giây và nói chung là điều bạn có thể chấp nhận được.

Vấn đề thứ hai. Nếu đột nhiên thư viện V8 muốn cấp phát bộ nhớ cho chính nó mà không được thì nó “bị treo” ngay lúc đó. Hiện tại khi chúng tôi đang làm việc trên công cụ tạo mẫu này với JavaScript trên máy chủ, tôi đã liên hệ được với nhà phát triển V8 - Vyacheslav Egorov. Nhân tiện, anh ấy thường biểu diễn, anh ấy là một người nổi tiếng. Bạn có thể dễ dàng tìm thấy thông tin về nó. Anh gần như đã xác nhận những suy đoán này. Anh ấy tuyên bố (thành thật mà nói, chúng tôi chưa kiểm tra) rằng trong quá trình triển khai V8 hiện tại, nếu nó không phân bổ được bộ nhớ, nó sẽ đưa ra một ngoại lệ có thể bị bắt.

Nhưng anh thành thật thừa nhận rằng ngoại lệ này chỉ có thể giúp khởi động lại toàn bộ và đúng thời hạn. Bối cảnh đã chết và không thể làm được gì với nó. Anh ấy không phản ứng với bất cứ điều gì và mọi thứ vẫn còn trong trí nhớ của anh ấy.

Đối với Nginx, rất có thể hành vi này là nghiêm trọng. Tại Mail.ru, theo một đồng nghiệp của chúng tôi, trong cùng RB, làm việc trong điều kiện bộ nhớ thấp được coi là một tình huống bình thường. Và khi việc thiếu bộ nhớ được coi là tình trạng bình thường thì rất có thể sẽ có vấn đề. Nhưng nếu chúng ta đang nói về một dự án thông thường, thì nếu máy của bạn đột nhiên hết bộ nhớ, bạn sẽ không nghĩ đến động cơ V8 mà là về những thứ hoàn toàn khác.

Một khoảnh khắc khó chịu khác.

Bài này viết về V8. Trunk V8 dường như đang được phát triển rất tích cực. Bản thân Vyacheslav đã không thể tái hiện lại tình huống này. Nhưng ở đây nó được tái tạo với một tiếng nổ. Tôi hy vọng chúng ta có thể giúp anh ấy giải quyết nó.

Tại một thời điểm nào đó, chúng tôi đã tung ra V8 và phát hiện ra rò rỉ bộ nhớ. Chúng tôi đã tìm kiếm sự rò rỉ trong một thời gian rất dài, sau đó chuyển từ trung kế sang phiên bản 3.6.8 và vấn đề đã biến mất. Thân cây có vấn đề. Phiên bản ổn định của Node.js hiện là 06.14 và nó cũng tồn tại trên 3.6. Nếu bạn đang làm việc với trunk, hãy nhớ: bạn đang làm việc với thứ gì đó không ổn định lắm. Vẫn chuyển sang phiên bản ổn định, mà các nhà phát triển chịu trách nhiệm.

Chỉ là một liên kết tới API V8 mà bạn sẽ thực sự cần nếu bạn đột nhiên quan tâm đến vấn đề này. Liên kết đến công cụ tạo mẫu của chúng tôi. Tôi không thể nói đó là OpenSource vì một lý do đơn giản. Trên thực tế, OpenSource chịu một số trách nhiệm về những gì bạn làm. Rất có thể chúng tôi sẽ tự mình gánh lấy nó, nhưng hiện tại chúng tôi chưa sẵn sàng cho việc này. Vì vậy tôi chỉ nói rằng chúng tôi chỉ đang phát triển một cách công khai.

Mọi điều tôi nói về cốp V8 đều có thể xảy ra với chúng ta. Hiện tại chúng tôi chưa ổn định được điều gì. Đây là sản phẩm do chúng tôi phát triển cho chính mình, nhưng biểu mẫu mở. Hãy nhớ rằng chúng tôi muốn xuất bản nó trên OpenSource. Nếu có bất kỳ yêu cầu nào như “yêu cầu kéo” (nhân tiện, chúng đã đến từ một số người), thì tất nhiên chúng tôi hoan nghênh sự quan tâm đó.

Đó là tất cả những gì tôi muốn nói. Tôi sẵn sàng trả lời câu hỏi của bạn.

Câu hỏi và câu trả lời

Bản sao từ hội trường: Cảm ơn đã báo cáo. Tôi có một câu hỏi. Tôi thực sự không hiểu cốt truyện tại sao phải sử dụng động cơ V8. Bạn đã có một trang web...

Andrey Sumin: Nhiều hơn một trang web.

Bản sao từ hội trường: Bạn đã có kịch bản. Các tập lệnh này trên máy chủ phụ trợ bắt đầu chậm lại. Có phải như vậy hay không?

Andrey Sumin: Không hoàn toàn không. Khi nói “trang web”, ý bạn là dự án “Mail.ru Pochta”?

Bản sao từ hội trường: Đúng.

Andrey Sumin: Có một số vấn đề chính. Đầu tiên, chúng tôi có mẫu kép. Các mẫu được sử dụng trên máy chủ không thể được sử dụng trên máy khách. Đây là vấn đề. Chúng ta phải hiển thị danh sách các chữ cái trên cả máy chủ và máy khách. Vì vậy, chúng tôi cần các mẫu có thể hoạt động ở mọi nơi. Điều cần thiết là cùng một mẫu tạo ra cùng một kết quả trên cả máy khách và máy chủ. Đây là điều kiện tiên quyết đầu tiên và quan trọng nhất để chuyển sang sử dụng động cơ V8.

Tiền đề thứ hai. Tôi có rất nhiều người trong nhóm biết JavaScript. Nhưng không có một người nào đủ trình độ để Mail.ru biết, chẳng hạn như C, Python hoặc bất cứ thứ gì tương tự. Tôi có những người có thể viết JavaScript nhanh, tốt, không bị rò rỉ bộ nhớ, v.v. Nhưng không có người có thể viết điều này bằng ngôn ngữ khác. Không phải vì về cơ bản họ không có năng lực mà vì họ không làm việc đó hàng ngày. Ngoài ra, ngoài nhu cầu về các mẫu thống nhất trên máy khách và máy chủ, chúng tôi còn cần các chuyên gia có thể thực hiện việc này. Đây là hai lý do chính.

Bản sao từ hội trường: Không, nhìn đây. Nếu tôi cần hiển thị danh sách trên máy chủ, tôi sẽ hiển thị danh sách này ở đó và gán một số mã định danh cho từng thành phần ở đó. Hoặc tôi chỉ định một lớp cho một nhóm phần tử. Tôi đang viết thư cho Tập lệnh JavaScript ai đang làm gì đó ở đó Có thể có một số sản phẩm thay thế, tôi không biết... Động cơ sử dụng không hoàn toàn rõ ràng. Tại sao lại có khuôn mẫu kép?

Andrey Sumin: Chúng tôi có một danh sách các chữ cái trên “Mail”. Nó được tổng hợp từ một số dữ liệu, nó cần được rút ra. Sau đó, chúng tôi đến gặp khách hàng và thỉnh thoảng danh sách các bức thư của chúng tôi được cập nhật (vì người đó có thể nhận được những bức thư mới). Theo đó, nó phải được kết xuất lại. Tất nhiên, nó đến với khách hàng dưới dạng dữ liệu. “Đuổi” html rất tốn thời gian. Nó có dạng một số JSON.

Ngoài ra, chúng tôi có nhiều loại tối ưu hóa khác nhau. JSON đã đến, nó cần được chuyển thành html. Điều này, một lần nữa, là khuôn mẫu. Cộng với danh sách các chữ cái. Đối với mỗi chữ cái có đủ thông tin để khi người dùng nhấp vào chữ cái đó, người dùng có thể hiển thị nội dung nào đó - ví dụ: tiêu đề của bức thư. Chúng ta có chủ đề, tác giả, chúng ta có thể hiển thị nội dung này trong khi chờ nội dung thư. Đây là một mẫu khác.

Chúng tôi có rất nhiều mẫu trên máy khách. Tất cả các loại thủ thuật như “Tôi sẽ thêm mã nhận dạng và viết mã đơn giản bằng JavaScript” thực sự không hiệu quả. Và khi một người ở trên trang có một chữ cái, anh ta có thể nhấn F5 ở đó và tại thời điểm này, chúng ta phải hiển thị chữ cái này trên máy chủ, vì cách này nhanh hơn, thật kỳ lạ.

Viết là một chủ đề phức tạp. Có rất nhiều logic mẫu ở đó. “Từ”, “Tới”, “Đọc”, “Chưa đọc”, “Quan trọng”, “Không quan trọng”. Có đầu tư, không có đầu tư. Rất nhiều thứ.

Bản sao từ hội trường: Thông thoáng. Cảm ơn.

Bản sao từ hội trường: Tôi có hai câu hỏi. Đầu tiên: tại sao bạn chọn V8. bạn đã nhìn thấy chưa Phía JavaScript từ Mozilla (SpiderMonkey, TraceMonkey)?

Andrey Sumin: Thành thật mà nói, chúng tôi đã nhìn về hướng của anh ấy. Cá nhân tôi chọn động cơ V8 hơn là vì lý do chính trị. Một công ty lớn tạo ra sản phẩm cho chính nó. Lý do là thế này. Đặc biệt, khi chúng tôi bắt đầu chạy các mẫu kết quả trên máy khách, mẫu có danh sách email “được mở rộng” trong Chrome trong 6 mili giây và trong Mozilla trong 3 mili giây. Tôi nghĩ: có lẽ đã lựa chọn sai?

Kết quả là chúng tôi vẫn đạt được 1 mili giây (để so sánh: máy chủ của chúng tôi trong Gzip dành nhiều thời gian hơn V8). Tôi quyết định gắn bó với động cơ V8 bây giờ. Có lẽ động cơ V8 vẫn sẽ đánh bại được SpiderMonkey. Mặc dù hiện tại công cụ tạo mẫu SpiderMonkey của chúng tôi nhanh hơn.

Lý do vẫn mang tính chính trị. Có tính đến thực tế là về tốc độ, chúng ta không còn nơi nào để tiến xa hơn. Các vấn đề khác bây giờ cần được giải quyết.

Bản sao từ hội trường: Câu hỏi thứ hai. Máy chủ trông như thế nào từ quan điểm kiến ​​trúc? Đây có phải là một quy trình xử lý nhiều kết nối hay không?

Andrey Sumin: Igor sẽ trả lời - anh ấy đã viết nó. Tốt hơn là nên cho anh ta quyền trả lời.

Igor Sysoev: Có, đó là một quá trình xử lý nhiều kết nối.

Bản sao từ hội trường: Rõ ràng. Bạn có Epoll Linux không?

Igor Sysoev: Đúng. Một quá trình.

Bản sao từ hội trường: Tất cả các kết nối có được xử lý trong cùng một ngữ cảnh không?

Igor Sysoev: Vâng, một bối cảnh.

Bản sao từ hội trường: Rõ ràng. Cảm ơn.

Bản sao từ hội trường: Đầu tiên, tôi có một câu hỏi về việc xác định lại các mẫu. Làm thế nào để giải quyết một vấn đề như vậy? Giả sử chúng ta có một số khối, chúng ta muốn hiển thị chính xác khối này trên một số trang và thêm nội dung khác vào đó. Thêm một số thông tin bổ sung. Xác định lại việc gọi khối cơ sở. Bạn nói bạn có JavaScript. Điều này sẽ được thể hiện như thế nào? Bạn có phải viết một đoạn chèn tập hợp vào cú pháp XML này bằng JavaScript không?

Andrey Sumin: Có một số lựa chọn. Đương nhiên, đây có thể là một phần chèn lắp ráp hoặc bạn có thể tự mình mở rộng ngôn ngữ mẫu. Nếu chúng tôi cần và không bị chậm tốc độ, chúng tôi sẽ làm điều đó, có lẽ trong công cụ tạo mẫu hiện tại. Nếu bạn cần điều này và yêu cầu tốc độ tương tự thì bạn có thể chỉ cần mở rộng cú pháp hiện tại bằng cú pháp của riêng mình. Hoặc gửi cho chúng tôi một bản vá.

Bản sao từ hội trường: Không, tất nhiên, tôi hiểu rằng những tiện ích ngữ nghĩa như vậy không được cung cấp “miễn phí” về tốc độ. Câu hỏi của tôi thì khác. Khi đó bạn có thư viện khối nào mà bạn không cần ghi đè bằng lệnh gọi phương thức cơ sở?

Andrey Sumin: Bây giờ tôi thực sự không hiểu câu hỏi.

Bản sao từ hội trường: Bạn có thư viện nào được sử dụng và có phần ghi đè trong đó không? Hoặc chỉ là mọi thứ đều được viết trên một dự án trong một lớp và không có phần ghi đè nào, do đó không cần ngữ nghĩa phong phú.

Andrey Sumin: Một dự án được viết chính xác như thế này. Hai hoặc ba dự án nữa hiện đang được viết. Ở đó chúng tôi đã suy nghĩ về những điều này. Hai hoặc ba dự án này đơn giản hơn một chút khi nói đến năng suất. Rất có thể, chúng tôi sẽ tinh chỉnh nó ở đó.

Bản sao từ hội trường: Tôi có một câu hỏi nữa. Bạn đã nói với tôi rằng thật tuyệt vời khi có những chuyên gia JavaScript giỏi. Đối với họ, tất cả điều này là rõ ràng và thuận tiện. Tại sao lại sử dụng cú pháp XML, tại sao không đưa cú pháp đó vào cú pháp JavaScript? Sau đó, chuyên gia sẽ sử dụng trình soạn thảo JavaScript “gốc” chẳng hạn. Anh ta sẽ dễ dàng đọc mã tầm thường hơn vì đó là cùng một mã. Có vẻ như chúng tôi đã thống nhất việc thực thi các mẫu này theo quan điểm của công cụ. Nhưng từ quan điểm cú pháp, ngược lại, chúng ta đã tạo ra một thực thể thứ hai.

Andrey Sumin: Thực thể đã được tạo. Nhưng có một số lý do. Đây là hệ quả của một số quyết định. Đầu tiên, tôi đề cập rằng vấn đề mà chúng tôi chắc chắn cần giải quyết là học cách “nấu” JavaScript trên máy chủ. Để giải quyết nó, tôi không muốn bị phân tâm khi nghĩ ra các cú pháp, giải quyết các vấn đề bằng cách “thoát”, v.v.

Bản sao từ hội trường: Nhưng cú pháp đã được phát minh bằng JavaScript và các vấn đề về “thoát” đã được giải quyết. Hoàn toàn giống với XML.

Andrey Sumin: Không, khi bạn tạo khuôn mẫu bằng JavaScript, dù sao thì bạn cũng sẽ phát minh ra ngôn ngữ của riêng mình.

Bản sao từ hội trường: Tại sao? Tại sao tôi lại phát minh ra một ngôn ngữ thay vì viết bằng JavaScript?

Andrey Sumin: Bởi vì nối chuỗi trong JavaScript là một công việc vô cùng bạc bẽo.

Bản sao từ hội trường: ĐƯỢC RỒI. Tôi không hiểu.

Andrey Sumin: Thứ hai. Có thể khi JavaScript trên máy chủ trở nên phổ biến trong nhiều dự án (có thể không phải cho toàn bộ dự án), ít nhất là khi nó được coi như một thông lệ, rất có thể sẽ có một công cụ tạo khuôn mẫu khác ngoài lễ hội. Nó rất có thể là như vậy. Tại sao không?

Nhưng đây là một nhiệm vụ có trật tự khác. Không cần phải giải quyết ngay bây giờ, vì còn có vấn đề quan trọng hơn.

Thứ hai. 99% kết quả đầu ra của chúng tôi là XML. Khi bạn có cấu trúc điều khiển XML và đầu ra là XML, dự án sẽ dễ dàng hơn nhiều vì người soạn thảo hiểu được XML. Họ xác thực nó và có rất nhiều công cụ để làm việc với XML. Hiện tại đây là quyết định cuối cùng. Tôi không thể nói điều gì sẽ xảy ra trong một năm nữa.

Bản sao từ hội trường: OK cảm ơn bạn. Tôi đang hoàn thiện. Vâng, theo ý kiến ​​của tôi thì điều bạn nói là đúng. Vấn đề chính là đưa JavaScript đến máy chủ và sau đó nó có thể được tối ưu hóa. Nói một cách đại khái thì đây là một bước cơ bản. Và sau đó là những cải tiến nhỏ không theo nguyên tắc có thể được thực hiện trong tương lai. Cảm ơn bạn cũng đã có trải nghiệm này.

Bản sao từ hội trường: Tôi có một câu hỏi tiếp nối một trong những câu hỏi trước - về một quy trình. Có thực sự có một quy trình mà tất cả các yêu cầu đều thực hiện không? Hay đây là một số quy trình trên các cổng khác nhau, chẳng hạn như ở đâu, thông qua thượng nguồn, Nginx truyền các yêu cầu khác nhau từ những người dùng khác nhau?

Igor Sysoev: KHÔNG. Không có Nginx. Ở đó - vâng, có một quá trình mà mọi thứ diễn ra. Trên thực tế, có nhiều nhánh trên một máy. Tất cả đều treo trên hạt nhân. Khách hàng bằng cách nào đó được cân bằng ở đó.

Bản sao từ hội trường: Rõ ràng. Cảm ơn.

Bản sao từ hội trường: Câu hỏi khác. Vài năm trước tôi cũng đã thử làm JavaScript trên máy chủ. Gỡ lỗi hoàn toàn là một địa ngục. Bạn sử dụng công cụ gỡ lỗi nào để lập hồ sơ tất cả điều này?

Andrey Sumin: Bây giờ chúng tôi có một phần thưởng rất lớn - đây là Node.js. Mọi thứ chúng tôi chạy đều có sẵn trong Node.js. Có một công cụ sửa lỗi khá tốt ở đó. Ngoài ra, nếu chúng ta đang nói về công cụ tạo mẫu, chúng ta luôn có thể gửi mẫu của mình cho khách hàng. Thậm chí còn có nhiều công cụ gỡ lỗi hơn.

Thứ ba: như tôi đã nói, có thể có một số điểm trùng lặp cụ thể với môi trường. Bạn có thể có môi trường chỉ đơn giản là “chuyển tiếp” chức năng. Chúng tôi có một chức năng “chuyển tiếp” nhật ký. Trên thực tế, nó “chuyển tiếp” “log”, “var” và “error”, và V8 có thể “giao tiếp” với thế giới bên ngoài. Môi trường sẽ xuất dữ liệu này ở đâu đó. Ngoài ra, trong API V8 có rất nhiều công cụ để làm việc với V8 thông qua API V8. Ít nhất khi nó “rơi”, thông qua API nó sẽ thông báo rằng nó “rơi”.

Bản sao từ hội trường: Cảm ơn rất nhiều.

Bản sao từ hội trường: Cám ơn vì sự quan tâm của bạn.

Andrey Sumin: Cảm ơn mọi người.

  • Dịch

Vào năm 2009, nền tảng Node.js đã bước những bước đầu tiên khiêm tốn vào thế giới phát triển phụ trợ rộng lớn. Đây là nỗ lực thành công đầu tiên trong việc sử dụng JavaScript trong các ứng dụng máy chủ. Ngày nay, thật khó để tìm được một nhà phát triển web chưa từng nghe đến Node. Nhưng không thể nói rằng sự tồn tại của Node là không có mây mù. Nền tảng này đã trải qua sự chia rẽ trong cộng đồng, trở thành chủ đề của các cuộc chiến diễn đàn và khiến nhiều người tuyệt vọng.

Bạn có thể nghĩ rằng những lời phát biểu như vậy nghe có vẻ quá khoa trương. Tuy nhiên, hãy thử tìm kiếm trên Google và bạn sẽ bắt gặp một nguồn tranh luận bất tận không bao giờ cạn. Một số lập luận chống Node mà bạn có thể gặp phải bao gồm một số lập luận rằng, trong khi đặt câu hỏi điều gì đã xảy ra với tiên đề về việc sử dụng công cụ tốt nhất hiện có để giải quyết vấn đề, hãy chỉ ra rằng JS không ở gần các công cụ giải pháp phía máy chủ phù hợp. Những lời chỉ trích về JS, chẳng hạn như “Địa ngục gọi lại là có thật”, kêu gọi niềm tin vào thực tế của địa ngục gọi lại, nghe giống như những dòng trong một bài thơ. Một số nhà phê bình của Node nói thẳng thắn hơn: "Node là một căn bệnh ung thư".

Tôi tin rằng đã đến lúc khôi phục lại tình trạng thực sự của vấn đề, chấm dứt tất cả những điều tôi liên quan đến nền tảng Node.js và JavaScript làm ngôn ngữ phát triển máy chủ. Hôm nay chúng ta sẽ nói về tình trạng hiện tại và sự phát triển của Node.js, những trường hợp sử dụng thành công nhất cho nền tảng này, những hạn chế của nó và các công nghệ được tạo ra trên nền tảng này.

Trạng thái hiện tại của Node.js với tư cách là nền tảng máy chủ

Trước khi nói về nền tảng máy chủ Node ngày nay trông như thế nào, hãy nhớ nó là gì.

Cụ thể, đây là thời gian chạy JavaScript được xây dựng trên công cụ V8 JS do Google phát triển và sử dụng trong Google Chrome. Node.js sử dụng mô hình I/O không chặn, theo hướng sự kiện, giúp nền tảng trở nên đơn giản và hiệu quả.

Ở phần đầu của tài liệu này, Node được coi là cơn ác mộng của các lập trình viên. Tuy nhiên, không phải ngẫu nhiên mà nền tảng này lại trở nên rất phổ biến. Ở đây chúng tôi sẽ không dựa vào những tuyên bố vô căn cứ. Chúng ta hãy nhìn vào sự thật tốt hơn. Cụ thể, một nghiên cứu gần đây từ Stack Overflow cho thấy Node.js hiện là công nghệ phổ biến nhất trong số các nhà phát triển.


Ngoài ra, JS là ngôn ngữ có mức độ phổ biến tăng nhanh hơn các ngôn ngữ khác trong 5 năm qua, trong khi C# và PHP đang mất dần vị thế. Sự phổ biến của JavaScript, ngay cả khi chúng ta không nói riêng về Node, vẫn đang tăng lên.


Làm cách nào chúng tôi có thể giải thích tại sao JavaScript, với tư cách là ngôn ngữ phía máy chủ, lại được cộng đồng nhà phát triển áp dụng nhanh chóng và rộng rãi như vậy? Nói một cách đơn giản, Node đã trải qua một giai đoạn được coi là vui vẻ và bước vào giai đoạn ổn định và trưởng thành. Một cộng đồng hùng mạnh đã hình thành xung quanh nó, quy mô của cộng đồng này đang tăng lên đều đặn. Hệ sinh thái Node cũng đáng được đề cập, chẳng hạn như trình quản lý gói Node, npm, Hiện nayđược đại diện bởi cơ quan đăng ký phần mềm lớn nhất trên Internet.

Node.js không chỉ cách mạng hóa việc phát triển phía máy chủ mà còn góp phần nâng cao năng suất ứng dụng khách, vì các lực lượng nghiêm túc đã tham gia vào quá trình phát triển động cơ V8. Ngoài ra, anh còn đóng vai trò nổi bật trong việc mở rộng toàn bộ hệ sinh thái JavaScript và cải thiện các framework JS hiện đại như Angular, React hay Vue.

Theo thời gian, Node đã có thể lật ngược những định kiến ​​của những ngày đầu. Dưới đây là một số trong số họ.

Mã JavaScript cho Node.js nổi tiếng là khó gỡ lỗi.

Để gỡ lỗi các ứng dụng JS phía máy chủ, bạn có thể sử dụng các kỹ thuật tương tự mà bạn sử dụng để gỡ lỗi mã phía máy khách, bằng cách sử dụng trình kiểm tra nút có chứa các công cụ Công cụ dành cho nhà phát triển Chrome.

Nút không thể được sử dụng để phát triển ứng dụng máy chủ lớp công ty.

Tuyên bố này cũng không đúng sự thật. Dựa trên Node bạn có thể tạo hệ thống công ty. Khó khăn duy nhất là nó không có nhiều công cụ tích hợp để đơn giản hóa việc tạo ra các hệ thống như vậy. Tuy nhiên, những người chơi đáng chú ý trong thị trường CNTT sử dụng Node làm nền tảng web công ty. Trong số đó có Netflix. PayPal, Yahoo!, Walmart.

JavaScript là một ngôn ngữ động, vì vậy khi làm việc với nó, bạn không thể sử dụng những thứ như kiểm tra tĩnh các loại trong quá trình biên dịch.

Điều này là đúng. Tuy nhiên, các công cụ như TypeScript và Flow đã xuất hiện trong hệ sinh thái JS, nhằm mục đích làm việc với các loại trong JS, giúp tăng tính ổn định và khả năng dự đoán của chương trình cũng như đơn giản hóa việc gỡ lỗi. Trong lĩnh vực này, bạn cũng có thể tận dụng các khả năng của Trình biên dịch đóng cửa của Google.

JavaScript không được tạo làm ngôn ngữ để phát triển phía máy chủ.

Ở đây chúng ta chỉ có thể nói rằng JS có thể đã hoạt động trên các máy chủ cùng lúc với việc Netscape xây dựng hỗ trợ cho ngôn ngữ này vào trình duyệt của nó. Và đây đã là vào năm 1995. JS thường được gọi là ngôn ngữ phát triển web phía máy khách chỉ vì nó đã hoàn toàn chiếm lĩnh lĩnh vực này.

Trong thực tế, danh sách này cứ lặp đi lặp lại.

Bây giờ hãy nói về các trường hợp sử dụng Node.js và những hạn chế của nó để hiểu rõ hơn về vị trí của công nghệ này trong thế giới hiện đại.

Kịch bản ứng dụng nút

Vậy tại sao lại coi Node.js là công cụ phát triển phía máy chủ trong kho công nghệ của bạn?

▍Ưu điểm và đặc điểm chung

Hãy để tôi tóm tắt những điều quan trọng nhất một cách ngắn gọn:
  • Rất có thể các phần phía máy khách của ứng dụng web của bạn được viết bằng JavaScript. Trong trường hợp này, tính linh hoạt của mã trong ngăn xếp công nghệ được áp dụng là một lợi thế quan trọng của việc sử dụng JS trên máy chủ, điều đáng ghi nhớ.
  • Các công cụ như webpack giúp tái sử dụng mã trên cả máy khách và máy chủ, dẫn đến tính nhất quán trên tất cả các cấp độ của hệ thống.
  • Bằng cách sử dụng JS trên máy khách và máy chủ, bạn có thể tạo các ứng dụng web có thể hiển thị trên cả trình duyệt và máy chủ. Hơn nữa, những hệ thống như vậy thường hoạt động rất rõ ràng và dễ hiểu. Tôi nghĩ điều này thật tuyệt vời.
  • Việc giới thiệu async/await trong Node đã thay đổi hoàn toàn cách tiếp cận viết mã không đồng bộ. Bây giờ mã này giống với mã đồng bộ thông thường và vẻ bề ngoài, và theo hành vi. Cơ chế async/await đã được hỗ trợ trong Node kể từ phiên bản 7.6. Đặc biệt, nó là một giải pháp cho vấn đề callback hell khét tiếng.
Một số người coi sự hội tụ của cơ sở mã máy khách và máy chủ là một nhược điểm của Node.js, cho rằng nó buộc nhà phát triển phải sử dụng JavaScript. Tuy nhiên, điều này không hoàn toàn đúng. Nếu cần, các ứng dụng Node có thể truy cập vào các thư viện chuyên biệt của bên thứ ba.

Giả sử bạn cần các công cụ mã hóa video. Để trang bị chúng cho dự án viết bằng JavaScript của bạn, bạn không cần phải tìm kiếm một số thư viện khó hiểu, bí ẩn cho Node. Bạn có thể dễ dàng tận dụng các công cụ đã được chứng minh bằng cách tương tác với chúng từ Node. Hoặc, ví dụ: nếu có một thư viện Python nào đó thực hiện những gì bạn cần tính toán phức tạp, đặc biệt để làm việc với nó, bạn có thể khởi chạy một microservice và truy cập các chức năng tương ứng của thư viện này thông qua API REST.

Xem xét tất cả những điều trên, chúng ta có thể nêu bật các trường hợp sử dụng sau của Node.js, trong đó nó bộc lộ đầy đủ các điểm mạnh của mình.

▍Kịch bản số 1. Ứng dụng thời gian thực

Ứng dụng cho sự hợp tác(chẳng hạn như Trello và Google Tài liệu), trò chuyện trực tiếp, nhắn tin tức thời và trò chơi trực tuyến là những ví dụ về ứng dụng thời gian thực có thể hưởng lợi từ kiến ​​trúc Node.js.

Theo quan điểm của người dùng, thời gian cần thiết để các ứng dụng này thực hiện một số hành động nhất định có thể được mô tả bằng các từ “ngay lập tức” và “bây giờ”. Để các ứng dụng như vậy hoạt động bình thường, hệ thống dựa trên chúng phải cung cấp rất tốc độ cao phản hồi với hành động của người dùng và độ trễ thấp. Nút đáp ứng các yêu cầu này.

Nút giúp dễ dàng xử lý nhiều yêu cầu từ máy khách, kiến ​​trúc của nó tạo điều kiện thuận lợi sử dụng hiệu quả thư viện, nó cung cấp khả năng đồng bộ hóa dữ liệu rất nhanh giữa máy khách và máy chủ.

▍Tình huống số 2. Ứng dụng trang đơn

Ứng dụng một trang là một ứng dụng được thể hiện bằng một trang web duy nhất tải vào trình duyệt, nội dung của trang web này được cập nhật động khi người dùng tương tác với nó. Phần lớn tải khi chạy các ứng dụng như vậy rơi vào phần máy khách của hệ thống, được viết bằng JavaScript.

Mặc dù các ứng dụng trang đơn là một bước quan trọng trong quá trình phát triển web nhưng chúng cũng có những vấn đề, chẳng hạn như kết xuất. Đặc biệt, điều này có thể ảnh hưởng xấu đến việc tối ưu hóa công cụ tìm kiếm trên trang. Một giải pháp phổ biến cho những vấn đề này là kết xuất phía máy chủ bằng Node.js.

▍Tình huống số 3. Khả năng mở rộng

Máy chủ Node sẽ không bao giờ mạnh hơn mức cần thiết. Vẻ đẹp của kiến ​​trúc Node nằm ở sự tối giản của nó, trên thực tế là phía máy chủ của ứng dụng có thể được mở rộng tùy theo nhu cầu của dự án. Bí mật ở đây nằm ở thái độ đúng đắn đối với năng suất.

Ngay cả tên của chủ đề cuộc trò chuyện của chúng ta, “nút”, cũng tập trung vào khả năng xây dựng hệ thống từ nhiều nút điện toán phân tán nhỏ có thể trao đổi dữ liệu với nhau.

Tính mô-đun của Node cho phép bạn tạo các ứng dụng nhỏ mà không cần phải duy trì cơ sở hạ tầng khổng lồ, nhiều phần trong số đó sẽ không được sử dụng trong bất kỳ trường hợp cụ thể nào. Khi phát triển các ứng dụng Node, lập trình viên chọn chính xác những gì mình cần và nếu cần, sẽ mở rộng giải pháp.

Tuy nhiên, cần lưu ý rằng những cơ hội mở rộng quy mô như vậy cũng đi kèm với những khó khăn nhất định. Và nếu không cẩn thận, Node.js có thể trở nên... nguy hiểm.

Hạn chế của Node.js

Thành thật mà nói, Node cho phép nhà phát triển, như họ nói, “tự bắn vào chân mình”. Trên thế giới này bạn phải trả tiền cho mọi thứ, kể cả nhiều cơ hội về việc thiết lập hệ thống và điều chỉnh nó theo nhu cầu của bạn. Nếu bạn làm việc với Node mà không có đủ kinh nghiệm hoặc thường xuyên để mọi thứ có cơ hội, bạn có thể gặp phải những vấn đề nghiêm trọng như mất khách hàng.

Ngược lại với các cách tiếp cận truyền thống hơn vốn quy định chặt chẽ các tính năng kiến ​​trúc nhất định của hệ thống, bạn là người tạo ra cấu trúc hỗ trợ phần máy chủ trong ứng dụng của mình. Do đó, nhiều quyết định phải được đưa ra, tức là nhà phát triển cần biết chính xác những gì mình đang làm và điều gì sẽ xảy ra với dự án nếu nó cần được mở rộng.

Ví dụ, trong trường hợp của các ngôn ngữ khác, chẳng hạn như Ruby và khung Ruby on Rails nổi tiếng, ý tưởng cho rằng các quy ước được ưu tiên hơn cấu hình hệ thống. Những khuôn khổ truyền thống này theo đúng nghĩa đen là dẫn dắt nhà phát triển tận tay, chỉ cho anh ta cách chính xác, an toàn để giải quyết các vấn đề thường gặp.

Có thể nói, nút đảo ngược mọi thứ. Nhà phát triển được trao nhiều tự do hơn, nhưng con đường hiện thực hóa kế hoạch có thể đầy rẫy nguy hiểm nếu đưa ra những quyết định sai lầm trong quá trình làm việc. Ở đây sẽ rất thích hợp để nhớ lại “địa ngục gọi lại” khét tiếng, đột nhiên hóa ra hoàn toàn có thật.


Điều này không có nghĩa là bạn không thể xây dựng các ứng dụng phía máy chủ lớn trên Node, nhưng bạn nên ghi nhớ những điều trên.

Ngay cả người tạo ra Node.js, Ryan Dahl, cuối cùng cũng nhận ra những hạn chế của hệ thống trước khi chuyển sang các dự án khác. Ông đã nói rất rõ ràng về vấn đề này:

« Tôi nghĩ Node không phải là hệ thống tốt nhất để tạo các dự án máy chủ quy mô lớn. Tôi sẽ dùng . Và thành thật mà nói, đó là lý do tại sao tôi rời bỏ Node. Tôi đã từng nhận ra rằng, trên thực tế, đây không phải là hệ thống tốt nhất để phát triển máy chủ chút nào».

Những định kiến ​​​​được đề cập trước đây về Node đều đúng cho đến thời điểm tồn tại không lâu của Node và ở một mức độ nào đó, chúng vẫn không phải là những lời nói suông. Node đã đủ trưởng thành và phát triển; điểm yếu của nó, nếu cần thiết và có thời gian, có thể khắc phục được. Và các công cụ do cộng đồng phát triển cho phép bạn tạo hầu hết mọi thứ dựa trên Node.js.

Các công cụ phổ biến để phát triển JS phía máy chủ

Cách đây không lâu, nếu ai đó nghĩ đến việc xây dựng tất cả các phần trong hệ thống của họ bằng JS, thì ý nghĩ về ngăn xếp MEAN (MongoDB, Express, Angular và Node) ngay lập tức xuất hiện trong đầu.

Bộ công cụ này ngày nay vẫn không mất đi sự liên quan, tuy nhiên, hiện tại trong hệ sinh thái JS có nhiều công cụ thú vị hơn cho cả phát triển máy khách và máy chủ, vì vậy bạn không nên giới hạn mình ở MEAN.

Dưới đây là một số khung JS phía máy chủ hiện đại phổ biến:

  • Express.js đã và vẫn là framework Node.js phổ biến nhất. Nó nhanh, gọn và không áp đặt các quyết định kiến ​​trúc cứng nhắc lên nhà phát triển. Cơ sở của sự phát triển nhanh chóng của nó là sự đơn giản và rõ ràng. Có lẽ về mặt ý thức hệ, nó gần gũi hơn tất cả các công cụ khác với các ý tưởng cơ bản của Node, theo đó nó là một hệ thống mô-đun nhẹ.
  • Mặt khác, Meteor sử dụng JavaScript và Node.js thuần túy bên trong một thiết kế khá lớn. Bản thân Meteor là cả một hệ sinh thái có thể phù hợp để phát triển các ứng dụng máy chủ phức tạp hơn. Tuy nhiên, việc sử dụng Meteor có thể trở nên phức tạp nếu bạn cần thứ gì đó không được tích hợp sẵn trong hệ thống.
  • Sails.js là một khung MVC thời gian thực. Nó được thiết kế để mô phỏng mẫu MVC trên nền tảng Ruby on Rails, nhưng cũng nhằm hỗ trợ các yêu cầu ứng dụng web hiện đại. Tất cả đều hoạt động nhờ các API được điều khiển bởi dữ liệu, với sự hiện diện của kiến ​​trúc hướng dịch vụ, có thể mở rộng.

    Tôi nghĩ điều quan trọng nhất tôi muốn làm là chỉ ra rằng giữa “có” và “không” có thể tìm thấy trong nhiều cuộc thảo luận về Node và về JS như một ngôn ngữ phía máy chủ, nếu có một phạm vi rộng của “có thể”.

    Và dù muốn hay không thì sự quan tâm đến Node vẫn không ngừng tăng lên.


    Ở phần cuối của tài liệu này, tôi muốn nói rằng bạn không nên coi bất kỳ khuôn khổ nào như cây đũa thần sẽ giải quyết mọi vấn đề một cách thần kỳ. Node.js chỉ là một công cụ trong vũ trụ phát triển web khổng lồ. Trong một số tình huống, anh ấy giải quyết các vấn đề được giao một cách xuất sắc, trong khi ở những tình huống khác, làm việc với anh ấy có thể biến thành một cơn ác mộng.

    Nhiệm vụ của mỗi nhà phát triển bao gồm lựa chọn cẩn thận các công nghệ phù hợp để thực hiện bất kỳ dự án mới nào. Đồng thời, điều quan trọng là phải tính đến tất cả các khả năng và không loại bỏ ngay các lựa chọn thay thế có sẵn.

    Ví dụ, công ty nơi tôi làm việc, Snipcart, sử dụng kiến ​​trúc .NET, về kiến ​​trúc này có thể nói ra rất nhiều điều khó chịu. Tại sao cô ấy được chọn? Có, đơn giản vì tại một thời điểm cụ thể, nó lại trở thành công cụ tốt nhất để giải quyết nhiệm vụ được giao cho chúng ta.

    Tôi hy vọng câu chuyện của tôi về Node sẽ giúp bạn đưa ra quyết định đúng đắn khi chọn nền tảng máy chủ cho dự án tiếp theo của mình.

    Thẻ: Thêm thẻ

Câu hỏi “Tại sao?” - điều quan trọng nhất khi đưa ra bất kỳ quyết định nào. Trong trường hợp của chúng tôi có một số lý do.

Trước hết, mọi người. Công cụ tạo mẫu hiện tại được xử lý bởi C. Tất cả các câu hỏi về những thay đổi của nó không được giải quyết nhanh chóng. Và điều quan trọng nhất là công cụ tạo mẫu được viết bởi một số người và được sử dụng bởi những người hoàn toàn khác nhau.

Nói chung, điều này là phổ biến và theo tôi thì không mấy thực hành tốt công cụ viết dành cho người thiết kế bố cục. Rõ ràng là họ cần các công cụ, nhưng những công cụ này được thực hiện bởi những người chỉ có ý tưởng mơ hồ về công việc hàng ngày của người thiết kế bố cục. Ngược lại, các quyết định thường được đưa ra theo kiểu “hãy để họ viết các điều kiện và chu trình, nhưng họ sẽ không cần bất cứ thứ gì khác cho bố cục”. Có lẽ đây là lỗi của chính người thiết kế bố cục và trình độ của họ.

Nhưng Mail.Ru Group có cả một đội ngũ gồm những người có trình độ cao, biết về JS, có thể tự viết một công cụ và quan trọng nhất là họ sẽ sử dụng nó.

Thứ hai, nhiệm vụ. Hãy thực hiện dự án [email protected]. Chúng tôi không thể từ chối việc tạo khuôn mẫu trên máy chủ - chúng tôi cần tải nhanh ngay lần nhập cảnh đầu tiên. Chúng tôi không thể từ chối việc tạo khuôn mẫu trên máy khách - mọi người phải thấy tốc độ phản hồi cao đối với hành động của họ, điều đó có nghĩa là cần phải có AJAX và việc tạo khuôn mẫu trên máy khách.

Vấn đề rất rõ ràng: hai bộ mẫu hoàn toàn khác nhau trên máy chủ và trên máy khách. Và điều khó chịu nhất là họ giải quyết cùng một vấn đề. Sự trùng lặp của logic đơn giản là làm chúng tôi kiệt sức.

V8 là một trình thông dịch JavaScript, có nghĩa là chúng ta có thể lấy một mẫu hoạt động trên cả máy chủ và máy khách.

Thứ ba, tốc độ. Sau khi đọc nhiều bài viết ca ngợi tốc độ của v8, chúng tôi quyết định rằng chúng tôi cần kiểm tra tính hợp lệ của chúng. Nhưng trước tiên, chúng tôi cần hiểu chúng tôi muốn công cụ tạo mẫu mới trông như thế nào.

Bạn cần gì

Tôi sẽ nói ngay rằng chúng tôi rất hạn chế về thời gian chuyển đổi của máy chủ, vì vậy việc triển khai một cái gì đó rất khó khăn. chức năngđã không có. Tuy nhiên, việc để lại chức năng cũ với điểm khác biệt duy nhất là việc bổ sung một lớp từ v8 là một ý tưởng kỳ lạ.

Tôi đã sử dụng nó rất nhiều trong một thời gian dài phép biến đổi XSLT(không phải tùy chọn chuyển đổi nhanh nhất), mặc dù nếu được sử dụng đúng cách, nó sẽ hiển thị những con số tốt (tôi đang nói về libxslt). Nhưng XSLT có một công cụ tạo khuôn mẫu rất mạnh - ghi đè mẫu. Chúng tôi quyết định thực hiện điều gì đó tương tự nhưng đơn giản hơn nhiều.

/head.xml ... <fest:get name=”title”/> Thư.ru/mail.xml ... Thư.ru thư

Sẽ thật lạ khi sử dụng v8 và không cung cấp quyền truy cập vào JavaScript trong các mẫu.

var text = “mail.ru” chữ

Và rất nhiều điều nhỏ nhặt khác, ngoài các điều kiện và chu trình tiêu chuẩn.

Chúng tôi lấy XML làm cú pháp cho công cụ tạo mẫu.

Hỗ trợ chức năng cơ bản trong IDE. Một trăm phần trăm các IDE phổ biến đều biết XML là gì. Bạn nhận được tính năng gạch nối, đánh dấu và tự động hoàn thành cơ bản miễn phí.

Xác thực ở cấp độ IDE. HTML hợp lệ có được thông qua các mẫu hợp lệ. Một lần nữa, tất cả các IDE đều có thể xác thực xml như vậy.

Tính mô-đun ngay lập tức (không gian tên). Tính năng cơ bản Công cụ tạo mẫu sẽ rất nhanh chóng muốn được mở rộng. Ví dụ: thêm thẻ cho phép bạn tạo dự án bằng nhiều ngôn ngữ. Hệ thống Name Spaces làm cho việc này trở nên dễ dàng.

Một loạt các công cụ làm sẵn. Qua nhiều năm, nhiều công cụ để xử lý XML đã được tích lũy, chẳng hạn như các thư viện để xử lý XML bằng XSL hoặc toàn bộ lớp trình phân tích cú pháp SAX, các lược đồ XSD và DTD để xác thực, v.v.

Sự trùng hợp về cú pháp của cấu trúc xử lý và cấu trúc kết quả. Nói cách khác, việc tạo XML bằng XML rất thuận tiện, các mẫu lễ hội rất dễ đọc. Ngoài ra, tất cả các vấn đề về bảo vệ dữ liệu đã được giải quyết.

Thực hiện

Chủ nghĩa cao bồi. Bản thân tôi gần đây đã biết rằng có một thuật ngữ như vậy.

Trước đó, tôi chắc chắn rằng hầu hết cách đáng tin cậy hoàn thành nhiệm vụ - lập trình cặp và kiểm tra. Các bài kiểm tra, như mọi khi, tự chứng minh, nhưng vẫn có những lựa chọn thay thế cho lập trình cặp.

Sự khác biệt giữa nhiệm vụ này và nhiệm vụ thông thường: mẫu và HTML kết quả mà mẫu này sẽ tạo ra đã được biết đến. Kostya (nhà phát triển thư Frontend) và tôi bắt đầu viết các triển khai của riêng mình. Mỗi tuần một lần, chúng tôi so sánh các phép đo về tốc độ chuyển đổi.

Chúng tôi thực hiện hai cách tiếp cận khác nhau: anh ấy biên dịch mẫu thành một hàm và tôi biên dịch thành một cấu trúc. Một ví dụ về cấu trúc đơn giản nhất:

... ", 04 (hành động:"giá trị"), 05 "json.value" 06 ]

Dòng thứ hai đánh dấu sự bắt đầu của mẫu. Cái thứ ba chỉ nên được cung cấp cho trình duyệt. Điều thứ tư nói rằng điều thứ năm phải được thực thi dưới dạng JavaScript và kết quả thực thi sẽ được cung cấp cho trình duyệt.

01 [ 02 (hành động:"mẫu"), 03 " ....”, 04 (hành động:"if"), 05 "json.value", 06 "true", 07 "false" 08 ]

Tùy chọn phức tạp hơn một chút. Dòng thứ tư có nghĩa là dòng thứ năm phải được thực thi và nếu kết quả đúng hoặc sai thì ghi dòng thứ sáu hoặc thứ bảy tương ứng.

Tùy chọn với chức năng không cần phải giải thích cụ thể.

01 mẫu hàm(json)( 02 var html = ""; 03 html += " ..."; 04 html += json.value; 05 trả về html; 07 )

Nhìn về phía trước, tôi sẽ nói rằng phiên bản của anh ấy hóa ra nhanh hơn. Trong một thời gian, chúng tôi đã đi bộ gần như ngang bằng, nhưng tùy chọn cấu trúc đã chạm trần sớm hơn nhiều.

Để hiểu cách tiếp cận này mang lại lợi ích gì: lần triển khai đầu tiên của tôi đã hoàn thành nhiệm vụ sau 200 mili giây. Khi chúng tôi cố gắng hết sức có thể và sau đó kết hợp những gì tốt nhất của hai chương trình, chúng tôi nhận được 3 mili giây.

Nếu chúng ta mô tả ngắn gọn việc triển khai hiện tại, chúng ta sẽ chuyển các chu kỳ thành các chu kỳ, câu điều kiện vào các câu lệnh có điều kiện, v.v.

Fest:foreach for(i = 0; i< l; i++) {} fest:if if(value) {} fest:choose if(value) {} else {}

Không thu hẹp bối cảnh. Đúng, đây là một hạn chế, nhưng không có chi phí nào để giới hạn bối cảnh và điều quan trọng nhất là ngay khi bạn thu hẹp bối cảnh, nhiệm vụ ngay lập tức đặt ra là lấy thứ gì đó từ bối cảnh toàn cầu hoặc từ bối cảnh ở cấp độ cao hơn. mức độ.

Điều quan trọng là các mẫu phải được dịch sang hàm JS hoạt động ở chế độ nghiêm ngặt. Điều này ngăn cản người lập trình viết mã dẫn đến rò rỉ bộ nhớ.

Bất cứ nơi nào bạn cần nó công việc logic với dữ liệu, JavaScript có sẵn.

_javascript_

Tất cả các thiết kế liên quan đến Thực thi JavaScript, biến thành thử bắt.

Tất cả các cấu trúc mong đợi xuất ra HTML sau khi thực thi JavaScript đều vượt qua lối thoát HTML theo mặc định.

json.name
thử ( html += __escape(json.name) ) bắt(e) ()

Ngay từ đầu, việc phát triển công cụ tạo mẫu được thực hiện ở dạng mở.
https://github.com/mailru/fest

Tùy chọn tích hợp

Một mặt, v8 chỉ là một thư viện cho phép diễn giải JavaScript. Bản thân nó có vẻ vô dụng - không có quyền truy cập vào hệ thống. Nhưng mặt khác, nó có thể dễ dàng chuyển sang các ngôn ngữ khác.

Không có kinh nghiệm lập trình C và Perl, tôi đã tạo các trường hợp thử nghiệm bằng cả hai ngôn ngữ. Ngoài ra, hiện tại chúng tôi có kết nối với Python.

Và tất nhiên, NodeJS dành cho nguyên mẫu và trình duyệt - môi trường nơi các mẫu JavaScript hoạt động vượt trội.

Điều kiện cận chiến

Nhận được 3ms, tôi đến gặp các lập trình viên phía máy chủ. Khi được hỏi tôi có bao nhiêu thời gian cho yêu cầu trả về danh sách email của người dùng, họ nói: không quá 4 mili giây. Tôi đã có 3ms để chuyển đổi, tôi phải thử nó.

Danh sách các chữ cái của chúng tôi được cung cấp bởi máy chủ http của chúng tôi, được viết bằng C. Nhận dữ liệu là các thao tác không cạnh tranh bộ xử lý nên không được đo lường. Chúng tôi đã quyết định chuẩn bị dữ liệu cho quá trình chuyển đổi và về chính quá trình chuyển đổi.

Vì lý do lịch sử của chúng tôi máy chủ http lưu trữ dữ liệu trong một hàm băm phẳng.

Msg_length = 5 msg_1_title = “chữ cái” msg_1_Chưa đọc = 1

Vì chúng ta đang nói về JavaScript nên điều đầu tiên bạn nghĩ đến là JSON

Msg = [ (tiêu đề: “bức thư”, Chưa đọc: đúng) ]

Chúng tôi lấy một chuỗi có hàm băm phẳng, đặt nó vào bộ nhớ và bắt đầu đạt được kết quả khi chuyển đổi mẫu trong v8, JavaScript hoạt động với JSON.

Chúng tôi đã trải qua rất nhiều lựa chọn. Truyền một đối tượng, truyền một chuỗi và phân tích cú pháp nó trong JavaScript, truyền một chuỗi và chuyển nó qua JSON.parse.

Thật kỳ lạ, điều nhanh nhất hóa ra lại là chuyển đổi hàm băm phẳng thành một chuỗi khớp với JSON và trong v8 đưa ra chuỗi

“template([ (tiêu đề: \“letter\”, Chưa đọc: true) ])”

Tuy nhiên, bất chấp mọi thứ, chúng tôi đạt được 6 mili giây với phép chuyển đổi 2 mili giây. Mọi người đều sẵn sàng bỏ cuộc. Tôi vẫn quyết định lấy dữ liệu gốc, một chuỗi băm phẳng và sử dụng cùng một mẫu được biên dịch để lấy HTML mong muốn trong NodeJS.

Có 4ms. Thành thật mà nói, khi tôi đến gặp các kỹ sư của chúng tôi với con số này, tôi đã mong đợi cụm từ “Tuyệt vời, nhưng chúng tôi không có đủ nguồn lực để viết NodeJS.” Nhưng thay vào đó tôi lại nghe thấy “Nếu NodeJS có thể làm điều đó trong 4ms, thì chúng tôi cũng có thể làm được!”

Đó là lúc tôi nhận ra rằng chúng tôi sẽ đưa sản phẩm này vào sản xuất. Có một cơn gió thứ hai!

Giải pháp hóa ra lại đơn giản. Vì chúng ta mất 67% thời gian cho việc chuẩn bị dữ liệu và về nguyên tắc là chúng ta đã có dữ liệu nên chúng ta cần phải loại bỏ việc chuẩn bị dữ liệu.

Chúng tôi đã chuyển tiếp hàm __get('key') sang v8. Do đó, từ v8, chúng tôi đã lấy dữ liệu trực tiếp từ hàm băm của máy chủ http của mình. Không có chuyển đổi dữ liệu sang định dạng được yêu cầu. Không có sự chuyển đổi chuỗi này thành một đối tượng bên trong v8. Chúng tôi đạt tới 3 mili giây và có biên độ 1 mili giây.

Gần như sản xuất

Vì vậy, mọi thứ đều có vẻ ổn, nhưng chúng tôi vẫn chưa tiến gần đến giai đoạn sản xuất. Tay tôi ngứa ngáy muốn thử.

Chúng tôi lấy một máy chủ riêng, cài đặt trên đó một phiên bản của máy chủ http hoạt động với v8 và sao chép các yêu cầu thực sự tới nó. Chúng tôi để một lõi Xeon 2,2 GHz trong 30 giờ.

Hơn 10.000.000 lượt truy cập Thời gian chuyển đổi trung bình 1,6 mili giây 992.422 10% trong khoảng từ 2 đến 5 mili giây 208.464 2% trong khoảng từ 5 đến 10 mili giây 39.649 0,4% trên 10 mili giây

Chỉ có 12% lớn hơn 2ms. v8 hoạt động ổn định từ bộ nhớ.

Sản xuất

Tôi đưa những con số mới nhất cho phó giám đốc kỹ thuật, nói rằng v8 đã sẵn sàng để sản xuất, chúng tôi cần thực hiện một dự án nhỏ riêng biệt, nếu có thì có thể bị lãng quên trong trường hợp thất bại. Câu trả lời tôi nhận được là “những con số tốt, một dự án riêng biệt có thất bại không quá nghiêm trọng - điều đó đúng, nhưng bạn có thực sự muốn ra mắt v8 không? Bắt đầu với trang chính của Mail.Ru." Câu hỏi được đặt ra một cách chính xác - hoặc chúng ta thực hiện công việc, hoặc chúng ta vui vẻ bên lề.

Việc bố trí trang chính tại lễ hội mất ba ngày. Chúng tôi đã tắt một máy chủ khỏi bộ cân bằng, tải phiên bản v8 lên đó và sao chép các yêu cầu. Tất cả các phép tính sẽ diễn ra trong bối cảnh của một daemon/kernel.

Luôn tìm hiểu chi tiết những gì biểu đồ của bạn hiển thị. Chúng tôi đặt một nửa tải lên máy chủ thử nghiệm. Mức tiêu thụ CPU cao gấp ba lần so với bình thường. Nó trông giống như một sự thất bại, tổn thất tài nguyên gấp sáu lần so với công cụ tạo mẫu hiện tại.

Họ bắt đầu xem. Sau đây tôi sẽ kể cho bạn nghe một chút về kiến ​​trúc chính. Nó thu thập thông tin từ các dự án khác nhau. Nó được lắp ráp nội bộ, chúng tôi gọi nó là RB. Trong số 165kb được tạo cho nguồn cấp dữ liệu chính, RB thu thập 100kb. Và điều sau đây xảy ra: RB gửi các đoạn HTML thông qua máy chủ http tới v8, v8 nối chúng bằng các chuỗi riêng của nó và kết quả sẽ trả lại tất cả cho máy chủ http.

Có chuyển tiếp dữ liệu kép. Chúng tôi đã thực hiện tối ưu hóa. Bây giờ ở phiên bản 8, thay vì xây dựng một chuỗi lớn bao gồm dữ liệu từ RB, hãy gửi dữ liệu trực tiếp đến máy chủ http.

Push_string('foo'); __push_rb(id); __push_string('bar');

Ngoài ra, không có nối chuỗi trên v8, không chuyển tiếp kép RB từ máy chủ sang v8 và ngược lại, và quan trọng nhất, mọi chuyển tiếp dữ liệu đều là chuyển đổi từ utf-8 sang utf-16 và ngược lại. V8 lưu trữ mọi thứ trong utf-16.

Có lãi, tài nguyên được tiêu thụ gấp đôi bình thường chứ không phải ba. Những thứ kia. chúng tôi vẫn thua bốn lần, mặc dù có vẻ như chúng tôi đã vắt kiệt từng giọt nước mắt.

Bây giờ đến phần giáo dục. Để giải trí, tôi lấy tải mà chúng tôi đã thử nghiệm và nhân nó với hai, với số lượng quỷ trên máy và với số lượng máy. Đã nhận được 440.000.000 lượt truy cập. Đồng thời, chúng tôi có 110.000.000 lượt truy cập mỗi ngày. Những nghi ngờ mơ hồ len lỏi vào.

Chúng ta hãy đi xem nhật ký. Hóa ra đối với mỗi yêu cầu có tải, chúng tôi nhận được ba yêu cầu có báo cáo trong nhật ký để thống kê! Tải thực tế trên một máy chủ http thấp hơn bốn lần so với những gì chúng tôi đang thử nghiệm!

Sáng hôm sau chúng tôi tung ra phiên bản v8 của trang chính.

Dữ liệu cho ngày hôm nay:
Kích thước của HTML đầu ra mà v8 tạo ra là 65kb.
Thời gian v8 hoạt động theo yêu cầu 1ms.
Trung bình v8 yêu cầu 40 MB cho mỗi ngữ cảnh.

Một vài lời làm rõ

Mọi người nghĩ về v8 đều đã xem qua một bài viết của Igor Sysoev