https://www.google.com.vn/?gfe_rd=cr&ei=saWWVOaGKquL8QeSz4GgDw&gws_rd=ssl#q=setup+subdirectory+in+nginx
http://wiki.nginx.org/WordPress
http://robido.com/nginx/nginx-wordpress-subdirectory-configuration-example/
http://forum.nginx.org/read.php?11,2531
Hiển thị các bài đăng có nhãn nginx. Hiển thị tất cả bài đăng
Hiển thị các bài đăng có nhãn nginx. Hiển thị tất cả bài đăng
Chủ Nhật, 21 tháng 12, 2014
Thứ Hai, 15 tháng 12, 2014
Setting up a virtual host in Nginx
1. https://www.digitalocean.com/community/tutorials/how-to-set-up-nginx-virtual-hosts-server-blocks-on-ubuntu-12-04-lts--3
2. http://www.rackspace.com/knowledge_center/article/ubuntu-and-debian-nginx-virtual-hosts
3. http://www.codero.com/knowledge-base/questions/304/How+to+setup+nginx+%28with+directory+structure,+virtual+hosts,+port+forwarding%29,+mysql,+php,+fastcgi
4. https://www.udemy.com/blog/nginx-virtual-host/
5. http://www.nginxtips.com/nginx-virtual-hosts-server-blocks/
2. http://www.rackspace.com/knowledge_center/article/ubuntu-and-debian-nginx-virtual-hosts
3. http://www.codero.com/knowledge-base/questions/304/How+to+setup+nginx+%28with+directory+structure,+virtual+hosts,+port+forwarding%29,+mysql,+php,+fastcgi
4. https://www.udemy.com/blog/nginx-virtual-host/
5. http://www.nginxtips.com/nginx-virtual-hosts-server-blocks/
Thứ Ba, 25 tháng 11, 2014
How To Set Up nginx Virtual Hosts (Server Blocks) on Ubuntu 12.04 LTS
1. https://www.digitalocean.com/community/tutorials/how-to-set-up-nginx-virtual-hosts-server-blocks-on-ubuntu-12-04-lts--3
2. https://www.digitalocean.com/community/tutorials/how-to-set-up-nginx-server-blocks-virtual-hosts-on-ubuntu-14-04-lts
3. http://kbeezie.com/nginx-configuration-examples/
4. https://www.digitalocean.com/community/tutorials/how-to-configure-the-nginx-web-server-on-a-virtual-private-server
2. https://www.digitalocean.com/community/tutorials/how-to-set-up-nginx-server-blocks-virtual-hosts-on-ubuntu-14-04-lts
3. http://kbeezie.com/nginx-configuration-examples/
4. https://www.digitalocean.com/community/tutorials/how-to-configure-the-nginx-web-server-on-a-virtual-private-server
How To Install Linux, nginx, MySQL, PHP (LEMP) stack on Ubuntu 14.04
1. https://www.digitalocean.com/community/tutorials/how-to-install-linux-nginx-mysql-php-lemp-stack-on-ubuntu-14-04
2. How To Install Linux, nginx, MySQL, PHP (LEMP) stack on Ubuntu 12.04
3. http://www.unixmen.com/install-lemp-server-nginx-mysql-mariadb-php-phpmyadmin-ubuntu-14-1014-0413-10/
4. http://ubuntuhandbook.org/index.php/2014/04/install-nginx-with-php5-mysql-lemp-in-ubuntu-14-04-server/
2. How To Install Linux, nginx, MySQL, PHP (LEMP) stack on Ubuntu 12.04
3. http://www.unixmen.com/install-lemp-server-nginx-mysql-mariadb-php-phpmyadmin-ubuntu-14-1014-0413-10/
4. http://ubuntuhandbook.org/index.php/2014/04/install-nginx-with-php5-mysql-lemp-in-ubuntu-14-04-server/
Hướng dẫn cài đặt LEMP Server trên Ubuntu Precise 12.04
1. http://www.quantrimang.com.vn/m/huong-dan-cai-dat-lemp-server-tren-ubuntu-precise-12-04-87599#nav
2. http://hocvps.com/thu-thuat-toi-uu-lemp-server-tren-ubuntu/
3. http://hocvps.com/huong-dan-config-vps-chiu-tai-lon-voi-hocvps-script/
4. http://hostingaz.net/vps/huong-dan-cai-dat-lemp-linux-nginx-mysql-php-tren-ubuntu-12-04.html
5.
2. http://hocvps.com/thu-thuat-toi-uu-lemp-server-tren-ubuntu/
3. http://hocvps.com/huong-dan-config-vps-chiu-tai-lon-voi-hocvps-script/
4. http://hostingaz.net/vps/huong-dan-cai-dat-lemp-linux-nginx-mysql-php-tren-ubuntu-12-04.html
5.
Thứ Sáu, 1 tháng 8, 2014
Tối ưu hóa Nginx và PHP-FPM
Trong bài viết “Cài đặt Nginx và PHP-FPM trên CentOS 6”
mình đã trình về những bước cài đặt và cấu hình cơ bản của Nginx +
PHP-FPM. Trong bài viết tiếp theo này mình sẽ trình bày về một số cách
tối ưu, giúp chúng ta dễ dàng hơn trong việc quản lý, cũng như duy trì
hệ thống Web Server trên nền Nginx.
I – Tối ưu Nginx:
1) Bố trí lại các tệp tin cấu hình:
Thông thường thì các tệp tin cấu hình của Nginx sẽ được lưu trữ trong thư mục “/etc/nginx”. Một cách tổ chức lại việc lưu trữ tốt hơn theo phong cách của Apache như sau
Phần tệp tin cấu hình virtual host sẽ có 2 thư mục chính:
Vì chúng ta tách biệt phần file cấu hình của các virtual host ra lưu trữ riêng nên ta cần phải include dòng địa chỉ thư mục lưu trữ các file cấu hình này vào file cấu hình chính. Ở file nginx.conf ta thêm vào
Chú ý: Việc tối ưu lại cách sắp xếp này giúp chúng ta dễ dàng quản lý hệ thống webserver hơn chứ không có tác dụng tới hiệu suất tới hiệu suất.
2) Tối ưu worker_processes:
Với cấu hình mặc định, Nginx sẽ sử dụng một CPU để xử lý các tác vụ của mình. Tùy theo mức độ hoạt động của web server mà chúng ta có thể thay đổi lại thiết lập này. Ví dụ với các web server hay sử dụng về SSL, gzip thì ta nên đặt chỉ số của worker_processes này lên cao hơn. Nếu website của bạn có số lượng các tệp tin tĩnh nhiều, và dung lượng của chúng lớn hơn bộ nhớ RAM thì việc tăng worker_processes sẽ tối ưu băng thông đĩa của hệ thống.
Để xác định số cores của CPU của hệ thống ta có thể thực hiện lệnh
# cat /proc/cpuinfo | grep processor
Như ở trên, CPU của chúng ta có 4 cores. Để thay đổi mức sử dụng CPU của nginx ta sửa tệp tin cấu hình chính
# vi /etc/nginx/nginx.conf
Tại dòng số 3 ta thay đổi giá trị của worker_processes là 4.
3) Tối ưu worker_connections:
worker_connections sẽ cho biết số lượng connection mà CPU sẽ xử lý. Mặc định, số lượng connection này được thiết lập là 1024. Để xem về mức giới hạn sử dụng của hệ thống bạn có thể dụng lệnh ulimit
# ulimit –n
Con số thiết lập của worker_connections nên nhỏ hơn hoặc bằng giới hạn này!
Nếu bạn đã điều chỉnh lại giá trị worker_processes giúp Nginx sử dụng nhiều cores để xử lý các tác vụ hơn thì có thể thêm dòng cấu hình sau để tăng số lượng clients lên cao nhất
4) Tối ưu buffers (bộ nhớ đệm):
Một trong những cấu hình quan trọng để tối ưu Nginx là thiết đặt các giá trị buffer. Nếu bạn thiết lập bộ nhớ buffer quá nhỏ thì sẽ dễ dẫn tới tình trạng “thắt cỗ chai” khi web server của chúng ta tiếp nhận một lượng traffic lớn. Để thay đổi các giá trị buffer này, chúng ta có thể thêm vào các dòng cấu hình ở thẻ http của file cấu hình chính nginx.conf
Trong đó:
Trong đó:
Mặc định thì Nginx sẽ ghi lại các request lên một file trên đĩa cứng như là một việc ghi logs. Nêu bạn không sử dụng các access logs thì bạn có thể tắt tính năng này đi để giảm bớt thời gian nhập xuất. Để thực hiện điều này, trong thẻ server của file cấu hình chính nginx.conf bạn có thể đặt giá trị sau
6) Nén các gói dữ liệu gửi đi bằng Gzip
Gzip sẽ giúp nén các dữ liệu trước khi chuyển chúng tới Client. Đây là một cách để tăng tốc độ tuy cập website của cúng ta. Trong thẻ http của file cấu hình chính nginx.conf ta có thể thêm
7) Cache nội dung các tệp tin tĩnh:
Hầu hết các request từ client tới website của chúng ta để load các nôi dung như: hình ảnh, java script, css, flash,... Chúng ta nên thực hiện việc lưu cache lại các tệp tin có nội dung tĩnh này trên Nginx
8) Ẩn phiên bản của Nginx:
Việc ẩn đi phiên bản của Nginx từ Server Header sẽ giúp hệ thống webserver của chúng ta được bảo mật tốt hơn. Để thực hiện điều này, trong thẻ http của của tệp tin cấu hình chính nginx.conf ta thêm vào dòng sau
9) Thực thi các tệp tin PHP thông qua PHP-FPM:
Ở đây ta có thể sử dụng TCP/IP stack mặc định hoặc dùng trự tiếp Unix Socket Connection. Chúng ta cũng có thể sử dụng PHP-FPM để lắng nghe trên IP:Port (thường là 127.0.0.1:9000).
Chúng ta hoàn toàn có thể tách biệt PHP-FPM và Nginx chạy trên các server khác nhau.
10) Cấm các truy cập tới các tệp tin ẩn trên Nginx:
Đôi khi trên các thư mục web chúng ta có lưu những tệp tin ẩn (bắt đầu với dấu chấm “.”) như .svn, .htaccess. Đây là các tệp tin không mang tính public đối với người dùng. Để ngăn chặn các truy xuất tới các tệp tin ẩn này ta có thể thêm vào đoạn cấu hình sau
II – Tối ưu PHP-FPM
1) Bố trí lại các tệp tin cấu hình:
Thông thường thì các cấu hình của PHP-FPM được thiết lập trong file cấu hình /etc/php-fpm.conf và ở thư mục /etc/php-fpm.d. Các tệp tin cấu hình khác của PHP-FPM nên đặt trong cùng thư mục/etc/php-fpm.d. Chúng ta có thể thêm dòng cấu hình sau vào file php-fpm.conf để thực hiện điều này
2) Cấu hình nhiều PHP-FPM Pool:
Đối với PHP-FPM ta có thể tạo ra nhiều pool khác nhau cho các website khác nhau có trên web server. Bằng cách này chúng ta có thể có được các cấu hình cấp phát tài nguyên và nhóm sở hữu khác nhau đối với từn website. Ví dụ ở đây mình tạo 3 pool cho 3 website khác nhau là
/etc/php-fpm.d/site.conf
/etc/php-fpm.d/blog.conf
/etc/php-fpm.d/forums.conf
Các cấu hình mẫu:
/etc/php-fpm.d/site.conf
/etc/php-fpm.d/blog.conf
/etc/php-fpm.d/forums.conf
3) Cấu hình PHP-FPM Pool Process Manager (pm):
Trong việc quản lý các tiến trình của PHP-FPM ta nên sử dụng cách quản lý động để chỉ khởi động những tiến trình khi cần thiết. Các cấu hình ở đây cũng tương tự như là cấu hình các thông số của worker_porcess và worker_connection của Nginx mà mình đã trình bày ở trên. Tùy theo lượng truy cập tới website của chúng ta và dung lượng bộ nhớ RAM của web server hiện có mà ta có các cách cấu hình cho phù hợp.
Giải sử Web Server của chúng ta có 512 MB ram, ở những lúc website có lượng truy cập cao, ta check dung lượng bộ nhớ RAM hiện đang dùng (bằng lệnh top chẳn hạn). Dung lượng RAM được cấp phát cho PHP-FPM là 220 MB, mỗi tiến trình của nó sử dụng 24 MB. Ta có thể tính được giá trị của max_children là 220/24 = 9.17.
Vậy giá trị pm.max_children ta nên thiết đặt cho web server là 9.
Trong file cấu hình pool của website ta có thể có cấu hình mẫu như sau:
Mặc định thì số lượng request ở mỗi tiến trình là không bị giới hạn.
Tuy nhiên ta nên thiết đặt lại nó ở một giá trị xác định để tránh các
vấn đề về bộ nhớ. Như ở ví dụ trên pm.max_requests được gán giá trị là 200.
I – Tối ưu Nginx:
1) Bố trí lại các tệp tin cấu hình:
Thông thường thì các tệp tin cấu hình của Nginx sẽ được lưu trữ trong thư mục “/etc/nginx”. Một cách tổ chức lại việc lưu trữ tốt hơn theo phong cách của Apache như sau
## Tệp tin cấu hình chính ## /etc/nginx/nginx.conf ## Tệp tin cấu hình các virtual host ## /etc/nginx/sites-available/ /etc/nginx/sites-enabled/ ## Các tệp tin cấu hình khác... ## /etc/nginx/conf.d/
- sites-available: Chứa danh sách các file cấu hình khác nhau như: file cấu hình hoàn chỉnh, file cấu hình tạm thời, file cấu hình lỗi,…Lưu trữ những tệp tin cấu hình mà ta hiện có.
- sites-enabled: Chứa danh sách các symbolic link trỏ tới các tệp tin cấu hình hoàn chỉnh, đã tối ưu ở thư mục sites-available.
Vì chúng ta tách biệt phần file cấu hình của các virtual host ra lưu trữ riêng nên ta cần phải include dòng địa chỉ thư mục lưu trữ các file cấu hình này vào file cấu hình chính. Ở file nginx.conf ta thêm vào
## Tệp tin cấu hình virtual host. ## include /etc/nginx/sites-enabled/*; ## Các tệp tin cấu hình khác.../ ## include /etc/nginx/conf.d/*;
Chú ý: Việc tối ưu lại cách sắp xếp này giúp chúng ta dễ dàng quản lý hệ thống webserver hơn chứ không có tác dụng tới hiệu suất tới hiệu suất.
2) Tối ưu worker_processes:
Với cấu hình mặc định, Nginx sẽ sử dụng một CPU để xử lý các tác vụ của mình. Tùy theo mức độ hoạt động của web server mà chúng ta có thể thay đổi lại thiết lập này. Ví dụ với các web server hay sử dụng về SSL, gzip thì ta nên đặt chỉ số của worker_processes này lên cao hơn. Nếu website của bạn có số lượng các tệp tin tĩnh nhiều, và dung lượng của chúng lớn hơn bộ nhớ RAM thì việc tăng worker_processes sẽ tối ưu băng thông đĩa của hệ thống.
Để xác định số cores của CPU của hệ thống ta có thể thực hiện lệnh
# cat /proc/cpuinfo | grep processor
[root@server ~]# cat /proc/cpuinfo | grep processor processor : 0 processor : 1 processor : 2 processor : 3
Như ở trên, CPU của chúng ta có 4 cores. Để thay đổi mức sử dụng CPU của nginx ta sửa tệp tin cấu hình chính
# vi /etc/nginx/nginx.conf
Tại dòng số 3 ta thay đổi giá trị của worker_processes là 4.
3) Tối ưu worker_connections:
worker_connections sẽ cho biết số lượng connection mà CPU sẽ xử lý. Mặc định, số lượng connection này được thiết lập là 1024. Để xem về mức giới hạn sử dụng của hệ thống bạn có thể dụng lệnh ulimit
# ulimit –n
Con số thiết lập của worker_connections nên nhỏ hơn hoặc bằng giới hạn này!
Nếu bạn đã điều chỉnh lại giá trị worker_processes giúp Nginx sử dụng nhiều cores để xử lý các tác vụ hơn thì có thể thêm dòng cấu hình sau để tăng số lượng clients lên cao nhất
max_clients = worker_processes * worker_connections
4) Tối ưu buffers (bộ nhớ đệm):
Một trong những cấu hình quan trọng để tối ưu Nginx là thiết đặt các giá trị buffer. Nếu bạn thiết lập bộ nhớ buffer quá nhỏ thì sẽ dễ dẫn tới tình trạng “thắt cỗ chai” khi web server của chúng ta tiếp nhận một lượng traffic lớn. Để thay đổi các giá trị buffer này, chúng ta có thể thêm vào các dòng cấu hình ở thẻ http của file cấu hình chính nginx.conf
client_body_buffer_size 8K; client_header_buffer_size 1k; client_max_body_size 2m; large_client_header_buffers 2 1k;
- client_body_buffer_size: Thiết đặt giá trị kích thước của body mà client yêu cầu. Nếu kích thước được yêu cầu lớn hơn giá trị buffer thì sẽ được lưu vào temporary file.
- client_header_buffer_size: Thiết đặt giá trị kích thước của header mà client yêu cầu. Thông thường thì kích thước này 1K là đủ.
- client_max_body_size: Thiết đặt giá trị kích thước tối đa của body mà client có thể yêu cầu được, xác định bởi dòng Conent-Length trong header. Nếu kích thước body yêu cầu vượt giới hạn nãy thì client sẽ nhận được thông báo lỗi “Request Entity Too Large” (413).
- large_client_header_buffers: Thiết đặt giá trị kích về số lượng và kích thước lớn nhất của buffer dùng để đọc các headers có kích thước lớn từ các request của client. Nếu client gửi một header quá lớn Nginx sẽ trả về lỗi “Request URL too large” (414) hoặc “Bad request” (400) nếu header của request quá dài.
client_body_timeout 10; client_header_timeout 10; keepalive_timeout 15; send_timeout 10;
- client_body_timeout: Thiết đặt thời gian tải body của webpage từ client. Nếu quá thời gian này, client sẽ nhận thông báo trả về “Request time out” (408).
- client_header_timeout: Thiết đặt thời gian tải title của webpage từ client. Nếu quá thời gian này, client sẽ nhận thông báo trả về “Request time out” (408).
- keepalive_timeout: Thiết đặt thời gian sống của kết nối từ client, nếu quá thời gian này thì kết nối sẽ bị đóng.
- send_timeout: Thiết đặt thời gian phản hồi dữ liệu giữa client và server, nếu quá thời gian này thì nginx sẽ tắt kết nối.
Mặc định thì Nginx sẽ ghi lại các request lên một file trên đĩa cứng như là một việc ghi logs. Nêu bạn không sử dụng các access logs thì bạn có thể tắt tính năng này đi để giảm bớt thời gian nhập xuất. Để thực hiện điều này, trong thẻ server của file cấu hình chính nginx.conf bạn có thể đặt giá trị sau
access_logs off;
6) Nén các gói dữ liệu gửi đi bằng Gzip
Gzip sẽ giúp nén các dữ liệu trước khi chuyển chúng tới Client. Đây là một cách để tăng tốc độ tuy cập website của cúng ta. Trong thẻ http của file cấu hình chính nginx.conf ta có thể thêm
gzip on; gzip_comp_level 2; gzip_min_length 1000; gzip_proxied expired no-cache no-store private auth; gzip_types text/plain application/xml; gzip_disable "MSIE [1-6]\.";
7) Cache nội dung các tệp tin tĩnh:
Hầu hết các request từ client tới website của chúng ta để load các nôi dung như: hình ảnh, java script, css, flash,... Chúng ta nên thực hiện việc lưu cache lại các tệp tin có nội dung tĩnh này trên Nginx
location ~* "\.(js|ico|gif|jpg|png|css|html|htm|swf|htc|xml|bmp|cur)$" {
root /home/site/public_html;
add_header Pragma "public";
add_header Cache-Control "public";
expires 3M;
access_log off;
log_not_found off;
}
8) Ẩn phiên bản của Nginx:
Việc ẩn đi phiên bản của Nginx từ Server Header sẽ giúp hệ thống webserver của chúng ta được bảo mật tốt hơn. Để thực hiện điều này, trong thẻ http của của tệp tin cấu hình chính nginx.conf ta thêm vào dòng sau
server_tokens off;
9) Thực thi các tệp tin PHP thông qua PHP-FPM:
Ở đây ta có thể sử dụng TCP/IP stack mặc định hoặc dùng trự tiếp Unix Socket Connection. Chúng ta cũng có thể sử dụng PHP-FPM để lắng nghe trên IP:Port (thường là 127.0.0.1:9000).
location ~* \.php$ {
try_files $uri /index.php;
fastcgi_index index.php;
fastcgi_pass 127.0.0.1:9000;
#fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
10) Cấm các truy cập tới các tệp tin ẩn trên Nginx:
Đôi khi trên các thư mục web chúng ta có lưu những tệp tin ẩn (bắt đầu với dấu chấm “.”) như .svn, .htaccess. Đây là các tệp tin không mang tính public đối với người dùng. Để ngăn chặn các truy xuất tới các tệp tin ẩn này ta có thể thêm vào đoạn cấu hình sau
location ~ /\. {
access_log off;
log_not_found off;
deny all;
}
II – Tối ưu PHP-FPM
1) Bố trí lại các tệp tin cấu hình:
Thông thường thì các cấu hình của PHP-FPM được thiết lập trong file cấu hình /etc/php-fpm.conf và ở thư mục /etc/php-fpm.d. Các tệp tin cấu hình khác của PHP-FPM nên đặt trong cùng thư mục/etc/php-fpm.d. Chúng ta có thể thêm dòng cấu hình sau vào file php-fpm.conf để thực hiện điều này
include=/etc/php-fpm.d/*.conf
2) Cấu hình nhiều PHP-FPM Pool:
Đối với PHP-FPM ta có thể tạo ra nhiều pool khác nhau cho các website khác nhau có trên web server. Bằng cách này chúng ta có thể có được các cấu hình cấp phát tài nguyên và nhóm sở hữu khác nhau đối với từn website. Ví dụ ở đây mình tạo 3 pool cho 3 website khác nhau là
/etc/php-fpm.d/site.conf
/etc/php-fpm.d/blog.conf
/etc/php-fpm.d/forums.conf
Các cấu hình mẫu:
/etc/php-fpm.d/site.conf
[site] listen = 127.0.0.1:9000 user = site group = site request_slowlog_timeout = 5s slowlog = /var/log/php-fpm/slowlog-site.log listen.allowed_clients = 127.0.0.1 pm = dynamic pm.max_children = 5 pm.start_servers = 3 pm.min_spare_servers = 2 pm.max_spare_servers = 4 pm.max_requests = 200 listen.backlog = -1 pm.status_path = /status request_terminate_timeout = 120s rlimit_files = 131072 rlimit_core = unlimited catch_workers_output = yes env[HOSTNAME] = $HOSTNAME env[TMP] = /tmp env[TMPDIR] = /tmp env[TEMP] = /tmp
/etc/php-fpm.d/blog.conf
[blog] listen = 127.0.0.1:9001 user = blog group = blog request_slowlog_timeout = 5s slowlog = /var/log/php-fpm/slowlog-blog.log listen.allowed_clients = 127.0.0.1 pm = dynamic pm.max_children = 4 pm.start_servers = 2 pm.min_spare_servers = 1 pm.max_spare_servers = 3 pm.max_requests = 200 listen.backlog = -1 pm.status_path = /status request_terminate_timeout = 120s rlimit_files = 131072 rlimit_core = unlimited catch_workers_output = yes env[HOSTNAME] = $HOSTNAME env[TMP] = /tmp env[TMPDIR] = /tmp env[TEMP] = /tmp
/etc/php-fpm.d/forums.conf
[forums] listen = 127.0.0.1:9002 user = forums group = forums request_slowlog_timeout = 5s slowlog = /var/log/php-fpm/slowlog-forums.log listen.allowed_clients = 127.0.0.1 pm = dynamic pm.max_children = 10 pm.start_servers = 3 pm.min_spare_servers = 2 pm.max_spare_servers = 4 pm.max_requests = 400 listen.backlog = -1 pm.status_path = /status request_terminate_timeout = 120s rlimit_files = 131072 rlimit_core = unlimited catch_workers_output = yes env[HOSTNAME] = $HOSTNAME env[TMP] = /tmp env[TMPDIR] = /tmp env[TEMP] = /tmp
3) Cấu hình PHP-FPM Pool Process Manager (pm):
Trong việc quản lý các tiến trình của PHP-FPM ta nên sử dụng cách quản lý động để chỉ khởi động những tiến trình khi cần thiết. Các cấu hình ở đây cũng tương tự như là cấu hình các thông số của worker_porcess và worker_connection của Nginx mà mình đã trình bày ở trên. Tùy theo lượng truy cập tới website của chúng ta và dung lượng bộ nhớ RAM của web server hiện có mà ta có các cách cấu hình cho phù hợp.
Giải sử Web Server của chúng ta có 512 MB ram, ở những lúc website có lượng truy cập cao, ta check dung lượng bộ nhớ RAM hiện đang dùng (bằng lệnh top chẳn hạn). Dung lượng RAM được cấp phát cho PHP-FPM là 220 MB, mỗi tiến trình của nó sử dụng 24 MB. Ta có thể tính được giá trị của max_children là 220/24 = 9.17.
Vậy giá trị pm.max_children ta nên thiết đặt cho web server là 9.
Trong file cấu hình pool của website ta có thể có cấu hình mẫu như sau:
pm.max_children = 9 pm.start_servers = 3 pm.min_spare_servers = 2 pm.max_spare_servers = 4 pm.max_requests = 200
Cài đặt Nginx + PHP-FPM + MySQL
Chào các bạn
Sau khi tôi giới thiệu làm thế nào để tạo 1 Instance VPS free một năm với Amazon EC2.
Hôm nay tôi viết bài làm thế nào setup một webserver ( Nginx ) để chạy với PHP ( sử dụng PHP-FPM ) và cơ sở dữ liệu là Mysql.
Mục tiêu: Giúp các bạn hiểu sơ về web server sử dụng Nginx, PHP-FPM . Các bạn có thể setup đơn giản nhất webserver chạy bằng Nginx , PHP-FPM và Mysql
Tại sao là Nginx không phải là Apache hay là một web server khác ?
Nginx là open source, free , high performance HTTP server , chủ yếu tập trung vào vấn đề xử lý request ở cùng một thời điểm , tối ưu tài nguyên cho hệ thống như RAM, CPU .
Các bạn có thể tham khảo thêm thông tin ở link sau: Thấy tài liệu này cũng khá đủ, giải thích cũng khá chi tiết. Nếu tôi viết lại thì chắc là cũng dịch từ tài liệu bên dưới . He he. Thôi các bạn tự đọc vậy.
http://www.aosabook.org/en/nginx.html
PHP-FPM là gì ? Tại sao lại chọn nó ?
Để hiểu được PHP-FPM là gì ? Thì trước hết các bạn phải hiểu được cơ chế xử lý của web server.
Vậy làm thế nào webserver chạy được web viết bằng php, python, hay ruby …
Chẳng qua là webserver sẽ gọi những chương trình có thể hiểu được PHP, Python, ruby, xử lý những request và trả về thông tin cho
webserver từ đó trả về thông tin cho browser. Như hình bên dưới:
Vậy CGI là phương pháp giúp web server gọi những chương trình có thể hiểu được ( PHP, Ruby, Python ) để xử lý những request và trả về dữ liệu cho browser.
Mỗi lần gọi CGI Program’s để xử lý thì tạo một process để xử lý. Vậy mỗi request sinh ra 1 process để xử lý. Việc này làm tốn tài nguyên của hệ thống như CPU và RAM, nếu trong trường hợp heavy load đễ gây ra crash hệ thống.
Nên Fast CGI ra đời, với cơ chế persistent processes ( có thể hiểu là process nó luôn luôn ở chạy ở trạng thái luôn luôn chờ có một request tới để xử lý ) có thể xử lý nhiều request cùng một lúc. Chính vì điều này , tránh khỏi việc mỗi request tạo ra một process để xử lý, nên sử dụng tài nguyên hiệu quả hơn.
Như vậy các bạn đã hiểu rõ sơ về khái nhiệm GCI, Fast CGI.
Vậy PHP -FPM là gì ?
PHP-FPM (FastCGI Process Manager) là FastCGI với thêm một vài tính năng hỗ trợ khi site heavy load.
Trong danh sách tíng năng thì tính năng này được nói đầu tiên:
advanced process management with graceful stop/start;
Đơn giản nếu bạn dùng fast-cgi thuần tí, thì các bạn thay đổi config thì các bạn phải stop/start lại fast-cgi, như vậy thì site sẽ down một vài phút.
Còn với php-fpm thì các bạn có thể thay đổi config và reload lại, không làm site bị down.
Tính năng khác thêm vào các bạn có thể tham khảo ở đây:
http://www.php.net/manual/en/install.fpm.php
Cài đặt Nginx + PHP-FPM + MySQL
Nếu bạn sử dụng EC2 thì trước khi cài đặt bạn chỉnh thời gian, và một số gói cần thiết :
Thư mục sites-available là lưu tất cả các config của từng Vhost khác nhau:
Ví dụ bạn có 5 website cùng host trên một server, thì bạn có 5 file đặt trong thư mục này.
Nếu site nào bạn muốn bật lên thì chỉ việc tạo softlink vào thư mục sites-enabled mà thôi.
Trước mắt tôi tạo những thư mục sau:
public_html: thư mục web của bạn
logs: thư mục log, thì có access log, error log.
PHP-FPM Configuration
(/srv/www/mysite/public_html/index.php):
<?php phpinfo(); ?>
Vào browser và gõ địa chỉ IP và xem kết quả.
Chúc bạn thành công
Sau khi tôi giới thiệu làm thế nào để tạo 1 Instance VPS free một năm với Amazon EC2.
Hôm nay tôi viết bài làm thế nào setup một webserver ( Nginx ) để chạy với PHP ( sử dụng PHP-FPM ) và cơ sở dữ liệu là Mysql.
Mục tiêu: Giúp các bạn hiểu sơ về web server sử dụng Nginx, PHP-FPM . Các bạn có thể setup đơn giản nhất webserver chạy bằng Nginx , PHP-FPM và Mysql
Tại sao là Nginx không phải là Apache hay là một web server khác ?
Nginx là open source, free , high performance HTTP server , chủ yếu tập trung vào vấn đề xử lý request ở cùng một thời điểm , tối ưu tài nguyên cho hệ thống như RAM, CPU .
Các bạn có thể tham khảo thêm thông tin ở link sau: Thấy tài liệu này cũng khá đủ, giải thích cũng khá chi tiết. Nếu tôi viết lại thì chắc là cũng dịch từ tài liệu bên dưới . He he. Thôi các bạn tự đọc vậy.
http://www.aosabook.org/en/nginx.html
PHP-FPM là gì ? Tại sao lại chọn nó ?
Để hiểu được PHP-FPM là gì ? Thì trước hết các bạn phải hiểu được cơ chế xử lý của web server.
Vậy làm thế nào webserver chạy được web viết bằng php, python, hay ruby …
Chẳng qua là webserver sẽ gọi những chương trình có thể hiểu được PHP, Python, ruby, xử lý những request và trả về thông tin cho
webserver từ đó trả về thông tin cho browser. Như hình bên dưới:
Vậy CGI là phương pháp giúp web server gọi những chương trình có thể hiểu được ( PHP, Ruby, Python ) để xử lý những request và trả về dữ liệu cho browser.
Mỗi lần gọi CGI Program’s để xử lý thì tạo một process để xử lý. Vậy mỗi request sinh ra 1 process để xử lý. Việc này làm tốn tài nguyên của hệ thống như CPU và RAM, nếu trong trường hợp heavy load đễ gây ra crash hệ thống.
Nên Fast CGI ra đời, với cơ chế persistent processes ( có thể hiểu là process nó luôn luôn ở chạy ở trạng thái luôn luôn chờ có một request tới để xử lý ) có thể xử lý nhiều request cùng một lúc. Chính vì điều này , tránh khỏi việc mỗi request tạo ra một process để xử lý, nên sử dụng tài nguyên hiệu quả hơn.
Như vậy các bạn đã hiểu rõ sơ về khái nhiệm GCI, Fast CGI.
Vậy PHP -FPM là gì ?
PHP-FPM (FastCGI Process Manager) là FastCGI với thêm một vài tính năng hỗ trợ khi site heavy load.
Trong danh sách tíng năng thì tính năng này được nói đầu tiên:
advanced process management with graceful stop/start;
Đơn giản nếu bạn dùng fast-cgi thuần tí, thì các bạn thay đổi config thì các bạn phải stop/start lại fast-cgi, như vậy thì site sẽ down một vài phút.
Còn với php-fpm thì các bạn có thể thay đổi config và reload lại, không làm site bị down.
Tính năng khác thêm vào các bạn có thể tham khảo ở đây:
http://www.php.net/manual/en/install.fpm.php
Vậy là các bạn hiểu được sơ sơ về các khái niệm.
Bây h vào mục chính làCài đặt Nginx + PHP-FPM + MySQL
Nếu bạn sử dụng EC2 thì trước khi cài đặt bạn chỉnh thời gian, và một số gói cần thiết :
sudo ln -sf /usr/share/zoneinfo/Asia/Saigon /etc/localtime sudo yum install pcre-devel zlib-devel openssl-devel sudo yum install gcc sudo yum install make
Install Nginx và PHP-FPM
wget http://nginx.org/download/nginx-1.4.7.tar.gz tar fx nginx-1.4.7.tar.gz cd nginx-1.4.7 ./configure --sbin-path=/usr/local/sbin --with-http_ssl_module --with-http_stub_status_module make && make install
sudo yum install -y php-fpm
Install PHP extensions
sudo yum install -y php-devel php-mysql php-pdo \
php-pear php-mbstring php-cli php-odbc \
php-imap php-gd php-xml php-soap
Install PHP-APC
sudo yum install -y php-pecl-apc
sudo yum install -y pcre-devel
Install MySQL
sudo yum -y install mysql-server mysql
Nginx Configuration
Tao user Nginx:sudo adduser --system --no-create-home --user-group -s /sbin/nologin nginxBạn tạo vhost directory. Việc này giúp bạn dễ quản lý hơn nếu sau này trên VPS các bạn có thể quản lý nhiều website khác nhau.
Thư mục sites-available là lưu tất cả các config của từng Vhost khác nhau:
Ví dụ bạn có 5 website cùng host trên một server, thì bạn có 5 file đặt trong thư mục này.
Nếu site nào bạn muốn bật lên thì chỉ việc tạo softlink vào thư mục sites-enabled mà thôi.
mkdir /usr/local/nginx/sites-available mkdir /usr/local/nginx/sites-enabledThêm dòng include thư mục sites-enabled vào config chính của nginx.
sudo vi /usr/local/nginx/conf/nginx.conf
include /usr/local/nginx/sites-enabled/*;
Ví dụ, tôi tạo một Vhost là mysite để config cho trang web mysite.com
chẳng hạn. Tạo virtual host mysite file trong thư
mục /usr/local/nginx/sites-availableTrước mắt tôi tạo những thư mục sau:
public_html: thư mục web của bạn
logs: thư mục log, thì có access log, error log.
mkdir -p /srv/www/mysite/public_html mkdir -p /srv/www/mysite/logs chown -R nginx:nginx /srv/www/mysite
sudo vi /usr/local/nginx/sites-available/mysite
server {
server_name mysite.com;
access_log /srv/www/mysite/logs/access.log;
error_log /srv/www/mysite/logs/error.log;
root /srv/www/mysite/public_html;
location / {
index index.html index.htm index.php;
}
location ~ \.php$ {
try_files $uri =404;
# Include the standard fastcgi_params file included with nginx
include fastcgi_params;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
Tạo soft link những Vhost nào enable. Như trong phần này tôi enable vhost mysiteln -s /usr/local/nginx/sites-available/mysite /usr/local/nginx/sites-enabled/mysite
Tạo script restart Nginx:
sudo vi /etc/init.d/nginxCopy và Paste:
#!/bin/sh
#
# nginx - this script starts and stops the nginx daemin
#
# chkconfig: - 85 15
# description: Nginx is an HTTP(S) server, HTTP(S) reverse \
# proxy and IMAP/POP3 proxy server
# processname: nginx
# config: /usr/local/nginx/conf/nginx.conf
# pidfile: /usr/local/nginx/logs/nginx.pid
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0
nginx="/usr/local/sbin/nginx"
prog=$(basename $nginx)
NGINX_CONF_FILE="/usr/local/nginx/conf/nginx.conf"
lockfile=/var/lock/subsys/nginx
start() {
[ -x $nginx ] || exit 5
[ -f $NGINX_CONF_FILE ] || exit 6
echo -n $"Starting $prog: "
daemon $nginx -c $NGINX_CONF_FILE
retval=$?
echo
[ $retval -eq 0 ] && touch $lockfile
return $retval
}
stop() {
echo -n $"Stopping $prog: "
killproc $prog -QUIT
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
}
restart() {
configtest || return $?
stop
start
}
reload() {
configtest || return $?
echo -n $"Reloading $prog: "
killproc $nginx -HUP
RETVAL=$?
echo
}
force_reload() {
restart
}
configtest() {
$nginx -t -c $NGINX_CONF_FILE
}
rh_status() {
status $prog
}
rh_status_q() {
rh_status >/dev/null 2>&1
}
case "$1" in
start)
rh_status_q && exit 0
$1
;;
stop)
rh_status_q || exit 0
$1
;;
restart|configtest)
$1
;;
reload)
rh_status_q || exit 7
$1
;;
force-reload)
force_reload
;;
status)
rh_status
;;
condrestart|try-restart)
rh_status_q || exit 0
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
exit 2
esac
sudo chmod +x /etc/init.d/nginx sudo /etc/init.d/nginx start
PHP-FPM Configuration
sudo vi /etc/php-fpm.d/www.conf
[...] listen = /var/run/php-fpm/php-fpm.sock listen.owner = nginx listen.group = nginx listen.mode = 0664 user = nginx group = nginx [...]
sudo vi /etc/php.ini
cgi.fix_pathinfo=0
Auto Start Nginx, PHP-FPM, and MySQL in EC2 Amazon Linuxchkconfig nginx on chkconfig mysqld on chkconfig php-fpm on
Kiểm tra cấu hình Nginx and FastCGI:
Tạo file index.php(/srv/www/mysite/public_html/index.php):
<?php phpinfo(); ?>
Vào browser và gõ địa chỉ IP và xem kết quả.
Chúc bạn thành công
NginX hay Apache thì tốt hơn ?
Hiện tại tôi đang cài Apache cho server web của mình, nhưng qua
nghiên cứu tôi thấy rõ ràng rằng NghinX có nhiều lợi thế về tốc độ và
chống chọi với các cuộc tấn công DDOS tốt hơn Apache, nhưng đầu tiên ta
hãy nghiên cứu xem hai Web server này là gì nhé:
Apache là một trong các Webserver đơn giản nhất và phổ thông nhất để phát triển các dự án website, và từ 1996 Apache trở thành phần mềm webserver phổ biến nhất thế giới, và cho tới năm 2009 Apache đã chiếm 46 % tổng số website chạy trên nền tảng của nó.
NghinX là một trong các web server mạnh mẽ nhất, với nhiều website có số lượng truy cập lớn phải dùng tới NginX, lợi thế về tốc độ và an toàn cho server website, NghinX hiện nay đang được ưa chuộng để chạy các site lớn, ví dụ như Zing Mp3 của chúng ta:
Cơ chế hoạt động của hai Web Server này cũng khác nhau tạo nên hai
đặc điểm và ưu thế khác nhau, ví dụ NghinX có tất cả các chức năng mà
Apache có:
Trong khi đó Apache lại có những chức năng mở rộng hơn so với NghinX như sau:
Có một điều làm cho NghinX ít phổ thông hơn so với Apache chính là: NghinX chỉ thích hợp cho việc phục vụ các Server riêng, chứ không thích hợp cho Shared Hosting, với mỗi lần cấu hình NghinX lại phải load lại file config của nó trên server, người dùng nếu có quyền này chắc chắn dễ dàng làm chết cả server với hàng trăm website cùng nhau chạy.
NghinX tỏ ra ưu thế hơn hẳn Apache về tốc độ và sử dụng bộ nhớ của máy chủ, WordPress.org cũng đã có một cuộc thí nghiệm của riêng mình để đánh giá việc này, NghinX hoạt động tuyệt vời với 8000 request / giây ( http://barry.wordpress.com/2008/04/28/load-balancer-update/ )
Điều đặc biệt là NghinX dùng rất ít Ram và CPU, trong một cuộc thí nghiệm, NghinX ăn hết 25Mb Ram và 10% CPU load với 10 triệu lượt truy cập / ngày, không thể tưởng tượng được !
Apache và NghinX đều miễn phí, hoạt động và phát triển dưới các giấy phép mã nguồn mở, copyFree nên bạn không phải trả phí khi cài đặt chúng.
Tôi cũng đang muốn cài NghinX cho server của mình nhưng vì chưa có kinh nghiệm trong việc cấu hình nên đành phải hẹn bạn NghinX sau vài tháng nữa.
Các bạn nghĩ sao ? Nên dùng Apache phổ thông hay NghinX siêu tốc ?
Apache là một trong các Webserver đơn giản nhất và phổ thông nhất để phát triển các dự án website, và từ 1996 Apache trở thành phần mềm webserver phổ biến nhất thế giới, và cho tới năm 2009 Apache đã chiếm 46 % tổng số website chạy trên nền tảng của nó.
Logo của Apache
Logo của Nginx
NghinX là một trong các web server mạnh mẽ nhất, với nhiều website có số lượng truy cập lớn phải dùng tới NginX, lợi thế về tốc độ và an toàn cho server website, NghinX hiện nay đang được ưa chuộng để chạy các site lớn, ví dụ như Zing Mp3 của chúng ta:
Zing Mp3 sử dụng server NghinX
- Static file serving.
- SSL/TLS support.
- Virtual hosts.
- Reverse proxying.
- Load balancing.
- Compression.
- Access controls.
- URL rewriting.
- Custom logging.
- Server-side includes.
- Limited WebDAV.
- FLV streaming.
- FastCGI.
Trong khi đó Apache lại có những chức năng mở rộng hơn so với NghinX như sau:
- digest access authentication
- CGI
- administrative console
- .htaccess
Có một điều làm cho NghinX ít phổ thông hơn so với Apache chính là: NghinX chỉ thích hợp cho việc phục vụ các Server riêng, chứ không thích hợp cho Shared Hosting, với mỗi lần cấu hình NghinX lại phải load lại file config của nó trên server, người dùng nếu có quyền này chắc chắn dễ dàng làm chết cả server với hàng trăm website cùng nhau chạy.
NghinX tỏ ra ưu thế hơn hẳn Apache về tốc độ và sử dụng bộ nhớ của máy chủ, WordPress.org cũng đã có một cuộc thí nghiệm của riêng mình để đánh giá việc này, NghinX hoạt động tuyệt vời với 8000 request / giây ( http://barry.wordpress.com/2008/04/28/load-balancer-update/ )
Điều đặc biệt là NghinX dùng rất ít Ram và CPU, trong một cuộc thí nghiệm, NghinX ăn hết 25Mb Ram và 10% CPU load với 10 triệu lượt truy cập / ngày, không thể tưởng tượng được !
Apache và NghinX đều miễn phí, hoạt động và phát triển dưới các giấy phép mã nguồn mở, copyFree nên bạn không phải trả phí khi cài đặt chúng.
Tôi cũng đang muốn cài NghinX cho server của mình nhưng vì chưa có kinh nghiệm trong việc cấu hình nên đành phải hẹn bạn NghinX sau vài tháng nữa.
Các bạn nghĩ sao ? Nên dùng Apache phổ thông hay NghinX siêu tốc ?
Cấu hình Nginx làm Reserve Proxy trên CentOS
I – Giới thiệu:
Nginx là một máy chủ web (web server), proxy ngược (reserve proxy) và e-mail proxy (IMAP/POP3) nhẹ, hiệu năng cao, sử dụng giấy phép mở BSD. Nginx có thể chạy trên UNIX, Linux, các dòng BSD, Mac OS X, Solaris và Microsoft Windows. Theo thống kê của Netcraft, trong số 1 triệu website lớn nhất thế giới, có 6,52% sử dụng nginx. Tại Nga, quê hương của nginx, có đến 46,9% sử dụng máy chủ này. Nginx chỉ đứng sau Apache và IIS (của Microsoft).
Trên thực tế, số lượng webserver dùng Nginx để chạy website là rất ít, thay vào đó người ta sẽ sử dụng Apache bởi vì Apache tỏ ra tốt hơn Nginx trong việc phục vụ các trang web động (dynamic page). Nhưng vì tính đa dụng nên Apache có rất nhiều thành phần “thừa” khiến cho Web Server của chúng ta trở nên chậm chạp.
Giải pháp đưa ra là chúng ta sẽ sử dụng Nginx để làm proxy ngược. Nginx sẽ chạy ở phía trước (front-end) phục vụ port 80, còn Apache sẽ chạy ở phía sau (back-end) lắng nghe trên port 8080. Các Client truy vấn tới Web Server sẽ theo dạng Client <-----> Nginx <-----> Apache.
Trong bài này, mình sẽ trình bày cách cài đặt và cấu hình Nginx làm Reserve Proxy cho dịch vụ httpd trên hệ điều hành CentOS 6.
II – Yêu cầu:
Kích hoạt sử dụng lệnh yum tải các gói từ EPEL:
# rpm -Uvh http://download.fedora.redhat.com/pub/epel/6/i386/epel-release-6-5.noarch.rpm
# yum repolist
Cài đặt Nginx sử dụng lệnh yum
# yum install nginx -y
Cấu hình Reserve Proxy
Tạo file porxy.conf
# vi /etc/nginx/conf.d/proxy.conf
Thêm vào nội dung sau
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffers 32 4k;
Mở file nginx.conf
# vi /etc/nginx/nginx.conf
Thêm vào thông tin như sau
server {
listen 80;
server_name khanh.com.vn www.khanh.com.vn;
access_log /var/log/nginx/khanh.com.access.log ;
error_log /var/log/nginx/khanh.com.error.log ;
location / {
proxy_pass http://192.168.10.109:8080/ ;
include /etc/nginx/conf.d/proxy.conf;
}
}
Trong đó:
Sau khi sửa xong nội dung file nginx.conf, ta lưu lại và kiểm tra nội dung cấu hình đã chính xác chưa
# nginx -t
Sau đó khởi động lại Nginx
# /etc/init.d/nginx restart
Tiếp tục, ta sẽ cấu hình dịch vụ httpd listen trên cổng 8080
Mở file httpd.conf
vi /etc/httpd/conf/httpd.conf
Sửa giá trị NameVirtualHost là *:8080 và Listen là 8080
Sau đó ta sẽ khởi động lại dịch vụ httpd
# service httpd restart
Từ client ta truy cập tới Web Server thành công như hình dưới.
Trên Web Server ta kiểm tra lại các port đang Listen được kết quả như hình bên dưới.
# netstat -ltpn | grep 80
Cấu hình Nginx làm Reserve Porxy thành công!
Nginx là một máy chủ web (web server), proxy ngược (reserve proxy) và e-mail proxy (IMAP/POP3) nhẹ, hiệu năng cao, sử dụng giấy phép mở BSD. Nginx có thể chạy trên UNIX, Linux, các dòng BSD, Mac OS X, Solaris và Microsoft Windows. Theo thống kê của Netcraft, trong số 1 triệu website lớn nhất thế giới, có 6,52% sử dụng nginx. Tại Nga, quê hương của nginx, có đến 46,9% sử dụng máy chủ này. Nginx chỉ đứng sau Apache và IIS (của Microsoft).
Trên thực tế, số lượng webserver dùng Nginx để chạy website là rất ít, thay vào đó người ta sẽ sử dụng Apache bởi vì Apache tỏ ra tốt hơn Nginx trong việc phục vụ các trang web động (dynamic page). Nhưng vì tính đa dụng nên Apache có rất nhiều thành phần “thừa” khiến cho Web Server của chúng ta trở nên chậm chạp.
Giải pháp đưa ra là chúng ta sẽ sử dụng Nginx để làm proxy ngược. Nginx sẽ chạy ở phía trước (front-end) phục vụ port 80, còn Apache sẽ chạy ở phía sau (back-end) lắng nghe trên port 8080. Các Client truy vấn tới Web Server sẽ theo dạng Client <-----> Nginx <-----> Apache.
Trong bài này, mình sẽ trình bày cách cài đặt và cấu hình Nginx làm Reserve Proxy cho dịch vụ httpd trên hệ điều hành CentOS 6.
II – Yêu cầu:
- Hệ điều hành CentOS (mình sử dụng bản CentOS 6).
- Đã cài đặt dịch vụ httpd (tham khảo tại đây).
Kích hoạt sử dụng lệnh yum tải các gói từ EPEL:
# rpm -Uvh http://download.fedora.redhat.com/pub/epel/6/i386/epel-release-6-5.noarch.rpm
# yum repolist
Cài đặt Nginx sử dụng lệnh yum
# yum install nginx -y
Cấu hình Reserve Proxy
Tạo file porxy.conf
# vi /etc/nginx/conf.d/proxy.conf
Thêm vào nội dung sau
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffers 32 4k;
Mở file nginx.conf
# vi /etc/nginx/nginx.conf
Thêm vào thông tin như sau
server {
listen 80;
server_name khanh.com.vn www.khanh.com.vn;
access_log /var/log/nginx/khanh.com.access.log ;
error_log /var/log/nginx/khanh.com.error.log ;
location / {
proxy_pass http://192.168.10.109:8080/ ;
include /etc/nginx/conf.d/proxy.conf;
}
}
Trong đó:
- Listen 80: là port mà Nginx lắng nghe Client.
- Server_name: Domain của Website
- Proxy_pass: địa chỉ IP của Web Server kèm Port của httpd
- Include: trỏ tới tệp tin proxy.conf vừa cấu hình ở trên.
Sau khi sửa xong nội dung file nginx.conf, ta lưu lại và kiểm tra nội dung cấu hình đã chính xác chưa
# nginx -t
Sau đó khởi động lại Nginx
# /etc/init.d/nginx restart
Tiếp tục, ta sẽ cấu hình dịch vụ httpd listen trên cổng 8080
Mở file httpd.conf
vi /etc/httpd/conf/httpd.conf
Sửa giá trị NameVirtualHost là *:8080 và Listen là 8080
Sau đó ta sẽ khởi động lại dịch vụ httpd
# service httpd restart
Từ client ta truy cập tới Web Server thành công như hình dưới.
Trên Web Server ta kiểm tra lại các port đang Listen được kết quả như hình bên dưới.
# netstat -ltpn | grep 80
Cấu hình Nginx làm Reserve Porxy thành công!
Nginx & Unicorn
I – Nginx
I.1 – Nginx là gì
Nginx (pronounced “Engine-X”) : Là sản phẩm mã nguồn mở cho web server . Là một reverse proxy cho các giao thức HTTP, SMTP, POP3 and IMAP . Nhằn nâng cao hiệu xuất xử lý khi sử dung lượng RAM thấp . Được cấp phép bởi BSD chạy trên nên tảng Unix , Linux và các biến thểBSD, Mac OS X, Solaris, AIX, HP-UX và Microsoft Windows.
I.2 – Tổng quan
Nginx có thể triển khai nội dung của các trang web động bằng cách sử lý FastCGI, SCGI cho các scripts . Và có thể sử dụng như là một server cân bằng tải . Sau đó vấn đề C10K xuất hiện nói cách khác để cho phép mỗi máy chủ web phải có khả năng xử lý 10.000 khách hàng cùng một lúc. Cần phải phát triển một mạng lưới I / O tốt hơn và công nghệ quản lý chủ đề đã được xuất hiện. Sự xuất hiện của NGinx không phải là kết quả của một nỗ lực để giải quyết vấn đề C10K (như là một vấn đề phổ biến) nhưng “vấn đề C10K” đã thành công trong việc đưa ra các nỗ lực để nâng cao hiệu suất phát triển mạng máy chủ
Igor Sysoev phát triển nginx từ cách đây hơn 9 năm. Vào tháng 10/2004, phiên bản 0.1.0 được phát hành rộng rãi theo giấy phép BSD. Công dụng của nginx ngoài máy chủ web, còn có thể làm proxy nghịch cho Web và làm proxy email (SMTP/POP3/IMAP). Theo thống kê của Netcraft, trong số 1 triệu website lớn nhất thế giới, có 6,52% sử dụng nginx. Tại Nga, quê hương của nginx, có đến 46,9% sử dụng máy chủ này. Nginx chỉ đứng sau Apache và IIS (của Microsoft).
Nginx cung cấp gần như tất cả các chức năng máy chủ web:
I.3 – Cài đặt Nginx
#aptitude -y update
#aptitude -y install mongodb redis-server git-core libpcre3 libpcre3-dev libssl-dev mysql-server mysql-client libmysqlclient16-dev libxml2-dev libxslt-dev imagemagick libmagick9-dev libcurl3-dev libreadline-dev memcached build-essential openssl libreadline6 libreadline6-dev curl git-core zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev ncurses-dev automake libtool bison subversion openjdk-6-jre moni
#mkdir -p /var/tmp/nginx/{proxy,client,fcgi}
#cd /usr/local/src
#wget http://nginx.org/download/nginx-1.0.15.tar.gz
#tar zxvf nginx-1.0.15.tar.gz
#cd nginx-1.0.15
CFLAGS='-march=nocona' ./configure \ --prefix=/opt/nginx \ --conf-path=/opt/nginx/conf/nginx.conf \ --error-log-path=/var/log/nginx/error.log \ --pid-path=/var/run/nginx.pid \ --lock-path=/var/lock/nginx.lock \ --user=nobody \ --group=nogroup \ --with-http_stub_status_module \ --with-http_ssl_module \ --with-http_gzip_static_module \ --with-http_realip_module \ --http-log-path=/var/log/nginx/access.log \ --http-client-body-temp-path=/var/tmp/nginx/client/ \ --http-proxy-temp-path=/var/tmp/nginx/proxy/ \ --http-fastcgi-temp-path=/var/tmp/nginx/fcgi
#make
#make install #ln -s /opt/nginx/sbin/nginx /usr/sbin
I.4 – Cấu hình Nginx
#vim /opt/nginx/conf/nginx.conf #user nobody;
worker_processes 8;
events
{ worker_connections 1024; accept_mutex on; # "on" if nginx worker_processes > 1 use epoll; # enable for Linux 2.6+ }
http { include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';
upstream backend-unicorn-pc {
server localhost:5000;
}
upstream backend-unicorn-sp {
server localhost:5100;
sendfile on;
keepalive_timeout 30;
server {
listen 80;
server_name snap.framgia.com;
access_log /var/log/nginx/unicorn.access.log main;
client_max_body_size 5M;
set $is_sphone 0;
if ($http_user_agent ~ Android) {
set $is_sphone 1;
}
if ($http_user_agent ~ iPhone) {
set $is_sphone 1;
}
if ($http_user_agent ~ iPod) {
set $is_sphone 1;
}
if ($http_user_agent ~ iPad) {
set $is_sphone 1;
}
location /uploads/ {
root /usr/local/rails_apps/snap/current/public;
break;
}
location / {
root /usr/local/rails_apps/snap/current/public;
if (-f $request_filename) { break; }
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_read_timeout 60;
proxy_redirect off;
if ($is_sphone = 1) {
proxy_pass http://backend-unicorn-sp;
}
if ($is_sphone != 1) {
proxy_pass http://backend-unicorn-pc;
}
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
I.5 – Các thông số của NGinx
I.5.1 worker_processes
Với cấu hình mặc định, Nginx sẽ sử dụng một CPU để xử lý các tác vụ của mình. Tùy theo mức độ hoạt động của web server mà chúng ta có thể thay đổi lại thiết lập này. Ví dụ với các web server hay sử dụng về SSL, gzip thì ta nên đặt chỉ số của worker_processes này lên cao hơn. Nếu website của bạn có số lượng các tệp tin tĩnh nhiều, và dung lượng của chúng lớn hơn bộ nhớ RAM thì việc tăng worker_processes sẽ tối ưu băng thông đĩa của hệ thống.Để xác định số cores của CPU của hệ thống ta có thể thực hiện lệnh
# cat /proc/cpuinfo | grep processor processor : 0 processor : 1 processor : 2 processor : 3Như ở trên, CPU của chúng ta có 4 cores. Để thay đổi mức sử dụng CPU của nginx ta sửa tệp tin cấu hình chính
vim /opt/nginx/conf/nginx.conf worker_processes 4;
I.5.2 worker_connections
Worker_connections sẽ cho biết số lượng connection mà CPU sẽ xử lý. Mặc định, số lượng connection này được thiết lập là 1024. Để xem về mức giới hạn sử dụng của hệ thống bạn có thể dụng lệnh ulimit. Con số thiết lập của worker_connections nên nhỏ hơn hoặc bằng giới hạn này! Nếu bạn đã điều chỉnh lại giá trị worker_processes giúp Nginx sử dụng nhiều cores để xử lý các tác vụ hơn thì có thể thêm dòng cấu hình sau để tăng số lượng clients lên cao nhất.max_clients = worker_processes * worker_connections
I.5.3 Buffers
Một trong những cấu hình quan trọng để tối ưu Nginx là thiết đặt các giá trị buffer. Nếu bạn thiết lập bộ nhớ buffer quá nhỏ thì sẽ dễ dẫn tới tình trạng “thắt cỗ chai” khi web server của chúng ta tiếp nhận một lượng traffic lớn. Để thay đổi các giá trị buffer này, chúng ta có thể thêm vào các dòng cấu hình ở thẻ http của file cấu hình chính nginx.confclient_body_buffer_size 8K; client_header_buffer_size 1k; client_max_body_size 2m; large_client_header_buffers 2 1k;Trong đó:
client_body_buffer_size: Thiết đặt giá trị kích thước của body mà client yêu cầu. Nếu kích thước được yêu cầu lớn hơn giá trị buffer thì sẽ được lưu vào temporary file.
client_header_buffer_size: Thiết đặt giá trị kích thước của header mà client yêu cầu. Thông thường thì kích thước này 1K là đủ.
client_max_body_size: Thiết đặt giá trị kích thước tối đa của body mà client có thể yêu cầu được, xác định bởi dòng Conent-Length trong header. Nếu kích thước body yêu cầu vượt giới hạn nãy thì client sẽ nhận được thông báo lỗi “Request Entity Too Large” (413).
large_client_header_buffers: Thiết đặt giá trị kích về số lượng và kích thước lớn nhất của buffer dùng để đọc các headers có kích thước lớn từ các request của client. Nếu client gửi một header quá lớn Nginx sẽ trả về lỗi “Request URL too large” (414)hoặc “Bad request” (400)nếu header của request quá dài.
Ngoài ra chúng ta cũng cần thiết đặt lại các giá trị timeout để tối ưu hiệu suất hoạt động của web server với các client :
client_body_timeout 10; client_header_timeout 10; keepalive_timeout 15; send_timeout 10;Trong đó:
client_body_timeout: Thiết đặt thời gian tải body của webpage từ client. Nếu quá thời gian này, client sẽ nhận thông báo trả về “Request time out” (408).
client_header_timeout: Thiết đặt thời gian tải title của webpage từ client. Nếu quá thời gian này, client sẽ nhận thông báo trả về “Request time out” (408).
keepalive_timeout: Thiết đặt thời gian sống của kết nối từ client, nếu quá thời gian này thì kết nối sẽ bị đóng.
send_timeout: Thiết đặt thời gian phản hồi dữ liệu giữa client và server, nếu quá thời gian này thì nginx sẽ tắt kết nối.
I.5.4 Nén các gói dữ liệu gửi đi bằng Gzip
Gzip sẽ giúp nén các dữ liệu trước khi chuyển chúng tới Client. Đây là một cách để tăng tốc độ tuy cập website của cúng ta. Trong thẻ http của file cấu hình chính nginx.conf ta có thể thêm
gzip on; gzip_comp_level 2; gzip_min_length 1000; gzip_proxied expired no-cache no-store private auth; gzip_types text/plain application/xml; gzip_disable "MSIE [1-6]\.";
V.5.5 Cache nội dung các tệp tin tĩnh
Hầu hết các request từ client tới website của chúng ta để load các nôi dung như: hình ảnh, java script, css, flash,… Chúng ta nên thực hiện việc lưu cache lại các tệp tin có nội dung tĩnh này trên Nginx location ~* "\.(js|ico|gif|jpg|png|css|html|htm|swf|htc|xml|bm p|cur)$" {
root /home/site/public_html;
add_header Pragma "public";
add_header Cache-Control "public";
expires 3M;
access_log off;
log_not_found off;
I.5.6 Ẩn phiên bản của Nginx
Việc ẩn đi phiên bản của Nginx từ Server Header sẽ giúp hệ thống webserver của chúng ta được bảo mật tốt hơn. Để thực hiện điều này, trong thẻ http của của tệp tin cấu hình chính nginx.conf ta thêm vào dòng sauserver_tokens off;
I.5.7 Cấm các truy cập tới các tệp tin ẩn trên Nginx
Đôi khi trên các thư mục web chúng ta có lưu những tệp tin ẩn (bắt đầu với dấu chấm “.”) như .svn, .htaccess. Đây là các tệp tin không mang tính public đối với người dùng. Để ngăn chặn các truy xuất tới các tệp tin ẩn này ta có thể thêm vào đoạn cấu hình sau location ~ /\. {
access_log off;
log_not_found off;
deny all;
}
I.5.8Các thông số cơ bản của caching
http {
proxy_cache_path /var/www/cache levels=2 keys_zone=my-cache:8m max_size=1000m inactive=600m;
proxy_temp_path /var/www/cache/tmp;
server {
location / {
proxy_pass http://example.net;
proxy_cache my-cache;
proxy_cache_valid 200 302 60m;
proxy_cache_valid 404 1m;
}
}
}
/vr/www/cache là thư mục chứa cachelevel=2 phân cấp thư mục lưu cache
key_zone=cache_one:8m tên của cache zone là cache_one
inactive=1d: thành phần cache nào không được truy cập trong vòng 1 ngày sẽ bị xóa.
proxy_cache cache_one : chỉ định cache vào zone cache_one
proxy_cache_valid 200 15m : các request có file tồn tại (200) sẽ có giá trị cache trong vòng 15m.
proxy_cache_key $host$request_uri : chỉ định key cache, giúp nginx lần được cache của một URL ở đâu trong thư mục cache.
proxy_set_header X-Forwarded-For $remote_addr: dùng để thêm một dòng trong header trả về cho client.
proxy_ignore_headers : cái này để thông báo cho nginx bỏ qua những header nào của client. Trong các header của người dùng có thể có những trường để điều khiển cache (cache control) nên chúng ta cần báo cho nginx biết bỏ qua những thông số này để việc cache được kiểm soát tối đa.
proxy_read_timeout Default: 60s
II- Unicorn
II.1 – Unicorn là gì ?
Unicorn là server HTTP cho RubyNginx gửi các request tới worker Unicorn thông qua Unix Domain Socket or TCP . Mỗi server đều có một con số worker nhất định mà trong giờ “cao điểm ” có thể đáp ứng được đồng thời nhiều yêu cầu bằng cách sắp xếp hàng đợi . Unicorn biết rõ được các worker đang xử lý tiến trình nào , hay bao bao lâu mỗi worker sử lý một yêu cầu. Thay vì xếp chồng hàng đợi chồng chất Unicorn sẽ hủy bỏ worker và ngay lập tức tạo 1 worker mới để phục vụ yêu cầu
II.2 – Cài đặt – Cấu hình
#gem install rails #gem install unicorn #cd /var/www/ #rails new unicorn #cd unicorn#unicorn_rails
I, [2012-09-07T23:57:09.486924 #2523] INFO -- : listening on addr=0.0.0.0:8080 fd=5 I, [2012-09-07T23:57:09.487888 #2523] INFO -- : worker=0 spawning... I, [2012-09-07T23:57:09.489175 #2523] INFO -- : master process ready I, [2012-09-07T23:57:09.490946 #2525] INFO -- : worker=0 spawned pid=2525 I, [2012-09-07T23:57:09.491675 #2525] INFO -- : Refreshing Gem list I, [2012-09-07T23:57:15.208629 #2525] INFO -- : worker=0 ready#mkdir /etc/unicorn
#cd /etc/unicorn/
#vim /etc/unicorn/unicorn2.conf
RAILS_ROOT=/var/www/unicorn RAILS_ENV=production#vim /etc/init.d/unicorn_2
#!/bin/sh
set -e
sig () {
test -s "$PID" && kill -$1 `cat "$PID"`
}
oldsig () {
test -s "$OLD_PID" && kill -$1 `cat "$OLD_PID"`
}
cmd () {
case $1 in
start)
sig 0 && echo >&2 "Already running" && exit 0
echo "Starting"
$CMD
;;
stop)
sig QUIT && echo "Stopping" && exit 0
echo >&2 "Not running"
;;
force-stop)
sig TERM && echo "Forcing a stop" && exit 0
echo >&2 "Not running"
;;
restart|reload)
sig USR2 && sleep 5 && oldsig QUIT && echo "Killing old master" `cat $OLD_PID` && exit 0
echo >&2 "Couldn't reload, starting '$CMD' instead"
$CMD
;;
upgrade)
sig USR2 && echo Upgraded && exit 0
echo >&2 "Couldn't upgrade, starting '$CMD' instead"
$CMD
;;
rotate)
sig USR1 && echo rotated logs OK && exit 0
echo >&2 "Couldn't rotate logs" && exit 1
;;
*)
echo >&2 "Usage: $0 <start|stop|restart|upgrade|rotate|force-stop>"
exit 1
;;
esac
}
setup () {
echo -n "$RAILS_ROOT: "
cd $RAILS_ROOT || exit 1
export PID=$RAILS_ROOT/tmp/pids/unicorn.pid
export OLD_PID="$PID.oldbin"
CMD="unicorn_rails -c config/unicorn.rb -E $RAILS_ENV -D"
}
start_stop () {
# either run the start/stop/reload/etc command for every config under /etc/unicorn
# or just do it for a specific one
# $1 contains the start/stop/etc command
# $2 if it exists, should be the specific config we want to act on
if [ $2 ]; then
. $2
setup
cmd $1
else
for CONFIG in /etc/unicorn/unicorn2.conf; do
# import the variables
. $CONFIG
setup
# run the start/stop/etc command
cmd $1
done
fi
}
ARGS="$1 $2"
start_stop $ARGS
#chmod +x /etc/init.d/unicorn_2#cd /var/www/unicorn/config
#vim unicorn.rb
app_path = "/var/www/unicorn"
listen 2008 # by default Unicorn listens on port 8080
worker_processes 2 # this should be >= nr_cpus
pid "#{app_path}/tmp/pids/unicorn2.pid"
stderr_path "#{app_path}/log/unicorn2.log"
stdout_path "#{app_path}/log/unicorn2.log"
before_exec do |server|
ENV['BUNDLE_GEMFILE'] = "/var/www/unicorn/Gemfile"
end
before_fork do |server, worker|
defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!
old_pid = "#{server.config[:pid]}.oldbin"
if old_pid != server.pid
begin
sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
Process.kill(sig, File.read(old_pid).to_i)
rescue Errno::ENOENT, Errno::ESRCH
end
end
end
###################require "redis"
after_fork do |server, worker|
if defined?(ActiveRecord::Base)
ActiveRecord::Base.establish_connection
end
if defined?(MultiDb::ConnectionProxy)
begin
# MultiDb::ConnectionProxy.sticky_slave = true
MultiDb::ConnectionProxy.setup!
rescue
end
end
if Rails.cache.respond_to?(:reset)
Rails.cache.reset
end
port = 5000 + worker.nr
child_pid = server.config[:pid].sub('.pid', ".#{port}.pid")
system("echo #{Process.pid} > #{child_pid}")
end
Kiểm tra các kết nối#netstat -natp
Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.1:27017 0.0.0.0:* LISTEN 864/mongod tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN 880/mysqld tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 989/redis-server tcp 0 0 127.0.0.1:11211 0.0.0.0:* LISTEN 924/memcached tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 840/boa tcp 0 0 0.0.0.0:2001 0.0.0.0:* LISTEN 939/monkey tcp 0 0 127.0.0.1:28017 0.0.0.0:* LISTEN 864/mongod tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1748/sshd tcp 0 0 192.168.4.106:22 192.168.4.100:49216 ESTABLISHED 2001/sshd: kiloccnp tcp 0 52 192.168.4.106:22 192.168.4.100:49396 ESTABLISHED 2533/sshd: kiloccnp tcp6 0 0 :::22 :::* LISTEN 1748/sshd tcp6 0 0 :::8000 :::* LISTEN 999/webfsd
#/etc/init.d/unicorn_2 start
#netstat -natp
Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.1:27017 0.0.0.0:* LISTEN 864/mongod tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN 880/mysqld tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 989/redis-server tcp 0 0 127.0.0.1:11211 0.0.0.0:* LISTEN 924/memcached tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 840/boa tcp 0 0 0.0.0.0:2001 0.0.0.0:* LISTEN 939/monkey tcp 0 0 127.0.0.1:28017 0.0.0.0:* LISTEN 864/mongod tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1748/sshd tcp 0 0 0.0.0.0:2008 0.0.0.0:* LISTEN 3069/unicorn.rb -E tcp 0 0 192.168.4.106:22 192.168.4.100:49216 ESTABLISHED 2001/sshd: kiloccnp tcp 0 52 192.168.4.106:22 192.168.4.100:49396 ESTABLISHED 2533/sshd: kiloccnp tcp6 0 0 :::22 :::* LISTEN 1748/sshd tcp6 0 0 :::8000 :::* LISTEN 999/webfsdcd /var/www/unicorn/log
cat unicorn2.log
I, [2012-09-08T00:13:37.402200 #3069] INFO -- : listening on addr=0.0.0.0:2008 fd=5 I, [2012-09-08T00:13:37.402872 #3069] INFO -- : worker=0 spawning... I, [2012-09-08T00:13:37.403439 #3069] INFO -- : worker=1 spawning... I, [2012-09-08T00:13:37.403980 #3069] INFO -- : master process ready I, [2012-09-08T00:13:37.409890 #3072] INFO -- : worker=0 spawned pid=3072 I, [2012-09-08T00:13:37.410073 #3072] INFO -- : Refreshing Gem list I, [2012-09-08T00:13:37.412841 #3074] INFO -- : worker=1 spawned pid=3074 I, [2012-09-08T00:13:37.413020 #3074] INFO -- : Refreshing Gem list I, [2012-09-08T00:13:42.680852 #3074] INFO -- : worker=1 ready I, [2012-09-08T00:13:42.684405 #3072] INFO -- : worker=0 ready
Đăng ký:
Bài đăng (Atom)
Học lập trình web căn bản với PHP
Bài 1: Các kiến thức căn bản Part 1: https://jimmyvan88.blogspot.com/2012/05/can-ban-lap-trinh-web-voi-php-bai-1-cac.html Part 2: https://...
-
IMindMap 8.0.4 iMindMap là công cụ tuyệt vời để vẽ bản đồ tư duy đem mọi chi tiết trong đầu bạn ra thành các ý tươgnr, để nắm bắt ý tư...
-
1. Download Bamboo in : http://www.atlassian.com/software/bamboo/download?os=linux cd ~ mkdir BAMBOO cd BAMBOO wget http://www.atlassia...
-
1.Giới thiệu về Vim Vim – Vi iMprove là bản cải thiện của Vim – một trình soạn thảo phổ biến trên Unix. Vim có tính cấu hình rất cao ...