月度归档:2017年06月

mysql 主从报错

mysql从机宕机bin日志报错解决办法

show slave status\G
提示错误:Relay log read failure: Could not parse relay log event entry
查看状态
Exec_Master_Log_Pos =
操作
mysql>stop slave;
mysql>change master to Master_Log_File=’mysql-bin.005121′, Master_Log_Pos=4;
mysql>start slave;
更新master的 当前要执行的日志位置,Master_Log_Pos 的值为 Exec_Master_Log_Pos 的值。

 

Linux Logrotate 配置使用

Logrotate 会自动对日志进行截断(或轮循)、压缩以及删除旧的日志文件。解决日志不断增大,备份,处理难的问题。

日志配置

/var/log/log-file {
monthly
rotate 5
compress
delaycompress
missingok
notifempty
create 644 root root
postrotate
/usr/bin/killall -HUP rsyslogd
endscript
}

monthly: 日志文件将按月轮循。其它可用值为‘daily’,‘weekly’或者‘yearly’。
rotate 5: 一次将存储5个归档日志。对于第六个归档,时间最久的归档将被删除。
compress: 在轮循任务完成后,已轮循的归档将使用gzip进行压缩。
delaycompress: 总是与compress选项一起用,delaycompress选项指示logrotate不要将最近的归档压缩,压缩将在下一次轮循周期进行。这在你或任何软件仍然需要读取最新归档时很有用。
missingok: 在日志轮循期间,任何错误将被忽略,例如“文件无法找到”之类的错误。
notifempty: 如果日志文件为空,轮循不会进行。
create 644 root root: 以指定的权限创建全新的日志文件,同时logrotate也会重命名原始日志文件。
postrotate/endscript: 在所有其它指令完成后,postrotate和endscript里面指定的命令将被执行。在这种情况下,rsyslogd 进程将立即再次读取其配置并继续运行。

 

compress 启用压缩,指的是轮替后的旧日志,这里默认用的是gzip压缩的
compressoptions 以gzip -9的模式压缩
uncompresscmd 解压日志,默认是gunzip
daily 每天轮替选项
dateext 轮替的日志文件会附加上一个短横线和YYYYMMDD格式的时间戳
delaycompress 将以前的日志文件压缩推迟到下一次轮替
ifempty 即使日志文件是空的也轮替
mail 将轮替后的文件发送到指定E-mail地址
copytruncate 用于还在打开中的日志文件,把当前日志备份并截断,开始轮替
mailfirst/maillast 向邮件发送轮替文件/轮替后历史文件(默认)
monthly 一个月轮替一次
nocompress 如果在logrotate.conf中启用了压缩,这里是做不用压缩的参数
nomail 不发送邮件到任何地址
ifempty 如果日志时空的就不轮替
olddir directory 轮替后日志文件放入指定的目录,必须和当前日志文件在同一个文件系统
postrotate/endscript 在做完轮替后的命令,两个关键字必须单独成行,使用的操作在2者之间相当于分组“{}”,注意的使用外部指令时要用绝对路径
prerotate/endscript 在做轮替前的命令,同上
rotate count 轮替最多保留之前的数据几次,超出的将被删除或邮件接收,设为0则不保存
size size 当日志增长到指定大小的时候开始轮替,它不会考虑
start count 轮替文件名基于这个数字。
例如,指定0时,原日志文件轮替的备份文件以.0为扩展名,如果指定9,就直接从.9开始跳过0-8
然后再继续向后轮替rotate指定的次数。
weekly 如果当前的星期几比上次轮替的星期几少,或者过了一个多星期,就会发生轮替通常是在每周的第一天轮替,如果logrotate不是每天运行的,会在第一次有机会时进行轮替。
yearly 如果当前年份不同于上次轮替的年份,则进行日志轮替
create mode owner group 在轮替动作之后,postrotate脚本执行之前,立即使用刚轮替的日志文件名创建日志文件。
MODE 指定日志文件的权限(0660之类)
OWNER 指定日志文件的属主
GROUP 指定日志文件的属组
extension ext 日志文件可在轮替后使用指定的EXT扩展名。如果使用压缩,通常EXT后还会加上压缩文件的扩展名,通常是.gz。例如想把mylog.foo轮转为mylog.1.foo.gz而不是mylog.foo.1.gz

依据日志文件大小来轮循日志
/var/log/log-file {
size 50M
rotate 5
create 644 root root
postrotate
/usr/bin/killall -HUP rsyslogd
endscript
}
日志文件名中包含日期信息
/var/log/log-file {
monthly
rotate 5
dateext
create 644 root root
postrotate
/usr/bin/killall -HUP rsyslogd
endscript
}

运行

全部运行
logrotate /etc/logrotate.conf
指定配置运行
logrotate /etc/logrotate.d/log-file
测试
logrotate -d /etc/logrotate.d/log-file
强制轮循
logrotate -vf /etc/logrotate.d/log-file
logrotate运行日志
日志通常存放于/var/lib/logrotate/status
也可以指定
logrotate -vf –s /var/log/logrotate-status /etc/logrotate.d/log-file
定时任务
默认在 /etc/cron.daily/logrotate
可查看脚本具体情况

常用密码检验正则

/^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,10}$/

^ 匹配一行的开头位置
(?![0-9]+$) 预测该位置后面不全是数字
(?![a-zA-Z]+$) 预测该位置后面不全是字母
[0-9A-Za-z] {6,10} 由6-10位数字或这字母组成
$ 匹配行结尾位置
密码至少包含数字、大字母、小写字母、符号至少两种,6-16位长度
^(?![A-Z]+$)(?![a-z]+$)(?!\d+$)(?![\W_]+$)\S{6,16}$

(?![A-Z]+$) 非全大写
(?![a-z]+$) 非全小写
(?!\d+$) 非全数字
(?![\W_]+$) 非全特殊字符
\S{6,16} 非空格的6-16位字符

(?!正则)负向向前查找 :扫描匹配的内容是否符合正则,(取反)
^((?=.*[0-9].*)(?=.*[A-Za-z].*)(?=.*_.*))[_0-9A-Za-z]{6,16}$

(?=.*[0-9].*) 检测匹配内容 任意字符+数字+任意字符
(?=.*[A-Za-z].*)检测匹配内容 任意字符+大小写字母+任意字符
(?=.*_.*) 检测匹配内容 任意字符+下划线+任意字符
[_0-9A-Za-z]{6,10} 包含数字、字母及下划线 6-10位

(?=正则)正向向前查找 : 扫描匹配的内容是否符合正则

^(?:(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])).{6,12}$
密码是否含有小写字母、大写字母、数字….,且密码长度为6-12位

WordPress 使用SMTP

wordpress 发邮件默认使用系统的mail,mail发送的邮件经常被直接放垃圾箱或直接屏敝掉,使用SMTP是另一种简单的选择。

配置

在主题的function.php中加入


add_action('phpmailer_init','mail_init');
function mail_init(&$mail){
	$mail->isSMTP();
	$mail->Host = 'smtp.163.com';
	//$mail->SMTPDebug = 4;
	$mail->SMTPAuth = true;
	$mail->From = 'test@163.com';
	$mail->Username = 'test@163.com';
	$mail->Password = 'password';
}

 

WordPress rewrite

Apache

.htaccess


# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

Nginx


location / {
        try_files $uri $uri/ /index.php?$args;
}

# Add trailing slash to */wp-admin requests.
rewrite /wp-admin$ $scheme://$host$uri/ permanent;

 

php facst-cgi 502 bad gate way

当nginx + PHP 使用 unix socket 配置时

location ~ [^/]\.php(/|$)
{
try_files $uri =404;
fastcgi_pass unix:/tmp/php-cgi.sock;
fastcgi_index index.php;
include fastcgi.conf;
}
nginx 必须要有 /tmp/php-cgi.sock 套接字文件有读写权限,不然会报 502 bad gateway 的错误。

一般php-fpm的用户与nginx为同一用户,这样可减少权限的问题。

slf4j与common-logging

相通点:

  • 两者都为通用日志接口

异同:

  • slf4j 静态绑定日志(编译时绑定)
  • jcl 动态绑定(动态绑定跟类加载器有关,会有一定的问题)

slf4j 解决 jcl 以下两点问题

解决加载问题

Commons Logging存在的ClassLoader问题,即当服务器本身引入Commons Logging时,如果在服务器中载入Commons Logging包,则该包中的类由服务器的ClassLoader加载,从而在加载Log4J中的Logger类时会出现ClassNotFoundException,因为服务器中的ClassLoader没法找到Web App下的jar包。对于父ClassLoader优先的类加载机制来说,目前的一个解决方案是使用commons-logging-api-1.1.1.jar包,该包的Log实现类只包含Jdk14Logger、SimpleLog、NoOpLog三个类,因而在加载这几个类时会使用Web App中的Commons Logging包,从而解决ClassNotFoundException的问题,然而这种方式对那些实现Child ClassLoader First的服务器来说,由WebClassLoader父ClassLoader加载的类在使用日志时会存在问题,因为它们的Log接口由加载自身类的ClassLoader加载,而Log4JLogger类却由WebClassLoader加载。

性能优一些

在使用Commons Logging时,我们经常会看到以下方法的写法:
if (logger.isDebugEnabled()) {
logger.info(“Loading XML bean definitions from ” + encodedResource.getResource());
}

存在isDebugEnabled()的判断逻辑是为了在避免多余的字符串拼接,即如果不存在isDebugEnabled()判断,即使当前日志级别为ERROR时,在遇到logger.info()调用时,它还会先拼接日志消息的字符串,然后进入该方法内,才发现这个日志语句不用打印。而这种多余的拼接不仅浪费了多余的CPU操作,而且会增加GC的负担。SLF4J则提供以下的方式来解决这个问题:

logger.info(“Loading XML bean definitions from {}”, encodedResource.getResource());

Java环境变量

主要配置

  • 配置JAVA_HOME
  • 配置PATH
  • 配置CLASS_PATH

如:

在/etc/profile下增加或在~/.bash_profile下增加
export JAVA_HOME=/usr/share/jdk1.6.0_14
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

jstl 中 c:set 的 scope 作用域要注意的问题

在jstl使用c:set 时,去设置一个变量,需要注意 变量的 scope 问题。设置一个值的行为,相当于,变量已经存在,则更新变量的值,不存在则建增值。

在项目中遇到这样的情况,已经设置了一个session级别的变量a(scope=session),当前页需要新建一个变量,恰好名称也为a。

<c:set var=”a” value=”b”/>

c:set 会首先查找变显是否存在,当未指定 scope 的情况下,查找的顺序为:page->request->session->application,一直往上找,直到找到为止。项目中遇到恰好在session级时找到同名变量存在,c:set 就会把session级的变量 更新了,但实际项目是在当前页创建一个变,在这情况下,就会产生意想不到的问题。

所以使用c:set的话,最好明确指定scope 避免不必要的错误。