mac 安装nginx,并配置nginx的运行环境
1. 安装nginx
// 查询有没有nginx brew search nginx //开始安装nignx brew install nginx
2. 检查nignx是否安装成功
nginx -V 查看nginx版本及安装的本地位置 ngxin -v 查看nginx版本(此方法依然可以检测是否安装某一软件,如git,hg等)
//同时你也可以在浏览器上输入,来查看运行结果,出现下图应该就可以了
localhost:8080
3. nginx安装在哪?为什么会安装在这里?
--prefix=/usr/local/Cellar/nginx/1.15.5 // 没错就是安装在这里了
那么为什么会安装在这里呢?
/usr用于存放系统应用程序,比较重要的目录/usr/local本地系统管理员软件安装目录(安装系统级的应用)。这是最庞大的目录,要用到的应用程序和文件几乎都在这个目录。
显然,nignx属于系统级应用,所以就安装在了/usr/local下。
不过有一点需要注意:/usr目录下一般安装系统应用,/usr/local目录下安装用户下载的系统应用。然后可能会有人说,你这不是在扯淡吗?这两个有什么差别?别急,真的有差别!
/usr/local目录 安装用户下载的系统应用,比如nginx,mysql,zsh,openssl等系统软件 都放在这些个地方, /usr目录存放安装linux系统时安装的应用,明白了吗?一个是系统安装时安装的应用,一个是用户安装的应用,两者不是一会事儿。
4. nginx启动和暂停指令
nginx关闭很简单,稍微有点复杂的是nginx的开启
//关闭, kill和pkill的区别,kill只能通过进程id杀死进程,pkill可以通过进程名字杀死所有的进程 pkill nginx;
nginx开启,首先你要知道nginx的可以执行文件在哪。那么怎么知道呢?看下面的代码
-v : show version and exit // 告诉我们nginx的配置信息 -V : show version and configure options then exit // 不仅告诉我们配置信息,还会告诉我们配置选项,然后停止 -t : test configuration and exit // 检查配置是不是正确 -T : test configuration, dump it and exit // 检查配置,并把这些配置打印出来,然后就停止 -q : suppress non-error messages during configuration testing -s signal : send signal to a master process: stop, quit, reopen, reload // 给主进程发信息,比如stop, quit, reopen, reload这些指令(Quit 是一个优雅的关闭方式,Nginx在退出前完成已经接受的连接请求;Stop 是快速关闭,不管有没有正在处理的请求) -p prefix : set prefix path (default: /usr/local/Cellar/nginx/1.15.5/) // -s reopen 重新打开日志(不懂日志) -c filename : set configuration file (default: /usr/local/etc/nginx/nginx.conf) // nginx到底以哪个配置文件为准 -g directives : set global directives out of configuration file
这个时候我们可以先执行
nginx -V
然后会看到
进入--sbin-path指示的地方,然后执行下面代码就可以了
./nginx -t // 如果配置文件不正确的话,可以使用./nginx -c location 来指定配置文件
5. nginx配置好了,利用nginx来做事情了。先看看nginx主要的配置,及它们的含义
worker_processes 4; #Nginx运行时使用的CPU核数 events { worker_connections 1024; #一个woeker进程的最大连接数 } http { #Nginx用作虚拟主机时使用。每一个server模块生成一个虚拟主机。
include mime.types; #定义MIME类型和后缀名关联的文件的位置 default_type application/octet-stream; #指定mime.types文件中没有记述到的后缀名的处理方法 log_format main '$remote_addr - $remote_user [$time_local] "$request" ' #定义日志的格式。可以选择main或者ltsv,后面定义要输出的内容。
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
1.$remote_addr 与$http_x_forwarded_for 用以记录客户端的ip地址;
2.$remote_user :用来记录客户端用户名称;
3.$time_local :用来记录访问时间与时区;
4.$request :用来记录请求的url与http协议;
5.$status :用来记录请求状态;
6.$body_bytes_s ent :记录发送给客户端文件主体内容大小;
7.$http_referer :用来记录从那个页面链接访问过来的;
8.$http_user_agent :记录客户端浏览器的相关信息;。
access_log /usr/local/var/log/nginx/access.log main; #连接日志的路径,上面指定的日志格式放在最后 sendfile on; #是否使用OS的sendfile函数来传输文件 keepalive_timeout 65; #HTTP连接的持续时间。设的太长会使无用的线程变的太多 server { listen 80; #监听端口 server_name localhost; #服务地址 charset utf-8; #编码方式 access_log /usr/local/var/log/nginx/localhost.access.log main; #nginx请求日志地址 root /var/www; #你的网站根目录 location / { # 所有的请求都会走的路径 index index.html index.htm index.php; try_files $uri /$uri index.php?$args; #从左边开始找指定文件是否存在 } error_page 404 /404.html; error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } location ~ \.php$ { # 正则表达式: .php文件走的路径 fastcgi_pass 127.0.0.1:9000; #走fastcgi 路径 fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /var/www$fastcgi_script_name; #定义的根目录 以及 请求的脚本名 include fastcgi_params; # 请求参数 } location ~ /\.ht { # 当前项目的根路径 deny all; } } include sites-enabled/nginx-*.conf; # 添加的文件其他虚拟主机配置 }
6. 看完各种配置之后,可以尝试着自己写一波了。
运行:sudo /usr/sbin/php-fpm,因为usr/sbin目录下放的是可执行文件,所以当你访问/usr/sbin/php-fpm的时候就相当于在启动fpm。但很遗憾,出现了这样的错误:
[22-Oct-2018 21:15:38] ERROR: failed to open configuration file '/private/etc/php-fpm.conf': No such file or directory (2) [22-Oct-2018 21:15:38] ERROR: failed to load configuration file '/private/etc/php-fpm.conf' [22-Oct-2018 21:15:38] ERROR: FPM initialization failed
看看这个错误提示的意思是没有 '/private/etc/php-fpm.conf',找不到不要紧,我们再往里面查,发现里面有一个默认的文件
拷贝一份过去不就得了?
sudo cp /private/etc/php-fpm.conf.default /private/etc/php-fpm.conf
拷贝完之后接着执行 :sudo /usr/sbin/php-fpm 发现报错:
[22-Oct-2018 21:16:27] WARNING: Nothing matches the include pattern '/private/etc/php-fpm.d/*.conf' from /privat; Start a new pool named 'www'. ; the variable $pool can be used in any directive and will be replaced by the e/etc/php-fpm.conf at line 125. ; Start a new pool named 'www'. [22-Oct-2018 21:16:27] ERROR: failed to open error_log (/usr/var/log/php-fpm.log): No such file or directory (2) [22-Oct-2018 21:16:27] ERROR: failed to post process the configuration [22-Oct-2018 21:16:27] ERROR: FPM initialization failed
很简单,找不到file和directory,既然找不到,先创建个文件夹:sudo mkdir -p /usr/var/log,结果发现:
mkdir: /usr/var/log: Operation not permitted
为啥啊?mac EI Captian系统权限收紧了,不让创建了。那好,不让创建就不创建了。我换个地方建行不行?sudo mkdir -p /usr/local/var/log/nginx/ 幺西,可以了。我再执行:sudo /usr/sbin/php-fpm
[22-Oct-2018 21:17:54] WARNING: Nothing matches the include pattern '/private/etc/php-fpm.d/*.conf' from /private/etc/php-fpm.conf at line 125.
[22-Oct-2018 21:17:54] ERROR: failed to open error_log (/usr/var/log/php-fpm.log): No such file or directory (2)
[22-Oct-2018 21:17:54] ERROR: failed to post process the configuration
[22-Oct-2018 21:17:54] ERROR: FPM initialization failed
; Start a new pool named 'www'.
what?这是个什么叼!老子配个环境,跟唐僧去西天取经一样。我忍。不就是错误吗,查!
Mac OSX 10.9的系统自带了PHP、php-fpm,省去了安装php-fpm的麻烦。 这里需要简单地修改下php-fpm的配置,否则运行php-fpm
会报错。
<!-- lang: shell --> sudo cp /private/etc/php-fpm.conf.default /private/etc/php-fpm.conf vim /private/etc/php-fpm.conf
修改php-fpm.conf文件中的error_log
项,默认该项被注释掉,这里需要去注释并且修改为error_log = /usr/local/var/log/php-fpm.log
。如果不修改该值,运行php-fpm的时候会提示log文件输出路径不存在的错误。
这个问题解决了,我接着再运行:sudo /usr/sbin/php-fpm 服了,改了,够了。又出现了这样的错误。
[22-Oct-2018 21:22:04] WARNING: Nothing matches the include pattern '/private/etc/php-fpm.d/*.conf' from /private/etc/php-fpm.conf at line 125. [22-Oct-2018 21:22:04] ERROR: No pool defined. at least one pool section must be specified in config file [22-Oct-2018 21:22:04] ERROR: failed to post process the configuration [22-Oct-2018 21:22:04] ERROR: FPM initialization failed
查!!!!!!!!!!
大概意思就是说找不到/private/etc/php-fpm.d/*.conf目录下的配置文件。 进入里面的目录,会有一个www.conf.default文件。执行下面命名复制一份
root@ubuntu:/opt/php7/etc/php-fpm.d/# cp www.conf.default www.conf 复制好之后,编辑该文件 定位到里面文件的 user = nobody 和 group = nobody ,调整为 www-data。这一步和5版编译安装一样。最后启动PHP-FPM
改好之后,再次执行:sudo /usr/sbin/php-fpm
nginx: the configuration file /usr/local/etc/nginx/nginx.conf syntax is ok nginx: [emerg] bind() to 0.0.0.0:80 failed (13: Permission denied) nginx: configuration file /usr/local/etc/nginx/nginx.conf test failed
苹果对1024一下的端口都做了限制,要有root权限才能执行,所以用sudo命令或者将端口改为1024以上就可以解决这个问题了。 我采用的方法是把端口号改成了8088。
然后访问localhost:8080,结果出现了这个问题:
Bad GateWay什么鬼?没关系我们看一下错误日志:
2018/10/23 11:25:17 [crit] 28716#0: *26 stat() "/Users/qudian/Documents/project/quxuexi/3.0/quxuexi.service.merchant/public/" failed (13: Permission denied), client: 127.0.0.1, server: quxuexi.merchant, request: "GET / HTTP/1.1", host: "localhost:8088" 2018/10/23 11:25:17 [crit] 28716#0: *26 stat() "/Users/qudian/Documents/project/quxuexi/3.0/quxuexi.service.merchant/public/" failed (13: Permission denied), client: 127.0.0.1, server: quxuexi.merchant, request: "GET / HTTP/1.1", host: "localhost:8088" 2018/10/23 11:25:17 [crit] 28716#0: *26 connect() to unix:/var/run/php/php7.2-fpm.sock failed (2: No such file or directory) while connecting to upstream, client: 127.0.0.1, server: quxuexi.merchant, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/var/run/php/php7.2-fpm.sock:", host: "localhost:8088" 2018/10/23 11:25:17 [crit] 28716#0: *26 stat() "/Users/qudian/Documents/project/quxuexi/3.0/quxuexi.service.merchant/public/favicon.ico" failed (13: Permission denied), client: 127.0.0.1, server: quxuexi.merchant, request: "GET /favicon.ico HTTP/1.1", host: "localhost:8088", referrer: "http://localhost:8088/" 2018/10/23 11:25:17 [crit] 28716#0: *26 stat() "/Users/qudian/Documents/project/quxuexi/3.0/quxuexi.service.merchant/public/favicon.ico" failed (13: Permission denied), client: 127.0.0.1, server: quxuexi.merchant, request: "GET /favicon.ico HTTP/1.1", host: "localhost:8088", referrer: "http://localhost:8088/" 2018/10/23 11:25:17 [crit] 28716#0: *26 connect() to unix:/var/run/php/php7.2-fpm.sock failed (2: No such file or directory) while connecting to upstream, client: 127.0.0.1, server: quxuexi.merchant, request: "GET /favicon.ico HTTP/1.1", upstream: "fastcgi://unix:/var/run/php/php7.2-fpm.sock:", host: "localhost:8088", referrer: "http://localhost:8088/"
总的来说错误日志给出了三种错误提示:
(1)访问/Users/qudian/Documents/project/quxuexi/3.0/quxuexi.service.merchant/public/" failed 失败了
(2)connect() to unix:/var/run/php/php7.2-fpm.sock failed (2: No such file or directory) 失败了,没有这样的文件和文件夹,也就是说可能文件和文件夹的位置不对劲吧
(3)stat() "/Users/qudian/Documents/project/quxuexi/3.0/quxuexi.service.merchant/public/favicon.ico" failed (13: Permission denied)访问 public目录下的favicon.ico失败。错误和(1)差不多,但是不清楚为什么访问public目录下的favicon.ico文件。
既然找到了问题出在哪,就可以尝试着去解决问题了,首先查询第一个问题。结果发现第一个问题的解决方法解决不了。
既然如此就先解决第二个问题吧,查查查。脑子懵了,没查到。后来问了问同事,找到了解决问题的解决方法了。
这个时候问题就出现了,你nginx服务器监听的是8088端口,然后nginx将接收到的信息也转发到8088端口,这样怎么可以呢?暂且不说fastcgi监听的是哪个端口,正常的逻辑应该是这样,我nginx监听从8088来的信息,然后根据这些信息的类型把这些信息转发到php-fpm监听的端口,这本身就是两个进程,监听的端口也不一样。有人会问,为什么不一样?举个例子,如果两个人都监听8088端口,那fastcgi能不能收到和有没有权利收到信息是一回事儿,更严重的问题是nginx自己监听自己发送的信息,这样不符合逻辑啊。可以理解为,自己给自己写信。那好,可能又会有人说,那我让两个进程监听一个端口,然后ngnix不做转发不可以吗?我还真不知道可不可以,所以去查了一下:其实是可以的,这就能理解成是信箱,我们把信息千里迢迢的发送到信箱,然后有人去信箱取信,那到底是谁来取,几个人可以取,一个人取几个都是由人规定的。
出于好奇,我又产生了一个疑问,为什么要有端口这样的东西呢?两台计算机进程之间直接通信不可以吗?其实是不可以的,这就好比两个陌生人之间的通信。彼此之间互相不认识,怎么通信。最好的选择就是给彼此个地址,然后你发信息,我取信息,这样就是进程间通信的过程。通过广播的方式在全世界寻找一个ip中的一个进程号,这显然是不现实的。因为你在发信息的时候根本就不知道这个进程号是多少。当然你也可以在通信之前就发送某个进程号过去,告诉它我们之间用这个进程号通信,但是这样的限制太死了。为什么呢?你这个进程号怎么发送过去?尴尬了吧!而且,进程号是系统动态分配的,不同的系统会使用不同的进程标识符,应用程序在运行之前不知道自己的进程号,如果需要运行后再广播进程号则很难保证通信的顺利进行。
好了,终于把这些问题搞懂了,然后就开始改配置,解决问题了。
看下php-fpm的监听的端口号
问题来了你怎么找到这个配置在哪里呢?
php-fpm -t // 检测配置
打开显示的php-fpm配置文件,然后发现:
打开这个文件,你会发现php-fpm监听的是哪个端口,以及使用的是什么来监听的。
那这个php-fpm.d/*.conf文件是干什么的呢?
我在这个地方找到了答案:http://ask.apelearn.com/question/5299
从php-5.3版本以后,php-fpm.conf 的格式不再是xml格式,而是和php.ini所使用的格式一样。新版本的php-fpm.conf 从宏观上看共分为两大块:一个是全局配置[global],一个是Pool Definitions, [www] 其中global部分就是配置一些全局的参数,比如错误日志、pid、日志级别等,第二部分的pool可以定义多个,而且[]的name可以自定义:例如配置文件可以这样写 [global] ... ... ... [www.domain1.com] ... ... ... [www.domain2.com] ... ... ...
当然每一个[www]部分都可以单独写一个配置文件,就像nginx的vhosts一样。这就需在php-fpm.conf中首先加一句
include=etc/fpm.d/*.conf
然后,需要在etc目录下创建一个fpm.d目录,把每一个pool配置文件放到fpm.d下。
为了安全起见,需要定义每个pool所启用的账户,还需要定义open_basedir,如下
- [www.domain.com]
- user = user0
- group = users
- listen = /tmp/php-fcgi-www.default.com.sock
- listen.owner = user0
- listen.group = users
- pm = dynamic
- pm.max_children = 20
- pm.start_servers = 5
- pm.min_spare_servers = 4
- pm.max_spare_servers = 10
- pm.max_requests = 500
- slowlog = log/www.default.com.slow
- request_slowlog_timeout = 1
- php_admin_value[open_basedir]=/data/release/www.domain.com/:/tmp/
- [www.domain2.com]
- user = user1
- group = users
- listen = /tmp/php-fcgi-www.default2.com.sock
- listen.owner = user1
- listen.group = users
- pm = dynamic
- pm.max_children = 20
- pm.start_servers = 5
- pm.min_spare_servers = 4
- pm.max_spare_servers = 10
- pm.max_requests = 500
- slowlog = log/www.default2.com.slow
- request_slowlog_timeout = 1
- php_admin_value[open_basedir]=/data/release/www.domain.com/:/tmp/