分类:未分类
iptables,netfilter,firewalld关系
在centos6上,我们用的是iptables服务,而在centos7上,我们用的是firewalld服务。同样的,centos6上安装的是iptables包,而centos7上安装的是firewalld包。
不管是centos6还是centos7,核心其实都是netfilter,netfilter是linux的一个内核模块,iptables命令是linux内核自带的。
centos6上的iptables服务和centos7上的firewalld服务,其实都是用来定义防火墙规则功能的防火墙管理工具。它们都是将定义好的规则交由内核中的netfilter即网络过滤器来读取,从而真正实现防火墙功能,所以其实在配置规则的思路上是完全一致的。
MySQL延迟主从复制
世界上没有卖后悔药的,一旦做错了,后悔莫及。我们作为运维,尤其是不小心误删除数据库里的数据时,那更是损失巨大。对于MySQL来说,这里有一种方法,可以避免这种悲剧的发生。
这儿所谓的延迟,并不是经常说的网络延迟,而是我们故意把从库复制的步伐放慢,比如让从库比主库慢30分钟。这样,如果在半小时内发现数据有问题,还能补救。
MySQL 5.6 已经支持延迟复制, 可设置备节点的延迟时间, 延迟复制是有意义的,例如防止主节点数据误删,查看数据库历史状态等。
配置也不难,做完主从后,再加上这句:
CHANGE MASTER TO MASTER_DELAY = N;
这里的N单位是秒,这样从库则会比主库延时N秒。做完之后,在show slave status的时候,就可以看到SQL_Delay的值。
SQL_Delay: xxx
正则表达式非贪婪匹配
我们学习正则时,用到过贪婪匹配.*
其实,还有一个相对的概念,叫做非贪婪匹配。
如:str=”abcaxc”
p=”a.*c”
贪婪匹配:正则表达式一般趋向于最大长度匹配,也就是所谓的贪婪匹配。如上面使用模式p匹配字符串str,结果就是匹配到:abcaxc。
非贪婪匹配:就是匹配到结果就好,最少的匹配字符。如上面使用模式p匹配字符串str,结果就是匹配到:abc(a.*c)。
shell中如何区分两种模式?
默认是贪婪模式;
在量词后面直接加上一个问号?就是非贪婪模式。
常用的量词有:
{m,n}: m到n个
*: 任意多个
+: 一个到多个
?: 0或一个
示例:
str=”123abc0axc456″
echo $str|grep ‘a.*c’
结果: 123abc0axc456
echo $str|grep -P ‘a.*?c’
结果: 123abc0axc456
elastic stack 使用redis作为日志缓冲
直接上步骤:
1、首先建立一个配置文件,将output的数据写到redis中,而不是ES了。配置文件示例:
input { stdin { } } output { redis { host => "192.168.1.100" #redis服务器地址 port => "6379" #redis服务端口 db => "5" #使用redis第五个库,用其他库也可以 data_type => "list" #用list类型 key => "demo" #存储的key名,可自定义自己喜欢的 } }
2、指定配置文件然后运行Logstash,然后我们在标准输入中随便写点什么东西,这个时候输入的数据都会提交到redis中。登录redis后使用info命令可以查看keyspace相关信息,可以看到db5的keys数量有了变化,我们切换到db5再来看看
select 5 keys *
3、通过keys *命令可以看到有了一个key叫做demo,这个就是配置文件里设置的key名,使用LLEN demo可以看到该key的长度,input如果输入了100行,那么这个key就应该有100行
4、再次建立一个配置文件,这次input是从第一步里的redis里读取数据,然后output到ES中
input { redis { host => "192.168.1.100" port => "6379" db => "5" data_type => "list" key => "demo" } } output { elasticsearch { hosts => ["192.168.0.100:9200"] index => "redis-demo-%{+YYYY.MM.dd}" } }
5、运行该配置文件后去redis看看,之前的队列因为被output到了ES中,所以队列会消失掉或者是迅速减少长度
下面是一个改造后的配置文件,更符合实际需求
input { file { path => "/var/log/messages" type => "system" } output { if [type] == "system" { redis { host => "192.168.1.100" port => "6379" db => "5" data_type => "list" key => "system" } }
linux shell命名管道FIFO
在shell脚本中,我们想要实现多进程高并发,最简单的方法是把命令丢到后台去,如果量不大的话,没问题。 但是如果有几百个进程同一时间丢到后台去就很恐怖了,对于服务器资源的消耗非常大,甚至导致宕机。
那有没有好的解决方案呢? 当然有!
我们先来学习下面的常识。
1 文件描述符
文件描述符(缩写fd)在形式上是一个非负整数。实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。每一个unix进程,都会拥有三个标准的文件描述符,来对应三种不同的流:
除了上面三个标准的描述符外,我们还可以在进程中去自定义其他的数字作为文件描述符,后面例子中会出现自定义数字。每一个文件描述符会对应一个打开文件,同时,不同的文件描述符也可以对应同一个打开文件;同一个文件可以被不同的进程打开,也可以被同一个进程多次打开。
我们可以写一个测试脚本/tmp/test.sh,内容如下:
#!/bin/bash
echo “该进程的pid为$$”
exec 1>/tmp/test.log 2>&1
ls -l /proc/$$/fd/
执行该脚本 sh /tmp/test.sh,然后查看/tmp/test.log内容为:
总用量 0
lrwx—— 1 root root 64 11月 22 10:26 0 -> /dev/pts/3
l-wx—— 1 root root 64 11月 22 10:26 1 -> /tmp/test.log
l-wx—— 1 root root 64 11月 22 10:26 2 -> /tmp/test.log
lr-x—— 1 root root 64 11月 22 10:26 255 -> /tmp/test.sh
lrwx—— 1 root root 64 11月 22 10:26 3 -> socket:[196912101]
其中0为标准输入,也就是当前终端pts/3,1和2全部指向到了/tmp/test.log,另外两个数字,咱们暂时不关注。
2 命名管道
我们之前接触过的管道“1”,其实叫做匿名管道,它左边的输出作为右边命令的输入。这个匿名管道只能为两边的命令提供服务,它是无法让其他进程连接的。
实际上,这两个进程(cat和less)并不知道管道的存在,它们只是从标准文件描述符中读取数据和写入数据。
另外一种管道叫做命名管道,英文(First In First Out,简称FIFO)。
FIFO本质上和匿名管道的功能一样,只不过它有一些特点:
1)在文件系统中,FIFO拥有名称,并且是以设备特俗文件的形式存在的;
2)任何进程都可以通过FIFO共享数据;
3)除非FIFO两端同时有读与写的进程,否则FIFO的数据流通将会阻塞;
4)匿名管道是由shell自动创建的,存在于内核中;而FIFO则是由程序创建的(比如mkfifo命令),存在于文件系统中;
5)匿名管道是单向的字节流,而FIFO则是双向的字节流;
有了上面的基础知识储备后,下面我们来用FIFO来实现shell的多进程并发控制。
需求背景:
领导要求小明备份数据库服务器里面的100个库(数据量在几十到几百G),需要以最快的时间完成(5小时内),并且不能影响服务器性能。
需求分析:
由于数据量比较大,单个库备份时间少则10几分钟,多则几个小时,我们算平均每个库30分钟,若一个库一个库的去备份,则需要3000分钟,相当于50个小时。很明显不可取。但全部丢到后台去备份,100个并发,数据库服务器也无法承受。所以,需要写一个脚本,能够控制并发数就可以实现了。
控制并发的shell脚本示例:
#!/bin/sh function a_sub { sleep 2; endtime=`date +%s` sumtime=$[$endtime-$starttime] echo "我是$i,运行了2秒,整个脚本已经执行了$sumtime秒" } starttime=`date +%s` export starttime ##其中$$为该进程的pid tmp_fifofile="/tmp/$$.fifo" ##创建命名管道 mkfifo $tmp_fifofile ##把文件描述符6和FIFO进行绑定 exec 6<>$tmp_fifofile ##绑定后,该文件就可以删除了 rm -f $tmp_fifofile ##并发量为8,用这个数字来控制并发数 thread=8 for ((i=0;i<$thread;i++)); do ##写一个空行到管道里,因为管道文件的读取以行为单位 echo >&6 done ##循环100次,相当于要备份100个库 for ((i=0;i<100;i++)) do ##读取管道中的一行,每次读取后,管道都会少一行 read -u6 { a_sub || {echo "a_sub is failed"} ##每次执行完a_sub函数后,再增加一个空行,这样下面的进程才可以继续执行 echo >&6 } & ##这里要放入后台去,否则并发实现不了 done ##这里的wait意思是,需要等待以上所有操作(包括后台的进程)都结束后,再往下执行。 wait ##关闭文件描述符6的写 exec 6>&-
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界面的代码管理平台。
这个命令你看得懂么
2018年1月11日
未分类
No Comments
aming
直接上命令
对于read命令的了解,仅限于在shell脚本中使用read -p,对于这种用法从来没用过,更不知道它的含义。
今天抽空琢磨了一下,终于搞明白了来龙去脉。先来写几个命令吧:
到这,也许你似乎看出一些门道了。read命令,后面跟的是变量名,可以是1个,也可以是多个,用空格分隔。回车后,输入的字符就是在给这些变量赋值,输入的字符串也需要用空格分隔,如果和上面的变量名一个一个地对应,那么这样就一个一个地赋值了。
如果没有对应呢?通过上面的命令也可以发现,如果值比变量多,它只对应前面的。例如,变量只有x和y,而值是1 2 3,则它把x赋值1,后面的2 3一股脑赋值给最后面的变量y。
再来一个例子吧。
再回头看这条命令:
管道前面,history 1表示取最后一条命令。管道后面'{ }’内是一整体,相当于一个函数,函数里面可以有多条命令,用分号分割,而且最后一条命令也必须加分号。第一条命令和'{‘之间必须要有空格。