分类目录归档:Nginx

Let’s Encrypt SSL证书续期失败 ascii编解码器不能编码

今天复查服务器SSL证书,发现Let’s Encrypt证书就快要到期了,查看crontab定时任务计划日志,也是正常执行的。例如:

$ cat /var/log/cron
...
CROND[31471]: (root) CMD (/usr/bin/certbot renew --quiet && /bin/systemctl restart nginx)
CROND[31470]: (root) MAIL (mailed 375 bytes of output but got status 0x004b#012)
CROND[31482]: (root) CMD (run-parts /etc/cron.hourly)
...

奇怪的是,证书并没有正常续期,什么个原因呢,后来手动执行证书更新:

$ /usr/bin/certbot renew --quiet
Attempting to renew cert from /etc/letsencrypt/renewal/renwole.com.conf produced an unexpected error: 'ascii' codec can't encode characters in position 247-248: ordinal not in range(128). Skipping.

All renewal attempts failed. The following certs could not be renewed:
  /etc/letsencrypt/live/renwole.com.conf/fullchain.pem (failure)
1 renew failure(s), 0 parse failure(s)

更新失败,提示“ascii”编解码器不能编码字符。

经过分析研究发现,开发人员修改了网站根目录,导致LetsEncrypt找不到相关配置文件。
PS:唉,出了问题,都是运维的锅哈。

解决方案

修改以下配置文件中的网站根目录:

$ vim /etc/letsencrypt/renewal/renwole.com.conf
...
# Options used in the renewal process
[renewalparams]
authenticator = webroot
installer = None
account = a07a7160ea489g586aeaada1368ce0d6
[[webroot_map]]
renwole.com = /apps/data/www/renwolecom
...

修改蓝色部分为Nginx指定的根目录,其他默认,然后保存即可。

再次更新证书成功。

使用以下命令查看续期状态:

$ certbot certificates

Nginx创建密码验证保护网站目录

在生产环境中,网站需要授权访问的场景非常之多,比如数据库管理工具:phpMyAdminMysqlUpBackUp等等。有时还需要一些私有目录文件的保护,为了实现这一伟大目标,我们就需要用到Nginx location匹配规则,下面将进行讲解。

1.创建htpasswd文件

$ vim /usr/local/nginx/conf/htpasswd

添加以下内容:
renwole:xEmWnqjTJipoE

此文件的书写格式是:

用户名:密码

注意:每行一个用户和密码,这里的password不是明文,而是将password进行crypt(3)加密后的字符串。

2.密码生成

可以打开以下网址输入用户信息进行密码生成:

//tool.oschina.net/htpasswd

3.Nginx加密目录配置

在Nginx虚拟主机配置文件中的合适区域加入以下内容:

如果保护tools目录:

location ^~ /tools/ {
auth_basic            "Restricted Area";
auth_basic_user_file  conf/htpasswd;
}

说明:若不加 ^~ 只能对目录进行弹窗验证,访问此目录下的文件则无需验证。

如果保护整个网站根目录:

location / {
auth_basic            "Restricted Area";
auth_basic_user_file  conf/htpasswd;
}

添加需要保护的目录后,重载Nginx配置文件,否则不生效。

Apache Nginx 禁止目录执行PHP脚本文件

我们在搭建网站的时候,可能需要单独对一些目录进行设置权限,以达到我们需要的安全效果。下面举例说明在Apache或Nginx下如何设置禁止某个目录执行php文件。

1.Apache配置

<Directory /apps/web/renwole/wp-content/uploads>
 php_flag engine off
</Directory>
<Directory ~ "^/apps/web/renwole/wp-content/uploads">
 <Files ~ ".php">
 Order allow,deny
 Deny from all
 </Files>
</Directory>

2.Nginx配置

location /wp-content/uploads {
    location ~ .*\.(php)?$ {
    deny all;
    }
}

Nginx禁止多个目录执行PHP:

location ~* ^/(css|uploads)/.*\.(php)${
    deny all;
}

配置完成后,重载配置文件或重启Apache或Nginx服务,之后所有通过uploads来访问php文件,都将返回403,大大地增加了web目录安全性。

Redisson 缓存 Tomcat Redis Session Manager 变量

部署负载均衡时,使用一台Nginx作为前端服务器,多台Tomcat作为后端服务器。Nginx 会根据负载策略把请求分发给Tomcat服务器。默认Tomcat服务器的session(共享会话)是不可跨越服务器的,若是同一个用户的不同请求被分发到不同的Tomcat服务器,就会造成 session 变量丢失,需要用户重新登录。在讲解Redisson之前,我先来分析以下两种方案的Session会话共享。

方案一:Nginx原生 Upstream ip_hash

ip_hash 是根据请求的IP进行分发,对于同一个IP的请求会转发到同一台Tomcat服务器。

1.Nginx 配置如下:《Nginx 1.3 集群负载均衡器 反向代理安装配置优化

 upstream webservertomcat {
 ip_hash;
 server 10.10.204.63:8023 weight=1 max_fails=2 fail_timeout=2;
 server 10.10.204.64:8023 weight=1 max_fails=2 fail_timeout=2;
 #server 127.0.0.1:8080 backup;
 }
 server {
 listen 80;
 server_name www.myname.com myname.com;
 location / {
 proxy_pass //webservertomcat;
 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_buffer_size 4k;
 proxy_buffers 4 32k;
 proxy_busy_buffers_size 64k;
 proxy_temp_file_write_size 64k;
 add_header Access-Control-Allow-Origin *;
 }
 }

以上配置生产环境不建议使用,原因有二:

1.Nginx可能不是最前端的服务器,如Squid或CDN作为前端缓存,则Nginx实际是拿Squid或CDN服务器的IP地址,达不到根据客户端请求IP分流的效果。
2.有些机构是使用动态虚拟IP或有多个出口IP,用户访问会切换IP,则无法将某个用户的请求固定到同一个Tomcat服务器。

方案二:Nginx_Upstream_jvm_route

Nginx_upstream_jvm_route 是一个第三方 nginx 扩展模块,该模块通过 session cookie 实现 session 会话粘性,如果在cookie和url中并没有session,则这只是个简单的round-robin 负载均衡。

实现方法:用户初次请求分发到后端Server时;会把响应的Server标识添加到名称为JSESSIONID的cookie中,再次请求时;jvm_route看到session中有后端服务器的名称,它就把请求转到对应的服务器上。模块地址://code.google.com/archive/p/nginx-upstream-jvm-route/

1.Nginx配置如下:

 upstream tomcats_jvm_route {
 server 10.10.204.63:8023 srun_id=tomcat1;
 server 10.10.204.64:8023 srun_id=tomcat2;
 jvm_route $cookie_JSESSIONID|sessionid reverse;
 }

2.在多个Tomcat的server.xml添加配置如下:

 <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">
 <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat2">

3.配置后,请求的名称为JSESSIONID的cookie末尾会被添加服务器标识,如下:

 JSESSIONID=33775B80D8E0DB5AEAD61F86D6666C45.tomcat2;

4.生产环境不建议使用,原因:

4.1根据tomcat的特性,当server.xml配置文件中加了jvmRoute值后,会给sessionid加上jvmRoute值的后缀,根据这一特性 nginx_upstream_jvm_route对每次访问请求中的sessionId的值自动匹配对应的server。这样就会每次都访问都会到同一个Tomcat Server,这样就解决了访问不同tomcat节点session发生变化的问题。但是这种方式会出现一个问题,当一直被访问的Tomcat服务器宕机后,负载就会将用户分配到其他Server,这样就会造成session发生变化,从而就需要重新登录。

方案三:Tomcat Redis Session Manager

使用 Redis 共享 session,也就是本节中重点讲解的部分。以上两种方案均是将Session存储在Tomcat容器中,当请求从一个Tomcat转发到另一个Tomcat时,Session就会失效,因为Session在各个Tomcat中不能共享。如果使用Redis等缓存数据库系统存储Session,就可以在Tomcat实例之间实现Session共享。

Java框架redisson实现Tomcat会话管理器(Tomcat Session Manager),支持Apache Tomcat 6.x,7.x和8.x。配置方法如下:

1.编辑 TOMCAT_BASE/conf/context.xml 文件节点,添加以下内容:

<Manager className="org.redisson.tomcat.RedissonSessionManager"<Manager className="org.redisson.tomcat.RedissonSessionManager"  configPath="${catalina.base}/redisson-config.json" />

注:configPath – 是指的Redisson的JSON或YAML格式的配置文件路径。配置文件详见这里

2.拷贝相应的***两个***JAR包到指定的TOMCAT_BASE/lib目录下:

适用于 JDK 1.8+

redisson-all-3.5.0.jar

for Tomcat 6.x

redisson-tomcat-6-3.5.0.jar

for Tomcat 7.x

redisson-tomcat-7-3.5.0.jar

for Tomcat 8.x

redisson-tomcat-8-3.5.0.jar

3.按照 [Single instance mode]单实例模式的说明,创建编辑 Json 格式的 redisson-config.json 文件,添加以下内容,并将其上传到TOMCAT_BASE下,重载Tomcat服务即可。

{
 "singleServerConfig":{
 "idleConnectionTimeout":10000,
 "pingTimeout":1000,
 "connectTimeout":10000,
 "timeout":3000,
 "retryAttempts":3,
 "retryInterval":1500,
 "reconnectionTimeout":3000,
 "failedAttempts":3,
 "password":null,
 "subscriptionsPerConnection":5,
 "clientName":null,
 "address": "redis://127.0.0.1:6379",
 "subscriptionConnectionMinimumIdleSize":1,
 "subscriptionConnectionPoolSize":50,
 "connectionMinimumIdleSize":10,
 "connectionPoolSize":64,
 "database":0,
 "dnsMonitoring":false,
 "dnsMonitoringInterval":5000
 },
 "threads":0,
 "nettyThreads":0,
 "codec":null,
 "useLinuxNativeEpoll":false
 }

4.开始测试session。创建session.jsp并添加以下代码,上传到TOMCAT_BASE/webapps/ROOT/下。

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>shared session</title>
</head>
<body>
<br>session id=<%=session.getId()%>
</body>
</html>

5.浏览器访问会出现以下会话信息

 session id=1D349A69E8F5A27E1C12DEEFC304F0DC

6.现在查看Redis中是否存储了该值,如果存在会话值,此时你重启Tomcat后,该会话值也不会发生变化。

 # redis-cli
 127.0.0.1:6379> keys *
 1) "redisson_tomcat_session:1D349A69E8F5A27E1C12DEEFC304F0DC"

已经存储成功。

如果是Redis集群或多实例模式,可参阅以下更多资料进行配置:

//github.com/redisson/redisson/wiki/14.-Integration%20with%20frameworks#144-tomcat-redis-session-manager
//github.com/redisson/redisson/wiki/2.-Configuration
//github.com/redisson/redisson/wiki/2.-%E9%85%8D%E7%BD%AE%E6%96%B9%E6%B3%95 (中文文档)

最佳 Nginx 配置文件优化方案

以下是生产环境中适用的Nginx优化文件,你也可以根据自己的需求调优。

 user www www;
 #用户&组
 worker_processes auto;
 #通常是CPU核的数量存储数据的硬盘数量及负载模式,不确定时将其设置为可用的CPU内核数(设置为“auto”将尝试自动检测它)
 error_log /usr/local/nginx/logs/error.log crit;
 pid /usr/local/nginx/logs/nginx.pid;
 #指定pid文件的位置,默认值就可以

 worker_rlimit_nofile 65535;
 #更改worker进程的最大打开文件数限制
 events {
 use epoll;
 multi_accept on;
 #在Nginx接到一个新连接通知后,调用accept()来接受尽量多的连接
 worker_connections 65535;
 #最大访问客户数,修改此值时,不能超过 worker_rlimit_nofile 值
 }
 http {
 include mime.types;
 default_type application/octet-stream;
 #使用的默认的 MIME-type
 log_format '$remote_addr - $remote_user [$time_local] "$request" '
 '$status $body_bytes_sent "$http_referer" '
 '"$http_user_agent" "$http_x_forwarded_for"';
 #定义日志格式
 charset UTF-8;
 #设置头文件默认字符集
 server_tokens off;
 #Nginx打开网页报错时,关闭版本号显示
 access_log off;
 sendfile on;
 tcp_nopush on;
 #告诉nginx在一个数据包里发送所有头文件,而不一个接一个的发送
 tcp_nodelay on;
 #是否启用 nagle 缓存算法,告诉nginx不要缓存数据
 sendfile_max_chunk 512k;
 #每个进程每次调用传输数量不能大于设定的值,默认为0,即不设上限
 keepalive_timeout 65;
 #HTTP连接持续时间,值越大无用的线程变的越多,0:关闭此功能,默认为75
 client_header_timeout 10;
 client_body_timeout 10;
 #以上两项是设置请求头和请求体各自的超时时间
 reset_timedout_connection on;
 #告诉nginx关闭不响应的客户端连接
 send_timeout 30;
 #客户端响应超时时间,若客户端停止读取数据,释放过期的客户端连接,默认60s
 limit_conn_zone $binary_remote_addr zone=addr:5m;
 #用于保存各种key,如:当前连接数的共享内存的参数,5m是5兆字节,这个值应该被设置的足够大,以存储(32K*5)32byte状态或者(16K*5)64byte状态
 limit_conn addr 100;
 #key最大连接数,这里key是addr,我设置的值是100,这样就允许每个IP地址最多同时打开100个连接数
 server_names_hash_bucket_size 128;
 #nginx启动出现could not build the server_names_hash, you should increase错误时,请提高这个参数的值一般设成64就够了
 client_body_buffer_size 10K;
 client_header_buffer_size 32k;
 #客户端请求头部的缓冲区大小,这个可以根据你的系统分页大小进行设置
 large_client_header_buffers 4 32k;
 client_max_body_size 8m;
 #上传文件大小设置,一般是动态应用类型

 #线程池优化,使用--with-threads配置参数编译
 #aio threads;
 #thread_pool default threads=32 max_queue=65536;
 #aio threads=default;
 #关于更多线程请点击查看

 #fastcgi性能调优

 fastcgi_connect_timeout 300;
 #连接到后端 Fastcgi 的超时时间
 fastcgi_send_timeout 300;
 #与 Fastcgi 建立连接后多久不传送数据,就会被自动断开
 fastcgi_read_timeout 300;
 #接收 Fastcgi 应答超时时间
 fastcgi_buffers 4 64k;
 #可以设置为 FastCGI 返回的大部分应答大小,这样可以处理大部分请求,较大的请求将被缓冲到磁盘
 fastcgi_buffer_size 64k;
 #指定读取 Fastcgi 应答第一部分需要多大的缓冲区,可以设置gastcgi_buffers选项指定的缓冲区大小
 fastcgi_busy_buffers_size 128k;
 #繁忙时的buffer,可以是fastcgi_buffer的两倍
 fastcgi_temp_file_write_size 128k;
 #在写入fastcgi_temp_path时将用多大的数据块,默认值是fastcgi_buffers的两倍,该值越小越可能报 502 BadGateway
 fastcgi_intercept_errors on;
 #是否传递4**&5**错误信息到客户端,或允许nginx使用error_page处理错误信息.

 #fastcgi_cache配置优化(若是多站点虚拟主机,除fastcgi_cache_path(注意keys_zone=名称)全部加入php模块中)

 fastcgi_cache fastcgi_cache;
 #开启FastCGI缓存并指定一个名称,开启缓存可以降低CPU的负载,防止502错误出现
 fastcgi_cache_valid 200 302 301 1h;
 #定义哪些http头要缓存
 fastcgi_cache_min_uses 1;
 #URL经过多少次请求将被缓存
 fastcgi_cache_use_stale error timeout invalid_header http_500;
 #定义哪些情况下用过期缓存
 #fastcgi_temp_path /usr/local/nginx/fastcgi_temp;
 fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=1:2 keys_zone=fastcgi_cache:15m inactive=1d max_size=1g;
 #keys_zone=缓存空间的名字,cache=用多少内存,inactive=默认失效时间,max_size=最多用多少硬盘空间。
 #缓存目录,可以设置目录层级,举例:1:2会生成16*256个字目录
 fastcgi_cache_key $scheme$request_method$host$request_uri;
 #定义fastcgi_cache的key
 #fastcgi_ignore_headers Cache-Control Expires Set-Cookie;

 #响应头

 add_header X-Cache $upstream_cache_status;
 #缓存命中
 add_header X-Frame-Options SAMEORIGIN;
 #是为了减少点击劫持(Clickjacking)而引入的一个响应头
 add_header X-Content-Type-Options nosniff;

 #GZIP性能优化

 gzip on;
 gzip_min_length 1100;
 #对数据启用压缩的最少字节数,如:请求小于1K文件,不要压缩,压缩小数据会降低处理此请求的所有进程速度
 gzip_buffers 4 16k;
 gzip_proxied any;
 #允许或者禁止压缩基于请求和响应的响应流,若设置为any,将会压缩所有请求
 gzip_http_version 1.0;
 gzip_comp_level 9;
 #gzip压缩等级在0-9内,数值越大压缩率越高,CPU消耗也就越大
 gzip_types text/plain text/css application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript application/json image/jpeg image/gif image/png;
 #压缩类型
 gzip_vary on;
 #varyheader支持,让前端的缓存服务器识别压缩后的文件,代理
 include /usr/local/nginx/conf/vhosts/*.conf;
 #在当前文件中包含另一个文件内容的指令

 #静态文件的缓存性能调优

 open_file_cache max=65535 inactive=20s;
 #这个将为打开文件指定缓存,max 指定缓存数量.建议和打开文件数一致.inactive 是指经过多长时间文件没被请求后删除缓存
 open_file_cache_valid 30s;
 #这个是指多长时间检查一次缓存的有效信息,例如我一直访问这个文件,30秒后检查是否更新,反之更新
 open_file_cache_min_uses 2;
 #定义了open_file_cache中指令参数不活动时间期间里最小的文件数
 open_file_cache_errors on;
 #NGINX可以缓存在文件访问期间发生的错误,这需要设置该值才能有效,如果启用错误缓存.则在访问资源(不查找资源)时.NGINX会报告相同的错误

 #资源缓存优化
 server {

 #防盗链设置

 location ~* \.(jpg|gif|png|swf|flv|wma|asf|mp3|mmf|zip|rar)$ {
 #防盗类型
 valid_referers none blocked *.renwole.com renwole.com;
 #none blocked参数可选.允许使用资源文件的域名
 if ($invalid_referer) {
 return 403;
 #rewrite ^/ //renwole.com
 #若不符合条件域名,则返回403或404也可以是域名
 }
 }
 location ~ .*\.(js|css)$ {
 access_log off;
 expires 180d;
 #健康检查或图片.JS.CSS日志.不需要记录日志.在统计PV时是按照页面计算.而且写入频繁会消耗IO.
 }
 location ~* ^.+\.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|swf|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
 access_log off;
 log_not_found off;
 expires 180d;
 #视图&元素很少改变.可将内容缓存到用户本地.再次访问网站时就无需下载.节省流量.加快访问速度.缓存180天
 }
 }
 server {
 listen 80 default_server;
 server_name .renwole.com;
 rewrite ^ //renwole.com$request_uri?;
 }
 server {
 listen 443 ssl http2 default_server;
 listen [::]:443 ssl http2;
 server_name .renwole.com;
 root /home/web/renwole;
 index index.html index.php;

 ssl_certificate /etc/letsencrypt/live/renwole.com/fullchain.pem;
 ssl_certificate_key /etc/letsencrypt/live/renwole.com/privkey.pem;

 ssl_dhparam /etc/nginx/ssl/dhparam.pem;
 ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
 ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';

 ssl_session_cache shared:SSL:50m;
 ssl_session_timeout 1d;
 ssl_session_tickets off;
 ssl_prefer_server_ciphers on;
 add_header Strict-Transport-Security max-age=15768000;
 ssl_stapling on;
 ssl_stapling_verify on;

 include /usr/local/nginx/conf/rewrite/wordpress.conf;
 access_log /usr/local/nginx/logs/renwole.log;

 location ~ \.php$ {
 root /home/web/renwole;
 #fastcgi_pass 127.0.0.1:9000;
 fastcgi_pass unix:/var/run/www/php-cgi.sock;
 fastcgi_index index.php;
 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
 include fastcgi_params;
 }
 }
 }

以上就是本站所使用的环境优化情况,如你有更好的方案不妨分享出来。如有什么有不足之处,还请谅解。

更多模块了解,请参阅//nginx.org/en/docs/

Nginx 集群负载均衡器:NFS文件存储共享安装配置优化篇

上一篇文章中介绍了《Nginx 1.3 集群负载均衡 反向代理安装配置优化》这篇重点写文件存储(File Storage)过程。

10.10.204.62 Load Balancing
10.10.204.63 Nginx Web server
10.10.204.64 Nginx Web server
10.10.204.65 File Storage

1.File Storage 服务器安装

yum -y install nfs-utils

2.配置NFS并创建共享目录

# mkdir -p /Data/webapp
# vim /etc/exports

/Data/webapp 10.10.204.0/24(rw,sync,no_subtree_check,no_root_squash)

3.开启自启动

# systemctl enable rpcbind
# systemctl enable nfs-server
# systemctl start rpcbind
# systemctl start nfs

4.相关参数:

rw:read-write:可读写; ro:read-only,只读; sync:文件同时写入硬盘和内存。
no_root_squash:来访的root用户保持root帐号权限;显然开启这项是不安全的。
root_squash:将来访的root用户映射为匿名用户或用户组;通常它将使用nobody或nfsnobody身份。
all_squash:所有访问用户都映射为匿名用户或用户组;
anonuid:匿名用户的UID值,可以在此处自行设定。 anongid:匿名用户的GID值。
sync:将数据同步写入内存缓冲区与磁盘中,效率低,但可以保证数据的一致性。
async:文件暂存于内存,而不是直接写入内存。
no_subtree_check :即使输出目录是一个子目录,nfs服务器也不检查其父目录的权限,这样可以提高效率。

5.File Storage 服务器防火墙配置

# firewall-cmd --permanent --add-service=rpc-bind
# firewall-cmd --permanent --add-service=nfs
# firewall-cmd --reload

6.Nginx Web server 服务器安装以及挂载

# yum -y install nfs-utils
# mkdir -p /Data/webapp
# mount -t nfs 10.10.204.65:/Data/webapp /Data/webapp

7.如果需要开机自动挂载,在该文件最下方添加一行即可

# vim /etc/fstab

10.10.204.65:/Data/webapp /Data/webapp nfs auto,rw,vers=3,hard,intr,tcp,rsize=32768,wsize=32768 0 0

 

8.Nginx Web server 服务器测试

连续写16384个16KB的块到nfs目录下的testfile文件

# time dd if=/dev/zero of=/Data/webapp/testfile bs=16k count=16384

  16384+0 records in
  16384+0 records out
  268435456 bytes (268 MB) copied, 2.89525 s, 92.7 MB/s
  real 0m2.944s
  user 0m0.015s
  sys 0m0.579s

测试读的性能

# time dd if=/nfsfolder/testfile of=/dev/null bs=16k

  16384+0 records in
  16384+0 records out
  268435456 bytes (268 MB) copied, 0.132925 s, 2.0 GB/s
  real 0m0.138s
  user 0m0.003s
  sys 0m0.127s

综合来讲,NFS的速度还算理想。如果觉得速度慢,那么添加相关参数后,反复挂载卸载并测试读写,找到适合自己的配置方案。

Nginx 1.3 集群负载均衡器 反向代理安装配置优化

什么是负载均衡?简言之:负载平衡是指通过一组后端服务器(也称为服务器集群或服务器池)有效地分发传入的网络流量。就像交通信号灯一样,横跨能够履行最大化速度和容量的利用率,确保没有任何一台服务器是超负荷状态,并在所有服务器上路由客户端请求。如果单个服务器关闭或出现故障则可能会降低性能,负载平衡器会将流量重定向到其余的在线服务器。当新的服务器被添加到服务器组时,负载均衡器会自动开始向其发送请求。

环境:
OS:CentOS Linux release 7.3.1611 (Core) x86_64
Web server:nginx version: nginx/1.13.3

10.10.204.62 Load Balancing
10.10.204.63 Nginx Web server
10.10.204.64 Nginx Web server
10.10.204.65 File Storage

1.Nginx Web server安装,我就不在叙述,请参阅《Nginx安装篇》。

2.分别修改4台服务器的主机名,一般都是IP地址,修改完成后重启服务器。

[root@localhost ~]# vim /etc/hostname

3.10.10.204.62 Load Balancing Nginx完整配置文件。注;观察红色部分;

[root@10-10-204-62 ~]# cat /usr/local/nginx/conf/nginx.conf
 user www www;
 worker_processes 1;

 #error_log logs/error.log;
 #error_log logs/error.log notice;
 #error_log logs/error.log info;

pid /usr/local/nginx/logs/nginx.pid;

worker_rlimit_nofile 65535;

events {
 use epoll;
 worker_connections 65535;
 }

http {
 include mime.types;
 default_type application/octet-stream;
 server_tokens off;
 #log_format main '$remote_addr - $remote_user [$time_local] "$request" '
 # '$status $body_bytes_sent "$http_referer" '
 # '"$http_user_agent" "$http_x_forwarded_for"';
 #access_log logs/access.log main;

 sendfile on;
 tcp_nopush on;

 server_names_hash_bucket_size 128;
 client_header_buffer_size 32k;
 large_client_header_buffers 4 32k;
 client_max_body_size 8m;
 tcp_nodelay on;
 keepalive_timeout 65;
 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;

 gzip on;
 gzip_min_length 1100;
 gzip_buffers 4 16k;
 gzip_http_version 1.0;
 #gzip压缩的等级,0-9之间,数字越大,压缩率越高,但是cpu消耗也大。
 gzip_comp_level 9;
 gzip_types text/plain text/html text/css application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
 gzip_vary on;
 #
 upstream webserverapps {
 ip_hash;
 server 10.10.204.63:8023 weight=1 max_fails=2 fail_timeout=2;
 server 10.10.204.64:8023 weight=1 max_fails=2 fail_timeout=2;
 #server 127.0.0.1:8080 backup;
 }
 server {
        listen 80;
        server_name www.myname.com myname.com;
 location / {
     proxy_pass //webserverapps;
     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_buffer_size 4k;
     proxy_buffers 4 32k;
     proxy_busy_buffers_size 64k;
     proxy_temp_file_write_size 64k;
     add_header Access-Control-Allow-Origin *;
       }
    }
 }

4.Nginx Web server 服务器配置:10.10.204.63 & 10.10.204.64。

server {
 listen 8989;
 server_name IP地址;
 location / {
 root /home/web/wwwroot/;
 index index.html index.htm index.php;
 #获取Client端IP需要Nginx支持http_realip_module模块
 set_real_ip_from 10.10.204.0/24;
 real_ip_header X-Real-IP;
     }
 }

5.Nginx做负载均衡需要用到 upstream 是Nginx的HTTP Upstream模块。

Nginx 的负载均衡 upstream 模块目前支持 6 种调度算法,下面进行分别介绍,其中后两项属于第三方调度算法。

轮询(默认):每个请求按时间顺序逐一分配到不同的后端服务器,如果后端某台服务器宕机,故障系统被自动剔除,使用户访问不受影响。Weight 指定轮询权重值,Weight 值越大,分配到的访问机率越高。
ip_hash:每个用户请求按访问 IP 的 hash 结果分配,这样来自同一个 IP 的访客固定访问一个后端服务器,有效解决了动态网页存在的 session 共享问题。
fair:比上面两个更智能的负载均衡算法。此算法可以根据&加载时间的长短智能进行负载分配,根据后端服务器响应时长分配请求,响应时间越短就会优先分配。
url_hash:此方法按访问 url 的 hash 结果来分配请求,使每个 url 定向到同一个后端服务器,可以进一步提高后端缓存服务器的效率。
least_conn:最少连接负载均衡算法,简单来说就是每次选择的后端都是当前最少连接的一个 server(这个最少连接不是共享的,是每个 worker 都有自己的一个数组进行记录后端 server 的连接数)。
hash:这个 hash 模块又支持两种模式 hash, 一种是普通的 hash, 另一种是一致性 hash(consistent)。

6.在HTTP Upstream模块中,可以通过server指令指定后端服务器的IP地址和端口,同时还可以设定每个后端服务器在负载均衡调度中的状态。常用的健康状态有:

down:表示当前的 server 暂时不参与负载均衡。
backup:预留的备份机器。当其他所有的非 backup 机器出现故障或者忙的时候,才会请求 backup 机器,因此这台机器的压力最轻。
max_fails:允许请求失败的次数,默认为 1 。当超过最大次数时,返回 proxy_next_upstream 模块定义的错误。
fail_timeout:在经历了 max_fails 次失败后,暂停服务的时间。max_fails 可以和 fail_timeout 一起使用。

注:当负载调度算法为 ip_hash 时,后端服务器在负载均衡调度中的状态不能是 backup。

注:stream 是定义在 server{ } 之外,不能定义在 server{ } 内。定义好upstream后,用 proxy_pass 引用即可。此外每一次修改nginx.conf配置文件都需要重新加载Nginx服务。

7.关于 session 共享问题有更多解决方案,请继续参阅《Redis 缓存 PHP 7.2 session 变量共享》。

8.文件服务器

注意:其实大家可能会有个疑问,那么多服务器分布计算,他们需要的文件从哪里来,不仅要保证数据的一致性,还要保证数据的安全性。这个时候就要用到文件存储服务器了,只需要将10.10.204.65文件服务器的数据文件共享给 10.10.204.63 & 10.10.204.64 即可。通常由NFS网络文件系统完成文件共享,我这里已经安装完成。若你还没有安装,请参阅Nginx 集群负载均衡:NFS文件存储共享安装配置优化篇

Linux Nginx网站:Certbot安装配置Lets Encrypt SSL免费HTTPS加密证书

实验环境:CentOS Linux release 7.3.1611 (Core)
内核版本:Linux version 3.10.0-514.el7.x86_64
Nginx版本: Nginx-1.13.0

Let’s Encrypt是一个免费的、自动化、开放的证书颁发机构。由Mozilla、Cisco、Chrome、facebook、Akamai等众多公司和机构发起的,其安全稳定及其可靠。具体信息可以去letsencrypt官方网站了解详情。

今天我们就充分利用Lets Encrypt让你的网站实现https加密。

官网://letsencrypt.org/

1.安装certbot及源扩展包

$ yum install -y epel-release

Certbot是Let’s Encrypt官方指定推荐的客户端。通过 Certbot,你可以自动化部署 Let’s Encrypt SSL证书,以便为网站加上HTTPS加密支持。

$ yum install certbot
$ certbot certonly
Saving debug log to /var/log/letsencrypt/letsencrypt.log
How would you like to authenticate with the ACME CA?
//你是希望如何使用ACME CA进行身份验证?
-------------------------------------------------------------------------------
1: Place files in webroot directory (webroot)
//将文件放在webroot目录
2: Spin up a temporary webserver (standalone)
//使用临时Web服务器(独立目录)
-------------------------------------------------------------------------------
Select the appropriate number [1-2] then [enter] (press 'c' to cancel):1 【选择1回车】
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel):su@renwole.com【输入您的邮箱地址,用于紧急更新和安全通知】

Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org
-------------------------------------------------------------------------------
Please read the Terms of Service at
//letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf. You must agree
in order to register with the ACME server at
//acme-v01.api.letsencrypt.org/directory
-------------------------------------------------------------------------------
(A)gree/(C)ancel: A【选择A回车同意服务条款,C为拒绝】
-------------------------------------------------------------------------------
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about EFF and
our work to encrypt the web, protect its users and defend digital rights.
-------------------------------------------------------------------------------
(Y)es/(N)o:Y【您是否愿意分享您的电子邮件地址,建议选择Y回车】
Please enter in your domain name(s) (comma and/or space separated) (Enter 'c'
to cancel): blog.renwole.com【输入域名回车】
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for blog.renwole.com
Select the webroot for blog.renwole.com:
-------------------------------------------------------------------------------
1: Enter a new webroot
//输入网站绝对路径
-------------------------------------------------------------------------------
Press 1 [enter] to confirm the selection (press 'c' to cancel):1【选择数字1回车】
Input the webroot for blog.renwole.com: (Enter 'c' to cancel):/home/www/blog.renwole.com【输入网站所在绝对路径回车】
Waiting for verification...
Waiting for verification...
Cleaning up challenges
Generating key (2048 bits): /etc/letsencrypt/keys/0001_key-certbot.pem
Creating CSR: /etc/letsencrypt/csr/0001_csr-certbot.pem

IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/blog.renwole.com/fullchain.pem. Your cert
will expire on 2017-08-09. To obtain a new or tweaked version of
this certificate in the future, simply run certbot again. To
non-interactively renew *all* of your certificates, run "certbot
renew"
- If you like Certbot, please consider supporting our work by:

Donating to ISRG / Let's Encrypt: //letsencrypt.org/donate
Donating to EFF:

恭喜!您的SSL证书和密钥链接已保存,你的证书将于2017-08-09到期。

注意:这里需要说明,在生成证书之前,你必须保证nginx 443端口是运行状态,否则会生成证书失败。

2.自动续订

Certbot可以配置为在证书过期之前自动更新证书。由于Let’s Encrypt SSL证书有效期时间为90天,所以建议您利用此功能。您可以通过运行以下命令来测试证书的自动续订:

$ sudo certbot --nginx certonly

如果以上正常工作,你可以通过添加运行以下操作的cron或systemd定时任务安排自动更新:

certbot renew

我们写一个自动执行脚本,建议每小时执行一次:

$ sudo crontab -e

添加以下内容:

0 */6 * * * /usr/bin/certbot renew --quiet && /bin/systemctl restart nginx

保存并退出!

通过命令查看是否添加成功:

$ crontab -l
0 */6 * * * /usr/bin/certbot renew --quiet && /bin/systemctl restart nginx

重启crontab

$ systemctl status crond.service
$ systemctl restart crond.service

通过命令观察 crontab 是否执行:

$ tail -f /var/log/cron

证书是否续订成功,可以通过以下命令管理查看证书信息:

$ certbot certificates

更多Certbot命令请参阅官方文档 //certbot.eff.org/docs/

3.配置nginx.conf
接下来修改Nginx配置文件,修改sever段,去掉相应注释,将生成的SSL证书填写到ssl_certificate后面,将生成的密钥填写到ssl_certificate_key后面,保存并重启nginx服务器即可。

# vi /usr/local/nginx/conf/nginx.conf

server {
 listen 443 ssl;

 ssl_certificate /etc/letsencrypt/live/blog.renwole.com/fullchain.pem;
 ssl_certificate_key /etc/letsencrypt/live/blog.renwole.com/privkey.pem;

# ssl_session_cache shared:SSL:1m;
 ssl_session_timeout 5m;

# ssl_ciphers HIGH:!aNULL:!MD5;
 ssl_prefer_server_ciphers on;

# location / {
 # root html;
 # index index.html index.htm;
 # }
 }

使用谷歌浏览器访问//blog.renwole.com/可以看到绿色的安全小锁图标,说明网站已经https加密成功。

linux Nginx1.12.0平滑升级到新版本nginx-1.13.3

本篇演示生产环境:Centos7.3 64位 最小化安装版。

1.查看当前Nginx版本信息。代码如下:

# /usr/local/nginx/sbin/nginx -V
 nginx version: nginx/1.12.0
 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-11) (GCC)
 built with OpenSSL 1.0.1e-fips 11 Feb 2013
 TLS SNI support enabled
 configure arguments: --prefix=/usr/local/nginx --user=www --group=www --with-pcre --with-http_v2_module --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-http_image_filter_module --with-mail --with-threads --with-mail_ssl_module --with-stream_ssl_module

2.下载nginx-1.13.3版本到/usr/local/下,解压并进入解压后的目录。代码如下:

 # cd /usr/local/
 # wget //nginx.org/download/nginx-1.13.3.tar.gz
 # wget //www.openssl.org/source/openssl-1.1.0e.tar.gz //下载最新openssl
 # tar zxvf openssl-1.1.0e.tar.gz //解压文件
 # tar zxvf nginx-1.13.3.tar.gz
 # cd nginx-1.13.3

3.查看nginx版本的时候,configure后面有一大串模块,这也是你第一次安装nginx时所指定的模块,升级的时候也要同时指定,也可以添加其他模块。代码如下:

./configure \
 --prefix=/usr/local/nginx \
 --user=www \
 --group=www \
 --with-pcre \
 --with-openssl=/tmp/openssl-1.1.0e \
 --with-http_ssl_module \
 --with-http_v2_module \
 --with-http_realip_module \
 --with-http_addition_module \
 --with-http_sub_module \
 --with-http_dav_module \
 --with-http_flv_module \
 --with-http_mp4_module \
 --with-http_gunzip_module \
 --with-http_gzip_static_module \
 --with-http_random_index_module \
 --with-http_secure_link_module \
 --with-http_stub_status_module \
 --with-http_auth_request_module \
 --with-http_image_filter_module \
 --with-mail \
 --with-threads \
 --with-mail_ssl_module \
 --with-stream_ssl_module \
 # make

4.注意:make完以后,执行下面代码。不需要执行make install,否则会覆盖安装,nginx服务会出现各种问题。

不中断nginx web服务器的正常运行称之为平滑升级,先重命名之前的nginx二进制文件。代码如下:

# mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak

拷贝刚编译新生产的Nginx二进制文件到/usr/local/nginx/sbin/目录;代码如下:

# cp /usr/local/nginx-1.13.3/objs/nginx /usr/local/nginx/sbin/

5.开始执行升级命令。代码如下:

# cd /usr/local/nginx-1.13.3
 # make upgrade
 /usr/local/nginx/sbin/nginx -t
 nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
 nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
 kill -USR2 `cat /usr/local/nginx/logs/nginx.pid`
 sleep 1
 test -f /usr/local/nginx/logs/nginx.pid.oldbin
 kill -QUIT `cat /usr/local/nginx/logs/nginx.pid.oldbin`

6.再次查看nginx升级后的版本信息。代码如下:

# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.13.3
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-11) (GCC)
built with OpenSSL 1.1.0e 16 Feb 2017
TLS SNI support enabled

可以看到已经成功升级到1.13.3,本文教程可用于生产环境当中。希望能帮到大家。转载请注明!

Centos 7 源码编译安装 Nginx 1.13

关于nginx的相关介绍我就不说了,既然你选择nginx作为你的web服务器,想必你多少也对nginx server有不同认知和理解,接下来我就直接安装。

1.先决条件:

我使用的是centos7.3 64位核心版系统,安装配置nginx前必须安装nginx依赖包,请查看;Centos 7编译安装php7.1之生产篇,并安装前文开头所提供的依赖包。此依赖组件包适用于Nginx任意版本。

新建web用户和组

$ /usr/sbin/groupadd www
$ /usr/sbin/useradd -g www www
$ ulimit -SHn 65535 //设置linux高负载参数

2.从官方下载Nginx以及OpenSSL

下载Nginx时有两个版本:开发版和稳定版,如果用于生产就下载稳定版本,//nginx.org/en/download.html (最好下载最新版本的稳定版,这样会有bug修复以及新特性)我下载的是就是目前最新版本nginx-1.13.5。

$ cd /tmp
$ wget //www.openssl.org/source/openssl-1.1.0e.tar.gz
$ tar zxvf openssl-1.1.0e.tar.gz
$ wget //nginx.org/download/nginx-1.13.5.tar.gz
$ tar zxvf nginx-1.13.5.tar.gz
$ cd nginx-1.13.5

3.安装Nginx

你可能会注意到有些文档教程安装nginx的时候,并未指派这么多模块,(看起来好长),有的连模块和用户都没有指派,其实模块是根据自己的需要指派的, 如果想以后不麻烦,那么就按照下面的模块指派就行了,其实这也算是全能的了,不然后期你需要什么还得重新编译进去,不是很麻烦,但也不省事。至于是否指派用户组,我坚决会让你指派,这可关乎nginx配置的可用性和安全稳定。

$ ./configure \
--prefix=/usr/local/nginx \
--user=www \
--group=www \
--with-pcre \
--with-openssl=/tmp/openssl-1.1.0e \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_sub_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_mp4_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_random_index_module \
--with-http_secure_link_module \
--with-http_stub_status_module \
--with-http_auth_request_module \
--with-http_image_filter_module \
--with-http_slice_module \
--with-mail \
--with-threads \
--with-file-aio \
--with-stream \
--with-mail_ssl_module \
--with-stream_ssl_module \
$ make -j8 && make install //编译并安装

4.创建 systemctl 系统 Nginx 单元文件

安装完成后还需要开机自启动,不然每次开机都需要手动,那岂不是太麻烦。

$ vim /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/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/bin/kill -s HUP /usr/local/nginx/logs/nginx.pid
ExecStop=/bin/kill -s QUIT /usr/local/nginx/logs/nginx.pid
PrivateTmp=true

[Install]
WantedBy=multi-user.target

保存并退出。

5.加入开机自启动并启动Nginx

$ systemctl enable nginx.service
$ systemctl restart nginx.service

6.设置Firewalld防火墙

$ firewall-cmd --zone=public --add-port=80/tcp --permanent
$ firewall-cmd --reload

7.查看Nginx是否启动成功

$ ss -ntlp

可以查看到nginx进程已经运行了。到此nginx安装就完成了,可能你还会有疑问,nginx怎么解析并支持php程序呢,别慌,下一篇文章中我会写到。