1 / 86

搭建 Linux Web 服务器

搭建 Linux Web 服务器. 李博杰 BOJIELI@GMAIL.COM LUG@USTC 2013-03-23. 目录. 最小 权限原则 配置 SSH Key 理解 HTTP 配置 nginx 配置 php -fpm 配置 MySQL 性能测试、监控与优化 数据备份. 最小权限原则. 如果 Web 程序报 Permission Denied 错误 …… 网上教程通常是让把目录权限设成 777 有些 Web 程序为了方便安装,要求把上传目录权限改成 777 假设我们需要在服务器上运行一个自己编写的服务 ……

royce
Download Presentation

搭建 Linux Web 服务器

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 搭建Linux Web服务器 李博杰BOJIELI@GMAIL.COM LUG@USTC 2013-03-23

  2. 目录 • 最小权限原则 • 配置SSH Key • 理解HTTP • 配置nginx • 配置php-fpm • 配置MySQL • 性能测试、监控与优化 • 数据备份

  3. 最小权限原则 • 如果Web程序报Permission Denied错误…… • 网上教程通常是让把目录权限设成777 • 有些Web程序为了方便安装,要求把上传目录权限改成777 假设我们需要在服务器上运行一个自己编写的服务…… • 把数据放在/var/lib里,以root身份运行? • 把数据放在家目录里,以自己的身份运行? 善用Linux用户吧! • 新建一个用户和同名的组,以这个用户的身份运行 • 把代码和数据的owner和group改成这个用户 • 目录权限775,文件权限664 • 将需要修改代码/数据的其他用户加入这个组

  4. SSH是如何实现加密的 • 古人使用的加密技术都是对称加密,加密和解密使用同一个密钥,如何保证可靠地传递密钥呢? • SSH背后的技术是RSA,一种非对称加密算法 • 用公钥加密,用私钥解密 • 公钥可以发布出去,让对方把要传输的数据用公钥加密,自己再用私钥解密 • 通信双方分别拥有一对公私钥,就能在不安全的信道上进行双向数据传输了 • 中间人攻击:我想做你们的透明代理…… • ~/.ssh/known_hosts里存储了每个SSH过的计算机的公钥

  5. 配置SSH Key • 有多少人每次登录服务器都要输入密码? • 用ssh-keygen吧! • 生成的private key默认在~/.ssh/id_rsa,千万不要泄露哦 • 生成的public key默认在~/.ssh/id_rsa.pub,可以发布出去 • 将public key上传到服务器的~/.ssh/authorized_keys:ssh remote-host “mkdir –p ~/.ssh”ssh remote-host “chmod 700 ~/.ssh”scp ~/.ssh/id_rsa.pub remote-host:~/.ssh/authorized_keys • 如果你还在用root登录…… • adduser, sudo, visudo, /etc/group的基本操作一定要会哦

  6. HyperText Transfer Protocol 浏览器 服务器 TCP SYN 接受连接 TCP ACK GET / HTTP/1.1 准备 / 的内容 HTTP/1.1 200 OK TCP ACK 浏览器解析 GET /jquery.js HTTP/1.1 HTTP/1.1 200 OK

  7. HTTP Request • $ curl -v mirrors.ustc.edu.cn> GET / HTTP/1.1> User-Agent: curl/7.29.0> Host: mirrors.ustc.edu.cn> Accept: */*>< HTTP/1.1 200 OK< Server: nginx/0.7.67< Date: Thu, 21 Mar 2013 04:55:48 GMT< Content-Type: text/html< Content-Length: 14457< Last-Modified: Thu, 21 Mar 2013 04:55:02 GMT< Connection: keep-alive< Accept-Ranges: bytes 请求行 客户端类型 访问哪个主机 接受的响应类型 空行表示请求头结束 响应行 服务器类型 时间 内容类型 内容(不含头)长度 用于缓存 是否保持TCP连接 支持断点续传 Request Header Response Header

  8. HTTP请求行 • 格式:请求类型路径 HTTP/1.1 • 请求类型包括GET POST HEAD等 • GET用于“只读”请求 • POST用于有修改作用的请求 • HEAD只返回response header • 路径以/开头,一般格式为/path/to/file?param1=value1&param2=value2&option • HTTP请求中,\r\n表示换行

  9. HTTP响应行 • 格式:HTTP/1.1 状态码 状态解释 • 200 OK • 206 Partial Content 断点续传 • 301 Moved Permanently 永久重定向 • 302 Found 临时重定向 • 304 Not Modified 用缓存吧 • 400 Bad Request 请求格式错误 • 403 Forbidden • 404 Not Found • 500 Internal Server Error 2xx成功 3xx重定向 4xx请求错误 5xx服务器错误

  10. Bashttpd • 读请求行,获取请求类型、URI和HTTP版本号 • 依次匹配bashttpd.conf中的各条URI规则,一旦匹配上就执行对应的操作 • 以serve_dir_or_file_from操作为例: • 过滤非法路径 • 如果要读的是目录且有index.html,则输出之 • 如果要读的是目录且没有index.html,则调用ls • 如果要读的是文件,则获取文件类型和长度放进Response Header,并输出内容 • 如果读取失败,返回403;如果文件没找到,返回404

  11. Linux Web服务器组件 PHP MySQL Nginx Linux内核 网络协议栈

  12. Linux服务器请求过程 MySQL 浏览器 Nginx PHP 建立TCP连接 分配HTTP请求 执行脚本 数据库查询 执行脚本 数据库查询 执行脚本 接受PHP输出 返回给用户 浏览器渲染

  13. Apache进程模型 主进程 子进程 子进程 子进程 子进程 Web服务在线程“内部解决”,如mod_php模块。每个线程负责一个PHP请求。 线程 线程 线程 问题:每个请求的处理过程中始终占着一个线程,上下文切换频繁,难以支持高并发。 客户端 客户端 客户端

  14. Nginx进程模型

  15. Nginx为什么比Apache性能高 • select vs. epoll • Apache使用select系统调用,轮询所有连接看有没有新动态,没有则小睡一会再次轮询(每次轮询还得拷贝所有文件描述符到内核空间) • Nginx使用epoll系统调用,让内核保存需要监视的文件描述符,有新动态时就调用回调函数,不需要轮询 • 内部解决 vs. 任务外包 • Apache的处理模块在内部,看起来降低了进程间通信的开销,事实上使很多无关资源不能及时得到释放 • Nginx术业有专攻,把PHP之类的都“外包”给CGI,每个进程可以同时处理很多请求,节约资源

  16. Nginx的异步处理机制 • Nginx比起Apache的“大包大揽”,只是一个轻量级的HTTP反向代理服务器。 • 空闲worker进程“争着”接收客户端的HTTP请求,谁接收到了,就根据配置文件规则分发到对应的处理模块(还记得bashttpd吗?) • 如果是文件,就通过sendfile,把发送文件的任务丢给内核 • 如果需要通过php-fpm等CGI,就异步发给CGI • 此时worker可以去接收新的HTTP请求 • CGI处理完返回时触发worker,worker发送给客户端

  17. Nginx的异步处理机制 • 信号 • reload配置:kill –HUP `cat /var/run/nginx.pid` • logrotate:kill –USR1 `cat /var/run/nginx.pid` • 网络事件 • 各worker初始化时给监听的端口添加事件 • 如果有新请求,各worker在上锁的情况下争相accept,抢到的worker给这个连接初始化,添加读事件 • 如果有读事件,则根据这个连接目前的状态,决定解析请求行或请求头。两种解析分别是一个有限状态机,如果发现已读数据不够,则下次读事件再试。请求体由处理模块负责读取。 • 如果是超时事件,则结束对应的连接

  18. CGI vs. FastCGI • 前面的bashttpd就像CGI,本身只能处理一个请求。每处理一个请求,nginx就得fork出一个cgi来。 • FastCGI则是一个CGI在生命周期内可以一个接一个地处理很多请求,节省了进程创建和初始化的开销。

  19. Nginx配置文件结构 root 全局配置:error_log, worker_processes… events http server location location server https

  20. Nginx配置作用域 • 内层配置覆盖外层配置 • Nginx官方文档中每个选项(Directive)都有适用范围(Context) • 例如keepalive_timeout适用于http, server, location,则location配置优先于server配置,server配置优先于http配置 • 在Debian中,/etc/nginx/nginx.conf的httpblock有: • include /etc/nginx/conf.d/*.conf • include /etc/nginx/sites-enabled/* • 一般每个server(虚拟主机)一个配置文件,放在sites-available目录,再符号链接到sites-enabled

  21. Nginx处理请求的步骤 • 根据端口号和Host选择server • listen 80 default_server是什么意思? • server级别rewrite • 根据location匹配规则,选择第一个匹配到的location • location级别rewrite • 访问控制:allow, deny, auth_basic • 尝试文件:try_files • 显示内容:autoindex, fastcgi, gzip_static, uwsgi… • 记录日志:access_log

  22. location directive • location [ = | ~ | ~* | ^~ ] uri { ... } • 前缀匹配 • location / 匹配所有URI(它一般是fallback) • location ^~ /images/ 匹配所有/images/开头的URI • 完整匹配 • location = /favicon.ico 只匹配/favicon.ico这个URI • 正则表达式匹配 • location ~* \.(gif|jpg|jpeg|png)$ 匹配图片文件(大小写不敏感) • location ~ documents 匹配含有documents的URI(大小写敏感)

  23. location directive • 匹配顺序: • 完整匹配,如果匹配则停止 • 前缀匹配,如果找到的最长前缀匹配恰好用了^~修饰,则停止 • 正则表达式匹配,从上到下进行,只要找到匹配即停止 • 使用前缀匹配找到的最长前缀匹配

  24. 设置Web目录 • location /~boj/ { alias /home/boj/;} • 结果:/~boj/test.html => /home/boj/test.html • location /~boj/ {root /home/boj/;} • 结果:/~boj/test.html => /home/boj/~boj/test.html

  25. 设置Web目录 • location ~ ^/download/(.*)$ { alias /srv/www/static/$1;} • 结果:/download/test.html => /srv/www/static/test.html • location ~ ^/download/(.*)$ {root /srv/www/static/$1;} • 结果:/download/test.html => /srv/www/static/download/test.html

  26. Nginx配置文件中可用变量 • GET /test.php?a=1&b=helloHost: lug.ustc.edu.cnUser-Agent: Mozilla/5.0

  27. Nginx Rewrite • Rewrite,就是把一个URI换成另一个URI,重新走location定位过程。 • 为防止环路,一个请求的rewrite至多进行10次。 • break • 结束当前location块,不再执行后面的语句 • return • 直接返回错误状态码

  28. Nginx Rewrite • if • 字符串相同比较:=, != • 正则表达式:~, ~*, !~, !~* • 文件存在:-f, !-f • 目录存在:-d, !-d • 文件或目录存在:-e !-e • 文件可执行:-x !-x • if语句中可以使用前面说的变量,例如 • if ($http_user_agent ~ MSIE) {…} • 建议使用try_files(使用第一个找到的文件)代替if: • try_files$uri $uri/ /index.html;

  29. Nginx Rewrite • rewrite • last 结束当前rewrite的处理,但仍然执行非rewrite语句,重新调度 • break 不再执行当前location块中后续的rewrite,但仍然执行非rewrite语句 • 在location外,last与break等效 • 在location内一般用break,如果用last有可能重新进入此location,形成环路 • redirect 立即返回HTTP 302 • permanent 立即返回HTTP 301

  30. Nginx Rewrite • rewrite "/photos/([0-9]{2})([0-9]{2})([0-9]{2})" /path/to/photos/$1/$1$2/$1$2$3.png; • 效果:/photos/130321 => /path/to/photos/13/1303/130321.png • 比较: • rewrite “/photos/([0-9]*)” /path/to/photos/$1.png; • rewrite “/photos/([0-9]*)” /path/to/photos/$1.png redirect;

  31. Nginx proxy • location /linux/ {proxy_passhttp://202.38.70.187/;proxy_redirect default;} • Nginx将location中的部分(/linux/)替换成proxy_pass中指定的部分(http://202.38.70.187/)。 • proxy_redirect是对上游返回的response header中的Location重写(不然301/302跳转就出错了) • proxy_redirect default 相当于proxy_redirect http://202.38.70.187/ /linux/; • 前缀匹配前一个URI,替换成后一个URI

  32. Nginx proxy • 使用UNIX socket做上游: • proxy_pass http://unix:/path/to/backend.socket:/uri/; • 默认不forward request Host,如果需要forward: • proxy_set_header Host $host; • 如果location是用正则表达式匹配的,或者URI被location内的rewrite规则作用过,则直接在proxy_pass参数后附加从“/”开始的整个URI: • location /backend-task/ { rewrite /backend-task/([^/]+) /task?query=$1 break;proxy_pass http://192.168.0.100;}

  33. 负载均衡 – 权重 • 按照weight随机分配到backend: • upstream backends { server backend1.example.com weight=5; server backend2.example.com:8080; #默认weight=1 server unix:/var/run/backend3.sock;} • server { location /static/ {proxy_pass http://backends; }}

  34. 负载均衡 – IP hash • 按照IP地址的hash值分配,可以保证同IP用户始终被分配到同一后端,便于处理session: • upstream backends{ip_hash; server backend1.example.com; server backend2.example.com:8080; server unix:/var/run/backend3.sock down;} • server { location /dynamic/ {proxy_pass http://backends; }}

  35. 设置错误页 • error_page 404 /404.html; • error_page 502 503 504 /50x.html; • error_page 403 http://example.com/forbidden.html; • error_page 404 = @fallback; • location @fallback { • proxy_passunix:/var/run/backend.sock; • }

  36. Nginx Access Log • access_log path [format [buffer=size [flush=time]]] • format需在http中定义,默认为combined • log_format combined '$remote_addr - $remote_user [$time_local] ''"$request" $status $body_bytes_sent''"$http_referer" "$http_user_agent"'; • 除了前面提到的变量,还有一些可以log的统计量: • $request_length: 请求body的字节数 • $request_time: Nginx处理请求全过程所用毫秒数 • $connection: 连接的序列号

  37. 图片防盗链 • location ~* \.(jpg|gif|png|swf|flv|wma|wmv|asf|mp3|mmf|zip|rar)$ {valid_referrers none blocked *.example.com example.com; if ($invalid_referrer) { rewrite ^/ http://example.com/error.gif; }} • none表示没有Referer字段 • blocked表示Referer字段被防火墙mask

  38. 一些小问题 • 调整最大并发数: • connection:TCP连接,每个worker维护一个连接池 • 简单文件最大并发 = worker_connections * worker_processes • 反向代理服务器(fastcgi)最大并发 = worker_connections * worker_processes/ 2(由于nginx还要与fastcgi之间保持连接) • 上传大附件,出现413 Request Entity Too Large怎么办? • 调整请求body大小限制: • client_max_body_size 0(不限制)或100m

  39. PHP-FPM是什么 Nginx PHP-FPM master worker1 worker2 worker3

  40. 为什么选用PHP-FPM • php-fpm是fastcgi的另一种实现。它好在哪里呢? • 支持pid file, log file, setsid, setuid, setgid, chroot • 重启php-fpm服务器时不会丢失请求 • 限制请求来源IP • 根据负载动态调整worker个数 • 使用不同的php.ini配置和uid/gid/chroot环境启动worker • 对php程序的输出做日志 • fastcgi_finish_request()可以结束输出,但脚本继续执行,可以执行长时间的任务而不损害用户体验

  41. PHP请求过程 每个php-fpmworker只能同时处理一个PHP请求,也就是有多少个worker,就能并发处理多少个PHP请求。

  42. PHP-FPM信号处理 • SIGINT, SIGTERM: 立即停止服务 • SIGQUIT: 服务完当前请求后停止服务(service stop) • SIGUSR1: 重新打开日志文件(logrotate) • SIGUSR2: 各worker服务完当前请求后重启,达到重新载入配置文件的目的(service reload)

  43. Debianphp-fpm配置文件 • 在/etc/php5/fpm/目录下: • php.ini是与PHP语言相关配置 • conf.d目录是被php.ini include的,一般是PHP模块配置 • php-fpm.conf是与php-fpm进程池相关配置 • pool.d目录是被php-fpm.conf include的,每个文件是一个进程池,默认是www.conf这个进程池

  44. php-fpm常用配置 • 监听socket文件而非TCP端口: • listen = /var/run/php-fpm/php-fpm.sock • worker进程的所有者: • user = www-data • group = www-data • dynamic进程管理策略下的worker进程数: • pm.max_children最大worker数 • pm.start_servers PHP-FPM启动时spawn的worker数 • pm.min_spare_servers worker数少于此值就会spawn • pm.max_spare_servers最大worker数

  45. php-fpm常用配置 • 其他进程管理策略: • static:固定个数(pm.max_children)的worker • ondemand:有请求来时才spawn worker,每个worker空闲pm.process_idle_timeout就退出 • 如果第三方模块有内存泄漏…… • 每处理pm.max_requests个请求就重启worker • 事实上编写PHP扩展时,只要谨慎使用persistent resource就不会有内存泄漏,请求结束时emalloc的内存会被释放 • 查询php-fpm状态的Web接口:pm.status_path • 访问日志,参见www.conf的注释

  46. php.ini配置 • PHP配置分为四种级别: • PHP_INI_SYSTEM 只能在php.ini中,或Apache的httpd.conf中配置 • PHP_INI_PERDIR 只能在php.ini或.user.ini中,或Apache的httpd.conf或.htaccess中配置 • PHP_INI_USER 可以在php程序中用ini_set函数配置 • PHP_INI_ALL = PHP_INI_PERDIR | PHP_INI_USER • 在php-fpm中,worker配置 • php_flag[display_errors]可以覆盖php.ini的display_errors项 • php_admin_flag[log_errors]可以覆盖log_errors项,且此项不再可以在php程序中用ini_set修改

  47. php.ini常用配置 – 安全 • allow_url_fopen允许把URL当作文件名,用fopen打开 • allow_url_include允许把URL当作include的文件(危险) • disable_classes禁用类,用逗号隔开 • disable_functions禁用函数,用逗号隔开 • expose_php在reponse header中包括X-Powered-By信息 • open_basedir禁止访问basedir以外的文件 • safe_mode已经废弃,不要再用了

  48. php.ini常用配置– 错误 • display_errors遇到PHP错误时,是否输出错误信息 • error_reporting错误报告级别,包括E_ERROR, E_WARNING, E_PARSE, E_NOTICE, E_STRICT, E_DEPRECATED等,一般设为E_ALL & ~E_NOTICE • html_errors以HTML形式输出PHP错误 • log_errors是否写错误日志

  49. php.ini常用配置 – 资源限制 • max_execution_time最大执行的秒数 • max_input_vars $_GET, $_POST数组的最大元素数,用以避免hash冲突攻击 • post_max_size POST请求的大小限制,应当大于要上传的文件大小 • upload_max_filesize上传文件的大小限制 • max_file_uploads一个请求最多上传的文件数 • memory_limit内存限制,应当大于上传文件大小

  50. php.ini常用配置 – 其他 • auto_prepend_file自动在PHP脚本前添加代码 • auto_append_file自动在PHP脚本后添加代码(如果脚本中调用了exit则不会执行append_file) • extension_dirPHP扩展的查找路径 • sendmail_path mail函数发送邮件的命令

More Related