前言:
几年前写过一篇CentOS6编译LNMP搭建高性能WEB环境的教程,如今CentOS7已经成熟,同时迎来了PHP7时代,部分生产环境需要PHP5.6+7.x双版本,故更新本篇教程
这篇教程适合喜欢自己动手编译定制化环境的同学参考,懒人以及时间比较宝贵的公司运维人员推荐 OneinStack 一键安装工具
【2020.05更新】
这篇教程最早源自多年前,我在个人站长时期配置WEB服务器环境的笔记,后来改写成了教程,如今SSLv1.3与HTTP2.0已成为主流趋势,配置新环境时发现已变化太多,例如对SSL协议握手的优化考虑、SSLv1.3与早期版本的兼容等,然而国内并没有一篇文章系统的讲述,所以用业余时间重写了教程,降低技术搭建WEB环境的时间成本
一、获取开源程序与系统升级
① 将CentOS的yum默认源更为更快的国内源(可跳过):
sudo -s yum -y install wget cd /etc/yum.repos.d/ wget http://mirrors.163.com/.help/CentOS7-Base-163.repo mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup mv /etc/yum.repos.d/CentOS7-Base-163.repo /etc/yum.repos.d/CentOS-Base.repo yum clean all yum makecache
② 用yum命令安装、升级所需的程序库:
yum -y upgrade yum -y install gcc gcc-c++ autoconf automake libtool libjpeg libjpeg-devel libpng libpng-devel libwebp-devel freetype freetype-devel libxml2 libxml2-devel zlib zlib-devel glibc glibc-devel glib2 glib2-devel bzip2 bzip2-devel ncurses ncurses-devel readline-devel curl curl-devel e2fsprogs e2fsprogs-devel libaio-devel.x86_64 krb5-devel libidn libidn-devel openssl openssl-devel openldap openldap-devel nss_ldap openldap-clients openldap-servers bison libevent-devel cmake iptables-services sqlite-devel lua-devel git patch ntp numactl wget
③ 程序源码包下载:
mkdir -p /data0/software cd /data0/software wget https://tengine.taobao.org/download/tengine-2.3.2.tar.gz wget https://www.php.net/distributions/php-7.4.15.tar.gz wget https://www.percona.com/downloads/Percona-Server-5.7/Percona-Server-5.7.30-33/binary/tarball/Percona-Server-5.7.30-33-Linux.x86_64.ssl101.tar.gz wget https://github.com/jemalloc/jemalloc/archive/5.2.1.tar.gz -O jemalloc-5.2.1.tar.gz wget https://www.openssl.org/source/openssl-1.1.1g.tar.gz wget https://ftp.pcre.org/pub/pcre/pcre-8.44.tar.gz wget https://jaist.dl.sourceforge.net/project/mhash/mhash/0.9.9.9/mhash-0.9.9.9.tar.gz wget https://jaist.dl.sourceforge.net/project/mcrypt/Libmcrypt/2.5.8/libmcrypt-2.5.8.tar.gz wget https://jaist.dl.sourceforge.net/project/mcrypt/MCrypt/2.6.8/mcrypt-2.6.8.tar.gz wget https://ftp.gnu.org/gnu/libiconv/libiconv-1.16.tar.gz wget https://github.com/kkos/oniguruma/archive/v6.9.4.tar.gz -O oniguruma-6.9.4.tar.gz wget https://github.com/vision5/ngx_devel_kit/archive/v0.3.1.tar.gz -O ngx_devel_kit-0.3.1.tar.gz wget https://github.com/openresty/luajit2/archive/v2.1-20200102.tar.gz -O luajit2-2.1-20200102.tar.gz wget https://github.com/openresty/lua-ssl-nginx-module/archive/v0.01rc3.tar.gz -O lua-ssl-nginx-module-0.01rc3.tar.gz wget https://raw.githubusercontent.com/openresty/openresty/master/patches/openssl-1.1.1f-sess_set_get_cb_yield.patch wget https://raw.githubusercontent.com/hakasenyang/openssl-patch/master/openssl-equal-1.1.1e-dev_ciphers.patch wget https://raw.githubusercontent.com/pmkol/apad.pro/master/patch/tengine-2.3.2-ssl_cert_sees_cb_yield.patch wget https://pecl.php.net/get/redis-5.3.3.tgz wget http://download.redis.io/releases/redis-6.0.12.tar.gz
④ 升级OpenSSL 以支持 TLS 1.3:
patch BoringSSL 与 OpenResty 提供的补丁,解决 Nginx 的 ssl_ciphers 报错问题,并让 OpenSSL 的 session get callback 支持 yield
( 即用于支持Nginx集群时 SSL Seesion ID 重用共享 )
#编译安装最新版本的OpenSSL tar xzvf openssl-1.1.1g.tar.gz cd openssl-1.1.1g/ patch -p1 < /data0/software/openssl-1.1.1f-sess_set_get_cb_yield.patch patch -p1 < /data0/software/openssl-equal-1.1.1e-dev_ciphers.patch ./config shared zlib --prefix=/usr/local/openssl make make install cd ../ #替换旧版本的OpenSSL mv /usr/bin/openssl /usr/bin/openssl.old mv /usr/lib64/openssl /usr/lib64/openssl.old mv /usr/lib64/libssl.so /usr/lib64/libssl.so.old ln -s /usr/local/openssl/bin/openssl /usr/bin/openssl ln -s /usr/local/openssl/include/openssl /usr/include/openssl ln -s /usr/local/openssl/lib/libssl.so /usr/lib64/libssl.so #配置库文件搜索路径 echo "/usr/local/openssl/lib" >> /etc/ld.so.conf ldconfig #查看OpenSSL版本 openssl version -a
补丁的小版本号有时会低于最新的 OpenSSL,一般不影响使用
[返回目录]
二、安装 MySQL 5.7
建议选择MySQL的分支版本Percona Server 5.7,在功能与性能上有显著提升。
① 编译安装Jemalloc:
tar zxvf jemalloc-5.2.1.tar.gz cd jemalloc-5.2.1/ ./autogen.sh make make install cd ../ ln -s /usr/local/lib/libjemalloc.so.2 /usr/lib64/libjemalloc.so.2
② 安装MySQL:
创建mysql用户与用户组
/usr/sbin/groupadd mysql /usr/sbin/useradd -g mysql mysql
安装Percona Server 5.7二进制版本
tar zxvf Percona-Server-5.7.30-33-Linux.x86_64.ssl101.tar.gz mkdir -p /usr/local/webserver mv Percona-Server-5.7.30-33-Linux.x86_64.ssl101 /usr/local/webserver/mysql ln -s /usr/local/webserver/mysql/lib/libperconaserverclient.so.20 /usr/lib/libperconaserverclient.so.20
③ 一些相关设置:
创建MySQL数据库存放目录
mkdir -p /data0/mysql/3306/data/ mkdir -p /data0/mysql/3306/binlog/ chown -R mysql:mysql /data0/mysql/
添加环境变量
echo -e '\n\nexport PATH=/usr/local/webserver/mysql/bin:$PATH\n' >> /etc/profile && source /etc/profile
创建my.cnf配置文件
vi /usr/local/webserver/mysql/my.cnf
输入以下内容
#需要根据服务器硬件来设置,双核2G内存环境的my.cnf仅供参考 # The following options will be passed to all MySQL clients [client] port = 3306 socket = /data0/mysql/3306/mysql.sock default-character-set = utf8mb4 # The MySQL server [mysqld] port = 3306 socket = /data0/mysql/3306/mysql.sock basedir = /usr/local/webserver/mysql datadir = /data0/mysql/3306/data pid-file = /data0/mysql/3306/mysql.pid user = mysql bind-address = 0.0.0.0 server-id = 1 local_infile = OFF transaction-isolation = READ-COMMITTED init-connect = 'SET NAMES utf8mb4' character-set-server = utf8mb4 #sql_mode = NO_ENGINE_SUBSTITUTION #skip-name-resolve #skip-networking skip_symbolic_links = yes back_log = 600 max_connections = 2000 max_connect_errors = 10000 open_files_limit = 65535 table_open_cache = 128 max_allowed_packet = 64M binlog_cache_size = 1M max_heap_table_size = 8M tmp_table_size = 16M read_buffer_size = 2M read_rnd_buffer_size = 8M sort_buffer_size = 8M join_buffer_size = 8M key_buffer_size = 4M thread_cache_size = 16 query_cache_type = 1 query_cache_size = 8M query_cache_limit = 2M ft_min_word_len = 4 log_bin = /data0/mysql/3306/binlog/mysql-bin binlog_format = mixed expire_logs_days = 30 binlog_cache_size = 8M max_binlog_cache_size = 2048M max_binlog_size = 1024M log_error = /data0/mysql/3306/mysql-error.log slow_query_log = 1 long_query_time = 1 slow_query_log_file = /data0/mysql/3306/mysql-slow.log performance_schema = 0 explicit_defaults_for_timestamp #lower_case_table_names = 1 skip-external-locking default_storage_engine = InnoDB innodb_file_per_table = 1 innodb_open_files = 500 innodb_buffer_pool_size = 1024M innodb_write_io_threads = 4 innodb_read_io_threads = 4 innodb_thread_concurrency = 0 innodb_purge_threads = 1 innodb_flush_log_at_trx_commit = 2 innodb_log_buffer_size = 8M innodb_log_file_size = 512M innodb_log_files_in_group = 3 innodb_max_dirty_pages_pct = 90 innodb_lock_wait_timeout = 120 innodb_flush_method = O_DIRECT bulk_insert_buffer_size = 8M myisam_sort_buffer_size = 8M myisam_max_sort_file_size = 10G myisam_repair_threads = 1 interactive_timeout = 28800 wait_timeout = 28800 [mysqldump] quick max_allowed_packet = 64M [myisamchk] key_buffer_size = 8M sort_buffer_size = 8M read_buffer = 4M write_buffer = 4M
初始化数据库
/usr/local/webserver/mysql/bin/mysqld --initialize-insecure --user=mysql --basedir=/usr/local/webserver/mysql --datadir=/data0/mysql/3306/data
④ 配置MySQL服务脚本:
创建服务脚本
vi /usr/lib/systemd/system/mysqld.service #输入以下内容 [Unit] Description=MySQL Server Documentation=man:mysqld(7) Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html After=network.target After=syslog.target [Install] WantedBy=multi-user.target [Service] User=mysql Group=mysql Type=forking PIDFile=/data0/mysql/3306/mysqld.pid # Disable service start and stop timeout logic of systemd for mysqld service. TimeoutSec=0 # Start main service ExecStart=/usr/local/webserver/mysql/bin/mysqld --defaults-file=/usr/local/webserver/mysql/my.cnf --daemonize --pid-file=/data0/mysql/3306/mysqld.pid $MYSQLD_OPTS # Use this to switch malloc implementation EnvironmentFile=-/etc/sysconfig/mysql # Sets open_files_limit LimitNOFILE = 5000 Restart=on-failure RestartPreventExitStatus=1 PrivateTmp=false
加载Jemalloc动态库
echo "LD_PRELOAD=/usr/local/lib/libjemalloc.so.2" > /etc/sysconfig/mysql
加入启动项
systemctl enable mysqld
启动MySQL服务
systemctl start mysqld
解决MySQL与mariadb-libs的socket冲突
部分使用yum命令安装的扩展依赖mariadb-libs,而卸载mariadb-libs可能会导致依赖应用报错。当MySQL与mariadb-libs共存时,可使用如下方法测试是否冲突
mysql -u root -p #输入正确的密码后若报错如下信息则有冲突 ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
#解决方法 ln -s /data0/mysql/3306/mysql.sock /tmp/mysql.sock
设置数据库root用户密码
#友情提醒:最后的密码就不要跟着复制粘贴了 /usr/local/webserver/mysql/bin/mysqladmin password 12345678
[返回目录]
三、安装 Redis 6.0
① 升级gcc版本:
CentOS7默认的gcc版本是4.8.5,需升级gcc版本才可编译成功Redis 6.0版本,Redis 5.0及更早期版本请跳过这一步
升级到gcc 9.3 yum -y install centos-release-scl yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils scl enable devtoolset-9 bash #scl命令启用只是临时的,退出shell或重启就会恢复原系统gcc版本 #如果要长期使用gcc 9.3 echo "source /opt/rh/devtoolset-9/enable" >>/etc/profile
② 创建redis用户与用户组:
/usr/sbin/groupadd redis /usr/sbin/useradd -g redis redis
③ 编译安装Redis:
tar zxvf redis-6.0.12.tar.gz cd redis-6.0.12/ make make PREFIX=/usr/local/webserver/redis install make clean cp redis.conf /usr/local/webserver/redis/6379.conf cd ../ mkdir -p /data0/redis/6379/data/ chown -R redis:redis /data0/redis/ chown -R redis:redis /usr/local/webserver/redis/
④ 修改Redis配置文件:
vi /usr/local/webserver/redis/6379.conf #修改以下参数 bind 127.0.0.1 daemonize yes pidfile /data0/redis/6379/redis.pid logfile /data0/redis/6379/redis.log dir /data0/redis/6379/data maxmemory 256000000 io-threads 2 io-threads-do-reads yes
bind 仅本机使用填写127.0.0.1,后面可添加更多使用该redis的服务器IP
io-thread 数值设置为CPU线程数的1/2或3/4
⑤ 创建服务脚本:
vi /usr/lib/systemd/system/redis.service #输入以下内容 [Unit] Description=Redis daemon After=network.target [Service] Type=forking ExecStart=/usr/local/webserver/redis/bin/redis-server /usr/local/webserver/redis/6379.conf ExecReload=/usr/local/webserver/redis/bin/redis-server -s reload ExecStop=/usr/local/webserver/redis/bin/redis-server -s stop PrivateTmp=true User=redis Group=redis [Install] WantedBy=multi-user.target
加入启动项
systemctl enable redis
启动Redis服务
systemctl start redis
[返回目录]
四、安装 PHP 7.4
生产环境下,部分应用可能不支持PHP7.4版本,7.0~7.3版本均可参考,只需要修改当前PHP对应的extension_dir地址即可。
如部分更早期的应用需使用5.6版本,可参考《编译安装PHP5.6并与PHP7.0共存》
① 安装所需的支持库:
tar zxvf libiconv-1.16.tar.gz cd libiconv-1.16/ ./configure --prefix=/usr/local make make install make clean cd ../ tar zxvf libmcrypt-2.5.8.tar.gz cd libmcrypt-2.5.8/ ./configure make make install /sbin/ldconfig cd libltdl/ ./configure --enable-ltdl-install make make install cd ../ make clean cd ../ tar zxvf mhash-0.9.9.9.tar.gz cd mhash-0.9.9.9/ ./configure make make install make clean cd ../ ln -s /usr/local/lib/libmcrypt.la /usr/lib/libmcrypt.la ln -s /usr/local/lib/libmcrypt.so /usr/lib/libmcrypt.so ln -s /usr/local/lib/libmcrypt.so.4 /usr/lib/libmcrypt.so.4 ln -s /usr/local/lib/libmcrypt.so.4.4.8 /usr/lib/libmcrypt.so.4.4.8 ln -s /usr/local/lib/libmhash.a /usr/lib/libmhash.a ln -s /usr/local/lib/libmhash.la /usr/lib/libmhash.la ln -s /usr/local/lib/libmhash.so /usr/lib/libmhash.so ln -s /usr/local/lib/libmhash.so.2 /usr/lib/libmhash.so.2 ln -s /usr/local/lib/libmhash.so.2.0.1 /usr/lib/libmhash.so.2.0.1 ln -s /usr/local/bin/libmcrypt-config /usr/bin/libmcrypt-config tar zxvf mcrypt-2.6.8.tar.gz cd mcrypt-2.6.8/ /sbin/ldconfig ./configure make make install make clean cd ../ cp -frp /usr/lib64/libldap* /usr/lib/ echo '/usr/local/lib' >> /etc/ld.so.conf && /sbin/ldconfig #PHP7.0-7.3版本无需编译安装oniguruma tar zxvf oniguruma-6.9.4.tar.gz cd oniguruma-6.9.4/ ./autogen.sh ./configure --libdir=/lib64 make make install make clean cd ../ #PHP7.0-7.3版本无需升级libzip yum -y remove libzip libzip-devel yum -y install https://rpms.remirepo.net/enterprise/7/remi/x86_64/libzip-last-1.1.3-1.el7.remi.x86_64.rpm yum -y install https://rpms.remirepo.net/enterprise/7/remi/x86_64/libzip-last-devel-1.1.3-1.el7.remi.x86_64.rpm
② 编译安装PHP7.4:
tar zxvf php-7.4.15.tar.gz cd php-7.4.15/ ./configure --prefix=/usr/local/webserver/php --with-config-file-path=/usr/local/webserver/php/etc --with-mysqli --with-pdo-mysql --with-mysql-sock=/data0/mysql/3306/mysql.sock --with-iconv-dir=/usr/local --with-freetype --with-jpeg --with-webp --with-zlib --with-libxml --disable-mysqlnd-compression-support --enable-xml --disable-rpath --enable-bcmath --enable-shmop --enable-sysvsem --enable-inline-optimization --with-curl --enable-mbregex --enable-fpm --enable-gd --with-mhash --enable-pcntl --enable-sockets --with-xmlrpc --with-zip --enable-soap --enable-mbstring --enable-opcache make ZEND_EXTRA_LIBS=\'-liconv\' make install cp php.ini-production /usr/local/webserver/php/etc/php.ini mv /usr/local/webserver/php/etc/php-fpm.conf.default /usr/local/webserver/php/etc/php-fpm.conf mv /usr/local/webserver/php/etc/php-fpm.d/www.conf.default /usr/local/webserver/php/etc/php-fpm.d/www.conf make clean
PHP7.3~7.0版本编译参数
./configure --prefix=/usr/local/webserver/php --with-config-file-path=/usr/local/webserver/php/etc --with-mysqli --with-pdo-mysql --with-mysql-sock=/data0/mysql/3306/mysql.sock --with-iconv-dir=/usr/local --with-freetype-dir --with-jpeg-dir --with-png-dir --with-webp-dir --with-zlib --with-libxml-dir=/usr --disable-mysqlnd-compression-support --enable-xml --disable-rpath --enable-bcmath --enable-shmop --enable-sysvsem --enable-inline-optimization --with-curl --enable-mbregex --enable-fpm --with-gd --with-mhash --enable-pcntl --enable-sockets --with-xmlrpc --enable-zip --enable-soap --enable-mbstring --enable-opcache
③ 编译安装PHP7.4扩展模块:
编译安装openssl扩展
cd ext/openssl/ mv config0.m4 config.m4 /usr/local/webserver/php/bin/phpize ./configure --with-php-config=/usr/local/webserver/php/bin/php-config make make install make clean cd ../../../
注:当openssl版本较新时,编译PHP使用 –with-openssl 参数会报错,故采用该方法
编译安装redis扩展
tar zxvf redis-5.3.3.tgz cd redis-5.3.3/ /usr/local/webserver/php/bin/phpize ./configure --with-php-config=/usr/local/webserver/php/bin/php-config make make install make clean cd ../
PHP扩展均可参照该方法编译安装
在 php.ini 中使用 extension = xxx.so 加载即可
④ 修改PHP配置文件:
修改 /usr/local/webserver/php/etc/php.ini 中的以下参数
disable_functions = passthru,exec,system,chroot,chgrp,chown,shell_exec,proc_open,proc_get_status,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,stream_socket_server,fsocket,popen short_open_tag = On realpath_cache_size = 512k expose_php = Off max_execution_time = 600 memory_limit = 256M post_max_size = 200M upload_max_filesize = 10M date.timezone = Asia/Shanghai session.save_handler = redis session.save_path = "tcp://127.0.0.1:6379" session.use_strict_mode = 1 opcache.enable=1 opcache.enable_cli = 1 opcache.memory_consumption = 128 opcache.interned_strings_buffer = 8 opcache.max_accelerated_files = 10000 opcache.max_wasted_percentage=5 opcache.use_cwd=1 opcache.validate_timestamps=1 opcache.revalidate_freq = 60 opcache.consistency_checks=0 extension_dir = "/usr/local/webserver/php/lib/php/extensions/no-debug-non-zts-20190902" #并在下方添加 zend_extension = "/usr/local/webserver/php/lib/php/extensions/no-debug-non-zts-20190902/opcache.so" extension = "openssl.so" extension = "redis.so"
⑤ 创建www用户和用户组:
/usr/sbin/groupadd www /usr/sbin/useradd -g www www
⑥ 设置php-fpm:
vi /usr/local/webserver/php/etc/php-fpm.conf #修改以下参数 pid = run/php-fpm.pid log_level = warning emergency_restart_threshold = 20 emergency_restart_interval = 60s process_control_timeout = 5s
保存后
vi /usr/local/webserver/php/etc/php-fpm.d/www.conf #修改以下参数 user = www group = www listen = /dev/shm/php-cgi.sock listen.backlog = -1 listen.owner = www listen.group = www listen.mode = 0660 pm = static pm.max_children = 46 pm.start_servers = 31 pm.min_spare_servers = 16 pm.max_spare_servers = 46 pm.process_idle_timeout = 10s pm.max_requests = 2048 pm.status_path = /status slowlog = log/slow.log request_terminate_timeout = 120 rlimit_files = 51200 rlimit_core = 0 catch_workers_output = yes
⑦ 创建服务脚本文件
vi /usr/lib/systemd/system/php-fpm.service #输入以下内容 [Unit] Description=The PHP FastCGI Process Manager After=syslog.target network.target [Service] Type=forking PIDFile=/usr/local/webserver/php/var/run/php-fpm.pid ExecStart=/usr/local/webserver/php/sbin/php-fpm --fpm-config /usr/local/webserver/php/etc/php-fpm.conf ExecReload=/bin/kill -USR2 $MAINPID PrivateTmp=true [Install] WantedBy=multi-user.target
加入启动项
systemctl enable php-fpm
启动php-fpm服务
systemctl start php-fpm
[返回目录]
五、安装 Nginx 1.17
建议选择Nginx的分支版本Tengine,拥有更强的性能与扩展。
① 编译安装LuaJIT:
使Nginx支持Lua扩展
tar zxvf luajit2-2.1-20200102.tar.gz cd luajit2-2.1-20200102/ make install PREFIX=/usr/local/luajit cd ../ echo -e '\n\nexport LUAJIT_LIB=/usr/local/luajit/lib\nexport LUAJIT_INC=/usr/local/luajit/include/luajit-2.1\n' >> /etc/profile && source /etc/profile echo '/usr/local/luajit/lib' >> /etc/ld.so.conf.d/luajit.conf && /sbin/ldconfig
② 编译安装Tengine:
patch OpenResty 的Nginx补丁
使Nginx支持 ssl_session_fetch_by_lua* 与 ssl_certificate_by_lua* 参数,一般用于Nginx集群时 SSL Seesion ID 重用共享,降低服务器压力
OpenResty官方提供的两个patch不支持Tengine
tengine-2.3.2-ssl_cert_sees_cb_yield.patch 进行了修正与合并
tar zxvf tengine-2.3.2.tar.gz tar zxvf pcre-8.44.tar.gz tar zxvf ngx_devel_kit-0.3.1.tar.gz tar zxvf lua-ssl-nginx-module-0.01rc3.tar.gz git clone https://github.com/google/ngx_brotli.git && cd ngx_brotli && git submodule update --init && cd ../ cd tengine-2.3.2/ patch -p1 < /data0/software/tengine-2.3.2-ssl_cert_sees_cb_yield.patch ./configure --user=www --group=www --prefix=/usr/local/webserver/nginx --with-pcre=/data0/software/pcre-8.44 --with-pcre-jit --with-openssl=/data0/software/openssl-1.1.1g --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-threads --with-file-aio --with-stream --with-stream_ssl_module --with-http_v2_module --with-http_ssl_module --add-module=modules/ngx_http_concat_module --add-module=modules/ngx_http_trim_filter_module --add-module=modules/ngx_http_slice_module --add-module=modules/ngx_http_lua_module --add-module=/data0/software/lua-ssl-nginx-module-0.01rc3 --add-module=/data0/software/ngx_devel_kit-0.3.1 --with-ld-opt='-Wl,-rpath,/usr/local/luajit/lib -ljemalloc' --add-module=/data0/software/ngx_brotli make make install make clean mkdir -p /data0/htdocs/conf/ mkdir -p /data0/htdocs/ssl/ cd ../
上述编译参数已安装常用模块,可以根据业务需求在 ./configure 中添加编译参数,安装更多模块
若不使用LUA模块,可参考如下参数编译
./configure --user=www --group=www --prefix=/usr/local/webserver/nginx --with-pcre=/data0/software/pcre-8.44 --with-pcre-jit --with-openssl=/data0/software/openssl-1.1.1k --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-threads --with-file-aio --with-stream --with-stream_ssl_module --with-http_v2_module --with-http_ssl_module --add-module=modules/ngx_http_concat_module --add-module=modules/ngx_http_trim_filter_module --add-module=modules/ngx_http_slice_module --with-ld-opt='-ljemalloc' --with-jemalloc=/data0/software/jemalloc-5.2.1 --add-module=/data0/software/ngx_brotli
Tengine 自身实现的模块,自2.3.x版本后已全部剥离到 modules 目录下,应使用如下方法添加编译
#Tengine <module_name> 名称查看 ls /data0/software/tengine-2.3.2/modules/ #Tengine <module_name> 添加编译 --add-module=modules/<module_name>
Nginx 第三方模块应使用如下方法添加编译
--add-module=/data0/software/<module_name> #/data0/software/ 为插件解压缩后所在的绝对目录地址 #<module_name> 为插件解压缩后的文件夹名称
③ 创建Tengine日志目录:
mkdir -p /data1/logs/ chmod +w /data1/logs/ chown -R www:www /data1/logs/
④ 创建Tengine配置文件:
mv /usr/local/webserver/nginx/conf/nginx.conf /usr/local/webserver/nginx/conf/nginx.conf.old vi /usr/local/webserver/nginx/conf/nginx.conf
输入并保存以下内容
user www www; worker_processes auto; worker_cpu_affinity auto; error_log /data1/logs/nginx_error.log crit; pid /usr/local/webserver/nginx/nginx.pid; worker_rlimit_nofile 65535; events { use epoll; worker_connections 65535; } thread_pool default threads=32 max_queue=65536; 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"'; log_format https '$remote_addr - $remote_user [$time_local] ' '$ssl_protocol/$ssl_cipher <$ssl_session_id> $ssl_session_reused ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" "$http_x_forwarded_for"'; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; trim off; gzip on; gzip_min_length 1k; gzip_buffers 4 16k; gzip_http_version 1.0; gzip_comp_level 4; gzip_vary on; gzip_disable "MSIE [1-6]\.(?!.*SV1)"; gzip_types text/xml application/xml application/atom+xml application/rss+xml application/xhtml+xml image/svg+xml text/javascript application/javascript application/x-javascript text/x-json application/json application/x-web-app-manifest+json text/css text/plain text/x-component font/eot font/opentype font/otf font/truetype font/ttf application/x-font-ttf application/vnd.ms-fontobject application/x-font-opentype application/x-font-truetype image/x-icon image/x-win-bitmap; fastcgi_connect_timeout 300; fastcgi_send_timeout 300; fastcgi_read_timeout 300; fastcgi_buffer_size 64k; fastcgi_buffers 4 64k; fastcgi_busy_buffers_size 128k; fastcgi_temp_file_write_size 128k; server_tokens off; limit_req_zone $binary_remote_addr zone=qps:10m rate=1r/s; server { listen 80 default_server; listen 443 default_server ssl; server_name _; access_log /data1/logs/unknown.log https; ssl_certificate /data0/htdocs/ssl/default.pem; ssl_certificate_key /data0/htdocs/ssl/default.key; ssl_prefer_server_ciphers on; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers [TLS13+AESGCM+AES128|TLS13+AESGCM+AES256|TLS13+CHACHA20]:[EECDH+ECDSA+AESGCM+AES128|EECDH+ECDSA+CHACHA20]:EECDH+ECDSA+AESGCM+AES256:EECDH+ECDSA+AES128+SHA:EECDH+ECDSA+AES256+SHA:[EECDH+aRSA+AESGCM+AES128|EECDH+aRSA+CHACHA20]:EECDH+aRSA+AESGCM+AES256:EECDH+aRSA+AES128+SHA:EECDH+aRSA+AES256+SHA:RSA+AES128+SHA:RSA+AES256+SHA:RSA+3DES; limit_req zone=qps burst=2; return 444; } include /data0/htdocs/conf/*.conf; }
生成 default.key 与 default.pem
#使nginx.conf的default_server不报错 openssl genrsa -out /data0/htdocs/ssl/default.key openssl req -new -x509 -key /data0/htdocs/ssl/default.key -out /data0/htdocs/ssl/default.pem -days 3650
一般情况下 nginx.conf 配置完成后无需修改,只需使用default_server为80/443端口添加默认站点,返回为444状态禁止nginx未绑定的域名访问即可
建议在 include 指向的目录中添加新站点,这样有助nginx的运维
⑤ 添加站点:
在include指向的 /data0/htdocs/conf/ 目录下,生成 .conf 结尾的站点配置文件,检测后reload nginx即可完成站点的添加
#添加变量环境 echo -e '\nexport PATH=/usr/local/webserver/nginx/sbin:$PATH\n' >> /etc/profile && source /etc/profile #检测配置文件 nginx -t #加载配置文件 nginx -s reload
同理删除对应的.conf文件后reload nginx即可永久删除站点,也可以更改.conf文件的扩展名(例如.conf.del)临时删除站点
⑥ 添加HTTP测试站点:
#创建测试站点目录 mkdir -p /data0/htdocs/wwwroot/ chmod +w /data0/htdocs/wwwroot/ chown -R www:www /data0/htdocs/wwwroot/ #生成测试站点配置文件 vi /data0/htdocs/conf/wwwroot.conf
输入并保存以下内容
server { listen 80 reuseport; server_name ip_or_domain.name; root /data0/htdocs/wwwroot; index index.html index.htm index.php; #charset gb2312; client_max_body_size 0; #limit_req zone=qps burst=5; #trim on; #trim_js on; #trim_css on; access_log /data1/logs/wwwroot-logs.log main; gzip on; brotli on; brotli_comp_level 6; brotli_static on; brotli_min_length 1k; brotli_types text/xml application/xml application/atom+xml application/rss+xml application/xhtml+xml image/svg+xml text/javascript application/javascript application/x-javascript text/x-json application/json application/x-web-app-manifest+json text/css text/plain text/x-component font/eot font/opentype font/otf font/truetype font/ttf application/x-font-ttf application/vnd.ms-fontobject application/x-font-opentype application/x-font-truetype image/x-icon image/x-win-bitmap; location ~ \.php$ { try_files $uri =404; fastcgi_pass unix:/dev/shm/php-cgi.sock; fastcgi_index index.php; include fastcgi.conf; } location /status { stub_status on; access_log off; } # Rewrite rules location / { try_files $uri $uri/ /index.php$is_args$args; } location ~* \.(jpg|jpeg|gif|png|bmp|swf|ico|rar|zip|7z|tgz|tar.gz|txt|flv|mid|doc|docx|pptx|ppt|xlsx|xls|pdf|mp3|wma)$ { expires 30d; access_log off; aio threads; directio 5m; } location ~* \.(js|css)?$ { expires 24h; access_log off; concat on; concat_max_files 20; } location ~* \.(eot|ttf|woff|woff2|svg)$ { expires max; access_log off; #add_header Access-Control-Allow-Origin *; #add_header Access-Control-Allow-Headers X-Requested-With; #add_header Access-Control-Allow-Methods GET,POST,OPTIONS; } location = /favicon.ico { log_not_found off; } location = /robots.txt { #deny all; log_not_found off; } #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # location ~ /\.ht { deny all; } # proxy the PHP scripts to Apache listening on 127.0.0.1:80 # #location ~ \.php$ { # proxy_pass http://127.0.0.1; #} }
配置文件已做优化,只需要修改 server_name、root、access_log 三个参数即可,其它参数请根据实际需求调整或添加
测试站点目录一般用于存放php探针、phpmyadmin等工具,或测试web应用
将 server_name 设置成服务器外网IP时,可通过IP访问该测试站点。安全考虑,日常不使用时应重命名 wwwroot 目录,这样可以在不reload nginx的情况下禁止访问
注意:同一端口有多个站点时,listen指令后的reuseport参数只需要添加一次, 否则NGINX会报错。 示例: server { listen 80 reuseport; ... } server { listen 80; ... }
⑦ 添加HTTPS业务站点:
#创建业务站点目录 mkdir -p /data0/htdocs/sitename.com/ chmod +w /data0/htdocs/sitename.com/ chown -R www:www /data0/htdocs/sitename.com/ #生成业务站点配置文件 vi /data0/htdocs/conf/sitename.com.conf
输入并保存以下内容(将sitename.com替换成业务使用的域名)
server { listen 80; listen 443 ssl http2 reuseport; server_name sitename.com; root /data0/htdocs/sitename.com; index index.html index.htm index.php; resolver 223.5.5.5 8.8.8.8 valid=300s; resolver_timeout 5s; ssl_stapling on; ssl_stapling_verify on; ssl_trusted_certificate /data0/htdocs/ssl/sitename.pem; ssl_certificate /data0/htdocs/ssl/sitename.pem; ssl_certificate_key /data0/htdocs/ssl/sitename.key; ssl_session_tickets on; ssl_session_ticket_key /data0/htdocs/ssl/session_ticket.key; ssl_session_timeout 1440m; ssl_session_cache shared:SSL:128m; ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; ssl_ciphers [TLS13+AESGCM+AES128|TLS13+AESGCM+AES256|TLS13+CHACHA20]:[EECDH+ECDSA+AESGCM+AES128|EECDH+ECDSA+CHACHA20]:EECDH+ECDSA+AESGCM+AES256:EECDH+ECDSA+AES128+SHA:EECDH+ECDSA+AES256+SHA:[EECDH+aRSA+AESGCM+AES128|EECDH+aRSA+CHACHA20]:EECDH+aRSA+AESGCM+AES256:EECDH+aRSA+AES128+SHA:EECDH+aRSA+AES256+SHA:RSA+AES128+SHA:RSA+AES256+SHA:RSA+3DES; add_header Strict-Transport-Security "max-age=15768000; includeSubdomains"; add_header X-Content-Type-Options "nosniff"; add_header X-Frame-Options "SAMEORIGIN"; add_header X-XSS-Protection "1; mode=block"; #charset gb2312; client_max_body_size 0; #limit_req zone=qps burst=5; trim on; trim_js on; trim_css on; access_log "pipe:rollback /data1/logs/sitename/sitename.com.log interval=1h baknum=48 maxsize=2G" https buffer=64k flush=5s; gzip on; brotli on; brotli_comp_level 6; brotli_static on; brotli_min_length 1k; brotli_types text/xml application/xml application/atom+xml application/rss+xml application/xhtml+xml image/svg+xml text/javascript application/javascript application/x-javascript text/x-json application/json application/x-web-app-manifest+json text/css text/plain text/x-component font/eot font/opentype font/otf font/truetype font/ttf application/x-font-ttf application/vnd.ms-fontobject application/x-font-opentype application/x-font-truetype image/x-icon image/x-win-bitmap; location ~ \.php$ { try_files $uri =404; fastcgi_pass unix:/dev/shm/php-cgi.sock; fastcgi_index index.php; include fastcgi.conf; } # Rewrite rules location / { if ($server_port = 80 ) { return 301 https://$host$request_uri; } try_files $uri $uri/ /index.php$is_args$args; } location ~* \.(jpg|jpeg|gif|png|bmp|swf|ico|rar|zip|7z|tgz|tar.gz|txt|flv|mid|doc|docx|pptx|ppt|xlsx|xls|pdf|mp3|wma)$ { valid_referers none blocked sitename.com *.sitename.com *.baidu.com *.baiducontent.com; if ($invalid_referer) { return 412; } expires 30d; access_log off; aio threads; directio 5m; break; } location ~* \.(js|css)?$ { expires 7d; access_log off; concat on; concat_max_files 20; } location ~* \.(eot|ttf|woff|woff2|svg)$ { expires max; access_log off; #add_header Access-Control-Allow-Origin *; #add_header Access-Control-Allow-Headers X-Requested-With; #add_header Access-Control-Allow-Methods GET,POST,OPTIONS; } location = /favicon.ico { log_not_found off; } location = /robots.txt { #deny all; log_not_found off; } location ~ /\.(?!well-known).* { deny all; } #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } # proxy the PHP scripts to Apache listening on 127.0.0.1:80 # #location ~ \.php$ { # proxy_pass http://127.0.0.1; #} }
与HTTP站点相比,增加了对 SSL v1.3 与 HTTP 2.0 的支持,并做了生产环境的优化,参数可以在该模板的基础上,根据业务需求调整或添加
但必须将以下参数修改为实际业务的参数
server_name root ssl_trusted_certificate ssl_certificate ssl_certificate_key access_log
生成 session_ticket.key
openssl rand 48 > /data0/htdocs/ssl/session_ticket.key
单台nginx服务器使用,仅需不定期更换 session_ticket.key 秘钥既可。如果需要管理一整套nginx集群,可使用 lua-ssl-nginx-module 模块,实现集群层面上的密钥轮换
上传证书与秘钥
#证书可以在阿里云、腾讯云等平台免费申请 #一般将证书上传至 /data0/htdocs/ssl/ 目录即可 #或复制证书与秘钥的内容创建文件 vi /data0/htdocs/ssl/sitename.pem vi /data0/htdocs/ssl/sitename.key
ssl_trusted_certificate 应配置为ca根证书+和中级ca证书的列表
一般国内申请的免费证书只会下载到一个pem文件,已包含全部证书列表,所以 ssl_trusted_certificate 和 ssl_certificate 使用同一个pem证书即可
⑧ 创建服务脚本:
vi /usr/lib/systemd/system/nginx.service #输入以下内容 [Unit] Description=The nginx HTTP and reverse proxy server After=syslog.target network.target remote-fs.target nss-lookup.target [Service] Type=forking PIDFile=/usr/local/webserver/nginx/nginx.pid ExecStartPre=/usr/local/webserver/nginx/sbin/nginx -t ExecStart=/usr/local/webserver/nginx/sbin/nginx ExecReload=/usr/local/webserver/nginx/sbin/nginx -s reload ExecStop=/usr/local/webserver/nginx/sbin/nginx -s stop PrivateTmp=true [Install] WantedBy=multi-user.target
设置systemd延时防止pid报错
mkdir -p /etc/systemd/system/nginx.service.d printf "[Service]\nExecStartPost=/bin/sleep 0.1\n" > /etc/systemd/system/nginx.service.d/override.conf systemctl daemon-reload
加入启动项
systemctl enable nginx
启动Tengine服务
systemctl start nginx
⑨ 运维问题补充:
在HTTPS日志格式中,加入了 $ssl_session_reused 以便查看 ssl seesion 的复用率,但当站点开启HTTP 2.0支持时, 短时间内重新访问页面,日志会返回未重用状态
原因如下,可以临时关闭HTTP 2.0,使用HTTP 1.1进行测试
In HTTP/2 connections are usually kept open for a long time, and you aren't likely to see actual SSL session reuse due to this - in most cases you will see just another request in an already opened connection.
[返回目录]
六、设置与优化 CentOS 7
① 配置防火墙:
如果安装了FirewallD,需要关闭FirewallD服务
systemctl stop firewalld systemctl disable firewalld
配置iptables防火墙
vi /etc/sysconfig/iptables #修改防火墙配置文件规则如下 *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] -A INPUT -s 127.0.0.1/32 -d 127.0.0.1/32 -j ACCEPT -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A INPUT -p icmp --icmp-type any -j ACCEPT -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT -A INPUT -j REJECT --reject-with icmp-port-unreachable -A FORWARD -j REJECT --reject-with icmp-port-unreachable -A OUTPUT -j ACCEPT COMMIT #如需外部访问MySQL应增加一条3306端口规则 -A INPUT -p tcp -m tcp --dport 3306 -j ACCEPT #开启防火墙 systemctl enable iptables systemctl restart iptables
如果使用的是支持硬件防火墙设置的云主机,可以关闭 iptables
② 开启时间同步:
systemctl enable ntpd systemctl start ntpd #使用中国时区(一般无需修改) cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
③ 修改ulimit连接数最大值:
echo -e '\n\nulimit -SHn 65535\n' >> /etc/profile && source /etc/profile
④ 禁止Crontab产生邮件:
crontab -e #在第一行输入 MAILTO=""
可以避免 /var/mail/root 体积快速增长
⑤ 系统性能优化:
vi /etc/sysctl.conf #在最下方添加 net.ipv4.tcp_slow_start_after_idle 0 net.ipv4.tcp_syncookies = 1 net.ipv4.tcp_max_syn_backlog = 65536 net.core.netdev_max_backlog = 32768 net.core.somaxconn = 32768 net.core.wmem_default = 8388608 net.core.rmem_default = 8388608 net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 net.ipv4.tcp_timestamps = 0 net.ipv4.tcp_synack_retries = 2 net.ipv4.tcp_syn_retries = 2 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_mem = 94500000 915000000 927000000 net.ipv4.tcp_max_orphans = 3276800 net.ipv4.tcp_fin_timeout = 30 net.ipv4.ip_local_port_range = 1024 65535 vm.swappiness = 10
使配置立即生效
sysctl -p
至此,一台高性能的Web服务器配置完毕了!