Connection Pooling sinh ra để làm gì?
Khi làm việc với cơ sở dữ liệu cho những hệ thống tương đối lớn thì vấn đề rất quan trọng đó là đảm bảo yêu cầu hiệu năng cao. Một trong những vấn đề cần thiết nhất đó là phải xử lý để tối ưu số kết nối tới cơ sở dữ liệu.
Đối với lập trình viên mới vào nghề, bình thường với mỗi client request sẽ mở 1 kết nối tới database server và rồi lại đóng lại. Việc tạo và hủy các kết nối tới DB sẽ ảnh hưởng rất nhiều tới hiệu năng của ứng dụng bởi chúng cần thực hiện tiến trình quản lý tài nguyên cơ sở dữ liệu.
Điển hình là database server sẽ mất từ 1 đến 3s để thiết lập kết nối tới DB (trong đó bao gồm giao tiếp với server, chứng thực, và còn cả tá tác vụ khác). Và việc này cần thực hiện cho mỗi yêu kết nối tới server, nó sẽ không thể đáp ứng cho ứng dụng hiệu năng cao được.
Vậy giải pháp được đưa ra bởi các nhà cung cấp đó là phải quản lý và chia sẻ số kết nối – đó chính là kỹ thuật connection pooling.
Vậy Connection Pooling là gì?
Connection Pooling (tạm dịch là:
vùng kết nối):
là kỹ thuật cho phép tạo và duy trì 1 tập các kết nối dùng chung nhằm tăng hiệu suất cho các ứng dụng web bằng cách sử dụng lại các kết nối khi có yêu cầu thay vì việc tạo kết nối mới.Connection pooling làm việc như thế nào?
CPM (Connection Pool Manager) là trình quản lý vùng kết nối sẽ duy trì và vận hành 1 tập các kết nối cơ sở dữ liệu. Mỗi khi có yêu cầu kết nối tới cơ sở dữ liệu, CPM sẽ kiểm tra xem có kết nối nào đang rỗi, nó sẽ lấy kết nối đó ra thực hiện yêu cầu.
Nếu tất cả các kết nối trong CPM đều bận và pool chưa đầy (chưa đạt tới max số kết nối quy định trước) thì 1 kết nối mới sẽ được tạo ra và được CPM đưa vào Pool .
Khi Pool đầy thì các kết nối tiếp theo sẽ bị đưa vào hàng đợi, chờ đến khi nào có 1 kết nối trong Pool bị timeout hoặc chuyển sang trạng thái sẵn sàng.
Triển khai Connection Pooling trong JSP Servlet thế nào?
1. Tạo Context Resource
- Trong webapp, tạo folder META-INF
- Trong META-INF tạo file context.xml
Trong file context chúng ta cấu hình Resource cho Connection Pooling
<Context>
<Resource name="jdbc/codeleanvn" auth="Container" type="javax.sql.DataSource"
maxTotal="100" maxIdle="30" maxWaitMillis="10000"
username="root" password="" driverClassName="com.mysql.cj.jdbc.Driver"
url="jdbc:mysql://192.168.64.5:3306/javatest?useSSL=false"/>
</Context>
maxTotal(int) maxTotal="100" số lượng kết nối tối đa tại 1 thời điểm. Ví dụ trong hình maxTotal=100 nghĩa là 100 kết nối cùng lúc TẠI CÙNG 1 THỜI ĐIỂM. nếu để maxTotal=-1 có nghĩa là no limit, là không giới hạn.
maxIdle(int): maxIdle="30" là số lượng kết nối nhàn rỗi được duy trì tối đa. maxIdle=30 có nghĩa là nếu hiện tại hệ thống có í người kết nối ví dụ 10 20 thì số lượng kết nối được duy trì trong bể vẫn luôn là 30, để đảm bảo độ sẵn sàng cho dự án.
Chúng ta cần quy định cả 2 tham số, vì maxTotal để xác định giới hạn tối đa số lượng người dùng cùng kết nối tới database tại một thời điểm (ví dụ đây là 100). Nếu quá 100 thì xếp hàng chờ.
Còn maxIdel sẽ là số lượng connection luôn luôn được duy trì, nếu hệ thống đang không có quá nhiều người dùng, ý là hệ thống đang rảnh :D (ví dụ nếu có từ 1-30 người, thì hệ thống luôn duy trì 30 kết nối).
Điều này sẽ đảm bảo tối ưu hóa nguồn tài nguyên.
Ngoài ra, người ta hay nói "đợi chờ là hạnh phúc" .. nhưng hạnh phúc có lúc cũng cần giới hạn :D
Kết nối tới database cũng vậy, đợi mãi đợi hoài là không được, nên cần có giới hạn thời gian chờ đợi để tối ưu hóa tài nguyên.
Ta có maxWaitMillis maxWaitMillis="10000" là số mili giây tối đa đợi kết nối, sau số giây này thì coi như ko kết nối được, để hệ thống chuyển sang việc khác. Vậy trong ví dụ trên ... thì time đợi kết nối là 10 giây, sau 10 giây không được là báo lỗi
2. Sau bước này thì ta cần configure tham chiếu tới resource web.xml
Trong file web.xml ta thêm cấu hình resouce-ref (tham chiếu tới resouce)
<resource-ref>
<description>Student Connection</description>
<res-ref-name>jdbc/codeleanvn</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
3. Ta có thể tham chiếu tới kết nối đơn giản như sau
3.1 Nếu muốn sử dụng Connection Pool trong Servlet
Để tạo kết nối tới cơ sở dữ liệu thông qua Connection Pool:
1. Bạn khởi tạo Context rồi lookup resource và convert về DataSource
2. Sau đó getConnection là okie.
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
DataSource ds = (DataSource)
envCtx.lookup("jdbc/codeleanvn");
Connection conn = ds.getConnection();
//...use this connection to access the database ...
conn.close();
Bạn click vào đây để xem ví dụ hoàn chỉnh về Servlet với Connection Pooling
3.2 Nếu muốn sử dụng Connection Pool trong JSP
Ta dùng SQL JSTL, đặt dataSource là tên resource đã configue ở trên context.xml
thực hiện truy vấn
<sql:query var="rs" dataSource="jdbc/codeleanvn">
select id, foo, bar from testdata
</sql:query>
Truy vấn xong, ta có thể dùng JSTL để hiển thị
Bạn click vào đây để xem ví dụ hoàn chỉnh về JSP với Connection Pooling <c:forEach var="row" items="${rs.rows}">
Foo ${row.foo}<br/>
Bar ${row.bar}<br/>
</c:forEach>
Hy vọng bài viết đã giúp bạn bước đầu tiếp cận với Connection Pooling.
Để rõ hơn về các bước cụ thể, triển khai trong ví dụ mời bạn đọc 2 bài viết sau:
- 1. Connection Pooling với JSP
- 2. Connection Pooling với Servlet
إرسال تعليق