Rootop 服务器运维与web架构

2015-08-06
发表者 Venus
使用tmpfs提高性能已关闭评论

使用tmpfs提高性能

tmpfs介绍

tmpfs是一种虚拟内存文件系统,而不是块设备。是基于内存的文件系统,创建时不需要使用mkfs等初始化。
它最大的特点就是它的存储空间在内存中(虚拟为硬盘),VM(虚拟内存)是由linux内核里面的vm子系统管理的。
linux下面VM的大小由RM(Real Memory)和swap组成,RM的大小就是物理内存的大小,而Swap的大小是由自己决定的。
Swap是通过硬盘虚拟出来的内存空间,因此它的读写速度相对RM(Real Memory)要慢许多,当一个进程申请一定数量的内存时。
如内核的vm子系统发现没有足够的RM时,就会把RM里面的一些不常用的数据交换到Swap里面。
如果需要重新使用这些数据再把它们从Swap交换到RM里面。如果有足够大的物理内存,可以不划分Swap分区。

VM由RM+Swap两部分组成,因此tmpfs最大的存储空间可达(物理内存+swap交换内存)。
但是对于tmpfs本身而言,它并不知道自己使用的空间是RM还是Swap,这一切都是由内核的vm子系统管理的。
tmpfs默认的大小是RM的一半,假如你的物理内存是1024M,那么tmpfs默认的大小就是512M。
一般情况下,是配置的小于物理内存大小的。
tmpfs配置的大小并不会真正的占用这块内存,如果/dev/shm/下没有任何文件,它占用的内存实际上就是0字节
如果它最大为1G,里头放有100M文件,那剩余的900M仍然可为其它应用程序所使用,但它所占用的100M内存,是不会被系统回收重新划分的。
当删除tmpfs中文件,tmpfs 文件系统驱动程序会动态地减小文件系统并释放 VM 资源。

Oracle 中的Automatic Memory Management特性就使用了/dev/shm。
LINUX中可以把一些程序的临时文件放置在tmpfs中比如session文件,提升性能。

实验环境:
云主机:centos7.1 x86_64 2 Core 8G MEM

实现方式1 直接创建:

[root@a ~]# uname -a
Linux a.novalocal 3.10.0-229.el7.x86_64 #1 SMP Fri Mar 6 11:36:42 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
[root@a ~]# mkdir /mnt/tmp //创建虚拟硬盘挂载点
[root@a ~]# mount -t tmpfs -o size=500m tmpfs /mnt/tmp/ //创建一个tmpfs文件系统,大小为500m,挂载到/mnt/tmp
[root@a ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 20G 1.2G 18G 7% /
devtmpfs 3.9G 0 3.9G 0% /dev
tmpfs 3.9G 0 3.9G 0% /dev/shm
tmpfs 3.9G 8.3M 3.9G 1% /run
tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup
tmpfs 500M 0 500M 0% /mnt/tmp

如果不想用了,直接umount掉/mnt/tmp

实现方式2 配置fstab:

[root@a ~]# vi /etc/fstab 添加一行
tmpfs /mnt/tmp2 tmpfs defaults,size=4000M 0 0
 挂载点 大小

[root@a ~]# mount -a //挂载fstab中所有定义的选项
[root@a ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 20G 1.2G 18G 7% /
devtmpfs 3.9G 0 3.9G 0% /dev
tmpfs 3.9G 0 3.9G 0% /dev/shm
tmpfs 3.9G 8.3M 3.9G 1% /run
tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup
tmpfs 4.0G 0 4.0G 0% /mnt/tmp2

测试:

[root@a ~]# time dd if=/dev/zero bs=1024 count=3000000 of=/mnt/tmp2/3Gb.file
3000000+0 records in
3000000+0 records out
3072000000 bytes (3.1 GB) copied, 4.24275 s, 724 MB/s

real 0m4.244s
user 0m0.248s
sys 0m3.994s

这是用的云主机测试,速度大约比物理硬盘快10倍,如果不是云主机,物理机的话,性能还会高。

注意:系统重启后,数据丢失!这不是保存到物理硬盘。

2015-08-04
发表者 Venus
PDOException 异常处理已关闭评论

PDOException 异常处理

PDO 是基于向对象方式,那么错误处理也最好使用面向对象的方式来处理。在 PDOException 中定义了如下方法用于捕获错误信息:
方法                             说明
getMessage() 取得文本化的错误信息
getCode()       取得 SQLSTATE 错误代号
getFile()         取得发生异常的文件名
getLine()        取得 PHP 程序产生异常的代码所在行号
getTrace()     backtrace() 数组
getTraceAsString()  取得已格成化成字符串的 getTrace() 信息

例子:

try
{
$db = new PDO('mysql:host=localhost;dbname=test','root','roaot');
$db = null;
exit("mysql连接成功");
}catch (PDOException $e)
{
echo "错误代码:" . $e->getCode() . "<br/>";
echo "错误信息: " . $e->getMessage() . "<br/>";
echo "异常文件:" . $e->getFile() . "<br/>";
echo "异常行号:" . $e->getLine() . "<br/>";
die("提示信息:mysql连接失败") . "<br/>";
}

// PDOException 异常类,这里为针对PDO的异常
// $e 创建一个包含异常信息的对象
// -> 对象成员访问符号 => 数组成员访问符号

// die()和exit()作用一样,用于输出一个消息并且退出当前脚本
// 语法:
// void exit ([ string $status ] )
// void exit ( int $status )
// 如果 status 是一个字符串,在退出之前该函数会打印 status 。
// 如果 status 是一个 integer,该值会作为退出状态码,并且不会被打印输出。
// 退出状态码应该在范围0至254,不应使用被PHP保留的退出状态码255。 状态码0用于成功中止程序。
// 因为是一个语言构造器而不是一个函数,不能被 可变函数 调用。
// die("0"); //字符串
// die(0); // 返回一个整形,但不输出
// exit("1");
// die(1);

2015-08-03
发表者 Venus
关于PHP性能优化(转)已关闭评论

关于PHP性能优化(转)

1、升级硬件的一般规则:对于 PHP 脚本而言,主要的瓶颈是 CPU ,对于静态页面而言,瓶颈是内存和网络。一台 400 Mhz 的普通奔腾机器所下载的静态页面就能让 T3 专线(45Mbps)饱和。

2、Apache 处理 PHP 脚本的速度要比静态页面慢 2-10 倍,因此尽量采用多的静态页面,少的脚本。

3、PHP 脚本如果不做缓冲,每次调用都需要编译,因此,安装一个 PHP 缓冲产品能提升 25-100% 的性能。

4、把基于文件的会话切换到基于共享内存的会话。编译 PHP 时采用 –with-mm 选项,在 php.ini 中设置 setsession.save_handler=mm 。这个简单的修改能让会话管理时间缩短一半。

5、另外一项缓冲技术是把不常修改的 PHP 页面采用 HTML 缓冲输出。

6、如果你采用了 Linux 系统,建议升级内核到 2.6.0以上(现在最新版本为2.6.10)并开启抢占式内核支持,因为静态页面由内核服务。

7、采用最新版本的 Apache ,并把 PHP 编译其中,或者采用 DSO 模式,尽量不要采用 CGI 方式。

8、采用输出缓冲(请参考ob_start),如果你的代码有很多的 print 和 echo 语句,能提速 5-15% 。

9、不要在 Web 服务器上运行 X-Windows ,关掉没有必要运行的进程,如果已经安装了X-windows,请使用 init 3退出。

10、如果能够用文本就不要用图像,尽量减小图片的尺寸。

11、分散负载,把数据库服务器放到另外的机器上去。采用另外低端的机器服务图片和 HTML 页面,如果所有的静态页面在另外一台服务器上处理,可以设置 httpd.conf 中的 KeepAlives 为 off ,来减少断开连接的时间。

12、采用 hdparm 来优化磁盘,一般能提升 IDE 磁盘读写性能 200%,但是对 SCSI 硬盘没有效果。

13、修改 httpd.conf :

# 关闭 DNS lookups,PHP 脚本只拿 IP 地址
HostnameLookups off

# 关闭 htaccess 检测

AllowOverride none

打开 FollowSymLinks ,关闭 SymLinksIfOwnerMatch 以防 lstat() 系统调用:
Options FollowSymLinks
#Options SymLinksIfOwnerMatch
下面还有很多关于 httpd.conf 参数的调整。

14、Kurt 简洁而完整的 Apache Tuning Tips。

15、如果喜欢从修改 Apache 源码入手,可以安装 lingerd。在页面产生和发送后,每个 Apache 进程都会浪费一段时光在客户连接上,Lingerd 能接管这项工作,让 Apache 迅速服务下一个客户请求。

16、如果网络拥挤,CPU 资源不够用,采用 PHP 的 HTML 压缩功能:
output_handler = ob_gzhandler
PHP 4.0.4 及以前的用户请不要使用,因为存在内存泄漏问题。

17、修改 httpd.conf 中的 SendBufferSize 为你最大的页面文件的大小。加大内核的 TCP/IP 写缓冲大小。

18、另外一篇文章:Tuning Apache Web Servers for Speed,一篇 97 年的很古老的文章。

19、采用数据库的持久连接时,不要把 MaxRequestsPerChild 设置得太大。

20、Caching Tutorial for Web Authors and Webmasters 教你怎样实现浏览器缓冲。

21、如果你足够勇敢的话,还可以采用 Silicon Graphics 的 Accelerated Apache 补丁。这个工程能使 Apache 1.3 快 10 倍,使 Apache 2.0 快 4 倍。

22、来自Professional Apache的技巧。

23、官方的Performance Tuning 文档,很好的资料,但是十分繁琐。

24、编译 PHP 时,建议采用如下的参数: –enable-inline-optimization –disable-debug

25、安装mod_gzip(apache1.3)或者mod_deflate(apache2.0)等页面压缩软件减轻服务器拥堵。同时尽可能优化你的HTML文件和PHP文件。

26、优化 Linux ,more Linux 以及Solaris。

27、如果系统瓶颈在MYSQL的数据操作上,可以考虑将Mysql拆分成多个端口甚至多个服务器并适当优化my.cnf ,这比使用单个端口速度提高不少。

26、以上所有的方法都是针对单机而言的,如果你觉得系统还是不够快,可以采用集群,负载均衡,缓冲技术。采用 Squid 作为缓冲,配置 Squid 的方法。

2015-05-27
发表者 Venus
ssh反向连接(ssh隧道端口转发)已关闭评论

ssh反向连接(ssh隧道端口转发)

当一台linux服务器处于内网状态,没有权限映射到外网时,就需要ssh反向连接功能实现控制内网机器。
反向连接就是在公网有一台机器,通过内网机器连接到外网服务器,在外网服务器上连接这台内网。

内网机器IP:192.168.0.193
外网机器IP:42.62.73.33


内网:
执行下面命令
[root@localhost ~]# ssh -f -N -R 10000:*:22 root@42.62.73.33
root@42.62.73.33’s password:
会提示接收密钥,及输入公网机器密码。

命令意思就是在公网服务器上开一台10000端口,监听所有网络接口。

外网:
[root@1 ~]# netstat -tnlp | grep 10000
tcp 0 0 127.0.0.1:10000 0.0.0.0:* LISTEN 3411/sshd
tcp 0 0 ::1:10000 :::* LISTEN 3411/sshd

可以看到sshd监听在10000端口上。内网机器连接公网成功。

连接内网:
[root@1 ~]# ssh root@127.0.0.1 -p 10000 #公网服务器执行
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that the RSA host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
4e:75:a4:b4:15:14:52:a5:33:e3:be:cb:84:4a:34:e6.
Please contact your system administrator.
Add correct host key in /root/.ssh/known_hosts to get rid of this message.
Offending key in /root/.ssh/known_hosts:1
RSA host key for [127.0.0.1]:10000 has changed and you have requested strict checking.
Host key verification failed.
出现这个错误,表明之前已经连接过其它机器,需要删除保存在本地的密钥。

[root@1 ~]# rm -rf ~/.ssh/known_hosts

重试:
[root@1 ~]# ssh root@127.0.0.1 -p 10000
The authenticity of host ‘[127.0.0.1]:10000 ([127.0.0.1]:10000)’ can’t be established.
RSA key fingerprint is 4e:75:a4:b4:15:14:52:a5:33:e3:be:cb:84:4a:34:e6.
Are you sure you want to continue connecting (yes/no)? yes  #接受密钥
Warning: Permanently added ‘[127.0.0.1]:10000’ (RSA) to the list of known hosts.
root@127.0.0.1’s password: #输入内网服务器密码
Last login: Wed May 27 14:21:17 2015 from 192.168.0.16
[root@localhost ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:2e:59:9b brd ff:ff:ff:ff:ff:ff
inet 192.168.0.193/24 brd 192.168.0.255 scope global eth0
inet6 fe80::20c:29ff:fe2e:599b/64 scope link
valid_lft forever preferred_lft forever
连接成功。

参数解释:
-f Fork into background after authentication.
后台认证用户/密码,通常和-N连用,不用登录到远程主机。
-L port:host:hostport
将本地机(客户机)的某个端口转发到远端指定机器的指定端口. 工作原理是这样的, 本地机器上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, 该连接就经过安全通道转发出去, 同时远程主机和 host 的 hostport 端口建立连接. 可以在配置文件中指定端口的转发. 只有 root 才能转发特权端口. IPv6 地址用另一种格式说明: port/host/hostport
-R port:host:hostport
将远程主机(服务器)的某个端口转发到本地端指定机器的指定端口. 工作原理是这样的, 远程主机上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, 该连接就经过安全通道转向出去, 同时本地主机和 host 的 hostport 端口建立连接. 可以在配置文件中指定端口的转发. 只有用 root 登录远程主机才能转发特权端口. IPv6 地址用另一种格式说明: port/host/hostport
-D port
指定一个本地机器 “动态的’’ 应用程序端口转发. 工作原理是这样的, 本地机器上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, 该连接就经过安全通道转发出去, 根据应用程序的协议可以判断出远程主机将和哪里连接. 目前支持 SOCKS4 协议, 将充当 SOCKS4 服务器. 只有 root 才能转发特权端口. 可以在配置文件中指定动态端口的转发.
-C Enable compression.
压缩数据传输。
-N Do not execute a shell or command.
不执行脚本或命令,通常与-f连用。
-g Allow remote hosts to connect to forwarded ports.
在-L/-R/-D参数中,允许远程主机连接到建立的转发的端口,如果不加这个参数,只允许本地主机建立连接。注:这个参数在实践中似乎不起作用。

2015-05-22
发表者 Venus
利用expect实现自动化操作已关闭评论

利用expect实现自动化操作

比如在新上架的服务器,需要初始化一些参数(iptables selinux 内核参数等),一台台修改麻烦,用ssh密钥登陆还得制作密钥并复制。
这里用expect实现自动输入密码并执行脚本。

[root@localhost ~]# cat /etc/issue
CentOS release 6.6 (Final)

[root@localhost ~]# rpm -qa | grep expect #需要expect这个rpm包
expect-5.44.1.15-5.el6_4.x86_64

1、定义主机ip

[root@localhost ~]# cat ip.txt
192.168.0.192
192.168.0.193
192.168.0.194
192.168.0.195
192.168.0.196

2、定义脚本内容

[root@localhost ~]# cat script.sh
mkdir test_directory

不要加任何注释,直接写命令。也不需要#!/bin/bash开头,expect发送过去就是bash执行。

3、shell嵌套expect脚本

[root@localhost ~]# cat shut.sh
#!/bin/bash
#Create By : www.rootop.org
#MailAddress: venus@rootop.org
#Version : 1.0
#Data : 2015/05/22
#Last Modify: 2015/05/22-m1
#Desc : auto ops
#Tested : RedHat6/CentOS6 with "expect" package

passwd='123456'
sc=$(cat script.sh)

cat ip.txt | while read line
do

/usr/bin/expect <<EOF
set timeout 30
spawn ssh root@$line
expect {
"yes/no" { send "yes\r";exp_continue }
"password:" { send "$passwd\r" }
}
expect "]# "
send "$sc\r"
send "exit\r"
expect eof
EOF

done
exit 0

首先定义密码为passwd变量,把发送的命令定义为sc变量,然后用循环读ip地址定义为line变量。