Chương trình chạy tốt trên máy mình mà hỏng trên máy chủ thì gần như luôn do khác biệt môi trường: phiên bản phần mềm, cấu hình, quyền truy cập tệp, dữ liệu, múi giờ hay bộ nhớ đệm. Cách gỡ là liệt kê từng khác biệt rồi loại trừ dần, và về lâu dài là làm cho hai môi trường giống nhau nhất có thể.
Chào bạn, đây là Nhà Lập Trình. Câu nói trên máy em chạy mà anh có lẽ là câu nói nổi tiếng nhất trong nghề, nổi tiếng đến mức thành chuyện đùa. Nhưng lúc gặp thật thì chẳng buồn cười chút nào, nhất là khi đang đêm và khách hàng đang chờ. Tập này mình kể những khác biệt hay gặp nhất và cách đi tìm.
Máy của bạn và máy chủ là hai thế giới
Máy tính của bạn là nơi bạn đã cài cắm đủ thứ qua nhiều tháng. Có thư viện bạn cài từ lâu rồi quên. Có biến cấu hình bạn đặt một lần rồi thôi. Có quyền quản trị cho phép làm mọi thứ. Có dữ liệu thử nghiệm sạch sẽ, ít ỏi.
Máy chủ là một thế giới khác. Hệ điều hành có thể khác. Phiên bản ngôn ngữ có thể cũ hơn hoặc mới hơn. Chương trình chạy dưới một tài khoản có quyền hạn chế. Dữ liệu thật thì nhiều, bẩn, đủ kiểu lạ. Và có nhiều người dùng cùng lúc.
Mỗi khác biệt là một chỗ tiềm năng để chương trình hỏng. Và vì bạn đã quen với máy mình đến mức không còn để ý những gì mình đã cài, bạn không nghĩ ra ngay đâu là khác biệt.
Nên việc đầu tiên khi gặp loại lỗi này là thôi hỏi vì sao mã sai, mà hỏi hai máy khác nhau ở đâu.
Bảy khác biệt hay gặp nhất
Thứ nhất là phiên bản. Ngôn ngữ, thư viện, cơ sở dữ liệu trên máy chủ khác phiên bản với máy bạn. Một hàm mới có trên máy bạn nhưng chưa có trên máy chủ cũ. Thứ hai là thư viện thiếu: bạn dùng một thư viện đã cài sẵn trên máy mình nhưng quên khai báo trong danh sách phụ thuộc của dự án.
Thứ ba là cấu hình: tệp cấu hình trên máy chủ khác, thiếu một biến, sai một đường dẫn, sai địa chỉ cơ sở dữ liệu. Thứ tư là quyền: chương trình trên máy chủ không có quyền ghi vào thư mục tải lên, không có quyền đọc một tệp. Trên máy bạn thì bạn là quản trị, làm gì cũng được.
Thứ năm là phân biệt chữ hoa chữ thường trong tên tệp. Có hệ điều hành coi hai tên khác nhau ở chữ hoa là một, có hệ điều hành coi là hai. Tệp tên có chữ hoa được gọi bằng chữ thường chạy tốt trên máy bạn, hỏng trên máy chủ.
Thứ sáu là dữ liệu: dữ liệu thật có những trường hợp mà dữ liệu thử không có. Thứ bảy là bộ nhớ đệm: máy chủ vẫn đang chạy mã cũ đã được giữ trong bộ nhớ, dù bạn đã đưa mã mới lên. Mình đã thấy người ta sửa mã mười lần mà không có tác dụng, chỉ vì máy chủ chưa hề nạp lại.
So sánh có hệ thống
Khi gặp lỗi, đừng đoán từng khác biệt một cách ngẫu nhiên. Hãy lập danh sách và kiểm tra từng dòng. Phiên bản ngôn ngữ hai bên là gì? Phiên bản các thư viện chính? Cấu hình có khác gì? Chương trình chạy dưới tài khoản nào?
Đọc nhật ký lỗi trên máy chủ trước tiên. Rất nhiều lần, nhật ký nói thẳng: không tìm thấy lớp này, không có quyền ghi tệp kia. Người ta tốn cả giờ đoán trong khi câu trả lời nằm sẵn trong nhật ký.
Nếu được, thử chạy chương trình trên máy chủ bằng tay, trong môi trường thử nghiệm của máy chủ, với cùng tài khoản mà chương trình thật dùng. Bạn sẽ thấy lỗi xuất hiện trực tiếp, kèm thông báo đầy đủ.
Tuyệt đối tránh thử sửa trực tiếp trên máy chủ đang phục vụ khách. Một thay đổi vội trên máy thật có thể làm hỏng thêm thứ khác, và thay đổi đó không nằm trong hệ thống quản lý phiên bản, lần triển khai sau sẽ bị ghi đè hoặc gây nhầm lẫn.
Làm hai môi trường giống nhau hơn
Về lâu dài, cách tốt nhất để tránh loại lỗi này là thu hẹp khoảng cách giữa hai môi trường. Bước đầu là ghi rõ mọi phụ thuộc của dự án kèm phiên bản cụ thể, trong một tệp được lưu cùng mã. Ai cài dự án cũng cài đúng những phiên bản đó.
Bước tiếp là dùng cùng phiên bản ngôn ngữ và cơ sở dữ liệu với máy chủ. Nhiều đội dùng công nghệ đóng gói môi trường, để chương trình chạy trong một chiếc hộp giống hệt nhau ở mọi nơi. Không phải đội nào cũng cần, nhưng nguyên lý thì ai cũng nên theo.
Có một môi trường thử nghiệm giống máy chủ thật, gọi là môi trường chạy thử trước khi phát hành. Mọi thay đổi lên đây trước, chạy vài ngày, rồi mới lên máy thật. Lỗi môi trường sẽ lộ ra ở đây thay vì trước mặt khách hàng.
Và đưa mã lên máy chủ bằng một quy trình tự động, lặp lại được, thay vì chép tay từng tệp. Chép tay là cách nhanh nhất để quên một tệp hoặc chép nhầm phiên bản.
Bài học vượt ra ngoài kỹ thuật
Câu trên máy em chạy mà thường được nói với chút tự vệ. Người viết mã cảm thấy mình đã làm đúng, lỗi là do máy chủ. Nhưng với người dùng, không có máy của bạn, chỉ có sản phẩm đang chạy trước mặt họ. Mã chạy trên máy bạn mà hỏng trên máy chủ thì vẫn là mã hỏng.
Người làm nghề trưởng thành coi môi trường chạy thật là một phần trách nhiệm của mình. Họ hỏi máy chủ dùng phiên bản gì trước khi viết. Họ thử trên môi trường giống thật trước khi nói xong.
Điều này không có nghĩa bạn phải tự quản trị máy chủ. Nhưng nó có nghĩa bạn nên hiểu mã của mình sẽ sống ở đâu, và nói chuyện thường xuyên với người vận hành nơi đó.
Một chương trình chỉ thật sự xong khi nó chạy đúng ở nơi người dùng gặp nó.
Câu hỏi thường gặp
Vì sao chương trình chạy trên máy mình mà lỗi trên máy chủ?
Thường do khác biệt môi trường như phiên bản ngôn ngữ và thư viện, cấu hình, quyền truy cập tệp, phân biệt chữ hoa thường trong tên tệp, dữ liệu thật hoặc bộ nhớ đệm chưa được làm mới.
Việc đầu tiên nên làm khi lỗi xảy ra trên máy chủ là gì?
Đọc nhật ký lỗi của máy chủ. Nhiều khi nhật ký đã nói rõ nguyên nhân như thiếu thư viện hoặc không có quyền ghi tệp.
Có nên sửa mã trực tiếp trên máy chủ để chữa cháy không?
Nên tránh. Thay đổi trực tiếp dễ gây lỗi thêm và không được lưu trong hệ thống quản lý phiên bản. Hãy sửa ở nơi phát triển rồi triển khai lại theo quy trình.
Môi trường chạy thử trước khi phát hành là gì?
Là một môi trường giống máy chủ thật nhất có thể, dùng để thử mọi thay đổi trước khi đưa tới người dùng. Nó giúp phát hiện lỗi môi trường sớm.
Làm sao để máy mình giống máy chủ hơn?
Ghi rõ mọi phụ thuộc kèm phiên bản, dùng cùng phiên bản ngôn ngữ và cơ sở dữ liệu với máy chủ, và cân nhắc dùng công nghệ đóng gói môi trường để chạy giống nhau ở mọi nơi.