获取缓存值的问题
一般我们获取缓存值得姿势是这样的:
高并发下暴露问题
你的程序一直正常运行,直到某一日,运营的同事急匆匆的跑来找到你,你的程序挂了,可能是XXX在大量抓你的数据。我们重启了应用也没用,没几秒程序又挂了。
机智的你通过简单的排查,得出数据库顶不住访问压力,顺利的将锅甩走。 不过仔细一想,我们不是有缓存吗,怎么缓存没起作用? 查看下缓存,一切正常,也没发现什么问题啊?
进过各种debug、查日志、测试环境模拟,花了整整一下午,你终于找到罪魁祸首,原因很简单,正是我们没有使用正确的姿势使用缓存
guava是一个google发布的一个开源java工具库,其中guava cacha提供了一个轻量级的本地缓存实现机制,通过guava cache,我们可以轻松实现本地缓存。其中,guava cacha对缓存不存在或者过期情况下,获取缓存值得过程称之为Loading。
不过,这样虽然只有一个线程去执行loading动作,但是其他线程会等待loading线程接受后才能一同返回接口。此时,guava cache通过刷新策略,直接返回旧的缓存值,并生成一个线程去处理loading,处理完成后更新缓存值和过期时间。guava 称之为异步模式。
为你总结一些php系统类函数
#PHP的一些系统函数
- assert函数:检查assertion声明是否错误
- extension_loaded函数:检查PHP扩展是否加载
- get_cfg_var函数:获取PHP配置选项的值
- get_current_user函数:获取当前PHP脚本的所有者的名称
- get_defined_constants函数:返回一个包含PHP预定义常量信息的数组
- get_extension_funcs函数:返回一个包含指定模块中的所有函数名称的数组
- get_include_path函数:返回当前配置的文件包含路径的信息
- get_included_files函数:返回一个关于文件包含信息的数组
- get_loaded_extensions函数:返回一个包含所有装载模块信息的数组
- get_magic_quotes_gpc函数:获取magic_quotes_gpc的状态信息
- get_magic_quotes_runtime函数:获取magicquotes runtime的状态信息
- get_required_files函数:返回一个关于文件包含信息的数组
getenv函数:获取PHP环境变量的值
getlastmod函数:获取当前PHP页面文件的最后修改时间
- getmygid函数:获取当前PHP脚本页面所有者的GID号码
- getmyinode函数:获取当前PHP脚本页面的INODE号码
- getmypid函数:获取PHP的PID
- getmyuid函数:获取PHP脚本页面所有者的UID号码
- getopt函数:从命令行参数列表获取设置
- getrusage函数:获取当前的资源语法
- ini_get_all函数:获取所有配置选项
- ini_get函数:获取配置选项的值
- memory_get_usage函数:返回PHP脚本占用的内存空间
- php_ini_scanned_files函数:返回配置文件目录下的配置文件列表
- php_logo_guid函数:获取LOGO图片的GUID
- php_sapi_name函数:获取PHP和Web服务器之间的接口类型
- php_uname函数:获取PHP脚本运行的操作系统信息
- phpcredits函数:打印credits列表
- phpinfo函数:输出PHP的信息
- phpversion函数:获取PHP版本
- zend_logo_guid函数:获取ZEND的LOGO图片的GUID
zend_version函数:获取ZEND引擎的版本
assert_options函数:设置或者获取不同的声明标记
- ini_alter函数:设置PHP配置选项的值
- ini_restore函数:恢复配置选项的值
- ini_set函数:设置PHP配置选项的值
- putenv函数:设置环境变量
- restore_include_path函数:恢复文件包含路径配置信息
- set_include_path函数:设置文件包含路径配置选项
- set_magic_quotes_runtime函数:设置magic_quotes运行时间
- set_time_limit函数:设置最大执行时间
使用supervisor管理进程
#使用supervisor管理进程
Supervisor (http://supervisord.org) 是一个用 Python 写的进程管理工具,可以很方便的用来启动、重启、关闭进程(不仅仅是 Python 进程)。除了对单个进程的控制,还可以同时启动、关闭多个进程,比如很不幸的服务器出问题导致所有应用程序都被杀死,此时可以用 supervisor 同时启动所有应用程序而不是一个一个地敲命令启动。
安装
Supervisor 可以运行在 Linux、Mac OS X 上。如前所述,supervisor 是 Python 编写的,所以安装起来也很方便,可以直接用 pip :
sudo pip install supervisor
##supervisord配置
Supervisor 相当强大,提供了很丰富的功能,不过我们可能只需要用到其中一小部分。安装完成之后,可以编写配置文件,来满足自己的需求。为了方便,我们把配置分成两部分:supervisord(supervisor 是一个 C/S 模型的程序,这是 server 端,对应的有 client 端:supervisorctl)和应用程序(即我们要管理的程序)。
首先来看 supervisord 的配置文件。安装完 supervisor 之后,可以运行echo_supervisord_conf 命令输出默认的配置项,也可以重定向到一个配置文件里:
echo_supervisord_conf > /etc/supervisord.conf
去除里面大部分注释和“不相关”的部分,我们可以先看这些配置:
|
|
我们把上面这部分配置保存到 /etc/supervisord.conf(或其他任意有权限访问的文件),然后启动 supervisord(通过 -c 选项指定配置文件路径,如果不指定会按照这个顺序查找配置文件:$CWD/supervisord.conf, $CWD/etc/supervisord.conf, /etc/supervisord.conf):
supervisord -c /etc/supervisord.conf
查看 supervisord 是否在运行:ps aux | grep supervisord
###program 配置
上面我们已经把 supervisrod 运行起来了,现在可以添加我们要管理的进程的配置文件。可以把所有配置项都写到 supervisord.conf 文件里,但并不推荐这样做,而是通过 include 的方式把不同的程序(组)写到不同的配置文件里。
为了举例,我们新建一个目录 /etc/supervisor/ 用于存放这些配置文件,相应的,把 /etc/supervisord.conf 里 include 部分的的配置修改一下:
[include]
files = /etc/supervisor/*.conf
假设有个用 Python 和 Flask 框架编写的用户中心系统,取名 usercenter,用 gunicorn (http://gunicorn.org/) 做 web 服务器。项目代码位于 /home/leon/projects/usercenter,gunicorn 配置文件为 gunicorn.py,WSGI callable 是 wsgi.py 里的 app 属性。所以直接在命令行启动的方式可能是这样的:cd /home/leon/projects/usercenter
gunicorn -c gunicorn.py wsgi:app
现在编写一份配置文件来管理这个进程(需要注意:用 supervisord 管理时,gunicorn 的 daemon 选项需要设置为 False):
|
|
一份配置文件至少需要一个 [program:x] 部分的配置,来告诉 supervisord 需要管理那个进程。[program:x] 语法中的 x 表示 program name,会在客户端(supervisorctl 或 web 界面)显示,在 supervisorctl 中通过这个值来对程序进行 start、restart、stop 等操作。
###使用 supervisorctl
Supervisorctl 是 supervisord 的一个命令行客户端工具,启动时需要指定与 supervisord 使用同一份配置文件,否则与 supervisord 一样按照顺序查找配置文件。supervisorctl -c /etc/supervisord.conf
上面这个命令会进入 supervisorctl 的 shell 界面,然后可以执行不同的命令了:
|
|
上面这些命令都有相应的输出,除了进入 supervisorctl 的 shell 界面,也可以直接在 bash 终端运行:
|
|
###其它
除了 supervisorctl 之外,还可以配置 supervisrod 启动 web 管理界面,这个 web 后台使用 Basic Auth 的方式进行身份认证。
除了单个进程的控制,还可以配置 group,进行分组管理。
经常查看日志文件,包括 supervisord 的日志和各个 pragram 的日志文件,程序 crash 或抛出异常的信息一半会输出到 stderr,可以查看相应的日志文件来查找问题。
Supervisor 有很丰富的功能,还有其他很多项配置,可以在官方文档获取更多信息:http://supervisord.org/index.html
PHP那些鲜为人知的有用函数
levenshtein()
你有没有经历过需要知道两个单词有多大的不同的时候,这个函数就是来帮你解决这个问题的。它能比较出两个字符串的不同程度。
12345<?php$str1 = "carrot";$str2 = "carrrott";echo levenshtein($str1, $str2); //Outputs 2?>get_defined_vars()
这是一个在debug调试时非常有用的函数。这个函数返回一个多维数组,里面包含了所有定义过的变量。123<?phpprint_r(get_defined_vars());?>Source: http://php.net/manual/en/function.get-defined-vars.php
ignore_user_abort()
这个函数用来拒绝浏览器端用户终止执行脚本的请求。正常情况下客户端的退出会导致服务器端脚本停止运行。
123<?phpignore_user_abort();?>Source: http://www.php.net/manual/en/function.ignore-user-abort.php
highlight_string()
你想把PHP代码显示到页面上时,highlight_string()函数就会显得非常有用。这个函数会把你提供的PHP代码用内置的PHP语法突出显示定义的颜色高亮显示。这个函数有两个参数,第一个参数是一个字符串,表示这个字符串需要被突出显示。第二个参数如果设置成TRUE,这个函数就会把高亮后的代码当成返回值返回。
123<?phphighlight_string(' <?php phpinfo(); ?>');?>
> Source: http://php.net/manual/en/function.highlight-string.php
- highlight_file
这是一个非常有用的PHP函数,它能返回指定的PHP文件,并按照语法语义用高亮颜色突出显示文件内容。其中的突出显示的代码都是用HTML标记处理过的。
用法:
<?php
highlight_file(“php_script.php”);
?>
Source: http://www.php.net/manual/en/function.highlight-file.php
- php_strip_whitespace
这个函数也跟前面的show_source()函数相似,但它会删除文件里的注释和空格符。
用法:
<?php
echo php_strip_whitespace(“php_script.php”);
?>
Source: http://www.php.net/manual/en/function.php-strip-whitespace.php
PHP多进程实践
利用pcntl_fork实现PHP多进程代码如下:
|
|
部署脚本:
|
|
ssh服务
- 概述
SSH是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议,利用SSH协议可以有效防止远程管理过程中的信息泄露问题。SSH是Secure Shell的缩写,是建立在应用层和传输层基础上的安全协议。 - SSH服务的功能
- SSH可有效地提供防止DNS欺骗以及IP欺骗
- 压缩传输数据
- SSH提供了多种传输方式
- SSH构建Socket5代理
SSH常用配置
linux系统,SSH配置文件在 /etc/ssh/sshd_config常用配置说明:
Port 22 #SSH端口设置,这里默认使用的是22端口
Protocol 2,1 #选择SSH协议版本
ListenAddress 0.0.0.0 #监听的网卡IP
PermitRootLogin no #是否允许root登入,默认是允许的
PasswordAuthentication yes #是否开启密码验证
PermitEmptyPasswords no #是否允许密码为空
PrintMotd no #登入后是否显示一些信息,如上次登入时间及地点等。
PrintLastLog yes #显示上次登入的信息
KeepAlive yes #发送KeepAlive信息给客户端
MaxStartups 10 #允许尚未登入的联机画面数
DenyUsers #禁止用户登录,表示所有用户
AllowUsers * #允许用户登录SSH的认证方式与访问策略
- 基于口令的认证方式
ssh options username@hostnamecommand
- 基于秘钥的认证方式
ssh-keygen 生成公钥与秘钥,讲客户端公钥加入到服务端
cat id_rsa.pub >> ~/.ssh/authorized_keys
ssh 目录权限700 authorized_keys权限600 限制用户连接
可以修改ssh服务端配置文件 /etc/ssh/sshd_configDenyUsers test #禁止test用户登入
AllowUsers test #允许test用户登入
DenyGroups test #禁止test群组登入
AllowUsers test #允许test群组登入限制ip连接SSH
基于IP地址的访问策略有两种方式实现:iptables防火墙
iptables -A INPUT -p tcp –dport 22 -s 192.168.0.10/32 -j ACCEPT
iptables -A INPUT -p tcp –dport 22 -j DROPTCP Wrappers
/etc/hosts.allow
sshd:192.168.0.10/255.255.255.255/etc/hosts.deny
sshd:ALL 或 sshd:ALL EXCEPT 192.168.0.10
TCP Wrappers只支持长格式掩码,不能用192.168.0.0/24
- 基于口令的认证方式
配置ssh密钥认证自动登录
#配置ssh密钥认证自动登录
###在客户端来看,SSH提供两种级别的安全验证。
- 在本地机器创建公钥
ssh-keygen -t rsa -C 'your email@domain.com'
-t 指定密钥类型,默认即 rsa ,可以省略
-C 设置注释文字,比如你的邮箱 将公钥复制到ssh服务器
将前一步骤生成的公钥~/id_rsa.pub文件,复制到ssh服务器对应用户下的~/.ssh/authorized_keys文件,可以有多种方式,这里只介绍常用的三种。[适用于osx系统]使用ssh-copy-id-for-OSX工具将公钥复制至ssh服务器
123brew install ssh-copy-idssh-copy-id username@hostname #将username和hostname替换为你的ssh服务器用户名和IP当ssh服务器username用户目录下尚未有.ssh目录时使用此方式
cat ~/.ssh/id_rsa.pub | ssh username@hostname "mkdir ~/.ssh; cat >> ~/.ssh/authorized_keys"
- 通用方式 1234scp ~/.ssh/id_rsa.pub username@hostname:~/ #将公钥文件复制至ssh服务器ssh username@hostname #使用用户名和密码方式登录至ssh服务器mkdir .ssh #若.ssh目录已存在,可省略此步cat id_rsa.pub >> .ssh/authorized_keys #将公钥文件id_rsa.pub文件内容追加到 authorized_keys文件
快捷登录
完成以上步骤后,即可使用以下命令直接登录ssh服务器
ssh username@hostname #将username替换为你的ssh服务器用户名,hostname替换为服务器的ip
如果你本地终端使用的是zsh,那就太简单不过了,直接给zsh添加一条别名123echo "alias ssh-to-username='ssh username@hostname'" >> ~/.zshrc #将username和 hostname替换为你的服务器信息source ~/.zshrc #重新加载更改后的zshrc文件ssh-to-username #使用别名,一条命令即可登录你的ssh服务器
Mac下使用launchctl创建定时任务
#Mac下添加定时任务
编写任务脚本
把要执行的任务写好
编写任务描述文件
mac的任务描述文件是plist格式的。结构如下:
|
|
两种指定要执行命令的方法:
使用Program和ProgramArguments
Program, 运行命令或要执行文件路径
ProgramArguments, 执行时传入参数只使用ProgramArguments
此时,ProgramArguments的每个参数为要执行的命令或文件路径,其它参数为传入参数
两种设置执行时间的方法:
StartCalendarInterval
使用元素Minute, Hour, Day, Month, Weekday两指定执行时间,如:1234567<key>StartCalendarInterval</key><dict><key>Minute</key><integer>30</integer><key>Hour</key><integer>9</integer></dict>每天的9:30执行
StartInterval
设置执行的时间间隔,单位为秒12<key>StartInterval</key><integer>3600</integer>每小时执行一次
使用launchctl加载plist
任务描述文件写好后,怎么使用它呢?可以使用launchctl工具,添加任务到launchd。
系统定义了几个位置来存放任务列表
~/Library/LaunchAgents 由用户自己定义的任务项
/Library/LaunchAgents 由管理员为用户定义的任务项
/Library/LaunchDaemons 由管理员定义的守护进程任务项
/System/Library/LaunchAgents 由Mac OS X为用户定义的任务项
/System/Library/LaunchDaemons 由Mac OS X定义的守护进程任务项
为用户定义的任务项,只以用户登陆后才会执行,守护进程任务项无论用户是否登陆都会执行
根据添加的任务类型,把它拷贝到相应的目录,通过launchctl来加载:
建议添加到~/Library/LaunchAgents
添加 launchctl load ~/Library/LaunchAgents/com.test.plist
移除 launchctl unload ~/Library/LaunchAgents/com.test.plist
查看 launchctl list
最后这些如果你觉得麻烦,下面推荐你一款好用的工具“launchcontrol”
可以新增编辑任务,右边各种选项很方便。
INNODB关键特性
INNODB关键特性
INNODB关键特性包括如下:
- 插入缓冲(insert buff)
- 两次写(double write)
- 自适应哈希索引(Adaptive Hash Index)
- 异步IO(Async IO)
- 刷新邻接页(Flush Neighbor Page)
插入缓冲
插入缓冲带来了性能上的提升
两次写
带给innodb数据页的可靠性