分类:未分类


vim的加密功能


一、 利用 vim 加密:

优点:加密后,如果不知道密码,就看不到明文,包括root用户也看不了;
缺点:很明显让别人知道加密了,容易让别人把加密的文件破坏掉,包括内容破坏和删除;

vim编辑器相信大家都很熟悉了吧,vim里有一个命令是给文件加密的,举个例子:

1) 首先在root主目录/root/下建立一个实验文件text.txt:
#  vim  text.txt

2) 进到编辑模式,输入完内容后按ESC,然后输入:X(注意是大写的X),回车;

3) 这时系统提示让你输入密码,2次,如下所示:
输入密码: *******
请再输入一次: *******

4) 保存后退出,现在这个文件已经加密了;

5) 用cat或more查看文件内容,显示为乱码;用 vim重新编辑这个文件,会提示输入密码,如果输入的密码不正确,同样会显示为乱码!
注意:文件加密后,千万别忘了密码!

二、 vim编辑加密的文件(前提是你知道加密的密码):

1)  用 vim 打开文件如text.txt,要输入正确的密码,然后在编辑时,将密码设置为空,方法是输入下面的命令:
:set key=
然后直接回车,保存文件后,文件已经解密了。

2) 或者这样也行:
在正确打开文件后用 “:X” 指令,然后给一个空密码也可以。保存用“wq!”保存。
两种方法实际上效果是一样的。

apache rewrite死循环的问题


需求背景是: 把所有请求都转发到/111/目录下面,比如当访问 www.aminglinux.com/1.html时,应该跳转到www.aminglinux.com/111/1.html

核心配置语句是

RwriteRule ^(.*)$  /111/$1 [R,L]

使用curl测试,没有问题,但是使用浏览器访问时,出现了无限循环。
本来访问的是www.aminglinux.com/1.html时,结果变成了www.aminglinux.com/111/111/111/111/…..

解决该问题的方法是,加一个条件

RewriteCond   %{REQUEST_URI} !^/111

RewriteRule ^(.*) /111/$1 [R,L]

关于mysql优化的一些心得


先介绍下服务器架构及配置8核8G,10M带宽Centos6.5,64位,系统的架构为

Nginx 1.8.1,PHP  5.3.29,Mysql  5.5.42。

一电商网站后台查询订单时,经常php超时,导致php报错。以下是排查过程。

1、php执行超时,首先我们想到的就是php.ini文件中max_execution_time =  #把默认的值调大。

2、然后在后台执行订单查询php不报错了,但是查询耗时较长,用时65s。而且一些表成锁死状态碎片比较多,本人对mysql数据库优化不是很了解,于是请教了铭哥下,铭哥给出的答复是:一般mysql调优主要是根据慢查询日志去优化sql语句,my.cnf里面可调整的东西不多,而且效果也不明显。 下面就是调整参数,分析mysql慢查询日志。

3、mysql参数优化,主要调整的参数根据机器性能来调整,如果你对参数不是很了解,建议不要盲目的调。给大家一篇参数调整的文章 http://ask.apelearn.com/question/5758 (看第5条)

把一些配置参数修改好后重启mysqld服务,由原来的65s变成了十几秒。效果还是不是很理想,查看了下mysql默认引擎为MyISAM,决定把引擎改为Innodb。具体操作过程如下:

4、导出shop数据库的表结构

mysqldump -d -uxxx -p shop > shop_table.sql

其中-d参数表示不导出数据,只导出表结构

5、替换shop_table.sql里的MyISAM为INNODB

sed -i ‘s/MyISAM/INNODB/g’ shop_table.sql

6、新建数据库shop_new库,并导入表结构

mysql > create database shop_new;

mysql -uroot -p shop_new < shop_table.sql可以通过show table status来检查表引擎是否为INNODB。

7、导出shop的数据

mysqldump -t -uroot -p shop > shop_data.sql其中-t参数表示只导数据,不导表结构

8、导入数据到shop_new

mysql -uroot -p shop_new < shop_data.sql

9、 查看慢查询日志来定位mysql哪条语句执行慢,然后建立索引,优化sql执行语句。这台机器的慢查询日志片段,供大家参考

# Time: 160303 12:12:38

# User@Host: root[root] @  [10.165.34.182]

# Query_time: 10.145685  Lock_time: 0.000395 Rows_sent: 1  Rows_examined: 24306970

use shop;

SET timestamp=1456978358;

SELECT COUNT(*) FROM `shop`.`ecs_order_info` o LEFT JOIN`shop`.`ecs_users` u ON o.user_id = u.user_id LEFT JOIN `shop`.`ecs_affiliate_log` a ON o.order_id = a.order_id WHERE o.user_id > 0 AND (u.parent_id > 0 AND o.is_separate = 0 OR o.is_separate > 0);

# Time: 160303 12:12:44

# User@Host: root[root] @  [10.165.34.182]

# Query_time: 6.073441  Lock_time: 0.000152 Rows_sent: 15  Rows_examined: 24314767

SET timestamp=1456978364;

SELECT o.*, a.log_id, a.user_id as suid,  a.user_name as auser, a.money, a.point, a.separate_type,u.parent_id as up FROM `shop`.`ecs_order_info` o LEFT JOIN`shop`.`ecs_users` u ON o.user_id = u.user_id LEFT JOIN `shop`.`ecs_affiliate_log` a ON o.order_id = a.order_id WHERE o.user_id > 0 AND (u.parent_id > 0 AND o.is_separate = 0 OR o.is_separate > 0)  ORDER BY order_id DESC LIMIT 0,15;

通过慢日志发现其中有几个表查询耗时较长,下面就是把这个查询慢的表建立索引。用到的软件 NAvicat,对查询慢的表进行设计,增加索引。

 

根据 explain  的解释,查看下  索引是否建立,一般都是 这样调整 就行。

 

修改完后重启mysql 服务,查询时间从65s,缩短到 0.017407 秒

git,github,gitlab


如果初次接触git的朋友一定搞不清git,github以及gitlab这几个概念。

git如果不知道是啥,那你总知道svn是啥吧。什么?svn也不知道?那只好辛苦你动动手搜一下了。

git用一句话介绍:它是一个分布式的版本管理工具。然后我从网上找了两张图来对比svn和git的最主要的差异——分布式。

 

从上面两个图,可以看出使用svn的版本变化数据都是存在于服务端的,最终控制中心只有一个。而git,每一个客户端都可以作为一个版本管理中心,当然它也需要有一个公共的总控制点。

再给大家举一个例子吧,比如我和朋友一起开发一个软件,这个软件有很多代码片段,所以改动也比较频繁。如果使用svn,那我们无论谁每改动一段代码都要推送到svn中心去,而为了保证代码统一,其中一个人只要因为推送新的代码变动了控制中心,另一个人都要把改动的地方拉取到自己的电脑。所以这样就比较麻烦了。

而使用git时,我和朋友都可以在自己电脑上搞一个git控制中心,我们电脑里面的代码可以不一致,只需要用自己的git管理自己的那一部分代码。而git服务端只是用来合并我和朋友的最终版本代码的,平时的小改动由我们自己电脑里面的控制中心来管理,git服务端不用关心。

下面我用一个公司老总管理员工的例子再来总结一下svn和git的差异。svn架构里面的管理者比较独裁,不信任任何人,所有的事情都是亲力亲为,它宁愿管理所有员工也不设置下级管理者。

而git架构里面的老总比较明智,他比较偷懒,只管大事情,小事情都是交给下面的小leader去搞定的。每个小leader去管理自己的下属也不用关心其他leader的事情。但是所有leader都需要不定期向大boss汇报一下近期的情况。

github,是一个web界面的git管理平台,也就是说它底层的技术驱动依然是git。一句话区分,git是管理工具,github是在线的基于git的平台(或者叫做服务)。github的角色也就是我们上面例子中的大boss。github是公开的,谁都可以注册账号,并创建自己的项目,大部分项目以代码为主,比如wordpress、discuz都是托管在github里面的,当然还有好多好多开源的软件。

既然github是一个公共的,在线的提供服务的平台,那企业就可以把公司内部的代码托管在这里,为了安全我们可以选择付费服务,定制个性化方案。但毕竟github在国外,要想获得更好的功能还需要花钱,小企业或者个人用户自然是不愿意去开销了。

还好又一款开源的软件可以帮我们搭建一套类似github的平台,这就是接下来我要介绍的gitlab。 gitlab适合企业内部构建私有代码管理平台,它有健全的权限控制系统和各种强大的功能,很赞。

所以,gitlab和github一样,也是一个基于git的提供web界面的代码管理平台。

redis持久化rdb和aof


redis如果不把数据做持久化,则是把数据存储在内存里面的,所以速度很快。而持久化的目的是为了保证数据安全。redis提供了两种持久化的方案:rdb和appendonly(简称aof)。

简单讲,rdb形式就是把具体的数据(key以及value)存到到一个文件中;而aof这种是把操作过程以日志的形式存到一个文件里,类似于mysql的bin-log。

rdb,需要定义dir,也就是数据所存放的目录,其实aof文件也会放到这个目录下面,而dbfilename则定义了rdb文件的名字。配置文件中有一个参数“save”来定义redis按照什么样的规则把内存中的数据刷新到磁盘上的rdb文件里。当然我们也可以用命令“save”或者“bgsave”来手动把内存里面的数据更新到磁盘上。如果想要关闭rdb持久化,可以直接把save参数的值设置为空,即save “”,或者在redis-cli命令行里面执行:config set save “”.

aof,有一个参数是控制它的开关。“appendonly yes” 只有这个是yes时,才会在dir目录中生成一个aof文件,文件名字默认是appendonly.aof,当然我们可以用appendfilename参数去修改它。

对于aof文件,如果我们不做特殊操作,它会无限制增长,以至于把磁盘撑爆。如果业务对redis数据没有那么高的要求的话,可以不用开启aof。另外有一个方法可以实现aof文件的优化,就是执行命令 BGREWRITEAOF,这样就会重写aof文件,最终将aof文件的体积减小。这个过程可能会耗费一定的资源,建议在凌晨执行。

最后,再来总结一下。rdb并不会实时把内存数据写到磁盘中,意外断电时会丢一部分数据的,但是aof就安全得多,它几乎是实时记录日志的,通过参数appendfsync控制,默认everysec是一秒记录一次。两种持久化的方式是可以并存的,当数据恢复时,以aof优先。

CGI、FastCGI与php-fpm


这几个概念是在lamp、lnmp架构我们遇到的。好多同学对这几个概念一直不明白。下面我就简单说说我的理解。

在web开发领域中有个大概念大家必须要搞清楚,那就是静态和动态。静态就是一些诸如html、图片、js、css等请求元素,它们的特点是不需要和其他资源(比如数据库)打交道,可以直接由web server(httpd、nginx等)处理。如下图:

 

而动态则是需要和数据库等资源打交道的请求,在lamp/lnmp架构中,需要一个中间件(PHP解释器)去解析php代码,然后和mysql数据库打交道。如图:

当Web Server收到 index.php 这个请求后,会启动对应的 CGI 程序,这里就是PHP的解析器。接下来PHP解析器会解析php.ini文件,初始化执行环境,然后处理请求,再以规定CGI规定的格式返回处理后的结果,退出进程,Web server再把结果返回给浏览器。这就是一个完整的动态PHP Web访问流程,接下来再引出这些概念,就好理解多了。

我们再来解释几个概念:

CGI:是 Web Server 与 Web Application 之间数据交换的一种协议。

FastCGI:同 CGI,是一种通信协议,但比 CGI 在效率上做了一些优化。同样,SCGI 协议与 FastCGI 类似。

PHP-CGI:是 PHP (Web Application)对 Web Server 提供的 CGI 协议的接口程序。

PHP-FPM:是 PHP(Web Application)对 Web Server 提供的 FastCGI 协议的接口程序,额外还提供了相对智能一些任务管理。

WEB 中,Web Server 一般指Apache、Nginx、IIS、Lighttpd、Tomcat等服务器,Web Application 一般指PHP、Java、Asp.net等应用程序。

在这里我们还要了解另外一种方式 —— Apache的Module方式。 lamp架构中,php是以一个模块(libphp5.so)的方式被httpd调用的,这个模块是通过sapi把数据交给了php的解释器。

SAPI提供了一个和外部通信的接口,有点类似于socket,使得PHP可以和其他应用进行交互数据(apache,nginx等)。php默认提供了很多种SAPI,常见的提供给apache和nginx的php5_module、CGI、FastCGI,给IIS的ISAPI,以及Shell的CLI。

最后再来说一说,FastCGI为什么比CGI优秀。

不管是CGI还是FastCGI都是专门用来和WEB服务器打交道的,web服务器收到用户请求,就会把请求提交给cgi/fastcgi程序(如php-cgi),cgi/fastcgi程序根据请求提交的参数作应处理(解析php),然后输出标准的html语句,返回给web服服务器,WEB服务器再返回给客户端,这就是普通cgi/fastcgi的工作原理。

cgi和fastcgi不同在于,cgi需要在每一次WEB服务器把请求交给它时都需要启动一次进程,然后处理结束后还要关闭进程。这样当并发量很大时,就会造成服务器资源耗费严重。而fastcgi则为常驻进程,也就是说进程启动后会一直在线,不用频繁开启和关闭。另外fastcgi还支持分布式,也就是说可以支持在web服务器外的其他服务器上运行,通过tcp传输数据。

shell中的select用法


select也是循环的一种,它比较适合用在用户选择的情况下。
比如,我们有一个这样的需求,运行脚本后,让用户去选择数字,选择1,会运行w命令,选择2运行top命令,选择3运行free命令,选择4退出。脚本这样实现:

#!/bin/bashecho “Please chose a number, 1: run w, 2: run top, 3: run free, 4: quit”

echo

select command in w top free quit

do

case $command in

w)

w

;;

top)

top

;;

free)

free

;;

quit)

exit

;;

*)

echo “Please input a number:(1-4).”

;;

esac

done

执行结果如下:
sh select.sh
Please chose a number, 1: run w, 2: run top, 3: run free, 4: quit

1) w
2) top
3) free
4) quit
#? 1

16:06:58 up 109 days, 22:01,  1 user,  load average: 0.11, 0.05, 0.01

USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU WHAT

root     pts/0    222.128.156.84   16:05    0.00s  0.00s  0.00s w

#? 3
total       used       free     shared    buffers     cached
Mem:       1020328     943736      76592          0      86840     263624
-/+ buffers/cache:     593272     427056
Swap:      2097144      44196    2052948
#?

我们发现,select会默认把序号对应的命令列出来,每次输入一个数字,则会执行相应的命令,命令执行完后并不会退出脚本。它还会继续让我们再次输如序号。序号前面的提示符,我们也是可以修改的,利用变量PS3即可,再次修改脚本如下:

#!/bin/bash

PS3=”Please select a number: ”

echo “Please chose a number, 1: run w, 2: run top, 3: run free, 4: quit”

echo

select command in w top free quit

do

case $command in

w)

w

;;

top)

top

;;

free)

free

;;

quit)

exit

;;

*)

echo “Please input a number:(1-4).”

esac

done

如果想要脚本每次输入一个序号后就自动退出,则需要再次更改脚本如下:

#!/bin/bash

PS3=”Please select a number: ”

echo “Please chose a number, 1: run w, 2: run top, 3: run free, 4: quit”

echo

select command in w top free quit

do

case $command in

w)

w;exit

;;

top)

top;exit

;;

free)

free;exit

;;

quit)

exit

;;

*)

echo “Please input a number:(1-4).”;exit

esac

done

tomcat单机多实例


需求是: 同一个tomcat服务下,可以访问多个域名。

先来看看tomcat配置文件server.xml的结构

<Server>

<Service name=”xxx”>

<Host  name=”aaa.com” appBase=”dir1″>

</Host>

</Service>

<Server>

说明:

Service下面可以定义监听的端口,包含了<Host></Host>,而<Host></Host>里面定义虚拟主机,即,定义站点的域名和站点的目录。

 

两种方案:

1 可以在<Service></Service>里面定义多个<Host></Host>,这样就定义了多个站点,但端口不能变。

2 可以在<Server></Server>里面定义多个<Service></Service>,<Service></Service>里再定义<Host></Host>,这样做的好处是,可以更改监听端口。

 

假设需求为:

同一个服务器上跑两个站点

www.aaa.com  监听端口是8080

www.bbb.com  监听端口是8081

 

配置文件内容为:

<GlobalNamingResources>
<!– Editable user database that can also be used by
UserDatabaseRealm to authenticate users
–>
<Resource name=”UserDatabase” auth=”Container”
type=”org.apache.catalina.UserDatabase”
description=”User database that can be updated and saved”
factory=”org.apache.catalina.users.MemoryUserDatabaseFactory”
pathname=”conf/tomcat-users.xml” />
</GlobalNamingResources>

<!– A “Service” is a collection of one or more “Connectors” that share
a single “Container” Note: A “Service” is not itself a “Container”,
so you may not define subcomponents such as “Valves” at this level.
Documentation at /docs/config/service.html
–>
<Service name=”Catalina”>

<Connector port=”8080″ protocol=”HTTP/1.1″
connectionTimeout=”20000″
redirectPort=”8443″ />
<Connector port=”8009″ protocol=”AJP/1.3″ redirectPort=”8443″ />

<Engine name=”Catalina” defaultHost=”localhost”>

<Realm className=”org.apache.catalina.realm.LockOutRealm”>
<Realm className=”org.apache.catalina.realm.UserDatabaseRealm”
resourceName=”UserDatabase”/>
</Realm>

<Host name=”www.aaa.com” appBase=”webapps”
unpackWARs=”true” autoDeploy=”true”>

<Valve className=”org.apache.catalina.valves.AccessLogValve” directory=”logs”
prefix=”aaa.com_access” suffix=”.log”
pattern=”%h %l %u %t &quot;%r&quot; %s %b” />

</Host>
</Engine>
</Service>
<Service name=”aming”>

<Connector port=”8081″ protocol=”HTTP/1.1″
connectionTimeout=”20000″
redirectPort=”8443″ />

<Engine name=”aming” defaultHost=”localhost”>

<Realm className=”org.apache.catalina.realm.LockOutRealm”>
<Realm className=”org.apache.catalina.realm.UserDatabaseRealm”
resourceName=”UserDatabase”/>
</Realm>

<Host name=”www.bbb.com” appBase=”/data/tomcat”
unpackWARs=”true” autoDeploy=”true”>

<Valve className=”org.apache.catalina.valves.AccessLogValve” directory=”logs”
prefix=”bbb.com_access” suffix=”.log”
pattern=”%h %l %u %t &quot;%r&quot; %s %b” />

</Host>
</Engine>
</Service>

</Server>


nginx的alias和root的区别


假设,网站的域名为 http://abc.com/,下面分别写两个配置来说明alias和root的区别。

location /123/ {

root /data/wwwroot/abc.com;

}

location /123/ {

alias /data/dir/;

}

上面两段配置,如果访问的链接地址为 http://abc.com/123/1.jpg

第一段会访问服务器上的/data/wwwroot/abc.com/123/1.jpg

第二段配置会访问服务器上的/data/dir/1.jpg

总结一下,用root时,要加上location后面的目录/123/,用alias时,不加/123/目录。

另外还需要注意下面要求:

1) 使用alias时,后面跟的目录结尾必须要加/

2) alias只能在location中使用


httpd的三种模式比较


查看你的httpd使用了哪种模式:

/usr/local/apache2/bin/httpd -V |grep ‘Server MPM’

使用哪种模式,需要在编译的时候指定

–with-mpm=prefork|worker|event

当然也可以编译的时候,让三者都支持:

–enable-mpms-shared=all

然后在配置文件中,修改

LoadModule mpm_worker_module modules/mpd_mpm_worker.so

2.2版本默认为worker,2.4版本默认为event

再来比较一下三种模式的差异

1 prefork

prefork模式可以算是很古老但是非常稳定的Apache模式。Apache在启动之初,就预先fork一些子进程,然后等待请求进来。之所以这样做,是为了减少频繁创建和销毁进程的开销。每个子进程只有一个线程,在一个时间点内,只能处理一个请求。
优点:成熟稳定,兼容所有新老模块。同时,不需要担心线程安全的问题。(我们常用的mod_php,PHP的拓展不需要支持线程安全)
缺点:一个进程相对占用更多的系统资源,消耗更多的内存。而且,它并不擅长处理高并发请求,在这种场景下,它会将请求放进队列中,一直等到有可用进程,请求才会被处理。

2 worker

worker模式比起上一个,是使用了多进程和多线程的混合模式。它也预先fork了几个子进程(数量比较少),然后每个子进程创建一些线程,同时包括一个监听线程。每个请求过来,会被分配到1个线程来服务。线程比起进程会更轻量,因为线程通常会共享父进程的内存空间,因此,内存的占用会减少一些。在高并发的场景下,因为比起prefork有更多的可用线程,表现会更优秀一些。
有些人会觉得奇怪,那么这里为什么不完全使用多线程呢,还要引入多进程?
原因主要是需要考虑稳定性,如果一个线程异常挂了,会导致父进程连同其他正常的子线程都挂了(它们都是同一个进程下的)。为了防止这场异常场景出现,就不能全部使用线程,使用多个进程再加多线程,如果某个线程出现异常,受影响的只是Apache的一部分服务,而不是整个服务。

优点:占据更少的内存,高并发下表现更优秀。

缺点:必须考虑线程安全的问题,因为多个子线程是共享父进程的内存地址的。如果使用keep-alive的长连接方式,某个线程会一直被占据,也许中间几乎没有请求,需要一直等待到超时才会被释放。如果过多的线程,被这样占据,也会导致在高并发场景下的无服务线程可用。(该问题在prefork模式下,同样会发生)

注:keep-alive的长连接方式,是为了让下一次的socket通信复用之前创建的连接,从而,减少连接的创建和销毁的系统开销。保持连接,会让某个进程或者线程一直处于等待状态,即使没有数据过来。

3  event

这个是Apache中最新的模式,在现在版本里的已经是稳定可用的模式。它和worker模式很像,最大的区别在于,它解决了keep-alive场景下,长期被占用的线程的资源浪费问题(某些线程因为被keep-alive,空挂在哪里等待,中间几乎没有请求过来,甚至等到超时)。event MPM中,会有一个专门的线程来管理这些keep-alive类型的线程,当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放。这样增强了高并发场景下的请求处理能力。

event MPM在遇到某些不兼容的模块时,会失效,将会回退到worker模式,一个工作线程处理一个请求。官方自带的模块,全部是支持event MPM的。

注意一点,event MPM需要Linux系统(Linux 2.6+)对EPoll的支持,才能启用。

还有,需要补充的是HTTPS的连接(SSL),它的运行模式仍然是类似worker的方式,线程会被一直占用,知道连接关闭。部分比较老的资料里,说event MPM不支持SSL,那个说法是几年前的说法,现在已经支持了。