Cách xây dựng ứng dụng Golang có thể cắm và hưởng lợi từ AWS Lambda Layer.

Golang - tại sao nó đáng để bạn chú ý?

Golang là một ngôn ngữ lập trình nguồn mở được thiết kế và triển khai bởi Google. Nó được sử dụng rất rộng rãi trong các ứng dụng hiện đại, đặc biệt là trong đám mây. Nó có các tính năng đặc trưng nhất là:

  • Golang được gõ tĩnh - nó cung cấp ít linh hoạt hơn, nhưng bảo vệ bạn khỏi mắc lỗi,
  • Nó không hướng đối tượng. Tuy nhiên, bạn có thể tạo các cấu trúc và giao diện và cung cấp cho bạn 3 trong 4 nguyên tắc OOP: trừu tượng hóa dữ liệu, đóng gói và đa hình. Kế thừa là người duy nhất còn thiếu,
  • Khỉ đột! - việc thực hiện lớn nhất của các luồng ánh sáng tôi đã từng sử dụng. Nó cho phép bạn tạo một luồng mới theo cách siêu dễ dàng bằng cách sử dụng toán tử go và giao tiếp giữa các con khỉ đột khác nhau bằng các kênh,
  • Nó biên dịch thành nhị phân đơn với tất cả các phụ thuộc - không có thêm các gói xung đột!

Cá nhân, tôi coi Golang là ngôn ngữ tuyệt vời nhất mà tôi sử dụng hàng ngày. Tuy nhiên, bài viết này đã thắng về cách tạo ra chức năng đầu tiên của bạn hoặc in ấn Hello Hello World. Tôi sẽ chỉ cho bạn một thứ cao cấp hơn một chút. Nếu bạn là người mới bắt đầu và muốn tìm hiểu thêm về Golang, vui lòng truy cập trang chính của nó.

AWS Lambda & Golang

AWS Lambda là một trong những dịch vụ tính toán không có máy chủ phổ biến nhất trên đám mây công cộng, được phát hành vào tháng 11 năm 2014 bởi Amazon Web Services. Nó cho phép bạn chạy mã của mình để đáp ứng với các sự kiện như DynamoDB, SNS hoặc HTTP kích hoạt mà không cần cung cấp hoặc quản lý máy chủ! Bạn có biết những gì thực sự tuyệt vời? Kể từ tháng 1 năm 2018, nó hỗ trợ thời gian chạy Golang. Làm việc với AWS Lambda rất đơn giản - chỉ cần tải lên gói nén với mã của bạn và tất cả các phụ thuộc (nhị phân đơn khi sử dụng Golang).

Chuyển tiếp nhanh, 4 năm sau vào năm 2018 lại: Invent AWS phát hành Lớp Lambda cho phép bạn lưu trữ và quản lý dữ liệu được chia sẻ qua các chức năng khác nhau trong một hoặc thậm chí nhiều tài khoản AWS! Ví dụ: Trong khi sử dụng Python, bạn có thể đặt tất cả các phụ thuộc vào một lớp bổ sung mà sau này có thể được sử dụng bởi các Lambdas khác. Không cần phải đặt các phụ thuộc khác nhau trong mỗi gói nén nữa! Trong thế giới Golang thì khác, AWS Lambda yêu cầu bạn phải tải lên tệp nhị phân đã biên dịch. Làm thế nào chúng ta có thể hưởng lợi từ các lớp LambS AWS? Câu trả lời rất đơn giản - xây dựng một ứng dụng mô-đun bằng Golang Plugins!

Golang Plugins - một cách để xây dựng một ứng dụng mô-đun

Golang Plugins là tính năng được phát hành trong Go1.8, cho phép bạn tải động các thư viện chia sẻ (tệp .so). Nó cung cấp cho bạn cơ hội để xuất một số mã của bạn sang thư viện riêng hoặc sử dụng plugin được chuẩn bị và biên dịch bởi người khác. Đó là hứa hẹn, tuy nhiên, có một vài hạn chế:

  • Plugin của bạn phải là một mô-đun chính duy nhất,
  • Bạn chỉ có thể tải các hàm và biến được xuất dưới dạng ký hiệu ELF,
  • Do gõ tĩnh, bạn phải truyền mọi ký hiệu được tải sang đúng loại. Trong trường hợp xấu nhất, bạn cần xác định giao diện chính xác trong mã của mình,
  • Nó chỉ hoạt động cho Linux và MacOS. Cá nhân tôi không coi đây là một bất lợi :)

Xây dựng và thử nghiệm plugin đầu tiên của bạn

Bây giờ hãy để cùng nhau tạo ra plugin đầu tiên của chúng tôi. Ví dụ, chúng tôi sẽ tạo một mô-đun đơn giản để mã hóa chuỗi. Hãy để Lùi trở lại những điều cơ bản và thực hiện 2 thuật toán mã hóa đơn giản - Ceasar và Verman.

  • Mật mã Caesar là thuật toán được sử dụng đầu tiên bởi Julius Cease. Nó dịch chuyển mọi chữ cái trong văn bản theo số lượng vị trí cố định. Ví dụ: nếu bạn muốn mã hóa từ golang bằng khóa 4, bạn sẽ nhận được ktpek. Việc giải mã hoạt động theo cùng một cách. Bạn chỉ cần thay đổi các chữ cái theo hướng ngược lại.
  • Mật mã Verman tương tự như Ceaser, dựa trên cùng một ý tưởng dịch chuyển, sự khác biệt là bạn dịch chuyển từng chữ cái theo số lượng vị trí khác nhau. Để giải mã văn bản, bạn cần có khóa chứa các vị trí được sử dụng để mã hóa văn bản. Ví dụ: nếu bạn muốn mã hóa từ golang bằng khóa [-1, 4, 7, 20, 4, -2], bạn sẽ nhận được tương lai.

Việc thực hiện đầy đủ của ví dụ này có sẵn ở đây.

Plugin thực hiện

Đoạn mã sau có chứa việc thực hiện hai thuật toán được đề cập ở trên. Đối với mỗi một, chúng tôi thực hiện 2 phương pháp mã hóa và giải mã văn bản của chúng tôi:

Như bạn có thể thấy, chúng tôi đã xuất ở đây 3 biểu tượng khác nhau (Golang chỉ xuất các số nhận dạng này bắt đầu bằng chữ cái trên):

  • EncryptCeasar - chuỗi func (int, chuỗi) mã hóa văn bản bằng thuật toán Ceasar,
  • DecryptCeaser - chuỗi func (int, chuỗi) giải mã văn bản bằng thuật toán Caeser,
  • VermanCodes - biến kiểu vermanCodes thực hiện 2 phương thức: Mã hóa: chuỗi func (chuỗi) và Giải mã: func () (* chuỗi, lỗi)

Để biên dịch plugin này, bạn phải chạy lệnh sau:

đi xây dựng -buildmode = plugin -o plugin / cext.so plugin / cext.go

Hiện tại, không có gì đặc biệt - một vài chức năng đơn giản đã được tạo và một mô-đun được biên dịch thành plugin bằng cách thêm đối số -buildmode = plugin.

Tải và kiểm tra plugin

Niềm vui bắt đầu khi chúng tôi muốn sử dụng plugin được biên dịch trong ứng dụng của mình. Hãy tạo ra một ví dụ đơn giản:

Đầu tiên, bạn cần nhập gói plugin golang. Nó chỉ chứa hai hàm - hàm thứ nhất dùng để tải thư viện dùng chung và hàm thứ hai dùng để tìm biểu tượng xuất. Để tải thư viện của bạn, bạn phải sử dụng chức năng Mở yêu cầu cung cấp đường dẫn đến plugin được chia sẻ của bạn và trả về biến loại Plugin. Nếu không thể tải thư viện (ví dụ: đường dẫn không chính xác hoặc tệp bị hỏng), chức năng này sẽ trả về lỗi phải xử lý.

Bước tiếp theo là tải mọi biểu tượng đã xuất bằng phương thức Tra cứu. Một bất tiện nhỏ là bạn cần tải riêng từng chức năng xuất. Tuy nhiên, bạn có thể kết hợp nhiều chức năng với nhau theo cùng một cách như đã được thực hiện cho biểu tượng VermanCodes. Khi bạn đã tải tất cả các biểu tượng bạn muốn sử dụng, bạn phải đặt chúng vào đúng loại. Golang là ngôn ngữ gõ tĩnh nên không có cách nào khác để sử dụng các ký hiệu này mà không cần truyền. Hãy nhớ rằng, khi bạn xuất một biến thực hiện một vài phương thức, bạn cần chuyển nó sang loại giao diện chính xác (tôi phải xác định giao diện mã hóaEngine để xử lý việc này). \ Newline \ newline

Để biên dịch và chạy ứng dụng, sử dụng lệnh sau:

đi xây dựng ứng dụng
./app

Trong đầu ra, bạn sẽ thấy văn bản được mã hóa và giải mã như một bằng chứng cho thấy thuật toán hoạt động chính xác.

Sử dụng plugin trong AWS lambda

Để sử dụng plugin của chúng tôi trong AWS Lambda, chúng tôi cần thực hiện một vài sửa đổi trong ứng dụng của mình:

  • AWS Lambda gắn kết các lớp vào thư mục / opt trong thùng chứa lambda, vì vậy chúng tôi phải tải plugin của chúng tôi từ thư mục này.
  • Chúng ta cần tạo một hàm xử lý sẽ được sử dụng bởi công cụ Lambda để xử lý sự kiện thử nghiệm của chúng ta.

Đoạn mã sau chứa ứng dụng của chúng tôi được điều chỉnh để Lambda sử dụng:

Như bạn có thể thấy việc thực hiện rất giống với lần trước. Chúng tôi chỉ thay đổi thư mục mà chúng tôi đã tải plugin của mình và thêm phản hồi chức năng thay vì in các giá trị. Nếu bạn muốn tìm hiểu thêm về cách viết Lambdas bằng golang, vui lòng kiểm tra tài liệu AWS.

Triển khai AWS Lambda

Có hai cách để triển khai các chức năng và lớp AWS Lambda. Bạn có thể tạo và tải lên gói nén bằng tay hoặc sử dụng khung nâng cao hơn, điều này làm cho nó dễ dàng hơn và nhanh hơn nhiều. Đối với hầu hết các dự án của tôi, tôi sử dụng khung Serverless, vì vậy tôi đã chuẩn bị tệp cấu hình serverless.yml đơn giản bằng công cụ này:

dịch vụ: cryptService
frameworkVersion: "> = 1.28.0 <2.0.0"
các nhà cung cấp:
  tên: aws
  thời gian chạy: go1.x
các lớp:
  mật mã:
    đường dẫn: bin / plugin
    tương thích Thời gian:
      - go1.x
chức năng:
  động cơ:
    xử lý: bin / mật mãEngine
    gói:
      loại trừ:
        - ./
      bao gồm:
        - ./bin/codesEngine
    các lớp:
      - {Tham chiếu: CodesLayerLambdaLayer}

Trong phần các lớp, chúng tôi đã xác định một lớp duy nhất với đường dẫn đến plugin đã được tạo - nó sẽ được triển khai cùng với chức năng lambda. Bạn có thể xác định tối đa 5 lớp khác nhau mà thứ tự thực sự quan trọng. Chúng được gắn vào cùng thư mục / opt, vì vậy các lớp có số lượng cao hơn có thể ghi đè lên các tệp từ các lớp được gắn trước đó. Đối với mỗi lớp, bạn cần cung cấp ít nhất 2 tham số: đường dẫn đến thư mục chứa nguồn lớp (đường dẫn đến tệp nhị phân của plugin trong trường hợp của bạn) và danh sách thời gian chạy tương thích.

Phần chức năng tiếp theo là nơi bạn xác định danh sách các chức năng sẽ được triển khai. Đối với mọi chức năng, bạn cần cung cấp ít nhất đường dẫn đến ứng dụng đã biên dịch. Ngoài ra, chúng ta cần xác định tham số lớp với tham chiếu đến lớp được xác định ở trên. Điều này sẽ tự động gắn lớp vào chức năng Lambda của chúng tôi trong quá trình triển khai. Điều thú vị là bạn phải chuyển đổi tên lớp lambda của mình thành TitleCase và thêm hậu tố LambdaLayer nếu bạn muốn tham khảo tài nguyên đó. Có vẻ như nhóm Serverless đã triển khai nó theo cách này để giải quyết xung đột với tham chiếu đến các loại tài nguyên khác nhau.

Khi tệp cấu hình serverless.yml của chúng tôi đã sẵn sàng, điều cuối cùng cần làm là biên dịch ứng dụng, plugin và triển khai nó. Chúng ta có thể sử dụng Makefile đơn giản cho việc đó:

.PHONY: xây dựng bản dựngPlugin triển khai sạch
xây dựng:
 dep đảm bảo -v
 env GOOS = linux đi xây dựng
buildPlugin:
 env GOOS = linux hãy xây dựng
dọn dẹp:
 rm -rf ./bin ./vendor Gopkg.lock
triển khai: xây dựng sạchPlPlin xây dựng
 triển khai sls --verbose

Bạn có thể xây dựng và triển khai chức năng của mình bằng cách chạy lệnh sau:

thực hiện triển khai

Kiểm tra AWS Lambda

Như tôi đã đề cập trước đó AWS Lambda thực thi mã trong phản ứng với sự kiện. Tuy nhiên, chúng tôi không định cấu hình bất kỳ trình kích hoạt sự kiện nào, vì vậy nó đã thắng được gọi mà không cần sự giúp đỡ của chúng tôi. Chúng ta phải thực hiện thủ công bằng cách sử dụng khung Serverless hoặc công cụ awscli:

sls gọi -f function_name
aws lambda invoke - tên hàm function_name output_file

Trong phản hồi, bạn sẽ thấy đầu ra giống như trước đây, điều này chứng tỏ rằng hàm lambda của chúng tôi hoạt động chính xác và tải plugin từ lớp bổ sung. Bây giờ bạn có thể tạo các chức năng khác sẽ sử dụng cùng một lớp hoặc thậm chí chia sẻ nó với các tài khoản AWS khác.

Tóm lược

Thật thú vị khi sử dụng các mô-đun Golang và thử nghiệm cách tích hợp chúng với các Lớp AWS Lambda mới được phát hành. Thư viện plugin thực sự tuyệt vời, tuy nhiên vì những hạn chế và đặc tả Golang, nó chỉ có thể được sử dụng trong một số tình huống đặc biệt. Tôi nghĩ rằng đối với hầu hết các nhà phát triển đang làm việc trên các dự án tiêu chuẩn, nó sẽ giành được sự cần thiết hoặc thậm chí có thể sử dụng các plugin. Chỉ có hai lý do đến với tôi:

  • Việc thực hiện các thuật toán phức tạp có thể được sử dụng bởi các ứng dụng khác. mã hóa video hoặc thuật toán mã hóa.
  • Chia sẻ thuật toán của bạn với người khác mà không cần xuất bản mã của nó.