Alexey Naydenov. ITooLabs. Trường hợp phát triển trên nền tảng điện thoại Go (Golang). Phần 1

Alexey Naydenov, Giám đốc điều hành ITooLabs, nói về việc phát triển nền tảng viễn thông dành cho các nhà khai thác viễn thông bằng ngôn ngữ lập trình Go (Golang). Alexey cũng chia sẻ kinh nghiệm triển khai và vận hành nền tảng này tại một trong những nhà khai thác viễn thông lớn nhất châu Á, nơi sử dụng nền tảng này để cung cấp dịch vụ thư thoại (VoiceMail) và Virtual PBX (Cloud PBX).

Alexey Naydenov. ITooLabs. Trường hợp phát triển trên nền tảng điện thoại Go (Golang). Phần 1

Alexey Naydenov (sau đây gọi là – AN): - Chào mọi người! Tên tôi là Alexey Naydenov. Tôi là giám đốc của ITooLabs. Trước hết, tôi muốn trả lời tôi đang làm gì ở đây và tại sao tôi lại đến đây.

Nếu bạn nhìn vào Thị trường Bitrix24 (phần “Điện thoại”), thì 14 ứng dụng và 36 ứng dụng ở đó (40%) là của chúng tôi:

Alexey Naydenov. ITooLabs. Trường hợp phát triển trên nền tảng điện thoại Go (Golang). Phần 1

Chính xác hơn, đây là những đối tác điều hành của chúng tôi, nhưng đằng sau tất cả những điều này là nền tảng của chúng tôi (Nền tảng là Dịch vụ) - thứ chúng tôi bán cho họ với một xu nhỏ. Thực ra, tôi muốn nói về sự phát triển của nền tảng này và cách chúng tôi đến với Go.

Những con số cho nền tảng của chúng tôi bây giờ:

Alexey Naydenov. ITooLabs. Trường hợp phát triển trên nền tảng điện thoại Go (Golang). Phần 1

44 đối tác điều hành, trong đó có Megafon. Nói chung, chúng tôi thực sự thích tham gia vào các cuộc phiêu lưu khác nhau và chúng tôi có quyền truy cập thực tế vào 100 triệu người đăng ký của 44 nhà khai thác ở Nga. Vì vậy, nếu ai có ý tưởng kinh doanh nào, chúng tôi sẽ luôn sẵn lòng lắng nghe.

  • 5000 công ty người dùng.
  • Tổng cộng có 20 người đăng ký. Đây hoàn toàn là b000b - chúng tôi chỉ làm việc với các công ty.
  • 300 cuộc gọi mỗi phút trong ngày.
  • 100 triệu phút gọi vào năm ngoái (chúng tôi đã ăn mừng). Điều này không tính đến các cuộc đàm phán nội bộ có sẵn trên nền tảng của chúng tôi.

Nó bắt đầu như thế nào?

Làm thế nào để những người phù hợp thậm chí bắt đầu tạo nền tảng của họ? Chúng ta cũng phải tính đến việc chúng ta có lịch sử phát triển “doanh nghiệp hạng nặng” và thậm chí vào thời điểm chính xác nhất trong năm đối với một doanh nghiệp! Đó là khoảng thời gian hạnh phúc khi bạn đến gặp khách hàng và nói: “Chúng tôi cần thêm một vài máy chủ”. Và khách hàng: “Không cần hỏi nữa! Chúng tôi có mười cái trong giá.”

Vì vậy, chúng tôi đã làm Oracle, Java, WebSphere, Db2 và tất cả những thứ đó. Do đó, tất nhiên, chúng tôi đã sử dụng các giải pháp tốt nhất của nhà cung cấp, tích hợp chúng và cố gắng phát triển với nó. Chúng tôi tự mình bước đi. Đây sẽ là một khởi động nội bộ như vậy.

Tất cả điều này thực sự bắt đầu vào năm 2009. Từ năm 2006, chúng tôi đã tham gia chặt chẽ vào các giải pháp điều hành, bằng cách này hay cách khác. Chúng tôi đã tạo một số PBX ảo tùy chỉnh (giống như cái mà chúng tôi hiện đang đặt hàng): chúng tôi đã xem xét nó, quyết định rằng nó tốt và quyết định bắt đầu khởi nghiệp nội bộ.

Alexey Naydenov. ITooLabs. Trường hợp phát triển trên nền tảng điện thoại Go (Golang). Phần 1

Chúng tôi đã sử dụng VMWare. Vì chúng tôi chỉ có một mình nên chúng tôi phải ngay lập tức từ bỏ Kho chứa của nhà cung cấp tuyệt vời. Chúng tôi biết mọi thứ về họ: những lời hứa đó phải chia cho 3 và chi phí phải nhân với 10. Đó là lý do tại sao họ tạo ra DirDB, v.v.

Sau đó nó bắt đầu phát triển. Một dịch vụ thanh toán đã được thêm vào vì nền tảng này không thể đáp ứng được nữa. Sau đó, máy chủ thanh toán từ MySQL chuyển sang Mongo. Kết quả là chúng tôi đã có được một giải pháp hiệu quả có thể xử lý tất cả các cuộc gọi đến đó:

Alexey Naydenov. ITooLabs. Trường hợp phát triển trên nền tảng điện thoại Go (Golang). Phần 1

Nhưng ở đâu đó bên trong, sản phẩm của nhà cung cấp đó đang quay - sản phẩm chính, hạt nhân mà chúng tôi đã từng sử dụng. Vào khoảng cuối năm 2011, chúng tôi nhận ra rằng nút thắt chính đối với chúng tôi tất nhiên sẽ là sản phẩm cụ thể này - chúng tôi sẽ gặp phải nó. Chúng tôi nhìn thấy một bức tường trước mặt, nơi chúng tôi chạy hết tốc lực vào đó khi ngày càng có nhiều khách hàng đến.
Theo đó, chúng tôi cần phải làm điều gì đó. Tất nhiên, chúng tôi đã tiến hành khá nhiều nghiên cứu về các sản phẩm khác nhau - cả sản phẩm nguồn mở và sản phẩm của nhà cung cấp. Bây giờ tôi sẽ không nói đến vấn đề này nữa – đó không phải là điều chúng ta đang nói đến. Tùy chọn dự phòng cuối cùng mà chúng tôi nghĩ đến là tạo nền tảng của riêng mình.

Cuối cùng, chúng tôi đã đi đến lựa chọn này. Tại sao? Bởi vì tất cả các nhà cung cấp và sản phẩm nguồn mở đều được tạo ra để giải quyết các vấn đề đã tồn tại 10 năm. Vâng, nếu 10 tuổi, và nhiều hơn nữa! Sự lựa chọn trở nên rõ ràng đối với chúng tôi: hoặc chúng tôi nói lời tạm biệt với ý tưởng tuyệt vời của mình về một dịch vụ lý tưởng (cho đối tác, nhà điều hành và chính chúng tôi) hoặc chúng tôi làm điều gì đó của riêng mình.

Chúng tôi quyết định làm điều gì đó của riêng mình!

Yêu cầu nền tảng

Nếu bạn đã làm một việc gì đó trong một thời gian dài (sử dụng sản phẩm của người khác), thì trong đầu bạn sẽ dần hình thành một suy nghĩ: mình sẽ tự làm việc này như thế nào? Vì chúng tôi đều là lập trình viên trong công ty (trừ nhân viên bán hàng, không có người không phải lập trình viên) nên các yêu cầu của chúng tôi đã được đưa ra từ lâu và rất rõ ràng:

  1. Tốc độ phát triển cao. Sản phẩm của nhà cung cấp làm chúng tôi đau khổ, trước hết là không hài lòng vì mọi thứ diễn ra lâu và chậm. Chúng tôi muốn nó nhanh chóng - chúng tôi có rất nhiều ý tưởng! Chúng tôi vẫn còn rất nhiều ý tưởng, nhưng sau đó danh sách ý tưởng lại dày đặc đến mức tưởng chừng như đã có trước cả chục năm. Bây giờ chỉ trong một năm.
  2. Tận dụng tối đa sắt đa lõi. Điều này cũng quan trọng đối với chúng tôi vì chúng tôi thấy rằng sẽ ngày càng có nhiều lõi hơn.
  3. Độ tin cậy cao. Một cái gì đó chúng tôi cũng đã khóc.
  4. Khả năng chống thất bại cao.
  5. Chúng tôi muốn kết thúc với một quá trình phát hành hàng ngày. Đối với điều này, chúng tôi cần một sự lựa chọn ngôn ngữ.

Alexey Naydenov. ITooLabs. Trường hợp phát triển trên nền tảng điện thoại Go (Golang). Phần 1

Theo đó, từ những yêu cầu về sản phẩm mà chúng tôi đặt ra cho mình, những yêu cầu về ngôn ngữ ngày càng phát triển một cách logic rõ ràng.

  1. Nếu chúng ta muốn hỗ trợ cho các hệ thống đa lõi thì chúng ta cần hỗ trợ thực thi song song.
  2. Nếu chúng ta cần tốc độ phát triển, chúng ta cần một ngôn ngữ hỗ trợ phát triển cạnh tranh, lập trình cạnh tranh. Nếu ai chưa gặp sự khác biệt thì rất đơn giản:
    • Lập trình song song là về cách hai luồng khác nhau được thực thi trên các lõi khác nhau;
    • Thực thi đồng thời, hay chính xác hơn là hỗ trợ đồng thời, là về cách một ngôn ngữ (hoặc thời gian chạy, không quan trọng) giúp che giấu tất cả sự phức tạp đến từ việc thực thi song song.
  3. Tính ổn định cao. Rõ ràng, chúng tôi cần một cụm và một cụm tốt hơn những gì chúng tôi có trên sản phẩm của nhà cung cấp.

Alexey Naydenov. ITooLabs. Trường hợp phát triển trên nền tảng điện thoại Go (Golang). Phần 1

Chúng tôi thực sự không có nhiều lựa chọn như vậy, nếu bạn còn nhớ. Đầu tiên, Erlang - chúng tôi yêu thích và biết đến nó, đó là sở thích cá nhân của tôi. Thứ hai, Java thậm chí không phải là Java mà cụ thể là Scala. Thứ ba, một ngôn ngữ mà lúc đó chúng tôi chưa hề biết - Go. Khi đó nó mới xuất hiện, hay nói đúng hơn là nó đã tồn tại được khoảng hai năm nhưng vẫn chưa được phát hành.

Hãy thắng đi!

Lịch sử cờ vây

Chúng tôi đã tạo ra một nền tảng trên đó. Tôi sẽ cố gắng giải thích tại sao.

Sơ lược về lịch sử cờ vây. Nó bắt đầu vào năm 2007, mở cửa vào năm 2009, phiên bản đầu tiên được phát hành vào năm 2012 (nghĩa là chúng tôi đã bắt đầu làm việc ngay cả trước khi phát hành lần đầu tiên). Người khởi xướng là Google, công ty muốn thay thế Java, như tôi nghi ngờ.

Các tác giả rất nổi tiếng:

  • Ken Thomson, người đứng sau Unix, đã phát minh ra UTF-8, đã làm việc trên hệ thống Plan 9;
  • Rob Pike, người đã phát minh ra UTF-8 cùng với Ken, cũng từng làm việc trên Kế hoạch 9, Inferno, Limbo tại Bell Labs;
  • Robert Giesmer, người mà chúng ta biết và yêu mến vì đã phát minh ra Trình biên dịch Java HotSpot cũng như công trình của ông về trình tạo trong V8 (trình thông dịch Javascript của Google);
  • Và hơn 700 người đóng góp, bao gồm một số bản vá của chúng tôi.

Alexey Naydenov. ITooLabs. Trường hợp phát triển trên nền tảng điện thoại Go (Golang). Phần 1

Đi: cái nhìn đầu tiên

Chúng tôi thấy rằng ngôn ngữ ít nhiều đơn giản và dễ hiểu. Chúng ta có các kiểu rõ ràng: trong một số trường hợp chúng cần được khai báo, trong một số trường hợp khác thì chúng không cần thiết (điều này có nghĩa là các kiểu được suy ra theo cách này hay cách khác).

Alexey Naydenov. ITooLabs. Trường hợp phát triển trên nền tảng điện thoại Go (Golang). Phần 1

Có thể thấy rằng việc mô tả các cấu trúc là thời thượng. Có thể thấy chúng ta có khái niệm về con trỏ (nơi có dấu hoa thị). Có thể thấy có sự hỗ trợ đặc biệt cho việc khai báo khởi tạo mảng và mảng kết hợp.

Nó gần như rõ ràng - bạn có thể sống. Hãy thử viết Hello, world:

Alexey Naydenov. ITooLabs. Trường hợp phát triển trên nền tảng điện thoại Go (Golang). Phần 1

Chúng ta thấy gì? Đây là cú pháp giống C, dấu chấm phẩy là tùy chọn. Nó có thể là dấu phân cách cho hai dòng, nhưng chỉ khi đây là hai cấu trúc nằm trên cùng một dòng.

Chúng ta thấy rằng dấu ngoặc trong cấu trúc điều khiển (ở dòng thứ 14) là tùy chọn, nhưng dấu ngoặc nhọn luôn được yêu cầu. Chúng tôi thấy rằng việc gõ là tĩnh. Tim thường xuyên bị đưa ra ngoài. Ví dụ này phức tạp hơn một chút so với Hello, world thông thường - chỉ để cho thấy rằng có một thư viện.

Chúng ta còn thấy điều gì quan trọng nữa? Mã được tổ chức thành các gói. Và để sử dụng một gói trong mã của riêng bạn, bạn cần nhập gói đó bằng lệnh nhập - điều này cũng quan trọng. Chúng tôi khởi chạy nó - nó hoạt động. Tuyệt vời!

Hãy thử điều gì đó phức tạp hơn tiếp theo: Xin chào mọi người, nhưng bây giờ nó là máy chủ http. Chúng ta thấy điều gì thú vị ở đây?

Alexey Naydenov. ITooLabs. Trường hợp phát triển trên nền tảng điện thoại Go (Golang). Phần 1

Đầu tiên, hàm hoạt động như một tham số. Điều này có nghĩa là chức năng của chúng tôi là “công dân hạng nhất” và bạn có thể thực hiện rất nhiều điều thú vị với nó theo phong cách chức năng. Tiếp theo, chúng ta thấy một điều bất ngờ: lệnh nhập liên kết trực tiếp đến kho GitHub. Đúng vậy, là như vậy – hơn nữa, đó là cách nên làm.

Trong Go, mã định danh chung của gói là url của kho lưu trữ. Có một tiện ích Goget đặc biệt sẽ tìm nạp tất cả các phần phụ thuộc, tải xuống, cài đặt, biên dịch và chuẩn bị sử dụng nếu cần. Đồng thời, Goget cũng biết về html-meta. Theo đó, bạn có thể giữ một thư mục http chứa các liên kết đến kho lưu trữ cụ thể của bạn (ví dụ như chúng tôi làm).

Chúng ta còn thấy gì nữa? Http và Json trong thư viện chuẩn. Rõ ràng là có sự xem xét nội tâm - sự phản ánh, nên được sử dụng trong mã hóa/json, bởi vì chúng ta chỉ cần thay thế một số đối tượng tùy ý cho nó.

Chúng tôi chạy nó và thấy rằng chúng tôi có mã hữu ích gồm 20 dòng, mã này biên dịch, chạy và báo cáo tải trung bình hiện tại của máy (trên máy mà nó được khởi chạy).
Điều gì quan trọng khác mà chúng ta có thể thấy ngay ở đây? Nó được biên dịch thành một nhị phân tĩnh (buinary). Hệ nhị phân này không có sự phụ thuộc nào cả, không có thư viện! Bạn có thể sao chép nó vào bất kỳ hệ thống nào, chạy nó ngay lập tức và nó sẽ hoạt động.

Tiếp tục.

Đi: Phương thức và giao diện

Đi có phương pháp. Bạn có thể khai báo một phương thức cho bất kỳ loại tùy chỉnh nào. Hơn nữa, đây không nhất thiết phải là một cấu trúc, mà có thể là bí danh của một loại nào đó. Bạn có thể khai báo bí danh cho N32 và viết các phương thức để nó thực hiện bất kỳ điều gì hữu ích.

Và ở đây chúng ta lần đầu tiên rơi vào trạng thái sững sờ... Hóa ra cờ vây không có những lớp học như vậy. Những người biết về cờ vây có thể nói rằng có sự bao gồm kiểu, nhưng đó hoàn toàn là một điều khác. Nhà phát triển ngừng coi nó là sự kế thừa càng sớm thì càng tốt. Không có lớp nào trong Go và cũng không có sự kế thừa.

Câu hỏi! Nhóm tác giả do Google lãnh đạo đã mang lại cho chúng ta điều gì để phản ánh sự phức tạp của thế giới? Họ đã cho chúng tôi giao diện!

Alexey Naydenov. ITooLabs. Trường hợp phát triển trên nền tảng điện thoại Go (Golang). Phần 1

Giao diện là một loại đặc biệt cho phép bạn viết các phương thức, chữ ký phương thức đơn giản. Hơn nữa, bất kỳ loại nào mà các phương thức này tồn tại (được thực thi) sẽ tương ứng với giao diện này. Điều này có nghĩa là bạn có thể mô tả một cách đơn giản chức năng tương ứng cho một loại, cho loại khác (tương ứng với loại giao diện đó). Tiếp theo, khai báo một biến thuộc loại giao diện này và gán bất kỳ đối tượng nào trong số này cho nó.

Đối với những người hâm mộ cuồng nhiệt, tôi có thể nói rằng biến này thực sự sẽ có hai con trỏ: một cho dữ liệu, một cho một bảng mô tả đặc biệt, điển hình cho loại cụ thể này, cho giao diện của loại này. Nghĩa là, trình biên dịch tạo ra các bảng mô tả như vậy tại thời điểm liên kết.

Và tất nhiên trong Go có những con trỏ void. Từ giao diện {} (có hai dấu ngoặc nhọn) là một biến cho phép bạn trỏ đến bất kỳ đối tượng nào về nguyên tắc.
Cho đến nay mọi thứ đều ổn, mọi thứ đều quen thuộc. Không có gì đáng ngạc nhiên.

Đi: goroutines

Bây giờ chúng ta đến với điều mà chúng ta quan tâm: các quy trình nhẹ - goroutines (goroutines) trong thuật ngữ Go.

Alexey Naydenov. ITooLabs. Trường hợp phát triển trên nền tảng điện thoại Go (Golang). Phần 1

  1. Thứ nhất, chúng rất nhẹ (dưới 2 KB).
  2. Thứ hai, chi phí để tạo ra một goroutine như vậy là không đáng kể: bạn có thể tạo hàng nghìn goroutine mỗi giây - sẽ không có gì xảy ra.
  3. Chúng được phục vụ bởi bộ lập lịch riêng, đơn giản là chuyển quyền kiểm soát từ goroutine này sang goroutine khác.
  4. Trong trường hợp này, quyền kiểm soát được chuyển giao trong các trường hợp sau:
    • nếu gặp biểu thức go (nếu goroutine bắt đầu goroutine tiếp theo);
    • nếu lệnh gọi Đầu vào/Đầu ra bị chặn được bật;
    • nếu việc thu gom rác bắt đầu;
    • nếu một số thao tác với các kênh được khởi chạy.

Nghĩa là, bất cứ khi nào một chương trình Go chạy trên máy tính, nó sẽ xác định số lượng lõi trong hệ thống, khởi chạy bao nhiêu luồng nếu cần (có bao nhiêu lõi trong hệ thống hoặc bạn đã nói với nó bao nhiêu). Theo đó, bộ lập lịch sẽ chạy các luồng thực thi nhẹ này trên tất cả các luồng của hệ điều hành này trong mỗi lõi.

Cần lưu ý rằng đây là cách sử dụng sắt hiệu quả nhất. Ngoài những gì được hiển thị, chúng tôi còn làm được nhiều hơn thế. Ví dụ: chúng tôi tạo ra các hệ thống DPI cho phép một thiết bị phân phối 40 gigabit (tùy thuộc vào điều gì xảy ra trong các dòng này).

Ở đó, ngay cả trước Go, chúng tôi đã sử dụng chính xác cùng một sơ đồ vì lý do chính xác này: vì nó cho phép chúng tôi bảo toàn vị trí của bộ đệm bộ xử lý và giảm đáng kể số lượng chuyển đổi ngữ cảnh hệ điều hành (điều này cũng mất rất nhiều thời gian). Tôi nhắc lại: đây là cách sử dụng sắt hiệu quả nhất.

Ví dụ 21 dòng đơn giản này là một ví dụ đơn giản thực hiện echo-server. Xin lưu ý rằng hàm phục vụ cực kỳ đơn giản, nó là tuyến tính. Không có cuộc gọi lại, không cần phải bận tâm và suy nghĩ... Bạn chỉ cần đọc và viết!

Đồng thời, nếu bạn đọc và viết, nó thực sự sẽ chặn - goroutine này chỉ đơn giản được đặt trong hàng đợi và được bộ lập lịch thực hiện khi có thể thực thi lại. Nghĩa là, mã đơn giản này có thể hoạt động như một máy chủ echo cho số lượng kết nối mà hệ điều hành trên máy đó cho phép.

Sẽ sớm được tiếp tục...

Một số quảng cáo 🙂

Cảm ơn bạn đã ở với chúng tôi. Bạn có thích bài viết của chúng tôi? Bạn muốn xem nội dung thú vị hơn? Hỗ trợ chúng tôi bằng cách đặt hàng hoặc giới thiệu cho bạn bè, VPS đám mây cho nhà phát triển từ $4.99, một dạng tương tự duy nhất của các máy chủ cấp đầu vào do chúng tôi phát minh ra dành cho bạn: Toàn bộ sự thật về VPS (KVM) E5-2697 v3 (6 Cores) 10GB DDR4 480GB SSD 1Gbps từ 19$ hay cách share server? (có sẵn với RAID1 và RAID10, tối đa 24 lõi và tối đa 40GB DDR4).

Dell R730xd rẻ hơn gấp 2 lần tại trung tâm dữ liệu Equinix Tier IV ở Amsterdam? Chỉ ở đây 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 TV từ $199 ở Hà Lan! Dell R420 - 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB - từ $99! Đọc về Làm thế nào để xây dựng cơ sở hạ tầng corp. đẳng cấp với việc sử dụng máy chủ Dell R730xd E5-2650 v4 trị giá 9000 euro cho một xu?

Nguồn: www.habr.com

Thêm một lời nhận xét