Cách kết nối với AWS RDS MySQL Java

Bây giờ, chúng ta đã đề cập đến việc thiết lập AWS Lambdas để kết nối với các phiên bản RDS và Proxy RDS, hãy xem qua đoạn mã cần thiết để xác thực Java AWS Lambdas của bạn thông qua Xác thực IAM, cũng như xác thực người dùng/pwd truyền thống. Chúng tôi cũng sẽ đề cập đến việc khắc phục sự cố vì điều này hiếm khi hoạt động trong lần thử đầu tiên. 😅😅😅

từ chối trách nhiệm
I Love My Local Farmer là một công ty hư cấu lấy cảm hứng từ tương tác của khách hàng với AWS Solutions Architects. Bất kỳ câu chuyện nào được kể trong blog này đều không liên quan đến một khách hàng cụ thể. Những điểm tương đồng với bất kỳ công ty, con người hoặc tình huống thực tế nào hoàn toàn là ngẫu nhiên. Các câu chuyện trong blog này thể hiện quan điểm của các tác giả và không được AWS chứng thực

Xác thực đối với cơ sở dữ liệu RDS (hoặc RDS Proxy) thông qua Người dùng/Pwd trong Java

Mã trông giống như một kết nối JDBC thông thường

public static Connection createConnectionViaUserPwd(
@NonNull String username, @NonNull String pwd,
@NonNull String dbEndpoint) {
Connection connection;
try {
connection =
DriverManager.getConnection(JDBC_PREFIX + dbEndpoint,
username, pwd);
logger.info("Connection Established");
return connection;
} catch (SQLException e) {
logger.info("Connection FAILED");
logger.error(e.getMessage(), e);
}
return null;
}

Tuy nhiên, điều nổi bật là kết nối db phải được thiết lập trong khối tĩnh của trình xử lý Lambda

public class PopulateFarmDb 
implements RequestHandler {

static {
try {
con = DbUtil.createConnectionViaUserPwd(
DB_ADMIN_USER, DB_ADMIN_PWD, DB_ENDPOINT);
} catch (Exception e) {
logger.info("INIT connection FAILED");
logger.error(e.getMessage(), e);
}
}
@Override
public String handleRequest(Object event, Context context) {

Lý do khởi tạo kết nối cơ sở dữ liệu trong khối tĩnh chứ không phải trong phương thức handleRequest() là vì chúng tôi muốn duy trì kết nối DB trong Lambda giữa các lần gọi handleRequest. Nói cách khác, chúng tôi muốn Lambda duy trì đối tượng kết nối ngay cả sau khi yêu cầu kết thúc. Bằng cách này, chúng tôi chỉ trả tiền phạt về độ trễ kết nối đối với yêu cầu đầu tiên mà Lambda xử lý và mọi lệnh gọi tiếp theo đều sử dụng kết nối đã thiết lập (hoàn thành sau một phần nghìn giây)

Trong trường hợp của Lambda PopulateFarmDb, việc này không quá quan trọng vì chúng tôi chỉ gọi Lambda này một lần để điền vào các bảng và tạo người dùng lambda_iam. nhưng chúng tôi vẫn làm theo cách này để mọi người tập thói quen

Ngoài ra, hãy lưu ý rằng chúng ta đang chuyển thông tin đăng nhập của người dùng và điểm cuối cơ sở dữ liệu vào hàm. Chúng tôi làm điều đó bằng cách lưu trữ ARM của bí mật người dùng và điểm cuối db trong các biến môi trường Lambda, có thể được truy xuất trong mã thông qua Hệ thống. getenv()

Sau đó, chúng tôi sử dụng SecretsUtil. lớp java để gọi Trình quản lý bí mật để truy xuất bí mật của người dùng và giải mã thông tin đăng nhập

static final JSONObject DB_ADMIN_SECRET =          
SecretsUtil.getSecret(DB_REGION,
System.getenv("DB_ADMIN_SECRET"));
static final String DB_ADMIN_USER =
(String) DB_ADMIN_SECRET.get("username");
static final String DB_ADMIN_PWD =
(String) DB_ADMIN_SECRET.get("password");

Xác thực qua RDS IAM Authentication trong Java

Mặc dù với RDS IAM auth, chúng tôi cũng khởi tạo kết nối DB trong khối tĩnh, mã java để thực hiện IAM auth lại là một câu chuyện hoàn toàn khác. Một trong những lý do chính là chúng tôi cần tạo mã thông báo xác thực thay vì chỉ nhập mật khẩu

Mã kết nối trông như thế này

public Connection createConnectionViaIamAuth(
@NonNull String username,
@NonNull String dbEndpoint,
@NonNull String region) {
Connection connection;
try {
setSslProperties();
connection =
DriverManager.getConnection(
JDBC_PREFIX + dbEndpoint,
setMySqlConnectionProperties(username,
dbEndpoint,
region));
return connection;
} catch (Exception e) {
logger.info("Connection FAILED");
logger.error(e.getMessage(), e);
}
return null;
}

Để tạo mã thông báo xác thực, trước tiên chúng tôi đã tải xuống chứng chỉ RDS (chúng tôi đã chọn chứng chỉ toàn cầu nhưng bạn cũng có thể thử chứng chỉ khu vực), sau đó lưu trữ chứng chỉ đó trong thư mục ApiHandlers/resources

Sau khi có chứng chỉ RDS, mã thông báo xác thực có thể được tạo bằng cách sử dụng RdsUtilities của Java SDK v2

private static String generateAuthToken(
String username, String dbEndpoint, String region){
RdsUtilities utilities = RdsUtilities.builder()
.credentialsProvider(DefaultCredentialsProvider.create())
.region(Region.of(region))
.build();
GenerateAuthenticationTokenRequest authTokenRequest =
GenerateAuthenticationTokenRequest.builder()
.username(username)
.hostname(dbEndpoint)
.port(3306)
.build();
String authenticationToken =
utilities.generateAuthenticationToken(authTokenRequest);
return authenticationToken;
}

Xin lưu ý rằng RdsUtilities là phiên bản Java SDK v2 của RdsIamAuthTokenGenerator của Java SDK v1. Ban đầu chúng tôi sử dụng v1 nhưng sau đó phát hiện ra rằng v2 là anh em họ hiệu suất cao hơn của v1. Để xem triển khai đầy đủ, vui lòng xem DbUtils. java

Để đảm bảo chứng chỉ RDS (*. pem) được đóng gói vào Lambda, chúng tôi đưa thư mục tài nguyên vào bản dựng. hướng dẫn lớp

main.resources.srcDirs = ['scripts','resources']

Điều này đặt nội dung của thư mục tài nguyên vào thư mục gốc của lambda được tạo. zip và do đó làm cho nó có thể truy cập được chỉ bằng tên tệp bên trong Lambda

private static final String SSL_CERTIFICATE = 
"rds-ca-2019-root.pem";

private static X509Certificate createCertificate()
throws Exception {
URL url = new File(SSL_CERTIFICATE).toURI().toURL();

Mã hoàn chỉnh quá dài để sao chép toàn bộ trong bài đăng này, nhưng bạn có thể tìm thấy nó trong DbUtil. java

Quyết định xử lý sự cố
Mặc dù Proxy RDS có thể che giấu một số vấn đề về kết nối, nhưng bạn vẫn cần xử lý lỗi trên mã máy khách của mình. Ví dụ: nó không thể phát lại các giao dịch trên máy bay khi xảy ra lỗi… vì vậy nếu bạn đã đưa ra một câu lệnh CRUD và cơ sở dữ liệu bị lỗi trong quá trình đó vì bất kỳ lý do gì, bạn sẽ phải phát hành lại câu lệnh của mình

Một điều khác mà chúng tôi nhận thấy là chúng tôi phải xây dựng việc kiểm tra tính hợp lệ của đối tượng kết nối trước khi thực hiện bất kỳ câu lệnh Sql nào, bởi vì nếu kết nối trực tiếp bị đóng (e. g. trong sự kiện chuyển đổi dự phòng DB), Lambda sẽ giữ đối tượng kết nối hiện đã chết và Proxy RDS sẽ không tái chế nó. Để tránh sự cố này, chúng tôi kiểm tra và khởi tạo lại kết nối khi bắt đầu mỗi yêu cầu

Vì vậy, câu hỏi bây giờ là, chúng ta cần xử lý lỗi ở mức độ nào? . Điều này là do chúng tôi đang sử dụng ApiGateway trước Lambdas của chúng tôi và nó giới hạn các yêu cầu ở mức tối đa là 30 giây. và các sự cố quan trọng về cơ sở dữ liệu có thể sẽ không được giải quyết trong khoảng thời gian đó

Do đó, hiện tại, chúng tôi đang để ứng dụng khách của ứng dụng khách Lambda (trong trường hợp của chúng tôi là ứng dụng Magento) xử lý các lần thử lại dài dòng và chỉ quan tâm đến các lỗi kết nối ở cấp độ Lambda phục hồi dễ dàng hơn (e. g. lỗi mạng)

Khắc phục sự cố kết nối proxy RDS

Giúp đỡ. Phải làm gì khi không có gì hoạt động

Mẹo. Trước hết, hãy bật Ghi nhật ký nâng cao của Proxy RDS của bạn. tin tôi đi, nó sẽ giúp bạn tiết kiệm rất nhiều thời gian. Khi thực hiện, bạn sẽ tìm thấy nhật ký CloudWatch dưới tên Proxy RDS của mình cùng với một số thông tin kết nối hữu ích

Ví dụ: nơi Lambda của bạn chỉ có thể đăng nhập

[ERROR] Lập trình Lỗi. 1045 (28000). Truy cập bị từ chối đối với người dùng ‘lambda_iam’@’%’ (sử dụng mật khẩu. VÂNG)

trong nhật ký RDS Proxy, bạn sẽ tìm thấy một số loại đá quý hữu ích hơn như

Không thể truy xuất thông tin đăng nhập. Vai trò IAM “arn. aws. tôi là. 123456789012. role/DeliveryProject-Db-RdsProxyRole4…” không được phép đọc bí mật AWS Secrets Manager với ARN “arn. aws. người quản lý bí mật. eu-tây-2. 123456789012. bí mật. DbUserSecret-…”

hoặc là

Xác thực proxy với xác thực mật khẩu riêng của MySQL không thành công đối với người dùng “lambda_iam” khi bật TLS. Lý do. Thông tin không hợp lệ. Nếu bạn cung cấp mã thông báo IAM, hãy đảm bảo sử dụng đúng mật khẩu hoặc bật xác thực IAM

Thông tin này giúp tôi nhận ra rằng tôi đã thiếu chính sách IAM phù hợp để truy cập một trong các Bí mật và chứng chỉ của tôi không được sử dụng đúng cách để tạo mã thông báo xác thực
Hãy nhớ rằng cài đặt sẽ tự tắt sau 24 giờ

Mẹo. Đặt Thời gian chờ không hoạt động của Proxy RDS thành 1 (chỉ thực hiện trong Bảng điều khiển AWS) trong khi bạn kiểm tra. Tôi nhận thấy rằng đôi khi tôi thay đổi cài đặt để ngắt kết nối RDS Proxy nhưng Lambdas của tôi vẫn có thể kết nối. vì vậy rõ ràng là họ có thể cõng trên một kết nối đã được thiết lập đã hoạt động trước đó, mặc dù bây giờ tôi có cấu hình không tốt. Cũng vì lý do này, hãy đảm bảo 'tái chế' Lambda của bạn khi bạn thay đổi cài đặt (e. g. bằng cách thay đổi dung lượng bộ nhớ trên bảng điều khiển)

Mẹo. Nếu bạn không thể kết nối với Proxy RDS, hãy thử kết nối với cơ sở dữ liệu RDS từ máy cục bộ của bạn. Xin lưu ý rằng bạn không thể kết nối trực tiếp từ máy tính để bàn cục bộ của mình với proxy RDS. Để có thể thực hiện việc này, bạn sẽ phải cho phép các kết nối đến từ địa chỉ IP của mình vào cơ sở dữ liệu RDS

Truy cập Bảng điều khiển AWS và chỉnh sửa Nhóm bảo mật VPC của phiên bản RDS. Thêm Quy tắc gửi đến cho Loại MySql/Aurora và chọn MyIp làm Nguồn. Điều này sẽ cho phép địa chỉ IP của thiết bị của bạn kết nối với phiên bản RDS. Bây giờ hãy thử kết nối với MySql Workbench/Toad/dòng lệnh với tư cách là người dùng quản trị bằng mật khẩu của anh ấy, sau đó cũng thử kết nối với người dùng lambda_iam và mật khẩu của nó. Bạn có thể lấy mật khẩu đã tạo bằng cách vào bảng điều khiển Trình quản lý bí mật của mình và mở tệp DbUserSecret**(i. e. người dùng lambda_iam DB) và DeliveryProjectDbFarmer** (tôi. e. bí mật người dùng DB của quản trị viên)

Mẹo. Điều này làm chúng tôi bối rối ngay từ đầu. tính đến thời điểm viết bài này (tháng 6 năm 2021), RDS Proxy chưa hỗ trợ RDS MySql 8. Cơ sở hạ tầng của chúng tôi được hỗ trợ bằng cách sử dụng CDK vì nó giúp chúng tôi tiết kiệm một số bản tóm tắt cần thiết để mọi thứ hoạt động, nhưng trong trường hợp này, việc triển khai cdk sẽ không thành công mà không có dấu hiệu cho thấy điều gì sai 😑
Đảm bảo kiểm tra kỹ phiên bản RDS MySql bạn đang sử dụng với các giới hạn RDS Proxy

Các vấn đề kết nối khác và giải pháp của họ

Lỗi. Xác thực proxy với xác thực IAM không thành công đối với người dùng “lambda_iam” khi bật TLS. Lý do. Thông tin không hợp lệ. Nếu bạn cung cấp mã thông báo IAM, hãy đảm bảo sử dụng đúng mật khẩu hoặc bật xác thực IAM
Giải pháp. mã thông báo xác thực không được tạo đúng cách. Đảm bảo rằng chứng chỉ của bạn được bao gồm trong tệp zip lambda của bạn

Lỗi. java. sql. SQLException. Truy cập bị từ chối đối với người dùng ‘lambda_iam’@’%’ (sử dụng mật khẩu. KHÔNG)
Giải pháp. Đảm bảo biến môi trường DB_ENDPOINT của IAM-Auth Lambda của bạn trỏ đến điểm cuối của proxy mà không bao gồm “. 3306” biểu thị cổng

Nếu bạn vẫn gặp sự cố, đây là các tài nguyên khác để giúp bạn lấy lại sự tỉnh táo

  • Bài đăng này có một danh sách đơn giản những điều cần kiểm tra khi bạn phải khắc phục sự cố
  • Bài đăng này đã giúp tôi thiết lập mọi thứ trên bảng điều khiển để tôi có thể chắc chắn rằng các dịch vụ và chính sách IAM đã được thiết lập đúng
  • Bộ mã này đã giúp tôi kiểm tra một Python Lambda đơn giản, xem thiết lập RDS Proxy của tôi có hoạt động bình thường hay không
  • có thêm rất nhiều thông tin về mọi thứ liên quan đến RDS Proxy

Hy vọng bạn thích bài đăng này và nó hữu ích cho bạn. Như mọi khi, phản hồi luôn được hoan nghênh, vì vậy đừng ngại và để lại nhận xét

Làm cách nào để kết nối với cơ sở dữ liệu AWS RDS trong Java?

Kết nối với Phiên bản CSDL RDS .
Mở bảng điều khiển Elastic Beanstalk và trong danh sách Khu vực, hãy chọn Khu vực AWS của bạn
Trong ngăn điều hướng, chọn Môi trường rồi chọn tên môi trường của bạn từ danh sách. .
Trong ngăn điều hướng, chọn Cấu hình

Làm cách nào để kết nối với AWS RDS bằng MySQL Workbench?

Độ phân giải .
Mở MySQL Workbench, sau đó chọn dấu ⊕ bên cạnh MySQL Connections để thiết lập kết nối mới
Trong hộp thoại Thiết lập kết nối mới, nhập tên cho kết nối của bạn
Trong phần Tham số, nhập các chi tiết này
Tên máy chủ. Nhập điểm cuối RDS
Hải cảng. Nhập số cổng

Làm cách nào để kết nối cơ sở dữ liệu RDS với Spring Boot?

Quy trình phát triển .
Đăng nhập vào Bảng điều khiển AWS
Thiết lập cơ sở dữ liệu MySQL trên đám mây AWS bằng AWS RDS
Kết nối với cơ sở dữ liệu MySQL với bàn làm việc của MySQL để xác minh kết nối
Sao chép mã nguồn ứng dụng khởi động Spring từ GitHub
Cập nhật ứng dụng. tệp thuộc tính để thay đổi thuộc tính URL cơ sở dữ liệu MySQL

Lệnh kết nối phiên bản RDS MySQL là gì?

Để kết nối với cơ sở dữ liệu trên phiên bản CSDL bằng màn hình MySQL .
Mở bảng điều khiển RDS rồi chọn Cơ sở dữ liệu để hiển thị danh sách các phiên bản CSDL của bạn
Chọn tên phiên bản Cơ sở dữ liệu MySQL để hiển thị chi tiết của nó
Trên tab Kết nối & bảo mật, sao chép điểm cuối. Ngoài ra, lưu ý số cổng