Những gì tôi sẽ nói trong câu trả lời này không dành riêng cho Kohana, và có thể áp dụng cho rất nhiều dự án PHP.
Đây là một số điểm xuất hiện trong đầu tôi khi nói về hiệu suất, khả năng mở rộng, PHP, ...
Tôi đã sử dụng nhiều ý tưởng đó khi làm việc trên một số dự án - và chúng đã giúp ích; vì vậy họ có thể cũng có thể giúp đỡ ở đây.
Trước hết, khi nói đến màn trình diễn, có nhiều khía cạnh / câu hỏi cần được xem xét :
- cấu hình của máy chủ (cả Apache, PHP, MySQL, các daemon có thể có khác và hệ thống) ; bạn có thể được trợ giúp thêm về điều đó trên ServerFault , tôi cho rằng,
- Mã PHP,
- Truy vấn cơ sở dữ liệu,
- Sử dụng hay không sử dụng máy chủ web của bạn?
- Bạn có thể sử dụng bất kỳ loại cơ chế bộ nhớ đệm nào không? Hay bạn luôn cần thêm dữ liệu cập nhật trên trang web?
Sử dụng proxy ngược
Điều đầu tiên có thể thực sự hữu ích là sử dụng proxy ngược , như varnish , trước máy chủ web của bạn: hãy để nó lưu vào bộ nhớ cache nhiều thứ nhất có thể , vì vậy chỉ những yêu cầu thực sự cần tính toán PHP / MySQL (và tất nhiên, một số khác các yêu cầu, khi chúng không có trong bộ đệm ẩn của proxy) chuyển nó tới Apache / PHP / MySQL.
- Trước hết, CSS / Javascript / Hình ảnh của bạn - tốt, mọi thứ tĩnh - có thể không cần phải luôn được Apache phục vụ
- Vì vậy, bạn có thể có bộ nhớ cache proxy ngược tất cả những thứ đó.
- Cung cấp các tệp tĩnh đó không phải là vấn đề lớn đối với Apache, nhưng nó càng ít phải làm việc cho những tệp đó, thì nó càng có thể làm được nhiều hơn với PHP.
- Hãy nhớ rằng: Apache chỉ có thể phục vụ một số lượng yêu cầu hữu hạn, có giới hạn tại một thời điểm.
- Sau đó, yêu cầu proxy ngược cung cấp càng nhiều trang PHP càng tốt từ bộ đệm: có thể có một số trang không thay đổi thường xuyên và có thể được phân phát từ bộ đệm. Thay vì sử dụng một số bộ đệm dựa trên PHP, tại sao không để một máy chủ khác, nhẹ hơn, phục vụ chúng (và thỉnh thoảng tìm nạp chúng từ máy chủ PHP, vì vậy chúng luôn được cập nhật) ?
- Ví dụ: nếu bạn có một số nguồn cấp dữ liệu RSS (Chúng tôi thường có xu hướng quên những nguồn cấp dữ liệu này , khi cố gắng tối ưu hóa cho hiệu suất) được yêu cầu rất thường xuyên , việc đưa chúng vào bộ nhớ cache trong vài phút có thể lưu hàng trăm / nghìn yêu cầu vào Apache + PHP + MySQL!
- Tương tự đối với các trang được truy cập nhiều nhất trên trang web của bạn, nếu chúng không thay đổi trong ít nhất vài phút (ví dụ: trang chủ?) , Thì không cần lãng phí CPU để tạo lại chúng mỗi khi người dùng yêu cầu.
- Có thể có sự khác biệt giữa các trang được cung cấp cho người dùng ẩn danh (cùng một trang cho tất cả người dùng ẩn danh) và các trang được cung cấp cho người dùng đã xác định (ví dụ: "Xin chào Mr X, bạn có tin nhắn mới") ?
- Nếu vậy, bạn có thể có thể định cấu hình proxy ngược để lưu vào bộ nhớ cache của trang được phân phát cho người dùng ẩn danh (thường dựa trên cookie, như cookie phiên)
- Điều đó có nghĩa là Apache + PHP ít phải đối phó hơn: chỉ những người dùng đã được xác định - có thể chỉ là một phần nhỏ trong số người dùng của bạn.
Ví dụ: về việc sử dụng proxy ngược làm bộ nhớ đệm , đối với ứng dụng PHP, bạn có thể xem kết quả điểm chuẩn Hiển thị khả năng máy chủ tăng 400% -700% với APC và Squid Cache .
(Đúng, họ đang sử dụng Squid, và tôi đã nói về véc ni - đó chỉ là một khả năng khác ^^ Vecni mới ra đời hơn, nhưng chuyên dụng hơn cho bộ nhớ đệm)
Nếu bạn làm điều đó đủ tốt và quản lý để ngừng tạo lại quá nhiều trang lặp đi lặp lại, có thể bạn thậm chí sẽ không phải tối ưu hóa bất kỳ mã nào của mình ;-)
Ít nhất, có thể không phải vội vàng ... Và tốt hơn hết bạn nên thực hiện tối ưu hóa khi bạn không bị bắt quá nhiều ...
Như một phụ chú: bạn đang nói trong OP:
Một trang web mà tôi xây dựng với Kohana đã bị đánh sập với lượng truy cập khổng lồ vào ngày hôm qua,
Đây là loại tình huống đột ngột mà ngược lại proxy có thể tiết kiệm thời gian theo đúng nghĩa đen , nếu trang web của bạn có thể đối phó với việc không được cập nhật vào giây thứ hai:
- cài đặt nó, cấu hình nó, để nó luôn - mọi ngày bình thường - chạy:
- Định cấu hình nó để không giữ các trang PHP trong bộ nhớ cache; hoặc chỉ trong một thời gian ngắn; bằng cách này, bạn luôn có dữ liệu cập nhật được hiển thị
- Và, vào ngày bạn thực hiện hiệu ứng gạch chéo hoặc digg:
- Định cấu hình proxy ngược để giữ các trang PHP trong bộ nhớ cache; hoặc trong một khoảng thời gian dài hơn; có thể các trang của bạn sẽ không được cập nhật trước thứ hai, nhưng nó sẽ cho phép trang web của bạn tồn tại sau hiệu ứng digg!
Về điều đó, Làm cách nào tôi có thể phát hiện và sống sót khi bị “Slashdotted”? có thể là một bài đọc thú vị.
Về mặt PHP của những thứ:
Trước hết: bạn có đang sử dụng phiên bản PHP gần đây không? Thường xuyên có những cải tiến về tốc độ, với các phiên bản mới ;-)
Ví dụ: hãy xem Điểm chuẩn của các Chi nhánh PHP 3.0 đến 5.3-CVS .
Lưu ý rằng hiệu suất là một lý do chính đáng để sử dụng PHP 5.3 ( tôi đã thực hiện một số điểm chuẩn (bằng tiếng Pháp) , và kết quả rất tuyệt) ...
Một lý do khá tốt khác, tất nhiên là PHP 5.2 đã hết tuổi thọ , và không được duy trì nữa!
Bạn có đang sử dụng bất kỳ bộ nhớ cache opcode nào không?
- Tôi đang nghĩ về APC - Ví dụ: PHP Cache thay thế ( pecl , thủ công ) , đây là giải pháp mà tôi thấy được sử dụng nhiều nhất - và nó được sử dụng trên tất cả các máy chủ mà tôi đã làm việc.
- Nó thực sự có thể làm giảm tải CPU của máy chủ rất nhiều, trong một số trường hợp (tôi đã thấy tải CPU trên một số máy chủ tăng từ 80% xuống 40%, chỉ bằng cách cài đặt APC và kích hoạt chức năng opcode-cache!)
- Về cơ bản, việc thực thi một tập lệnh PHP trải qua hai bước:
- Biên dịch mã nguồn PHP thành mã opcodes (loại tương đương với bytecode của JAVA)
- Thực thi các mã opcodes đó
- APC giữ những mã này trong bộ nhớ, vì vậy sẽ có ít công việc phải thực hiện hơn mỗi khi tập lệnh / tệp PHP được thực thi: chỉ tìm nạp các mã opc từ RAM và thực thi chúng.
- Bạn có thể cần phải xem xét các tùy chọn cấu hình của APC , nhân tiện
- có khá nhiều trong số đó, và một số có thể có tác động lớn đến cả tốc độ / tải CPU / dễ sử dụng cho bạn
- Ví dụ, vô hiệu hóa
[apc.stat](https://php.net/manual/en/apc.configuration.php#ini.apc.stat)
có thể tốt cho quá trình tải hệ thống; nhưng nó có nghĩa là các sửa đổi được thực hiện đối với các tệp PHP sẽ không được tính đến trừ khi bạn xóa toàn bộ opcode-cache; về điều đó, để biết thêm chi tiết, hãy xem ví dụ To stat () hoặc Not To stat ()?
Sử dụng bộ nhớ cache cho dữ liệu
Càng nhiều càng tốt, tốt hơn là tránh làm đi làm lại cùng một việc .
Tất nhiên, điều chính tôi đang nghĩ đến là Truy vấn SQL: nhiều trang của bạn có thể thực hiện các truy vấn giống nhau và kết quả của một số trong số đó có lẽ gần như luôn giống nhau ... Điều đó có nghĩa là rất nhiều truy vấn "vô dụng" được thực hiện cho cơ sở dữ liệu, cơ sở dữ liệu này phải dành thời gian phục vụ cùng một dữ liệu lặp đi lặp lại.
Tất nhiên, điều này đúng với những thứ khác, như lệnh gọi Dịch vụ web, tìm nạp thông tin từ các trang web khác, tính toán nặng, ...
Nó có thể rất thú vị để bạn xác định:
- Truy vấn nào được chạy nhiều lần, luôn trả về cùng một dữ liệu
- Các phép tính (nặng) nào khác được thực hiện nhiều thời gian, luôn trả về cùng một kết quả
Và lưu trữ những dữ liệu / kết quả này trong một số loại bộ nhớ đệm, để chúng dễ lấy hơn - nhanh hơn - - và bạn không phải truy cập máy chủ SQL của mình để "không có gì".
Ví dụ: các cơ chế bộ nhớ đệm tuyệt vời là:
- APC : ngoài opcode-cache mà tôi đã nói trước đó, nó cho phép bạn lưu trữ dữ liệu trong bộ nhớ,
- Và / hoặc memcached ( xem thêm ) , rất hữu ích nếu bạn thực sự có nhiều dữ liệu và / hoặc đang sử dụng nhiều máy chủ , vì nó được phân phối.
- tất nhiên, bạn có thể nghĩ về các tệp; và có thể là nhiều ý tưởng khác.
Tôi khá chắc chắn rằng khuôn khổ của bạn đi kèm với một số thứ liên quan đến bộ nhớ cache; bạn có thể đã biết điều đó, như bạn đã nói "Tôi sẽ sử dụng thư viện Cache nhiều hơn trong thời gian tới" trong OP ;-)
Hồ sơ
Bây giờ, một điều thú vị cần làm là sử dụng tiện ích mở rộng Xdebug để lập hồ sơ ứng dụng của bạn : nó thường cho phép tìm ra một vài điểm yếu khá dễ dàng - ít nhất, nếu có bất kỳ chức năng nào mất nhiều thời gian.
Được định cấu hình đúng cách , nó sẽ tạo ra các tệp cấu hình có thể được phân tích bằng một số công cụ đồ họa, chẳng hạn như:
- KCachegrind : yêu thích của tôi, nhưng chỉ hoạt động trên Linux / KDE
- Wincachegrind dành cho windows; nó thực hiện ít công việc hơn KCacheGrind một chút, thật không may - nó thường không hiển thị đồ thị cuộc gọi.
- Webgrind chạy trên máy chủ web PHP nên hoạt động ở mọi nơi - nhưng có lẽ ít tính năng hơn.
Ví dụ, đây là một vài ảnh chụp màn hình của KCacheGrind:
(nguồn: pascal-martin.fr ) (nguồn: pascal-martin.fr )
(BTW, bảng gọi được trình bày trên ảnh chụp màn hình thứ hai thường là thứ mà cả WinCacheGrind và Webgrind đều không thể làm được, nếu tôi nhớ không nhầm ^^)
(Cảm ơn @Mikushi đã nhận xét) Một khả năng khác mà tôi chưa sử dụng nhiều là tiện ích mở rộng xhprof : nó cũng giúp lập hồ sơ, có thể tạo các biểu đồ gọi - nhưng nhẹ hơn Xdebug, có nghĩa là bạn có thể cài đặt nó trên một máy chủ sản xuất.
Bạn sẽ có thể sử dụng nó bên ngoài XHGui , điều này sẽ giúp hiển thị dữ liệu.
Về mặt SQL của mọi thứ:
Bây giờ chúng ta đã nói một chút về PHP, hãy lưu ý rằng nhiều khả năng nút thắt cổ chai của bạn không phải là phía PHP , mà là cơ sở dữ liệu ...
Ít nhất hai hoặc ba điều, ở đây:
- Bạn nên xác định:
- Các truy vấn thường xuyên nhất mà ứng dụng của bạn đang thực hiện là gì
- Liệu chúng có được tối ưu hóa hay không ( chủ yếu là sử dụng các chỉ mục phù hợp ?) , Bằng cách sử dụng
EXPLAIN
hướng dẫn, nếu bạn đang sử dụng MySQL
- liệu bạn có thể lưu vào bộ nhớ cache một số truy vấn này không (xem những gì tôi đã nói trước đó)
- MySQL của bạn có được cấu hình tốt không? Tôi không biết nhiều về điều đó, nhưng có một số tùy chọn cấu hình có thể có một số tác động.
Tuy nhiên, hai điều quan trọng nhất là:
- Đừng truy cập DB nếu bạn không cần thiết: cache càng nhiều càng tốt !
- Khi bạn phải truy cập vào DB, hãy sử dụng các truy vấn hiệu quả: sử dụng các chỉ mục; và hồ sơ!
Và làm gì bây giờ?
Nếu bạn vẫn đang đọc, điều gì khác có thể được tối ưu hóa?
Chà, vẫn còn chỗ để cải tiến ... Một vài ý tưởng theo định hướng kiến trúc có thể là:
- Chuyển sang kiến trúc n-tier:
- Đặt MySQL trên một máy chủ khác (2 tầng: một cho PHP; một cho MySQL)
- Sử dụng một số máy chủ PHP (và cân bằng tải người dùng giữa những máy chủ đó)
- Sử dụng một máy khác cho các tệp tĩnh, với một máy chủ web nhẹ hơn, như:
- lighttpd
- hoặc nginx - cái này ngày càng trở nên phổ biến hơn, btw.
- Sử dụng một số máy chủ cho MySQL, một số máy chủ cho PHP và một số proxy ngược trước những máy chủ đó
- Tất nhiên: cài đặt các daemon memcached trên bất kỳ máy chủ nào có dung lượng RAM trống và sử dụng chúng để lưu vào bộ nhớ cache nhiều nhất có thể / hợp lý.
- Sử dụng cái gì "hiệu quả hơn" mà Apache?
- Tôi ngày càng nghe nhiều hơn về nginx , được cho là tuyệt vời khi nói đến PHP và các trang web có dung lượng lớn; Bản thân tôi chưa bao giờ sử dụng nó, nhưng bạn có thể tìm thấy một số bài báo thú vị về nó trên mạng;
Chà, có lẽ một số ý tưởng đó hơi quá mức cần thiết trong tình huống của bạn ^^
Nhưng, vẫn ... Tại sao không nghiên cứu chúng một chút, đề phòng? ;-)
Còn Kohana thì sao?
Câu hỏi ban đầu của bạn là về việc tối ưu hóa một ứng dụng sử dụng Kohana ... Chà, tôi đã đăng một số ý tưởng đúng với bất kỳ ứng dụng PHP nào ... Có nghĩa là chúng cũng đúng với Kohana ;-)
(Ngay cả khi không cụ thể về nó ^^)
Tôi đã nói: sử dụng bộ nhớ cache; Kohana dường như hỗ trợ một số nội dung bộ nhớ đệm (Bạn đã tự nói về nó, vì vậy không có gì mới ở đây ...)
Nếu có bất cứ điều gì có thể được thực hiện nhanh chóng, hãy thử nó ;-)
Tôi cũng nói bạn không nên làm bất cứ điều gì không cần thiết; Có thứ gì được bật theo mặc định trong Kohana mà bạn không cần không?
Duyệt qua mạng, có vẻ như có ít nhất một cái gì đó về lọc XSS; bạn có cần cái đó không
Tuy nhiên, đây là một số liên kết có thể hữu ích:
Phần kết luận?
Và, để kết luận, một suy nghĩ đơn giản:
- Công ty của bạn sẽ phải trả bao nhiêu tiền cho bạn trong 5 ngày? - coi đó là khoảng thời gian hợp lý để thực hiện một số tối ưu hóa tuyệt vời
- Công ty của bạn sẽ tốn bao nhiêu tiền để mua (trả tiền?) Một máy chủ thứ hai và bảo trì nó?
- Điều gì sẽ xảy ra nếu bạn phải mở rộng quy mô lớn hơn?
- Chi phí bao nhiêu để dành 10 ngày? hơn? tối ưu hóa mọi bit có thể có của ứng dụng của bạn?
- Và bao nhiêu cho một vài máy chủ nữa?
Tôi không nói rằng bạn không nên tối ưu hóa: bạn chắc chắn nên!
Nhưng hãy thực hiện tối ưu hóa "nhanh chóng" sẽ giúp bạn nhận được phần thưởng lớn trước tiên: sử dụng một số bộ nhớ cache opcode có thể giúp bạn giảm từ 10 đến 50% tải CPU của máy chủ ... Và chỉ mất vài phút để thiết lập; - ) Mặt khác, chi tiêu 3 ngày cho 2 phần trăm ...
Ồ, và, btw: trước khi làm bất cứ điều gì: hãy đặt một số công cụ giám sát vào vị trí , để bạn biết những cải tiến nào đã được thực hiện và cách làm!
Nếu không có giám sát, bạn sẽ không biết hiệu quả của những gì bạn đã làm ... Thậm chí nếu đó là một tối ưu hóa thực sự hay không!
Ví dụ, bạn có thể sử dụng một cái gì đó như RRDtool + xương rồng .
Và hiển thị cho sếp của bạn một số đồ họa đẹp mắt với mức giảm tải 40% CPU luôn luôn tuyệt vời ;-)
Dù sao, và để thực sự kết luận: vui vẻ!
(Vâng, tối ưu hóa rất thú vị!)
(Ồ, tôi không nghĩ mình sẽ viết nhiều như vậy ... Hy vọng ít nhất một số phần của điều này là hữu ích ... Và tôi nên nhớ câu trả lời này: có thể hữu ích vào một số lần khác. ..)