rsync备份同步文件

一、介绍

Rsync具有可使本地和远程两台主机之间的数据快速复制同步镜像、远程备份的功能。
cp,scp等工具拷贝均为完整的拷贝,而rsync除了可以完整拷贝外,还具有增量拷贝的功能。

官方文档:https://www.samba.org/ftp/rsync/rsync.html

二、常见应用场景

1) rsync+crontab 数据同步
2)实时数据同步rsync+inotify

三、工作模式(三种)

1)单个主机本地直接的数据传输

rsync -avz   /etc/hosts    /tmp        相当于cp
rsync -avz  --delete  /null/  /tmp/   相当于rm

2)remote shell

push:   rsync -avzP -e ' ssh -p 22'   /tmp/  [email protected] :/tmp/
pull :      rsync -avzP -e ' ssh -p  22'  [email protected] :/tmp/   /tmp/

3)rsync daemon

四、rsync 服务端配置

1)vi /etc/rsyncd.conf(需要手动生成)

uid = root  
gid = root   
user chroot = no   
max connections = 20   
timeout = 60  
pid file = /var/run/rsyncd.pid   
lock file = /var/run/rsyncd.lock  
motd file = /etc/rsyncd.motd     
log file = /var/log/rsyncd.log   
[backup]   
path = /backup   
ignore errors   
read only = no   
list = no   
hosts allow = 192.168.1.101  
auth users = rsync   
secrets file =/etc/rsyncd.pwd  

2)创建rsync用户及共享目录/backup

useradd rsync -s   /sbin/nologin -M
id  rsync
mkdir /backup
chown -R  rsync  /backup

3)创建密码文件

echo "rsync:123456">/etc/rsyncd.pwd
chmod 600  /etc/rsync.password

4)启动服务

/usr/bin/rsync  --deamon
netstat   -lntup |grep  rsync
ps  -ef |grep rsync |grep -v grep

5)加入开机自启动

echo "/usr/bin/rsync --deamon">>/etc/rc.local
cat  /etc/rc.local

五、rsync客户端配置

1、客户端不用配置,直接使用rsync命令就可以,

rsync -vzrtopg --progress --delete [email protected]::backup  /data/
rsync -vzrtopg --progress --delete /data/  [email protected]::backup

2、rsync无密码登陆,客户端需配置密码文件,只包含服务器端auth user的密码,不需要配置用户名 。

vim /etc/rsyncd.pwd 
123456
chmod 600  /etc/rsyncd.pwd

注:此处密码一定要与rsync服务器端密码文件中密码保持一致。

rsync -vzrtopg --progress --delete --password-file=/etc/rsyncd.pwd [email protected]::backup /data/
rsync -vzrtopg --progress --delete --password-file=/etc/rsyncd.pwd /data/ [email protected]::backup

3、rsync定时任务(备份本地目录/data/到服务端192.168.1.100)

crontab -e
0 1  * * *  rsync -vzrtopg --progress --delete --password-file=/etc/rsyncd.pwd /data/ [email protected]::backup

4、Rsync 同步参数说明

-vzrtopg里的v是verbose,z是压缩,r是recursive,topg都是保持文件原有属性如属主、时间的参数。
–progress是指显示出详细的进度情况
–delete是指如果服务器端删除了这一文件,那么客户端也相应把文件删除

5、rsync常用参数:

#rsync [option] 源路径 目标路径
其中[option]为:

a:使用archive模式,等于-rlptgoD,即保持原有的文件权限
z:表示传输时压缩数据
v:显示到屏幕中
e:使用远程shell程序(可以使用rsh或ssh)

–delete:精确保存副本,源主机删除的文件,目标主机也会同步删除
–include=PATTERN:不排除符合PATTERN的文件或目录
–exclude=PATTERN:排除所有符合PATTERN的文件或目录
–password-file:指定用于rsync服务器的用户验证密码

六、rsync常见错误排错

1、

rsync: failed to connect to 118.244.216.177: No route to host (113)

rsync error: error in socket IO (code 10) at clientserver.c(124) [receiver=3.0.6]

原因:防火墙屏蔽了端口

解决:打开873段考

iptables -i INPUT -p tcp --dport 873 -j ACCEPT
iptables -L

如果以上指令不行,可以直接停掉防火墙

/etc/init.d/iptables stop

2、

@ERROR: auth failed on module backup

rsync error: error starting client-server protocol (code 5) at main.c(1506) [Receiver=3.0.7]

检查密码文件设置权限 chmod 600 /etc/rsyncd.pwd

3、

@ERROR: auth failed on module xxxxx

rsync: connection unexpectedly closed (90 bytes read so far)

rsync error: error in rsync protocol data stream (code 12) at io.c(150)

这是因为密码设错了, 无法登入成功, 请检查一下 rsyncd.scrt 中的密码, 二端是否一致?

4、

password file must not be other-accessible

continuing without password file

Password:

这表示 rsyncd.pwd 的档案权限属性不对, 应设为 600。

5、

@ERROR: chroot failed

rsync: connection unexpectedly closed (75 bytes read so far) 

rsync error: error in rsync protocol data stream (code 12) at io.c(150)

这通常是您的 rsyncd.conf 中的 path 路径所设的那个目录并不存在所致.请先用 mkdir开设好要备份目录

6、

@ERROR: access denied to www from unknown (192.168.1.123)

rsync: connection unexpectedly closed (0 bytes received so far) [receiver]

rsync error: error in rsync protocol data stream (code 12) at io.c(359)

最后原因终于找到了。因为有两个网段都需要同步该文件夹内容,但没有在hosts allow 后面添加另一个IP段

hosts allow = 192.168.1.0/24

改为

hosts allow = 192.168.1.0/24 192.168.2.0/24

重新启动rsync服务,问题解决

7、

@ERROR: auth failed on module backup

rsync error: error starting client-server protocol (code 5) at 
main.c(1506) [Receiver=3.0.7]

client端没有设置/etc/rsyncd.pwd这个文件,而在使用rsync命令的时候,加了这个参数–password-file=/etc/rsyncd.pwd

8、

rsync: recv_generator: mkdir "/teacherclubBackup/rsync……" failed: No space left on device (28)

*** Skipping any contents from this failed directory ***

磁盘空间满了

9、

rsync: opendir "/backup" (in dtsChannel) failed: Permission denied (13)

同步目录的权限设置不对,改为755

10、

rsync: read error: Connection reset by peer (104)

rsync error: error in rsync protocol data stream (code 12) at io.c(759) [receiver=3.0.5]

未启动xinetd守护进程

[root@CC02 /]# service xinetd start

11、

rsync: unable to open configuration file "/etc/rsyncd.conf": No such file or directory

xnetid查找的配置文件位置默认是/etc下,在/etc下找不到rsyncd.conf文件

12、

rsync: failed to connect to 203.100.192.66: Connection timed out (110)

rsync error: error in socket IO (code 10) at clientserver.c(124) [receiver=3.0.5]

连接服务器超时,检查服务器的端口netstat –tunlp,远程telnet测试

13、我需要在防火墙上开放哪些端口以适应rsync?

视情况而定。rsync可以直接通过873端口的tcp连接传文件,也可以通过22端口的ssh来进行文件传递,但你也可以通过下列命令改变它的端口:

rsync --port 8730 otherhost::

或者

rsync -e 'ssh -p 2002' otherhost:

14、我如何通过rsync只复制目录结构,忽略掉文件呢?

rsync -av --include '*/' --exclude '*' source-dir dest-dir

15、为什么我总会出现”Read-only file system”的错误呢?

看看是否忘了设”read only = no”了

16、

@ERROR: chroot failed

rsync error: error starting client-server protocol (code 5) at 
main.c(1522) [receiver=3.0.3]

原因:

服务器端的目录不存在或无权限。创建目录并修正权限可解决问题。

17、

@ERROR: auth failed on module backup

rsync error: error starting client-server protocol (code 5) at main.c(1522) [receiver=3.0.3]

原因:
服务器端该模块(tee)需要验证用户名密码,但客户端没有提供正确的用户名密码,认证失败。提供正确的用户名密码解决此问题。

18、

@ERROR: Unknown module ‘bcakup’

rsync error: error starting client-server protocol (code 5) at main.c(1522) [receiver=3.0.3]

原因:
服务器不存在指定模块。提供正确的模块名或在服务器端修改成你要的模块以解决问题。

19、权限无法复制。去掉同步权限的参数即可。(这种情况多见于Linux向Windows的时候)
(备份本地目录/data/到服务端192.168.1.100)

Linux VPS采用Rsync实现网站文件/服务器数据同步增量备份

无论我们选择虚拟主机,还是选择VPS、服务器,最为关键的就是服务器中的数据。相对而言,选择优质服务商和服务器的意外几率会小一些,但也不是没有。因为服务器的意外不是商家和我们用户控制的,包括服务器中程序的问题,也可能是我们人为的操作问题。

如果网站数据量不大,我们可以采用定期人工备份或者利用定时备份脚本。一键包环境或者是WEB面板都带有自动备份到本地和远程服务器的功能。如果数据量较大,我们其实可以采用Rsync实现同步增量备份。下面的记录是通过Rsync实现文件同步增量备份的。
设置过程却是比较繁琐,如果我们普通项目用户可以使用商家自带的快照定时或者脚本环境带的自动备份功能,以及我们自己的定期备份。(本文来自:https://www.laobuluo.com/1070.html)

第一、准备工作

1、数据备份

如果我们没有把握一次性搞定,我们可以准备两台测试环境服务器实现Rsync同步备份功能之后再用到生产环境。如果用到生产环境,我们可以将服务器快照备份,或者将网站、项目数据备份。

2、服务器准备

这里我们采用的是Rsync同步增量备份,所以我们需要准备主服务器、以及一台备份服务器。鉴于数据备份后的功能,我们可以直接备份到备份服务器某一个目录,或者将备份服务器安装主服务器环境,将需要备份的网站项目备份到对应的同目录中。

3、端口开放

如果我们服务器没有设定iptables防火墙规则,那就不要设置端口。如果我们有设置iptables防火墙,那就需要将873端口添加放行。

vi /etc/sysconfig/iptables

打开iptables规则文档,添加:

-A INPUT -p tcp -m state --state NEW -m tcp --dport 873 -j ACCEPT

未分类

编辑保存之后,然后/etc/init.d/iptables restart重启才能生效。同样的方法,我们需要在主服务器和备份服务器同时设置。

第二、配置备份服务器

1、安装rsync

未分类

2、配置文件

vi /etc/xinetd.d/rsync

将配置文件disable参数从”yes”换成”no”。

3、创建配置文件

vi /etc/rsyncd.conf

创建文件,然后将下面脚本添加:

log file = /var/log/rsyncd.log
pidfile = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
secrets file = /etc/rsync.pass
motd file = /etc/rsyncd.Motd
#创建一个模块名称,后面需要一致
[www.laobuluo.com]
#备份服务器目录地址
path = /home/wwwroot/www.laobuluo.com
#对应上面模块名称
comment = www.laobuluo.com
uid = root
gid = root
port = 873
use chroot = no
read only = no
list = no
max connections = 200
timeout = 600
#创建一个同步用户名,随便取,反正后面出现的时候要一致
auth users = www.laobuluo.com_user
#主服务器IP地址
hosts allow = xxx.xxx.xxx.xxx

根据我们网站项目以及服务器实际信息创建文件贴到配置文件中保存退出。

4、创建密码配对文件

vi /etc/rsync.pass

创建密码配对文件:

www.laobuluo.com_user:1234567890passwd

红色字段需要对应上面的auth users,蓝色部分是我们创建配对的密码。后面主服务器配置的时候也需要用到密码,所以必须一致。

5、开放权限和启动

chmod 600 /etc/rsyncd.conf
chmod 600 /etc/rsync.pass
service xinetd restart

未分类

第三、配置主服务器

1、安装rsync

yum install rsync xinetd -y

未分类

2、配置文件

vi /etc/xinetd.d/rsync

未分类

将配置文件disable参数从”yes”换成”no”。

3、创建密码配对文件

未分类

将我们上面在备份服务器中蓝色的密码丢进来,必须一致。

4、授权和启动

未分类

第四、配置主服务器

这一步我们继续配置主服务器,需要安装和配置inotify-tools来实现同步增量备份。

1、安装环境包

yum install make gcc gcc-c++ -y

未分类

2、下载和安装inotify-tools

cd /usr/local/src
wget https://download.laobuluo.com/tools/inotify-tools-3.14.tar.gz
tar -zxvf inotify-tools-3.14.tar.gz
cd inotify-tools-3.14
./configure --prefix=/usr/local/inotify
make
make install

未分类

3、配置环境变量

echo "PATH=/usr/local/inotify/bin:$PATH" >>/etc/profile.d/inotify.sh
source /etc/profile.d/inotify.sh
echo "/usr/local/inotify/lib" >/etc/ld.so.conf.d/inotify.conf
ln -s /usr/local/inotify/include /usr/include/inotify

4、配置参数

未分类

参考就脚本 – http://soft.laozuo.org/scripts/rsync.sh

修改自行的文件和目录,然后保存退出。

5、创建排除目录列表

vi /usr/local/inotify/exclude.list

创建一个排除目录,这里可以添加不同步的目录,一行一个目录。如果暂时没有可以留空,以后需要用到在添加。

6、授权和设置开机启动

chmod +x /usr/local/inotify/rsync.sh

这里我们授权。

vi /etc/rc.d/rc.local

最后一行添加:

sh /usr/local/inotify/rsync.sh &

未分类

第五、检测以及生效小结

1、检查生效

设置完毕之后,我们可以通过手工检查

sh /usr/local/inotify/rsync.sh &

在主服务器执行脚本,如果看到有目录在进度,说明完美,然后去备份服务器中可以看到已经备份到的文件目录。

未分类

2、自动生效

重启主服务器,然后就会自动生效。如果不放心我们可以在主服务器对应目录丢一个文件看看备份服务器是否有增加。

总结,这篇文章较为详细的将Linux VPS、服务器使用Rsync进行同步增量备份文件。

使用Python和Flask编写Prometheus监控

Installation

pip install flask
pip install prometheus_client

Metrics

Prometheus提供4种类型Metrics:Counter, Gauge, Summary和Histogram

Counter

Counter可以增长,并且在程序重启的时候会被重设为0,常被用于任务个数,总处理时间,错误个数等只增不减的指标。

import prometheus_client
from prometheus_client import Counter
from prometheus_client.core import CollectorRegistry
from flask import Response, Flask
app = Flask(__name__)
requests_total = Counter("request_count", "Total request cout of the host")
@app.route("/metrics")
def requests_count():
    requests_total.inc()
    # requests_total.inc(2)
    return Response(prometheus_client.generate_latest(requests_total),
                    mimetype="text/plain")
@app.route('/')
def index():
    requests_total.inc()
    return "Hello World"
if __name__ == "__main__":
    app.run(host="0.0.0.0")

运行改脚本,访问youhost:5000/metrics

# HELP request_count Total request cout of the host
# TYPE request_count counter
request_count 3.0

Gauge

Gauge与Counter类似,唯一不同的是Gauge数值可以减少,常被用于温度、利用率等指标。

import random
import prometheus_client
from prometheus_client import Gauge
from flask import Response, Flask
app = Flask(__name__)
random_value = Gauge("random_value", "Random value of the request")
@app.route("/metrics")
def r_value():
    random_value.set(random.randint(0, 10))
    return Response(prometheus_client.generate_latest(random_value),
                    mimetype="text/plain")
if __name__ == "__main__":
    app.run(host="0.0.0.0")

运行改脚本,访问youhost:5000/metrics

# HELP random_value Random value of the request
# TYPE random_value gauge
random_value 3.0

Summary/Histogram

Summary/Histogram概念比较复杂,一般exporter很难用到,暂且不说。

PLUS

LABELS

使用labels来区分metric的特征

from prometheus_client import Counter
c = Counter('requests_total', 'HTTP requests total', ['method', 'clientip'])
c.labels('get', '127.0.0.1').inc()
c.labels('post', '192.168.0.1').inc(3)
c.labels(method="get", clientip="192.168.0.1").inc()

REGISTRY

from prometheus_client import Counter, Gauge
from prometheus_client.core import CollectorRegistry
REGISTRY = CollectorRegistry(auto_describe=False)
requests_total = Counter("request_count", "Total request cout of the host", registry=REGISTRY)
random_value = Gauge("random_value", "Random value of the request", registry=REGISTRY)

Python 实现多线程下载器

前言

我为什么会想到要写一个下载器呢,实在是被百度云给逼的没招了,之前用 Axel 配合直链在百度云下载视频能达到满速,结果最近两天 Axel 忽然不能用了,于是我就想着要不干脆自己写一个吧,就开始四处查询资料,这就有了这篇博客。

我假设阅读这篇博客的你已经对以下知识有所了解:

  • Python 的文件操作
  • Python 的多线程
  • Python 的线程池
  • Python 的 requests 库
  • HTTP 报文的首部信息

下载

获取文件采用的是 requests 库,该已经封装好了许多 http 请求,我们只需要发送 get 请求,然后将请求的内容写入文件即可:

import requests

r = requests.get('http://files.smashingmagazine.com/wallpapers/july-17/summer-cannonball/cal/july-17-summer-cannonball-cal-1920x1080.png')
with open('wallpaper.png', 'wb') as f:
    f.write(r.content)

随后看看文件夹,那张名为 wallpaper.png 的图片就是我们刚刚下载的。

但是这个功能太简单了,甚至简陋,我们需要多线程并发执行下载各自的部分,然后再汇总。

拆分

为了拆分,首先得知道数据块的大小,HTTP 报文首部提供了这样的信息:

  • 用 head 方法去获取 http 首部信息,再从获取的信息提取出 Content-Length 字段(上文图片大小为 261258 bytes)
import requests

headers = {'Range': 'bytes={}-{}'.format(0, 100000)}
r = requests.get('http://files.smashingmagazine.com/wallpapers/july-17/summer-cannonball/cal/july-17-summer-cannonball-cal-1920x1080.png', headers = headers)
with open('wallpaper.png', 'wb') as f:
    f.write(r.content)

我们得到了图片的前 100001 个字节(Range 的范围是包括起始和终止的),打开 wallpaper.png 你应该能看到一幅“半残”的图。

这样我们里目标更近了一步,继续:

  • 确认线程数(比如 8 个),261258//8 = 32657,前 7 个线程都取 32657 个 bytes,第八个取剩余的
part = size // nums

for i in range(nums):
        start = part * i
        if i == num_thread - 1:   # 最后一块
            end = file_size
        else:
            end = start + part
  • 每个线程获取到的内容按顺序写入文件(file.seek() 调节文件指针)
def down(start, end):
    headers = {'Range': 'bytes={}-{}'.format(start, end)}
    # 这里最好加上 stream=True,避免下载大文件出现问题
    r = requests.get(self.url, headers=headers, stream=True)
    with open(filename, "wb+") as fp:
        fp.seek(start)
        fp.write(r.content)

嘛,线程多了起来就扔到线程池让它来帮我们调度。

封装

功能复杂了,用对象来封装整理一下:

class Downloader(): 
    def __init__(self, url, num, name):
        self.url = url
        self.num = num
        self.name = name
        r = requests.head(self.url)
        self.size = int(r.headers['Content-Length']) 

    def down(self, start, end):

        headers = {'Range': 'bytes={}-{}'.format(start, end)}
        r = requests.get(self.url, headers=headers, stream=True)

        # 写入文件对应位置
        with open(self.name, "rb+") as f:
            f.seek(start)
            f.write(r.content)


    def run(self):
        f = open(self.name, "wb")
        f.truncate(self.size)
        f.close()

        futures = []
        part = self.size // self.num 
        pool = ThreadPoolExecutor(max_workers = self.num)                                    
        for i in range(self.num):
            start = part * i
            if i == self.num - 1:   
                end = self.size
            else:
                end = start + part - 1
            # 扔进线程池
            futures.append(pool.submit(self.down, start, end))
        wait(futures)

至此,核心功能都完成了,剩下的就是实际体验的优化了。

完整的代码已托管至 GitHub,地址见这里: https://github.com/WincerChan/DAM

结语

很可惜,我写的这个下载器还是不能下载百度云直链,不过嘛,好多人都说结果不重要,都说重要的是过程,不是么?写这个下载器我也确实学到了许多,至于一开始我是出于什么样的目的?管他呢

Python并行计算简单实现

multiprocessing包是Python中的多进程管理包.
Pool(num)类提供一个进程池,然后在多个核中执行这些进程,
其中默认参数num是当前机器CPU的核数.

Pool.map(func, iterable[, chunksize=None])
2个参数, 第一个参数是函数, 第二个参数是需要可迭代的变量, 作为参数传递到func

如果func含有的参数多于一个,可以利用functools.partial 先处理.
以下是一个简单的例子.

from multiprocessing import Pool
from functools import partial 

def somefunc(str_1, str_2, iterable_iterm):
    print("%s %s %d" % (str_1, str_2, iterable_iterm))

def main():
    iterable = [1, 2, 3, 4, 5]
    pool = Pool()
    str_1 = "This"
    str_2 = "is"
    func = partial(somefunc, str_1, str_2)
    pool.map(func, iterable)
    pool.close()
    pool.join()

if __name__ == "__main__":
    main()

php-fpm优化方法 pm.min_spare_servers、pm.max_spare_servers

php-fpm进程池开启进程有两种方式,一种是static,直接开启指定数量的php-fpm进程,不再增加或者减少;
另一种则是dynamic,开始时开启一定数量的php-fpm进程,当请求量变大时,动态的增加php-fpm进程数到上限,

当空闲时自动释放空闲的进程数到一个下限。这两种不同的执行方式,可以根据服务器的实际需求来进行调整。

要用到的一些参数,分别是pm、pm.max_children、pm.start_servers、pm.min_spare_servers和pm.max_spare_servers。

pm表示使用那种方式,有两个值可以选择,就是static(静态)或者dynamic(动态)。

下面4个参数的意思分别为:

  • pm.max_children:静态方式下开启的php-fpm进程数量,在动态方式下他限定php-fpm的最大进程数(这里要注意pm.max_spare_servers的值只能小于等于pm.max_children)
  • pm.start_servers:动态方式下的起始php-fpm进程数量。
  • pm.min_spare_servers:动态方式空闲状态下的最小php-fpm进程数量。
  • pm.max_spare_servers:动态方式空闲状态下的最大php-fpm进程数量。如果dm设置为static,那么其实只有pm.max_children这个参数生效。系统会开启参数设置数量的php-fpm进程。php-fpm一个进程大概会占20m-40m的内存,所以他的数字大小的设置要根据你的物理内存的大小来设置,还要注意到其他的内存占用,如数据库,系统进程等,来确定以上4个参数的设定值!

如果dm设置为dynamic,4个参数都生效。系统会在php-fpm运行开始时启动pm.start_servers个php-fpm进程,

然后根据系统的需求动态在pm.min_spare_servers和pm.max_spare_servers之间调整php-fpm进程数。

参数要求pm.start_servers的值在pm.min_spare_servers和pm.max_spare_servers之间。

例:主机内存为1.6G,默认lnmp设置为20,10,10,20;改为如下25,5,5,25

因为网站访客人数很少,所以初始php-fpm线程5个就好了,不会占用过多内存,当访客突然增加,也会动态调整直到最高的限值25.

[www]
listen = /tmp/php-cgi.sock
listen.backlog = -1
listen.allowed_clients = 127.0.0.1
listen.owner = www
listen.group = www
listen.mode = 0666
user = www
group = www
pm = dynamic
pm.max_children = 25
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 25
request_terminate_timeout = 100
request_slowlog_timeout = 0
slowlog = var/log/slow.log

php-fpm占用内存过高分析及解决

昨天刚买了个vps搭建了一个wordPress博客,刚搭建的时候有一大堆的问题。好不容易搭建完成了发现运行一阵子以后内存几乎用完了。开始以为是服务器的问题,费了好大的劲把Apache服务器换成了Nginx。但是问题还是没有解决,最后用top命令看了一下是php-fpm的问题。问题的解决办法如下:

未分类

1、查看php-fpm的进程个数

ps -fe |grep "php-fpm"|grep "pool"|wc -l

2、查看每个php-fpm占用的内存大小

ps -ylC php-fpm --sort:rss

3、配置php-fpm参数

找到php-fpm的配置文件php-fpm.conf

pm = dynamic #对于专用服务器,pm可以设置为static。#如何控制子进程,选项有static和dynamic。如果选择static,则由pm.max_children指定固定的子进程数。如果选择dynamic,则由下开参数决定:
pm.max_children #子进程最大数
pm.start_servers #启动时的进程数
pm.min_spare_servers #保证空闲进程数最小值,如果空闲进程小于此值,则创建新的子进程
pm.max_spare_servers #保证空闲进程数最大值,如果空闲进程大于此值,此进行清理

对于内存大的服务器(比如8G以上)来说,指定静态的max_children实际上更为妥当,因为这样不需要进行额外的进程数目控制,会提高效率。

对于内存小的服务器,使用动态方式。具体最大数量根据 内存/20M 得到。比如512M的VPS,建议pm.max_spare_servers设置为20。至于pm.min_spare_servers,则建议根据服务器的负载情况来设置,比较合适的值在5~10之间。

解决Nginx环境WordPress或Typecho设置固定链接无法打开的问题

做网站搭博客,首选都是自己买个国外VPS,400+一年费用一般比国内的虚拟空间稍贵点,但相比买虚拟空间VPS好太多:

  • 私有独享ip
  • 足够多的存储空间:基本上都是10G起,要放什么文件都可以,数据库也可以随意多个
  • 足够多的流量:一般都是500G起,相比虚拟主机的10G优越不是一点两点,几个朋友一起用都不是什么问题
  • 最重要的是,境外VPS还有其他的用途:比如翻墙梯

当然,国外VPS也有个比不了的,那就是速度没有国内的虚拟主机快,但不需要备案啊!!!而且,就一个小网页,速度差别几乎感受不到。

错误现象

自己的VPS就需要自己维护了,就是一台远程的电脑,你自己能折腾出花来都行。自己不会折腾找卖家装好环境自己用就行。
一般搭网站用LNMP环境,对于静态网站,nginx默认设置就行,但对于WordPress或者Typecho这种动态站点,默认会出现设置带目录的链接时无法打开的情况。

http://xxx.com/blog/
http://xxx.com/2018/
http://xxx.com/%postname%.html

不加设置以上形式的链接都会出现404错误。

解决办法

不支持目录链接是因为缺少伪静态规则,我们只需要按以下方法添加伪静态即可。

添加伪静态规则

Nginx环境下WordPress或者Typecho伪静态规则如下:

location / { 
  index index.html index.php; 
  if (-f $request_filename/index.html) { 
    rewrite (.*) $1/index.html break; 
  } 
  if (-f $request_filename/index.php) { 
    rewrite (.*) $1/index.php; 
  } 
  if (!-f $request_filename) { 
    rewrite (.*) /index.php; 
  } 
}

以上规则在nginx或者vhost配置中修改都可以。保存配置后,重启nginx一般就正常了。

开启PATHINFO

如果Typecho访问内页出现No input file specified错误提示,那么是没有开启pathinfo的支持。

方法:

找到/usr/local/php/etc/php.ini文件,将cgi.fix_pathinfo=0 改成 cgi.fix_pathinfo=1,保存后输入命令:service php-fpm重启php-fpm 即可。

nginx 安装 SSL 证书

昨天在腾讯云那里申请了SSL证书,打算部署到服务器上,但是安装过程遇到了问题:

[root@izuf6hed2mdyv56471078kz sbin]# ./nginx -s reload
nginx: [emerg] unknown directive "ssl" in
/usr/local/nginx/conf/nginx.conf:91

于是查看了下nginx的安装信息,发现ssl模块并未被安装:

[root@izuf6hed2mdyv56471078kz sbin]# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.11.6
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-11) (GCC)
configure arguments:

原因大概是:在安装nginx的时候,没有将ssl模块编译进nginx

解决办法是:重装nginx,并在执行configure命令的时候加得上 –with-http_ssl_module 参数。

由于新的nginx版本已经出来了,就借此机会顺便升级一下吧。

步骤一、下载nginx解压

wget http://nginx.org/download/nginx-1.13.8.tar.gz

# 默认下载到root
cd /root

# 解压
tar xzvf nginx-1.13.8.tar.gz

# 进入解压后的目录
cd nginx-1.13.8

步骤二、安装nginx,并添加ssl模块

./configure --with-http_ssl_module

好吧,又报错了:

./configure: error: SSL modules require the OpenSSL library.
You can either do not enable the modules, or install the OpenSSL library
into the system, or build the OpenSSL library statically from the source
with nginx by using --with-openssl=<path> option.

提示我装openssl,好吧,我装。

步骤一点五、安装OpenSSL

这是centos 的安装方法:

yum -y install openssl openssl-devel

好,继续执行步骤二。

步骤二(续)、安装nginx,并添加ssl模块

cd /root/nginx-1.13.8
 ./configure --with-http_ssl_module

请先备份好nginx相关的文件!

请先备份好nginx相关的文件!

请先备份好nginx相关的文件!

然后是安装:

# 网上说这么做会覆盖之前的版本,我测试了下,似乎没有什么大问题...
# nginx.conf也没有变化,若心存疑虑,可以参考其他教程
make install

# 查看版本是否升级
/usr/local/nginx/sbin/nginx -V

步骤三、配置

编辑/usr/local/nginx/conf/nginx.conf 添加配置:

server {
        listen 443 ssl;
        server_name www.zxxblog.cn;
        ssl on;
        ssl_certificate /home/key/1_www.zxxblog.cn_bundle.crt;
        ssl_certificate_key /home/key/2_www.zxxblog.cn.key;
        ssl_session_timeout  5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 
        ssl_ciphers  HIGH:!aNULL:!MD5;
        #ssl_ciphers  ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;   
        ssl_prefer_server_ciphers   on;   

        # !! 这下面的是我自己的配置,不同的人可能有所不同 !!
        location / {
            proxy_pass http://localhost:8080;
        }
}

步骤四、重启nginx

# 如果不成功,就kill掉nginx,然后再打开
/usr/local/nginx/sbin/nginx -s reload

然后,我在阿里云的安全组里添加了443端口,搞定!

效果:

未分类

nginx+php-fpm出现502 bad gateway错误解决方法

1. php-fpm进程数不够用

使用 netstat -napo |grep “php-fpm” | wc -l 查看一下当前fastcgi进程个数,如果个数接近conf里配置的上限,就需要调高进程数。

但也不能无休止调高,可以根据服务器内存情况,可以把php-fpm子进程数调到100或以上,在4G内存的服务器上200就可以。

2. 调高调高linux内核打开文件数量

可以使用这些命令(必须是root帐号)

echo ‘ulimit -HSn 65536’ >> /etc/profile

echo ‘ulimit -HSn 65536’ >> /etc/rc.local

source /etc/profile

3. 脚本执行时间超时

如果脚本因为某种原因长时间等待不返回 ,导致新来的请求不能得到处理,可以适当调小如下配置。

nginx.conf里面主要是如下

fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;

php-fpm.conf里如要是如下

request_terminate_timeout = 10s

4. 缓存设置比较小

修改或增加配置到nginx.conf

proxy_buffer_size 64k;
proxy_buffers  512k;
proxy_busy_buffers_size 128k;

5. recv() failed (104: Connection reset by peer) while reading response header from upstream

可能的原因机房网络丢包或者机房有硬件防火墙禁止访问该域名

但最重要的是程序里要设置好超时,不要使用php-fpm的request_terminate_timeout,

最好设成request_terminate_timeout=0;

因为这个参数会直接杀掉php进程,然后重启php进程,这样前端nginx就会返回104: Connection reset by peer。这个过程是很慢,总体感觉就是网站很卡。