其他教程

其他教程

Products

当前位置:首页 > 其他教程 >

手把手教你学网站服务器常用脚本

GG网络技术分享 2025-03-18 16:14 0


大家好,这里是关于[宝塔面板磁盘空间满、inodes满处理办法],[手把手教你学网站服务器常用脚本]问题的解答,希望对您有所帮助。如果你还想了解更多这方面的信息,请关注本站其他相关内容,共同学习吧!

宝塔面板磁盘空间满、inodes满处理办法

教程大全inodes,宝塔面板,磁盘满

宝塔面板磁盘空间满、inodes满处理办法

宝塔面板inodes满

很多朋友使用服务器突然会发现服务器的网站无法访问,并且MySQL等服务无法重启,主要原因就是磁盘空间满了。下面就针对宝塔面板给出磁盘空间清理的几种方式。

连入服务器SSH输入下方命令即可清理。请对照自己的实际情况来使用。

清理网站日志/php站点session/系统邮件/临时文件

cd /www/server/panel && python tools.pyc clear

清空面板回收站

rm -rf /www/Recycle_bin/*

清除mysql二进制日志(操作过程中会停止重启数据库)

/etc/init.d/mysqld stop

rm -f /www/server/data/ib_logfile*

rm -f /www/server/data/mysql-bin.*

/etc/init.d/mysqld start

需要注意的是 执行rm命令时是不会返回任何提示的,直到能再次输入命令之前它都是正在删除文件的状态
能输入命令的时候即删除完成

清理完毕后可以输入以下命令检查磁盘剩余空间

df -h

只要Use%这一列没有一个达到100%就可以了
一般只需要关注系统盘,即第一行,若有挂载数据盘到www目录,也要注意。

手把手教你学网站服务器常用脚本

bt面板简介

在解释bt宝塔面板是什么之前,先简单说说一直以来建网站方法

  1. 比较久远的时候,以前都是在Linux环境下,在黑洞洞的命令行窗口,安装建立网站常用的软件。建立网站肯定离不开三件套嘛——http服务器、数据库、服务器运行语言(俗称后台)。
  2. 安装这三件套有各种各样的组合。后来逐步形成LAMP(Linux+Apache+MySQL+PHP)和LNMP(Linux+Nginx+MySQL+PHP)几个组合嘛。
  3. 这三件套一个个安装需要逐个输入命令,还有软件版本对应和依赖问题,以及权限及相关配置,很麻烦。后来就有人就编写了LAMP或者LNMP一键安装命令脚本。比如以下是LAMP的一键安装脚本。

wget -c ftp://soft.vpser.net/lnmp/lnmp1.3-full.tar.gz && tar zxf lnmp1.3-full.tar.gz && cd lnmp1.3-full && ./install.sh lamp

上面只是解决了安装的问题,关于网站后面还有很多维护工作需要——网站监控、数据库备份、日志记录等等。 如果有专门的服务器管理软件就省事多了。因此服务器管理软件(俗称面板)就出现了。

面板产品对比

面板的出现已经有很长历史了,bt面板、wdcp面板、plesk面板、amh面板、c panel。国外用C panel比较多,国内用BT宝塔面板。

C panel面板这个比较古老了,国外VPS厂商用的多。多数是英文版,并且操作起来不太符合国人操作习惯。

BT面板是国产的,原生支持中文,官网介绍“提升运维效率的服务器管理软件,支持一键LAMP/LNMP/集群/监控/网站/FTP/数据库/JAVA等100多项服务器管理功能。”还有他是免费的,收费功能针对技术支持等业务。

所以直接用bt面板来建网站和管理网站了。


bt面板官方网站

[bt面板官网] (https://www.bt.cn/?invite_code=MV9lcWR5emw=)。安装bt面板之后,注册账号,网站后台可以跟微信绑定,方便网站管理等。

具体安装过程可以查看 [阿里云服务器快速建网站_安装BT宝塔面板和wordpress] (https://zhuanlan.zhihu.com/p/137713506)

作为新手来说,免费版bt可满足大部分网站管理需求——网站搭建、运维监控、维护、备份数据库、备份网站、内存清理等等。



关于面板和原生Linux争议

有人说面板的出现,“简直是开历史倒车,把Linux的B格大大降低,一点都没有极客风,面板小白都可以操作”,因此对面板深恶痛绝。对此我就呵呵了。 现代社会节奏那么快,不是那么多人有大把时间能沉下心思来把Linux系统从头到家系统学习一遍的。还怀念以前读书时候,还专门花上几个月来把Linux的系统学习。像《鸟哥的 Linux 私房菜-基础篇·第三版》、《The Linux Command Line》(William E. Shotts Jr)、《深入理解 Linux 内核》( Daniel P.Bovet / Marco Cesati)。 以前年轻时候,也不怎么做笔记,都是背命令。但是尴尬的地方在于,等到年纪大了,发现以前的命令记得不太多了,毕竟老话说得好“好记性不如烂笔头”。另外不是专门干Linux运维,如果不怎么用,这些命令很快就会遗漏。对这个没体会的,可以试试会议一下以前你的小学同学、中学同学,还能记起几个人名字?自然就有体会了。

算了,不叨叨那么多了。

当然也可以学习一下bt面板的脚本,学习为自己所用嘛,这就是这篇文章的由来。

所以,面板的出现,还是降低了不少小白上手Linux门槛的,所以面板的历史很早就出现了。而且正因为bt面板符合国人习惯,并且是免费的,集成了一大堆网站维护工具,另外还有专门的收费类服务解决个人和企业难题,bt面板从2014年开始到现在那么流行。



对了,在使用bt面板之前得要有个云服务器吧。这里推荐阿里云的云服务器(Elastic Compute Service,简称ECS)。根据其官网介绍是阿里云提供的性能卓越、稳定可靠、弹性扩展的IaaS(Infrastructure as a Service)级别云计算服务。

ECS即类似于国外的VPS。(不要好奇那么多人买国外VPS干嘛用)。架设个人博客网站、企业门户都可以使用ECS。如果其网站如个人博客主要面向国内用户访问,为加快速度还是建议选用国内的服务器商。

[阿里云域名] (https://wanwang.aliyun.com/domain/com/?userCode=yos4xyvp)连接,

[阿里云服务器ECS] (https://www.aliyun.com/minisite/goods?userCode=yos4xyvp) 链接

为什么选择阿里云

  1. 以前域名注册一般选老牌域名服务商,其中万网已经被阿里收购到旗下了。
  2. 提供域名备案服务。备案业务还是很贴心的。提交完备案信息之后,第二天阿里云小姐姐会帮你免费形式审查一下,还会主动打电话过来帮助校正。如果是自己动手提交备案信息给ICP备案机构,万一因为低级错误被驳回就浪费了十天左右时间。
  3. 域名ICP备案需要服务器,阿里云也提供服务器购买,一条龙服务嘛。服务器在阿里云毕竟服务器才是支出大头,域名什么的都是小意思了。而且购买完服务器之后,还会有客服主动打电话过来询问使用情况,需不需要技术支持,还是挺不错的。
  4. 阿里云服务器购买新用户有优惠,最基础的话一年下来不超过100元。如果是本科生的话免费使用的。
  5. 备案完成之前,服务器不算租赁时间。比如说3月1日我购买了一年的服务器,域名提交备案。18日域名备案审核通过。服务器租赁时间重新按18日算起,即可以用到第二年3月18日。相当于免费多用几天。占了一点小便宜。


bt面板脚本

它的脚本有以下:

  1. 释放内存
  2. 日志分割
  3. 备份网站


一、释放内存

#!/bin/bash

PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin

export PATH

endDate=`date +"%Y-%m-%d %H:%M:%S"`

log="释放内存!"

echo "★[$endDate] $log"

echo '----------------------------------------------------------------------------'

for phpV in 52 53 54 56 70 71 72

do

if [ -f /etc/init.d/php-fpm-${phpV} ];then

/etc/init.d/php-fpm-${phpV} reload

fi

done

if [ -f "/etc/init.d/mysqld" ];then

/etc/init.d/mysqld reload

fi

if [ -f "/etc/init.d/nginx" ];then

/etc/init.d/nginx reload

fi

if [ -f "/etc/init.d/httpd" ];then

/etc/init.d/httpd graceful

fi

# httpd重新加载

if [ -f "/etc/init.d/pure-ftpd" ];then

pkill -9 pure-ftpd

sleep 0.3

/etc/init.d/pure-ftpd start 2>/dev/null

fi

# pkill -9 接进程名,杀死进程。

# 2>/dev/null的意思就是将标准错误stderr删掉。

sync

# sync 强制把文件系统buff写入磁盘,确保文件系统完整性。

sleep 2

sync

echo 3 > /proc/sys/vm/drop_caches

# 释放内存之前需要执行sync命令。sync 强制把文件系统buff写入磁盘,确保文件系统完整性。

# /proc是一个虚拟文件系统。

# 调整/proc/sys/vm/drop_caches来释放内存。

# 其默认值为0,值为1时表示可以释放pagecache缓存,值为2时可以释放pagecache和inode缓存,值为3时可以释放pagecache(页面缓存,磁盘块的任何内存映射)), dentries(目录的数据结构)和inodes(文件的数据结构)缓存。

# echo 3 > /proc/sys/vm/drop_caches,即调整其数值为3来释放内存(包括页面缓存、目录数据结构、文件数据结构等)。

echo '----------------------------------------------------------------------------'

#exit 0


CentOS 6.x 以前的版本中,系统的服务 (services) 启动的接口是在/etc/init.d/ 这个目录下,目录下的所有文件都是 scripts。

虽然/etc/init.d/* 这个脚本启动的方式 (systemV) 已经被新一代的 systemd 所取代 (从 CentOS 7 开始), 但是很多的个别服务在管理他们的服务启动方面,还是使用 shell script 的机制。

下面有nginx(nginx发音:恩静埃克斯 = Engine X)、mysqld、php-fpm-72等文件。


日期显示

endDate=`date +"%Y-%m-%d %H:%M:%S"`

  1. 注意bash脚本赋值中,变量后紧跟等于号,等于号之后不能有空格,否则会报错。因为shell会误以为变量是命令,而不是赋值。
  2. 单引号是全引用,被单引号括起的内容不管是常量还是变量都不会发生替换;双引号会替换表达式内变量。
  3. `反引号括起来的字符串被shell解释为命令行,在执行时,shell首先执行该命令行,并以它的标准输出结果取代整个反引号(包括两个反引号)部分。如date +"%Y-%m-%d %H:%M:%S"就是把这条命令的结果赋给变量endDATE。
  4. date +"%Y-%m-%d %H:%M:%S"能显示 2019-12-12 15:32:59


mysqld重新加载

if [ -f "/etc/init.d/mysqld" ];then

/etc/init.d/mysqld reload

fi

通过reload命令,将其清理内存。

reload (重新加载),reload会重新加载配置文件,服务不会中断。而且reload时会测试conf语法等,如果出错会rollback用上一次正确配置文件保持正常运行。也叫平滑重启,不会对已经连接的服务造成影响。

httpd重新加载

if [ -f "/etc/init.d/httpd" ];then

/etc/init.d/httpd graceful

fi

要在重启 Apache 服务器时不中断当前的连接,则应运行:/usr/local/sbin/apachectl graceful

ftpd重新加载

if [ -f "/etc/init.d/pure-ftpd" ];then

pkill -9 pure-ftpd

sleep 0.3

/etc/init.d/pure-ftpd start 2>/dev/null

fi

pkill -9 接进程名,杀死进程。

睡眠0.3秒后,重新启动ftpd,并且2>/dev/null的意思就是将标准错误stderr删掉。

释放内存

sync

echo 3 > /proc/sys/vm/drop_caches

  1. 释放内存之前需要执行sync命令。sync 强制把文件系统buff写入磁盘,确保文件系统完整性。
  2. /proc是一个虚拟文件系统,一般可以通过调整/proc/sys/vm/drop_caches来释放内存。 drop_caches其默认值为0,值为1时表示可以释放pagecache缓存(页面缓存,磁盘块对应的内存映射),值为2时可以释放pagecache和inode缓存(文件的数据结构),值为3时可以释放pagecache, dentries(目录的数据结构)和inodes缓存。 echo 3 > /proc/sys/vm/drop_caches,即调整其数值为3来释放内存。


二、日志分割

#!/usr/bin/python

#coding: utf-8

import sys

import os

import shutil

import time

import glob

print '=================================================================='

print '★['+time.strftime("%Y/%m/%d %H:%M:%S")+'],切割日志'

print '=================================================================='

print '|--当前保留最新的['+sys.argv[2]+']份'

logsPath = '/www/wwwlogs/'

oldFileName = logsPath+sys.argv[1]

if not os.path.exists(oldFileName):

print '|---'+sys.argv[1]+'文件不存在!'

exit()

logs=sorted(glob.glob(oldFileName+"_*"))

count=len(logs)

num=count - int(sys.argv[2])

for i in range(count):

if i>num:

break;

os.remove(logs[i])

print '|---多余日志['+logs[i]+']已删除!'

newFileName=oldFileName+'_'+time.strftime("%Y-%m-%d_%H%M%S")+'.log'

# time.strftime("%Y/%m/%d %H:%M:%S")生成为 '2019-12-12_200605'

shutil.move(oldFileName,newFileName)

if os.path.exists('/www/server/nginx/logs/nginx.pid'):

os.system("kill -USR1 `cat /www/server/nginx/logs/nginx.pid`");

# cat /www/server/nginx/logs/nginx.pid 显示nginx的pid进程号。因为nginx启动会在该路径下生成nginx.pid文件。

# `反引号括起来的字符串被shell解释为命令行,在执行时,shell首先执行该命令行,并以它的标准输出结果取代整个反引号(包括两个反引号)部分。

# kill -USR1 中,信号量USR1代表重新打开文件。其在core/ngx_config.h中定义

#if (NGX_LINUXTHREADS)

#define NGX_REOPEN_SIGNAL INFO

#define NGX_CHANGEBIN_SIGNAL XCPU

#else

#define NGX_REOPEN_SIGNAL USR1

#define NGX_CHANGEBIN_SIGNAL USR2

#endif

else:

os.system('/etc/init.d/httpd reload');

print '|---已切割日志到:'+newFileName

这个脚本里面核心部分是

if os.path.exists('/www/server/nginx/logs/nginx.pid'):

os.system("kill -USR1 `cat /www/server/nginx/logs/nginx.pid`");

cat /www/server/nginx/logs/nginx.pid 显示nginx的pid进程号。因为nginx启动会在该路径下生成nginx.pid文件。 `反引号括起来的字符串被shell解释为命令行,在执行时,shell首先执行该命令行,并以它的标准输出结果取代整个反引号(包括两个反引号)部分。

kill -USR1 中,信号量USR1代表重新打开文件。其在core/ngx_config.h中定义

#if (NGX_LINUXTHREADS)

#define NGX_REOPEN_SIGNAL INFO

#define NGX_CHANGEBIN_SIGNAL XCPU

#else

#define NGX_REOPEN_SIGNAL USR1

#define NGX_CHANGEBIN_SIGNAL USR2

#endif


备份网站

通过Python运行/www/server/panel/script/目录下的backup.py脚本,将网站www.xxx.com保存。保存备份数为3。

#!/bin/bash

PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin

export PATH

python /www/server/panel/script/backup.py site www.xxx.com 3

其调用的backup.py文件如下

#!/usr/bin/python

#coding: utf-8

#-----------------------------

# 宝塔Linux面板网站备份工具

#-----------------------------

import sys,os

reload(sys)

sys.setdefaultencoding('utf-8')

#Python2.x中由于str和byte之间没有明显区别,经常要依赖于defaultencoding来做转换。

# 在python3中有了明确的str和byte类型区别,从一种类型转换成另一种类型要显式指定encoding。

# 但是仍然可以使用这个方法代替

# import importlib,sys

# importlib.reload(sys)

os.chdir('/www/server/panel');

sys.path.append("class/")

# /www/server/panel/class 里有大量的模块文件,public.py, db.py。

# 通过改变路径方便下面导入模块。

import public,db,time

# 是class文件夹的模块文件

class backupTools:

def backupSite(self,name,count):

sql = db.Sql();

path = sql.table('sites').where('name=?',(name,)).getField('path');

#sql.table(self,table)设置表名

#def where(self,where,param):

# self.__OPT_WHERE = " WHERE " + where

# self.__OPT_PARAM = param

# WHERE name=?

#getField(self,keyName):#取回指定字段

#result = self.field(keyName).select();

startTime = time.time();

if not path:

endDate = time.strftime('%Y/%m/%d %X',time.localtime())

#'2019/12/12 20:41:01'

# %Y 年份2019 %m 月份 %d天 %X 标准的时间串

log = "网站["+name+"]不存在!"

print "★["+endDate+"] "+log

print "----------------------------------------------------------------------------"

return;

backup_path = sql.table('config').where("id=?",(1,)).getField('backup_path') + '/site';

if not os.path.exists(backup_path): public.ExecShell("mkdir -p " + backup_path);

filename= backup_path + "/Web_" + name + "_" + time.strftime('%Y%m%d_%H%M%S',time.localtime()) + '.tar.gz'

public.ExecShell("cd " + os.path.dirname(path) + " && tar zcvf '" + filename + "' '" + os.path.basename(path) + "' > /dev/null")

endDate = time.strftime('%Y/%m/%d %X',time.localtime())

if not os.path.exists(filename):

log = "网站["+name+"]备份失败!"

print "★["+endDate+"] "+log

print "----------------------------------------------------------------------------"

return;

outTime = time.time() - startTime

pid = sql.table('sites').where('name=?',(name,)).getField('id');

sql.table('backup').add('type,name,pid,filename,addtime,size',('0',os.path.basename(filename),pid,filename,endDate,os.path.getsize(filename)))

log = "网站["+name+"]备份成功,用时["+str(round(outTime,2))+"]秒";

public.WriteLog('计划任务',log)

print "★["+endDate+"] " + log

print "|---保留最新的["+count+"]份备份"

print "|---文件名:"+filename

#清理多余备份

backups = sql.table('backup').where('type=? and pid=?',('0',pid)).field('id,filename').select();

num = len(backups) - int(count)

if num > 0:

for backup in backups:

public.ExecShell("rm -f " + backup['filename']);

sql.table('backup').where('id=?',(backup['id'],)).delete();

num -= 1;

print "|---已清理过期备份文件:" + backup['filename']

if num < 1: break;

def backupDatabase(self,name,count):

sql = db.Sql();

path = sql.table('databases').where('name=?',(name,)).getField('path');

startTime = time.time();

if not path:

endDate = time.strftime('%Y/%m/%d %X',time.localtime())

log = "数据库["+name+"]不存在!"

print "★["+endDate+"] "+log

print "----------------------------------------------------------------------------"

return;

backup_path = sql.table('config').where("id=?",(1,)).getField('backup_path') + '/database';

if not os.path.exists(backup_path): public.ExecShell("mkdir -p " + backup_path);

filename = backup_path + "/Db_" + name + "_" + time.strftime('%Y%m%d_%H%M%S',time.localtime())+".sql.gz"

import re

mysql_root = sql.table('config').where("id=?",(1,)).getField('mysql_root')

mycnf = public.readFile('/etc/my.cnf');

rep = "\\[mysqldump\\]\\nuser=root"

sea = "[mysqldump]\\n"

subStr = sea + "user=root\\npassword=" + mysql_root+"\\n";

mycnf = mycnf.replace(sea,subStr)

if len(mycnf) > 100:

public.writeFile('/etc/my.cnf',mycnf);

public.ExecShell("/www/server/mysql/bin/mysqldump --opt --default-character-set=utf8 " + name + " | gzip > " + filename)

if not os.path.exists(filename):

endDate = time.strftime('%Y/%m/%d %X',time.localtime())

log = "数据库["+name+"]备份失败!"

print "★["+endDate+"] "+log

print "----------------------------------------------------------------------------"

return;

mycnf = public.readFile('/etc/my.cnf');

mycnf = mycnf.replace(subStr,sea)

if len(mycnf) > 100:

public.writeFile('/etc/my.cnf',mycnf);

endDate = time.strftime('%Y/%m/%d %X',time.localtime())

outTime = time.time() - startTime

pid = sql.table('databases').where('name=?',(name,)).getField('id');

sql.table('backup').add('type,name,pid,filename,addtime,size',(1,os.path.basename(filename),pid,filename,endDate,os.path.getsize(filename)))

log = "数据库["+name+"]备份成功,用时["+str(round(outTime,2))+"]秒";

public.WriteLog('计划任务',log)

print "★["+endDate+"] " + log

print "|---保留最新的["+count+"]份备份"

print "|---文件名:"+filename

#清理多余备份

backups = sql.table('backup').where('type=? and pid=?',('1',pid)).field('id,filename').select();

num = len(backups) - int(count)

if num > 0:

for backup in backups:

public.ExecShell("rm -f " + backup['filename']);

sql.table('backup').where('id=?',(backup['id'],)).delete();

num -= 1;

print "|---已清理过期备份文件:" + backup['filename']

if num < 1: break;

#连接FTP

def connentFtp(self):

from ftplib import FTP

ftp=FTP()

ftp.set_debuglevel(0)

ftp.connect('192.168.1.245','21')

ftp.login('uptest','admin')

ftp.cwd('test')

bufsize = 1024

return ftp;

#上传文件

def updateFtp(self,filename):

ftp = self.connentFtp();

file_handler = open(filename,'rb')

ftp.storbinary('STOR %s' % os.path.basename(filename),file_handler,bufsize)

ftp.set_debuglevel(0)

file_handler.close()

ftp.quit()

#从FTP删除文件

def deleteFtp(self,filename):

ftp = self.connentFtp();

ftp.delete(filename);

return True;

#获取列表

def getList(self):

ftp = self.connentFtp();

return ftp.nlst();

if __name__ == "__main__":

backup = backupTools()

# python /www/server/panel/script/backup.py site www.pythondaquan.com 3

type = sys.argv[1];

if type == 'site':

backup.backupSite(sys.argv[2], sys.argv[3])

else:

backup.backupDatabase(sys.argv[2], sys.argv[3])



作者的其他回答:

[自己拥有一台服务器可以做哪些很酷的事情]、

[阿里云服务器快速建网站 (安装BT宝塔面板和wordpress)]、

阿里云域名注册与备案、服务器ECS购买与登录 、

[七牛图床添加阿里云域名]、

[markdown多平台发布及七牛图床使用]

标签:

提交需求或反馈

Demand feedback