Java Spring: Zero to Hero
Sê-ri 60 bài đi từ IoC container tới Spring MVC, Spring Data, Spring Security và đưa ứng dụng lên sản xuất. Mỗi bài có mã chạy được và số đo thật.
60/60 phần đã đăng
Spring
1
Ba bean của bạn, 263 bean của Spring: cái giá của tiện lợi, và khi nào nó đáng
Spring như một nhà thầu chính: bạn đưa bản vẽ 'cái gì cần cái gì', nó dựng đồ thị phụ thuộc, tạo theo đúng thứ tự và dọn sạch khi tắt. IoC khác thư viện thường ra sao, và cái giá — 266 bean, một giây khởi động — phải trả cho sự tiện lợi đó.
14/06/2026
· 7 phút đọc
2
Một dòng spring-boot-starter-web kéo vào hơn bốn mươi thư viện — và vì sao bạn không viết số phiên bản
Một starter là gọi suất combo thay vì gọi lẻ từng món; parent POM là nhà bếp đã thử sẵn các món hợp vị nhau. Dựng dự án từ start.spring.io, hiểu starter, cấu trúc thư mục, và fat jar chạy được.
15/06/2026
· 6 phút đọc
3
Vì sao Spring dựng mọi bean ngay lúc khởi động, và vì sao một biến int trong @Service là lỗi đua chờ sẵn
ApplicationContext như một xưởng trung tâm dựng sẵn mọi dụng cụ trước giờ mở cửa, lắp mỗi cái với thứ nó cần, rồi cho cả nhà mượn chung một cái. Ba cách khai bean, vòng đời, và vì sao trạng thái chia sẻ là bẫy.
16/06/2026
· 7 phút đọc
4
Tiêm qua trường cho ra đối tượng trông hợp lệ mà NPE lần dùng đầu — vì sao chỉ nên tiêm qua hàm khởi tạo
Ba cách tiêm phụ thuộc như ba cách trao đồ nghề cho thợ: trao lúc tuyển thì không có đồ là không tuyển được; trao qua khe sau lưng thì trông sẵn sàng mà vớ vào hư không. Vì sao tiêm qua hàm khởi tạo là cách duy nhất nên dùng, và cách xử lý nhiều cài đặt.
17/06/2026
· 6 phút đọc
5
Tiêm prototype vào singleton thì bạn có một singleton — cái bẫy scope im lặng của Spring
Singleton như cái máy pha cà phê chung cả văn phòng dùng, prototype như cái cốc giấy phát mới mỗi lần. Một thiết bị lắp cố định chỉ nhận đúng một cốc lúc lắp — đó là lý do prototype tiêm vào singleton chỉ được tạo một lần. Sáu scope và bốn cách chữa.
18/06/2026
· 7 phút đọc
6
Spring Boot đọc cấu hình từ hơn mười nguồn — in danh sách ra là hết đoán 'sao giá trị không chịu đổi'
Nhiều nguồn cùng ra lệnh cho một thuộc tính, và Spring nghe theo cấp cao nhất như một chuỗi mệnh lệnh. Thứ tự ưu tiên in ra từ chính ứng dụng, profile, và cách chọn nguồn cho từng loại giá trị.
19/06/2026
· 6 phút đọc
7
Gom @Value rải rác thành một record: cấu hình sai làm app không khởi động, thay vì nổ lúc 2 giờ sáng
@Value là những mẩu nhãn rời ghim khắp mã, mỗi cái giữ một chuỗi thô; @ConfigurationProperties là một tờ khai có ô định sẵn kiểu, và một nhân viên từ chối ngay tại quầy nếu ô nào sai. Record có kiểu, chuyển kiểu tự động, validation lúc khởi động.
20/06/2026
· 6 phút đọc
8
Bạn viết 3 bean, Spring Boot dựng thêm 263 — và cách đọc 143 quyết định nó làm sau lưng bạn
Auto-configuration như một người quản gia mở vali của bạn ra và bày phòng theo đồ mang tới — nhưng lùi lại ngay chỗ bạn đã tự tay sắp. Cơ chế @Conditional, cách đọc báo cáo, và ba cách can thiệp khi Boot đoán sai.
21/06/2026
· 6 phút đọc
9
Bốn dòng log khởi động trả lời hầu hết sự cố 'dịch vụ không lên' — và vì sao log ồn làm bạn bỏ lỡ cảnh báo thật
Log khởi động là bảng kiểm tiền-cất-cánh của ứng dụng: phiên bản, profile, cổng, thời gian lên. Giải phẫu từng dòng, cách bật thông tin cần, cấu hình log cho sản xuất, và vì sao log ồn che mất WARN thật.
22/06/2026
· 7 phút đọc
10
Vì sao Actuator che 'password' nhưng để lộ 'mat-khau' — và bốn cửa đừng bao giờ mở ra Internet
Actuator như dãy cửa dịch vụ của một toà nhà: cửa lễ tân ai cũng vào, nhưng cùng hành lang có cả cửa phòng điện và két sắt. Endpoint sức khoẻ, 53 chỉ số có sẵn, đổi mức log lúc đang chạy, và cách khoá đúng cửa cho sản xuất.
23/06/2026
· 7 phút đọc
11
Mọi request Spring đi qua đúng một cửa — và Filter khác Interceptor không phải ở việc làm, mà ở TẦNG
Một request như bưu phẩm qua trung tâm chia thư: cổng ngoài soát mọi kiện (Filter, tầng Servlet), một quầy điều phối trung tâm đọc địa chỉ rồi giao đúng nhân viên (DispatcherServlet → @Controller), và các chốt tại quầy chỉ thấy thư đã được định tuyến (Interceptor). Sáu bước in ra thật.
24/06/2026
· 6 phút đọc
12
Spring đã trả đúng 415, 400, 405 — đừng bắt Exception rồi đôn tất cả lên 500
RestController như người phiên dịch đứng giữa hai thứ tiếng: bên ngoài nói HTTP, bên trong nói Java. Nó bóc phong bì request thành tham số, gói kết quả thành response. Ánh xạ URL/method, path variable, query param, body, và ResponseEntity để cầm mã trạng thái lẫn header.
25/06/2026
· 6 phút đọc
13
Thiếu @Valid là mọi ràng buộc bị bỏ qua trong im lặng — và validation không bao giờ thay được kiểm nghiệp vụ
Bean Validation như một tấm khuôn úp lên dữ liệu đến: mỗi chú thích kiểm một ô phải vừa khuôn, và nó chỉ soát HÌNH DẠNG chứ không soát sự thật. @Valid khác @Validated, gom hết lỗi một lần, thông báo tiếng Việt, và ranh giới 400 với 409.
26/06/2026
· 6 phút đọc
14
Bắt Exception là biến mọi 400 và 415 của Spring thành 500 — kế thừa handler có sẵn, đừng bắt tất
Xử lý ngoại lệ như một bàn điều phối cấp cứu: mọi sự cố dồn về một chỗ, mỗi cái được gán một mã chuẩn. Bắt Exception là ông điều phối lười gán mọi cuộc gọi thành 'khẩn cấp chung'. @RestControllerAdvice, ProblemDetail chuẩn RFC 7807, và cách chữa.
27/06/2026
· 6 phút đọc
15
Trả entity JPA thẳng ra API là trao cả hồ sơ nội bộ cho khách — bốn thứ hỏng, và vì sao luôn cần DTO
Entity là hồ sơ nội bộ đầy tham chiếu chéo và ghi chú hậu trường; DTO là tờ tóm tắt bạn soạn riêng cho khách. Cấu hình Jackson mặc định của Spring, java.time xử lý sẵn, vòng lặp tham chiếu, và vì sao tách hợp đồng API khỏi CSDL.
28/06/2026
· 6 phút đọc
16
th:text tự thoát HTML, th:utext thì không — và đó là ranh giới giữa an toàn và một lỗ hổng XSS
Template như một lá thư mẫu có chỗ trống để điền: máy chủ trộn dữ liệu vào rồi gửi đi trang hoàn chỉnh. th:text điền bằng chữ thô nên chống XSS sẵn, th:utext thì không; phục vụ tài nguyên tĩnh, và khi nào chọn render máy chủ thay vì SPA.
29/06/2026
· 6 phút đọc
17
Hai điều về Filter và Interceptor đi ngược sách vở: Interceptor CÓ chạy cho file tĩnh, và request lỗi qua chuỗi lọc hai lần
Filter như cổng an ninh ngoài cùng của sân bay — ai cũng qua, kể cả hàng hoá; Interceptor như nhân viên cổng ra máy bay, biết chính xác chuyến của bạn. Đo bốn trường hợp biên, hai kết quả bất ngờ, và hệ quả với MDC, đếm chỉ số, xác thực.
30/06/2026
· 7 phút đọc
18
Vì sao curl không bao giờ báo lỗi CORS — và CORS không hề bảo vệ máy chủ của bạn
CORS như người quản gia thận trọng của chính trình duyệt bạn: nó giao thư đi tới mọi máy chủ, nhưng chỉ đọc hồi âm cho JavaScript nếu máy chủ cho phép. Preflight đo được, ba cách cấu hình, vì sao allowCredentials không đi với dấu sao.
01/07/2026
· 7 phút đọc
19
Đừng tin cái nhãn nào trên tệp người dùng tải lên — và SVG là mã chạy được, không phải ảnh
Nhận tệp như thợ thẩm định ở quầy cầm đồ: khách dán nhãn gì cũng được, người giỏi tin món đồ chứ không tin cái nhãn. Giới hạn kích thước, vì sao lỗi vượt trần lọt khỏi advice, và bốn việc phải làm với tệp người dùng.
02/07/2026
· 7 phút đọc
20
RestClient mặc định không có phép chờ — nó giữ luồng của bạn 15 phút và kéo sập cả hệ thống
Gọi HTTP như gọi điện sang phòng ban khác: không đặt phép chờ là cầm máy chờ mãi, 200 cuộc cùng chờ là nghẽn tổng đài. Đo phép chờ mặc định của RestTemplate/RestClient/WebClient, chọn client nào, và ba thứ phải có trước khi gọi ra ngoài.
03/07/2026
· 8 phút đọc
21
Danh sách rỗng vẫn là 200, 204 không được có thân — và khi nào REST là hình dạng sai cho API của bạn
API tốt như một thành phố bàn cờ có biển báo chuẩn: biết quy luật là tìm được mọi địa chỉ, và biển báo (mã trạng thái) nghĩa như nhau với mọi tài xế. Mã trạng thái đúng, 201 kèm Location, ETag cho 304, và những chỗ tranh cãi REST không đáng bỏ thời gian.
04/07/2026
· 7 phút đọc
22
Trang 5000 là truy vấn đắt nhất hệ thống, và đánh phiên bản bằng Accept header làm gãy mọi client cũ
Phân trang offset như đếm từ trang 1 mỗi lần để tới trang 5000 — và chỗ đứng xô lệch khi có người chèn trang vào đầu; con trỏ như cái kẹp sách đặt đúng dòng bạn dừng. Bốn cách đánh phiên bản, cái bẫy 406, và vì sao bản tốt nhất là bản không cần cắt.
05/07/2026
· 7 phút đọc
23
Một giao diện rỗng cho bạn cả tầng truy vấn — và tên phương thức sai thì ứng dụng không lên
Repository như ra lệnh cho một trợ lý cực kỳ máy móc: bạn không chỉ CÁCH tìm, chỉ đặt TÊN cho thứ mình muốn theo một văn phạm chặt, và nó dịch cái tên đó ra SQL. Truy vấn dẫn xuất từ tên, projection, và chỗ tên phương thức không còn đáng dùng.
06/07/2026
· 7 phút đọc
24
21 truy vấn cho thứ cần đúng 1 — và vì sao @ManyToOne mặc định EAGER là lỗi thiết kế của JPA
N+1 như đi chợ: lấy danh sách 20 món rồi quay lại chợ MỘT chuyến cho mỗi món — 21 chuyến cho thứ cần một. Đo trên dữ liệu thật, ba cách chữa với số truy vấn đo được, và vì sao khai LAZY cho mọi quan hệ.
07/07/2026
· 7 phút đọc
25
LazyInitializationException là tấm phiếu chỉ đổi được khi quầy chưa đóng — và vì sao OSIV giấu nó đi là một món nợ
Quan hệ lazy như tấm phiếu chỉ đổi được tại quầy đang mở (session); giao dịch đóng là quầy đóng, phiếu thành vô giá trị. OSIV giữ quầy mở cả buổi để che lỗi — đổi lại N+1 lúc render và kết nối bị giữ. Cách sửa đúng.
08/07/2026
· 7 phút đọc
26
@Transactional: tự gọi thì vô hiệu, checked exception vẫn commit, readOnly nuốt thay đổi — ba cái bẫy im lặng
@Transactional như một buồng đệm hai cửa: mọi thứ bên trong hoặc cùng qua cửa (commit) hoặc bị đẩy ngược lại (rollback). Nhưng buồng đệm gắn ở CỬA, nên tự gọi thì không đi qua nó; checked exception mặc định vẫn commit; readOnly âm thầm nuốt thay đổi.
09/07/2026
· 8 phút đọc
27
Bắt được ngoại lệ mà bản ghi vẫn không lưu — vì sao rollback-only không gỡ được, và REQUIRES_NEW
Giao dịch như bản nháp viết chì, chỉ tô mực (commit) ở phút cuối, một lỗi xoá cả trang. REQUIRED để việc con viết lên trang của bạn nên lỗi của nó đóng dấu huỷ cả trang; REQUIRES_NEW cho nó trang riêng. Bảy mức lan truyền dùng khi nào.
10/07/2026
· 7 phút đọc
28
Số dư -100 là bằng chứng khoá CHẠY ĐÚNG, số dư 0 mới là lỗi — ba cách xử lý hai luồng cùng rút tiền
Hai người cùng sửa một trang sổ cái: khoá bi quan là khoá sổ vào ngăn kéo với cây bút duy nhất; khoá lạc quan là photocopy trang rồi bị từ chối nếu phiên bản đã đổi. Đo ba cách, và vì sao con số trông an toàn hơn lại là con số sai.
11/07/2026
· 8 phút đọc
29
Bốn ô lọc là mười sáu tổ hợp truy vấn — Specification cho bạn không một nhánh if nào
Mỗi điều kiện lọc như một tấm kính lắp vào giá: tấm để trống là kính trong, lắp vào mà không chặn gì. Ghép hết lại bằng and, cái null tự rụng khỏi câu truy vấn. Criteria API, metamodel an toàn kiểu, và vì sao ?sort= là một lỗ SQL injection.
12/07/2026
· 6 phút đọc
30
Đọc thì đừng lấy cả entity — và vì sao entity làm DTO của API là rò rỉ dữ liệu trong im lặng
Projection như xin cô lễ tân một tờ phiếu ghi đúng vài trường bạn cần; entity như rút cả bộ hồ sơ sống ra khỏi tủ — ghi chú lên nó là tự động được lưu lại, nó nối sang hồ sơ khác, và nặng gấp đôi. Ba cách projection, và vì sao đừng đưa hồ sơ cho người ngoài.
13/07/2026
· 7 phút đọc
31
Bốn chỗ nên vứt ORM và viết SQL thẳng — và JdbcClient của Spring 6.1 làm nó gọn tới mức nào
ORM như một phiên dịch nói chuyện với CSDL hộ bạn: tuyệt cho hội thoại thường ngày, nhưng vụng khi phải soạn một văn bản kỹ thuật dày (báo cáo). JdbcClient so JdbcTemplate, ánh xạ record, và cái bẫy khi JDBC và JPA cùng chạm một dòng.
14/07/2026
· 7 phút đọc
32
Một dòng cấu hình làm JPA chèn nhanh gấp tám — và vì sao saveAll() không gộp lô gì cả
Mỗi câu INSERT gửi riêng như lái xe ra chợ mua đúng một món rồi về, lặp 5000 lần. Đo bốn cách chèn, dòng cấu hình duy nhất làm JPA nhanh gấp tám, và vì sao IDENTITY tắt hẳn gộp lô mà không báo.
15/07/2026
· 7 phút đọc
33
Sửa một dòng chú thích trong migration cũ và ứng dụng từ chối khởi động — vì sao đó là tính năng
Migration lược đồ như cuốn nhật ký chỉ-thêm: mỗi bước một mục đánh số, chạy lại theo thứ tự là ra đúng lược đồ hôm nay, mục đã viết thì niêm lại. Vì sao ddl-auto update không phải chiến lược, và cách đổi lược đồ không dừng dịch vụ.
16/07/2026
· 8 phút đọc
34
Pool lớn hơn không nhanh hơn — và khi cạn pool, request không xếp hàng mà bị ném ngoại lệ
Pool kết nối như một đội xe chung của công ty: ký mượn một chiếc, chạy việc, ký trả; hết xe thì bị từ chối chứ không xếp hàng vô hạn. Vì sao đội xe đông hơn không chạy việc nhanh hơn, bốn tham số HikariCP, và nguyên nhân thật của cạn pool.
17/07/2026
· 7 phút đọc
35
Cache nhanh hơn 357 lần chỉ trong một dòng — nhưng nửa khó của nó là câu 'ai xoá khi dữ liệu đổi'
Cache như tờ giấy dán trên cửa tủ lạnh: đọc nhanh hơn mở tủ đếm, nhưng nó nói dối nếu ai lấy đồ mà quên sửa. @Cacheable đo được, ba cái bẫy, cache tầng hai Hibernate, và ba câu hỏi trước khi thêm cache.
18/07/2026
· 9 phút đọc
36
H2 không phải PostgreSQL nhẹ hơn — nó là CSDL khác đóng thế, và ba chỗ nó diễn sai làm hỏng sản xuất
H2 như diễn viên đóng thế giống người thật ở cảnh dễ nhưng là một CSDL khác bên dưới. Bảng đối chiếu chín hành vi H2 và PostgreSQL — gồm ký tự NUL từng làm hỏng blog này — @DataJpaTest, Testcontainers, và test đếm số truy vấn.
19/07/2026
· 7 phút đọc
37
Redis chậm hơn cache bộ nhớ bảy lần, và cái bẫy: đếm thao tác thay vì đếm lượt đi về mạng
Cache trong bộ nhớ như cuốn sổ tay riêng trên bàn mỗi người; Redis như một tấm bảng chung ngoài hành lang ai cũng đọc cũng ghi — phải đi ra đó một chuyến, đổi lại ai cũng thấy cùng một thứ. Đo cache/session/khoá/bộ đếm, và vì sao phải đếm lượt đi về.
20/07/2026
· 9 phút đọc
38
Một dòng findAll() là đỉnh tảng băng — chốt chặng dữ liệu và bốn thói quen nhìn xuống dưới mặt nước
ORM giấu việc truy cập CSDL quá giỏi, và mọi vấn đề tốn kém của tầng dữ liệu nằm đúng ở chỗ nó giấu. Bảng quyết định rút từ bảy phép đo thật, ba dòng cấu hình đáng đặt vào mọi dự án, và bốn thói quen đáng mang theo.
21/07/2026
· 7 phút đọc
39
Thêm một phụ thuộc là mọi endpoint bị khoá — và Spring Security chỉ là 15 bộ lọc xếp hàng, không phép màu
Spring Security như một bộ lọc nước nhiều tầng: nước qua một dãy lõi cố định, mỗi lõi lọc đúng một thứ, sai thứ tự là hỏng cả dãy — và cái van cuối mặc định ĐÓNG. Mười lăm bộ lọc in ra thật, năm header tự bật, và cấu hình đúng thứ tự.
22/07/2026
· 7 phút đọc
40
BCrypt chậm 52ms là TÍNH NĂNG, và nó lặng lẽ bỏ qua mọi ký tự sau byte thứ 72
Băm mật khẩu như một ổ khoá một chiều nặng và quay chậm có chủ đích: kiểm được chìa nhưng không đọc ngược ra chìa. Đo BCrypt theo từng mức cost, giới hạn 72 byte, DelegatingPasswordEncoder, và cách đổi thuật toán mà không bắt ai đặt lại mật khẩu.
23/07/2026
· 8 phút đọc
41
Chặn endpoint không phải chặn dữ liệu — và vì sao USER gọi lọt hàm chỉ-ADMIN mà không ai hay
Phân quyền như một thư viện: thẻ chứng bạn là ai ở quầy, nhưng mỗi khu đọc, mỗi tủ khoá trong khu, và câu hỏi 'cuốn này của AI' là ba lớp khác nhau. 401 khác 403, cái bẫy tiền tố ROLE_, lỗ hổng tự gọi qua proxy, và IDOR.
24/07/2026
· 8 phút đọc
42
Gửi đúng token CSRF vẫn 403: ba cách Spring Security 6 làm gãy SPA, và vì sao 403 hiện ra thành 401
Cookie như tấm thẻ hội viên trình duyệt tự chìa ra ở mọi cửa của một tên miền — kể cả khi kẻ xấu đẩy bạn tới đó. CSRF đo từ đầu tới cuối, ba thay đổi của Security 6, và vì sao mã lỗi bạn thấy không phải mã ban đầu.
25/07/2026
· 8 phút đọc
43
JWT không mã hoá gì cả và không thu hồi được — ba câu hỏi phải trả lời trước khi bỏ session
JWT như vòng đeo tay lễ hội dán niêm: ai cũng đọc được chữ in trên đó, không giả được, nhưng cổng đã phát thì không thu lại được tới khi hết hạn. Session như vé gửi đồ. Đo bốn kiểu token giả bị chặn, chi phí ký/xác minh, và vì sao không thu hồi được là vấn đề thật.
26/07/2026
· 8 phút đọc
44
OAuth2 không phải để đăng nhập — nó là chìa khoá valet, và dùng nhầm nó để xác thực là một lỗ hổng
Access token của OAuth2 như chìa khoá valet: cho phép làm một việc cụ thể mà không phải là bạn; OIDC mới kẹp thêm tấm thẻ căn cước (id_token) trả lời 'ai'. Luồng duy nhất còn đúng năm 2026, PKCE, đăng nhập Google trong Spring, và ánh xạ vào người dùng.
27/07/2026
· 8 phút đọc
45
Header bảo mật: server viết luật, trình duyệt mới là người thi hành — nên script nội tuyến chết thật mà test vẫn xanh
Header bảo mật như nội quy server dán ở cửa, nhưng người gác cửa thi hành là trình duyệt. CSP là danh sách khách mời cho script. Sáu header đo được, CSP viết cho đúng, HSTS biến mất sau nginx, và cái bẫy test xanh.
28/07/2026
· 8 phút đọc
46
Tám lỗ hổng Spring hay gặp nhất, mỗi cái một lệnh để tự tìm — bắt đầu từ cái không test nào bắt được
Đi một vòng quanh toà nhà của mình rà từng cánh cửa: chỗ thủng không phải cửa chính (xác thực) mà là cánh cửa khoá rồi vẫn mở cho nhầm người (IDOR), lối kỹ thuật bị quên (Actuator), cái chuông gọi bất kỳ số nào (SSRF). Danh sách kiểm kèm cách tìm.
29/07/2026
· 8 phút đọc
47
Test bảo mật xanh vẫn để lọt 405 thay vì 403 — ba lỗ MockMvc không bao giờ thấy
MockMvc như tập dượt trên sân khấu dựng tạm: tái hiện tầng MVC rất thật, nhưng không có toà nhà thật quanh nó (container) và không có khán giả thật (trình duyệt). Ba loại lỗi chỉ lộ khi diễn thật, và bốn test bảo mật đáng viết.
30/07/2026
· 7 phút đọc
48
Trong bảo mật, cái gào thét thường vô hại còn cái giết bạn thì im lặng — chốt chặng 10 bài
Sáu kết quả đo đi ngược trực giác, bốn chỗ proxy làm chú thích biến mất, danh sách kiểm đầy đủ trước khi lên sản xuất, và ba nguyên tắc. Vì sao triệu chứng không bao giờ tương ứng với mức nghiêm trọng.
31/07/2026
· 8 phút đọc
49
Lát cắt test không phải thứ làm bộ test nhanh — số lần Spring dựng lại ngữ cảnh mới quyết định 3 phút hay 30 phút
Dựng một ngữ cảnh Spring như khởi động lại cả máy: bộ đệm ngữ cảnh dùng chung một lần khởi động cho mọi test cùng cấu hình, nhưng lệch một nút là khởi động lại từ đầu. Đo lát cắt, số bean, và thứ thật sự làm bộ test chậm.
01/08/2026
· 7 phút đọc
50
Biến rỗng không phải 'chưa cấu hình' — và thứ tự ưu tiên quyết định giá trị nào thắng trong Spring Boot
Cấu hình như một chồng tấm kính trong suốt: mặc định nằm dưới cùng, dòng lệnh nằm trên cùng thắng. Thứ tự ưu tiên đo được, @ConfigurationProperties bắt lỗi lúc khởi động, profile, và ba cái bẫy đã trả giá.
02/08/2026
· 8 phút đọc
51
Vì sao một dịch vụ phụ chậm đi lại khiến Kubernetes giết sạch pod của bạn — và cách Actuator chặn nó
Actuator biến ứng dụng từ hộp đen thành bệnh nhân có máy theo dõi. Health group cho Kubernetes, chỉ số Micrometer có sẵn, đổi mức log lúc đang chạy, và những endpoint tuyệt đối không được lộ ra.
03/08/2026
· 7 phút đọc
52
Thêm traceId vào mọi dòng log bằng hai dòng cấu hình — và chỗ nó lặng lẽ biến mất
traceId như mã vận đơn đóng dấu ở mọi trạm: kéo một số ra là thấy cả hành trình một request. Chỗ nó đứt khi qua luồng khác, log có cấu trúc, chi phí một dòng log, và giữ log sạch để 2 giờ sáng còn dùng được.
04/08/2026
· 7 phút đọc
53
Hàng đợi @Async mặc định của Spring phình tới hết heap, và @Scheduled với ba bản sao chạy ba lần
@Async như giao việc cho một tổ thư ký nhỏ có cái khay đựng việc; @Scheduled như cái đồng hồ báo thức treo trên tường VĂN PHÒNG NÀY. Pool từ chối việc, tự gọi chạy đồng bộ, ngoại lệ bị nuốt, và cách chạy định kỳ đúng khi có nhiều bản sao.
05/08/2026
· 7 phút đọc
54
publishEvent không gửi vào hàng đợi — nó là lời gọi phương thức đồng bộ, và một listener ném là cả dây chuyền dừng
Sự kiện ứng dụng nghe như hô một thông báo rồi đi, nhưng thật ra là bạn đi từng bàn vỗ vai từng người, đứng chờ, và ai làm rơi thì bạn dừng cả errand. Chạy đồng bộ, @TransactionalEventListener, và khi nào cần hàng đợi thật.
06/08/2026
· 7 phút đọc
55
Luồng ảo nhanh gấp 2,2 lần — nhưng chỉ khi pool luồng đang là nút thắt, và nút thắt chỉ dịch chỗ
Luồng nền như trạm thu phí có số làn cố định; luồng ảo gỡ bỏ trạm đó — nhưng xe lại dồn ở cây cầu hẹp phía sau (pool kết nối). Đo thật hai cấu hình, và ba chỗ luồng ảo không giúp gì.
07/08/2026
· 7 phút đọc
56
Mẹo làm Spring Boot khởi động nhanh nhất lại là mẹo bạn KHÔNG được dùng trên sản xuất — đo năm cấu hình
JVM cần khởi động như vận động viên cần khởi động: cắt phần đó thì ra vạch xuất phát nhanh nhưng chạy chậm. Đo RSS và thời gian lên của năm cấu hình Spring Boot, thứ thật sự làm chậm, và CDS/AOT — cái nhanh mà không đánh đổi.
08/08/2026
· 8 phút đọc
57
Mã của bạn là 12 KB trong jar 24 MB — và vì sao mỗi lần sửa một dòng lại đẩy đi cả 24 MB
Một jar gộp hết vào một tầng Docker như nhét cả vali vào một túi buộc kín: đổi một cái áo phải mở lại cả túi. Jar phân tầng đo được, buildpacks, và những thứ phải làm đúng trong container.
09/08/2026
· 7 phút đọc
58
Khởi động nhanh gấp mười, ăn RAM ít hơn 66% — và ba thứ bạn phải đánh đổi khi dựng ảnh native GraalVM
Ảnh native như bữa ăn đông lạnh: mở tủ mười giây có ăn, gọn nhẹ, nhưng đã đúc cứng không nêm lại được. Đo GraalVM native image của một ứng dụng Spring Boot thật: khởi động, bộ nhớ, kích thước, thời gian build, và ba thứ bạn mất.
11/08/2026
· 8 phút đọc
59
Bốn mươi dòng kiểm trước khi bấm nút triển khai — mỗi dòng đến từ một lần đã hỏng
Danh sách kiểm rút từ toàn bộ sê-ri: cấu hình, dữ liệu, bảo mật, quan sát, vận hành — kèm lệnh kiểm cho từng mục. Không phải lý thuyết, mà là những chỗ tôi đã từng ngã.
10/08/2026
· 7 phút đọc
60
Sáu mươi ngày Java Spring: vì sao 'chạy thử đi rồi hãy tin' là điều duy nhất đáng mang theo
Nhìn lại toàn bộ sê-ri: năm chặng, mười hai lần phép đo nói ngược trực giác, bốn chỗ proxy làm chú thích biến mất trong im lặng, và vì sao lời khuyên kỹ thuật có hạn sử dụng.
12/08/2026
· 8 phút đọc