nginx学习笔记(一)

"nginx安装和启动"

Posted by wangtiegang on June 2, 2019

nginx介绍

传统的Web服务器体系结构中,每个客户端的连接作为一个单独的进程或者线程处理,随着并发连接数的增加,产生进程或线程,切换上下文会消耗额外的Cpu和内存,导致Web服务器减慢,延迟了对用户的响应。 Nginx采用可扩展的事件驱动架构,多进程(单线程) & 多路IO复用模型。Nginx启动后会有一个master进程和多个相互独立的worker进程,每个连接分配到一个worker进程处理,master进程能监控worker进程的运行状态,当worker异常退出后,自动启用新的worker进程。 worker进程数一般设置成机器cpu核数,如果超过cpu核数,会导致进程互相竞争cpu,从而带来不必要的上下文切换。

nginx安装

  • 进入nginx的官网,找到nginx的安装文档 Nginx安装

  • 我的安装环境为CentOS,安装用户为wtg,所以直接找到RHEL/CentOS对应章节,官网推荐的是yum方式安装。

  • 安装yum-utils工具包
    1
    
    sudo yum install yum-utils
    
  • 设置yum仓库
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
    # 进入/etc/yum.repos.d/目录,新建nginx.repo,添加如下内容
    [nginx-stable]
    name=nginx stable repo
    baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
    gpgcheck=1
    enabled=1
    gpgkey=https://nginx.org/keys/nginx_signing.key
    
    [nginx-mainline]
    name=nginx mainline repo
    baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
    gpgcheck=1
    enabled=0
    gpgkey=https://nginx.org/keys/nginx_signing.key
    
    # 默认启用的是nginx-stable稳定版的仓库,如果想安装mainline版本,则执行如下命令
    sudo yum-config-manager --enable nginx-mainline
    
    
  • 设置好repo之后,执行安装命令
    1
    2
    3
    4
    5
    6
    7
    
    # 正常情况下应该是直接安装成功,但是我在虚拟机中安装的时候,提示我源的速度太慢了,直接报错,
    # 我替换成阿里的源也报错,最后我把nginx.repo删除,使用redhat自带的源反而成功了,
    # 自动安装了1.4.0版本,网速可能跟我是在虚拟机中安装有关系。
    sudo yum install nginx
    
    # 查看安装版本
    nginx -v
    
  • 查看nginx安装路径
    1
    2
    3
    4
    5
    6
    
    # 查找安装的rpm包
    rpm -qa|grep nginx    # 输出 nginx-1.4.0-0.el6.ngx.x86_64
    
    # 根据rpm包查找安装路径
    rpm -ql nginx-1.4.0-0.el6.ngx.x86_64
    
    

    可以看到输出了/etc/nginx , /usr/sbin , /usr/share 多个目录,这是yum的默认安装路径。

    目录内容
    /etc一些配置文件的目录,例如/etc/nginx/nginx.conf
    /usr/bin 或 /usr/sbin一些可执行文件
    /usr/lib一些程序使用的动态函数库
    /usr/share/doc一些基本的软件使用手册与帮助文档
    /usr/share/man一些man page文件
  • 安装nginx还可以下载包安装,或者从源码安装。

nginx启动/停止/重新加载

1
2
3
4
5
6
7
8
9
10
11
12
# 默认配置启动
nginx
# 指定配置文件启动
nginx -c /etc/nginx/nginx.conf
# 正常关闭服务,所有worker进程停止接受新的请求,处理完已接受的请求之后再停止
nginx -s quit
# 快速停止
nginx -s stop
# 重新加载配置,master进程会在旧的worker进程处理完成请求后停止它,并用新的配置启动新的worker进程
nginx -s reload
# 重新打开日志文件
nginx -s reopen

执行 nginx 命令启动nginx,发现提示权限不够,于是执行 sudo nginx ,服务正常启动,然后打开浏览器访问localhost或者 curl localhost ,可以看到正常打开了nginx的欢迎页面。

然后问题来了,当我们执行 nginx -s reload 命令时,提示报错

post-nginx-note-1

首先提示的是无权限打开error.log文件,进入目录查看该文件,发现该日志文件归nginx用户所有

post-nginx-note-2

原来wtg用户sudo安装的时候创建了一个nginx用户,并在nginx.conf中配置了 user nginx ,启动nginx时会使用指定的user启动worker进程。报错的第二行也提示了这个问题,conf中的user配置,只有在使用root用户启动nginx时才会起效,其他用户启动nginx时会被忽略。

post-nginx-note-3

知道原因之后,只要在reload, quit, stop前加sudo以root权限执行就好了。

以普通用户启动nginx

刚刚是必须使用root权限启动才能nginx,不经对为什么不能以普通用户启动nginx感到好奇,网上搜索一番后发现很多说Linux系统限制非root权限使用1024一下的端口,nginx默认80端口,所以必须使用root权限启动,感觉网上大多是一句话带过,我也不懂,只能实际测试一下。

  • 打开nginx.conf修改默认启动端口为8000

    打开nginx.conf后发现无端口配置,在配置文件结尾发现include了conf.d下的所有配置文件,进入文件夹发现defalut.conf,打开修改默认端口80为8000。

  • wtg 用户下执行nginx

    还是报错,提示无权限打开日志文件,因为文件属于nginx用户。使用sudo启动,用 ss -lnp|grep 8000 可以看到端口确实修改成功了。

  • 删除/var/log/nginx下日志文件,再次执行启动命令

    还是无权限打开日志文件,查看nginx文件夹权限,属于root。

  • 切换到 nginx 用户下启动

    nginx创建的时候默认是不能登陆的,使用命令解除限制: usermod -s /bin/bash nginx nginx用户启动跟wtg用户一样,因为日志文件权限问题报错。

  • 退回到 wtg 用户,修改日志路径配置,指向 wtg 用户有权限的目录/home/wtg/log/,其他涉及到路径到地方也修改掉。

    启动nginx,发现还是报了/var/log/nginx/error.log无权限打开,但是服务正常启动了,并且在/home/wtg/log/下生成了日志文件,首页也能访问,找不到哪还有/var路径下的配置。 post-nginx-note-4 可以看到master和worker进程都是 wtg 用户启动的。

  • 将端口修改回80,再次启动。

    启动报错,可以看到最后一句提示bind到80端口无权限。 post-nginx-note-5

虽然这样能以普通用户的方式启动nginx,但是只是验证了端口限制问题,并不能确定这样启动是没有问题的,继续网上搜索普通用户方式启动nginx,看到大家通常是修改/usr/sbin/nginx执行文件的权限,让普通用户可以以root身份运行,这样既能启动,又能使用80端口,普通用户推荐这种方式启动

  • 修改 /usr/sbin/nginx 的权限
    1
    2
    3
    4
    
    # 一个可执行文件在被执行时,该文件只拥有调用者所具有的权限,而setuid可以改变这种设
    # 置,使用u+s可以让调用用户以文件拥有者的权限执行该文件,此处nginx属于root,则授权
    # 后,其他用户能以root身份执行,这样就不存在端口限制了,并且可以不需要sudo权限。
    chmod u+s nginx
    
  • wtg 用户下执行 nginx

    可以看到正常启动,master进程是以root身份运行的,worker进程是以nginx身份运行的,端口是80 post-nginx-note-6

配置nginx开机启动

  • 开机启动使用 systemd 实现,有些系统可能没有安装
  • 使用yum方式安装的nginx会自动生成 /usr/lib/systemd/system/nginx.service文件,该文件包含了systemd的unit配置信息,执行 systemctl status nginx.service

    可以看到服务处于disable状态 post-nginx-note-7

  • 执行 sudo systemctl enable nginx.service 激活开机启动

    服务状态变成了enable post-nginx-note-8

  • 重启服务器,执行 systemctl status nginx.service 查看状态

    nginx正常启动,可以看到systemctl对服务对管理状态 post-nginx-note-9

总结

  • 普通用户启动确实是因为80端口限制导致的,修改端口后可以启动
  • 普通用户启动,master,worker进程都是普通用户的。root启动,则master属于root,worker属于nginx.conf中配置的用户
  • 如果因为安全问题不能给sudo权限给普通用户的话,建议使用chmod u+s的方式授权普通用户以root身份启动
  • 可以使用 systemdsystemctl 命令设置开机启动,监控管理nginx服务