2018-01-22
在做性能测试时,无意中发现一个事情:在一个图片资源已经本地缓存到浏览器并且未过期的情况下,刷新网页和再次请求返回的状态不一致。
以资源ETag=W/“PSA-aj-5xx_WUsSsC"为例:
再次请求:
repsonse=200,直接从从本地缓存中取资源。
Request URL:http://guoj.top/wp-content/uploads/2018/01/QQ%E6%88%AA%E5%9B%BE20180115140217.png
Request Method:GET
Status Code:200 OK (from cache)
Remote Address:47.93.55.78:80
Response Headers
HTTP/1.1 200 OK
Server: nginx/1.13.7
Content-Type: image/png
Content-Length: 8487
Connection: keep-alive
Accept-Ranges: bytes
X-Original-Content-Length: 24343
ETag: W/"PSA-aj-5xx_WUsSsC"
Date: Tue, 16 Jan 2018 08:32:27 GMT
Expires: Wed, 14 Feb 2018 05:59:18 GMT
Cache-Control: max-age=2496410
Request Headers
GET /wp-content/uploads/2018/01/QQ%E6%88%AA%E5%9B%BE20180115140217.png HTTP/1.1
Host: guoj.top
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.104 Safari/537.36 Core/1.53.4295.400 QQBrowser/9.7.12661.400
Accept: image/webp,image/*,*/*;q=0.8
Referer: http://guoj.top/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8
Cookie: Hm_lvt_624adbfe276a5668e7b4779815c5ff38=1513561518; Hm_lvt_7e91fd8ec5e72f05612cc7e567977104=1513561518; wordpress_test_cookie=WP+Cookie+check; wordpress_logged_in_50ac8821fe935de01bdede6b95928a78=dong4stop%7C1516241303%7CRg3hAvZn7NOjg2mST5JurlQ55m4pDmbTzuiMGDygRfn%7Ccb8c3ee4f27ffba3171f763e4df91e2bb1514bfb5167a8af59a20cbc2dac74ec; wp-settings-1=editor%3Dtinymce%26libraryContent%3Dbrowse%26mfold%3Do%26editor_expand%3Don%26hidetb%3D1%26post_dfw%3Doff%26widgets_access%3Doff%26advImgDetails%3Dshow; wp-settings-time-1=1516087140; _GPSLSC=qEFEXaHVp1!Yd4ct0hstK!DAGQ2tgLU_
刷新网页
不同浏览器的效果不一样,又或者做了特别的设置造成。chrome会返回200(From Cache)。qqbrowser会返回304(Not Modified)。
这是因为qqbrowser刷新网页时在Request Header中加入了:
Cache-Control:max-age=0
If-None-Match:W/“PSA-aj-5xx_WUsSsC”;
Request URL:http://guoj.top/wp-content/uploads/2018/01/QQ%E6%88%AA%E5%9B%BE20180115140217.png
Request Method:GET
Status Code:304 Not Modified
Remote Address:47.93.55.78:80
Response Headers
HTTP/1.1 304 Not Modified
Server: nginx/1.13.7
Date: Tue, 16 Jan 2018 08:36:10 GMT
Connection: keep-alive
Request Headers
Accept:image/webp,image/*,*/*;q=0.8
Accept-Encoding:gzip, deflate, sdch
Accept-Language:zh-CN,zh;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
Cookie:Hm_lvt_624adbfe276a5668e7b4779815c5ff38=1513561518; Hm_lvt_7e91fd8ec5e72f05612cc7e567977104=1513561518; wordpress_test_cookie=WP+Cookie+check; wordpress_logged_in_50ac8821fe935de01bdede6b95928a78=dong4stop%7C1516241303%7CRg3hAvZn7NOjg2mST5JurlQ55m4pDmbTzuiMGDygRfn%7Ccb8c3ee4f27ffba3171f763e4df91e2bb1514bfb5167a8af59a20cbc2dac74ec; wp-settings-1=editor%3Dtinymce%26libraryContent%3Dbrowse%26mfold%3Do%26editor_expand%3Don%26hidetb%3D1%26post_dfw%3Doff%26widgets_access%3Doff%26advImgDetails%3Dshow; wp-settings-time-1=1516087140; _GPSLSC=qEFEXaHVp1!Yd4ct0hstK!DAGQ2tgLU_
Host:guoj.top
If-None-Match:W/"PSA-aj-5xx_WUsSsC"
Referer:http://guoj.top/
User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.104 Safari/537.36 Core/1.53.4295.400 QQBrowser/9.7.12661.400
2018-01-18
Ansible 是一个基于 Python 的自动化运维的工具,无需安装服务端和客户端,只需要有ssh即可,而且使用简单。同类的产品Puppet、Chef、SaltStack都是基于服务端+客户端的模式。
官方称之为 “Ansible is Simple IT Automation”。
官网 github
安装
sudo apt-get install software-properties-common
sudo apt-add-repository ppa:ansible/ansible
sudo apt-get update
sudo apt-get install ansible
命令应用基础
ansible [-f forks] [-m module_name] [-a args]
-f forks:启动的并发线程数
-m module_name: 要使用的模块
-a args: 模块特有的参数
ansible-doc -l 查看所有模块
ansible-doc -s MODULE_NAME 查看指定模块的详细帮助
查看全部模块文档
使用lineinfile模块向/tmp/test写入一行helloworld
ansible 127.0.0.1 -m lineinfile -a "dest=/tmp/test line='helloworld'"
使用git模块拉取资源到/tmp/ansible目录
ansible 127.0.0.1 -m git -a "repo='https://github.com/ansible/ansible.git' dest='/tmp/ansible'
playbook
playbook是ansible中批量执行命令的文件,基于yaml格式,类似于chef中的cookbook。
标准的playbook如下:
- hosts : webservers
vars :
http_port : 80
max_clients : 200
remote_user : root
tasks :
- name : ensure apache is at the latest version
yum : pkg=httpd state=latest
- name : write the apache config file
template : src=/srv/httpd.j2 dest=/etc/httpd.conf
notify :
- restart apache
- name : ensure apache is running
service : name=httpd state=started
handlers :
- name : restart apache
service : name=httpd state=restarted
ansible-playbook deploy.yml --check
ansible-playbook playbook.yml -f 10
2018-01-16
官方文档
性能测试
http{
# 启用ngx_pagespeed
pagespeed on ;
pagespeed Statistics on ;
pagespeed StatisticsLogging on ;
pagespeed LogDir /var/log/pagespeed ;
pagespeed FileCachePath /tmp/cache/ngx_pagespeed_cache ;
# 隐藏pagespeed版本信息
pagespeed XHeaderValue "Powered By ngx_pagespeed" ;
# google字体直接写入html 目的是减少浏览器请求和DNS查询
pagespeed EnableFilters inline_google_font_css ;
pagespeed RewriteLevel PassThrough ;
# 改善资源的可缓存性
pagespeed EnableFilters extend_cache ;
# 预解析DNS查询
pagespeed EnableFilters insert_dns_prefetch ;
pagespeed EnableFilters local_storage_cache ;
# 删除无用的url前缀
pagespeed EnableFilters trim_urls ;
# 合并head
pagespeed EnableFilters combine_heads ;
# 移除多余html标签
pagespeed EnableFilters elide_attributes ;
# 移除html空白
pagespeed EnableFilters collapse_whitespace ;
# 移除html注释
pagespeed EnableFilters remove_comments ;
# 移除html属性中的不必要的引号
pagespeed EnableFilters remove_quotes ;
# css
# 合并css
pagespeed EnableFilters combine_css ;
# 压缩css
pagespeed EnableFilters rewrite_css ;
# 将css内容移动到script之前,优先于script渲染
pagespeed EnableFilters move_css_above_scripts ;
pagespeed EnableFilters move_css_to_head ;
# 重写CSS,首先加载渲染页面的CSS规则
pagespeed EnableFilters prioritize_critical_css ;
pagespeed EnableFilters flatten_css_imports ;
pagespeed CssFlattenMaxBytes 5120 ;
# js
# 合并js
pagespeed EnableFilters combine_javascript ;
# 压缩js
pagespeed EnableFilters rewrite_javascript ;
pagespeed EnableFilters defer_javascript ;
# 将小的js文件已内联方式引入,避免http请求
pagespeed EnableFilters inline_javascript ;
# image
# 延时加载客户端看不见的图片
pagespeed EnableFilters lazyload_images ;
# 压缩图片
pagespeed EnableFilters rewrite_images ;
# 将小图片的http调用转成内联方式调用
pagespeed EnableFilters inline_images ;
pagespeed EnableFilters inline_preview_images ;
# 自动将多张背景图片合并成一张图片。
pagespeed EnableFilters sprite_images ;
pagespeed EnableFilters dedup_inlined_images ;
pagespeed EnableFilters responsive_images_zoom ;
# 移动端图片自适应重置
pagespeed EnableFilters resize_mobile_images ;
include /etc/nginx/conf.d/*.conf ;
include /etc/nginx/sites-enabled/* ;
}
2018-01-15
Linux-PAM工程的目的就是分离应用软件和验证机制的开发。通过验证函数库可以实现上述目的,一个应用程序可以使用这些函数库去进行用户的认证。
模块pam_*.so以动态可加载目标文件(使用dloptn(3)函数打开)的形式保存在 /lib/security、 /lib64/security、/lib/x86_64-linux-gnu/security/等。
配置文件:
/etc/pam.conf
/etc/pam.d/
/etc/security/*(其他PAM环境的配置文件)。
以/etc/pam.d/sudo配置为例:
[table id=3 /]
验证类型
控制标记
模块路径
模块参数
session
required
pam_env.so
readenv=1 envfile=/etc/default/locale user_readenv=0
验证类型
名称
说明
aut
用于检查用户和密码,并分配权限。
account
负责账户合法性检查,确认帐号是否过期,是否有权限登录系统等;
password
修改密码需要用到的。如果用户不修改密码,几乎用不到这个模块。
session
提供对会话的管理,限定会话限制的。比如:vsftpd下午6点不允许访问,那6点过后用户再去访问的话就会被限制,或内存不足不允许访问等。
控制标记
控制
说明
requuisite
与required类似,该模块必须返回成功才能通过认证。一旦失败就不再执行堆中后面的其他模块,并且鉴别过程到此结束,同时也会立即返回错误信息。
required
通过鉴别的必要条件。换句话说,只有当对应于应用程序的所有带 required标记的模块全部成功后,该程序才能通过鉴别。同时,如果任何带required标记的模块出现了错误,PAM并不立刻将错误消息返回给应用程序,而是在所有模块都调用完毕后才将错误消息返回调用他的程序。 反正说白了,就是必须将所有的模块都执行一次,其中任何一个模块验证出错,验证都会继续进行,并在执行完成之后才返回错误信息。这样做的目的就是不让用户知道自己被哪个模块拒绝,通过一种隐蔽的方式来保护系统服务。
sufficient
如果本条目的条件被满足,且本条目之前没有任何required条目失败,则立即返回“认证成功”信号;如果对本条目的验证失败,不对结果造成影响。
sufficient
表明本模块返回成功已经足以通过身份认证的要求,不必再执行同一stack内的其它模块,但是如果本模块返回失败的话可以忽略。可以认为是一个充分条件。
optional
表明本模块是可选的,它的成功与否一般不会对身份认证起关键作用,其返回值一般被忽略。即便该行所涉及的模块验证失败用户仍能通过认证。在PAM体系中,带有该标记的模块失败后将继续处理下一模块。也就是说即使本行指定的模块验证失败,也允许用户享受应用程序提供的服务。使用该标志,PAM框架会忽略这个模块产生的验证错误,继续顺序执行下一个层叠模块。
substack
运行其他配置文件中的流程,并将整个运行结果作为该行的结果进行输出。该模式和 include的不同点在于认证结果的作用域:如果某个流程栈include了一个带requisite的栈,这个requisite
include
在验证过程中调用其他的PAM配置文件。
模块路径
名称
说明
pam_unix.so
传统意义上的帐号和密码认证机制,这个机制实现了标准C库中基于让用户输入帐号密码并完成检测的认证过程。
pam_permit.so
直接通过,允许访问,定义默认策略。
pam_deny.so
拒绝访问,定义默认策略。
pam_cracklib.so
用来检验密码的强度,包括设定的密码是否在字典中,修改的密码是否能和上次一样,密码至少包含多 少个数字字符,可以输入多少次错误密码等,都是由这个模块定义的。
pam_shells.so
检查用户登录的shell是否是安全shell,也就是写在 /etc/shells中的shell
pam_securetty.so
限定管理员只能通过安全的tty登录,/etc/securetty,tty就是传统终端
pam_rootok.so
管理员su到其他用户不用输入密码就是靠这个定义的。
pam_nologin.so
可以限制一般用户是否能够登入主机,当/etc/nologin这个档案存在时,则所有一般使用者均无法再登入系统。
pam_limits.so
资源限定打开文件数,使用进程数等等,对任何人都生效,/etc/security/limits或/etc/security/limits.d/*。
2018-01-05
本地、测试、生产环境的不同,可能需要不同的配置文件。为了避免每次推送版本都修改配置文件,可以事先将配置文件放置在服务器端,推送完版本后通过软链接指向即可。
通过linked_files、linked_dirs可以将文件、目录链接到shared目录下的文件、目录。
例如:
shared的目录结构
shared/
├── conf
│ ├── database.conf
│ └── global.conf
├── main.conf
└── resources
配置文件
append :linked_files, "main.conf"
append :linked_dirs, "conf" , "resources"
推送版本的目录结构
注意:目录链接会导致原有目录下的文件丢失
├── conf -> /tmp/stock/shared/conf
├── main.conf -> /tmp/stock/shared/main.conf
├── README.md
├── resources -> /tmp/stock/shared/resources
└── REVISION
2018-01-04
在部署完项目后,可能会需要对部署好的项目文件和目录做一些权限上的更改。可以,通过下面两种方式的任务完成。其它,个性要求同理。
注意:capistrano v2中的latest_release,在capistrano v3已变更为release_path
namespace :permission do
desc "permission update"
task :update do
on roles( :app) , in: :sequence, wait: 5 do
execute :echo, "hello"
execute :chown, "-R www:www #{release_path}"
execute :chmod, "-R 755 #{release_path}"
end
end
end
namespace :deploy do
after :finishing, "permission:update"
end
或者
namespace :permission do
desc "permission update"
task :update do
on roles( :all) , in: :sequence, wait: 5 do
execute :echo, "change start"
within release_path do
execute :chown, "-R www:www *"
execute :chmod, "-R 755 #{release_path}"
end
end
end
end
namespace :deploy do
after :finishing, "permission:update"
end
2018-01-03
capistrano v3使用属性branch控制版本信息,默认值是:master。
实际中,经常需要根据测试、生成环境发布不同的版本。
修改deploy.rb
set :branch, ENV[ "REVISION" ] || ENV[ "BRANCH_NAME" ] || "master"
或者
set :branch, ENV.fetch( "REVISION" , "master" )
推送v1.0版本则运行:
REVISION = v1.0 cap production deploy
推送master则运行:
2018-01-02
后台脚本
在%GOGS_HOME%/scripts目录下,已经包含了各个系统的脚本,只需要稍微修改即可添加到自启动。
root@iZ2ze9hvf7pey4vrxv9r8gZ:/usr/local/gogs# tree scripts/
scripts/
├── autoboot.sh
├── build_freebsd.sh
├── build_linux64.sh
├── build.sh
├── init
│ ├── centos
│ │ └── gogs
│ ├── debian
│ │ └── gogs
│ ├── freebsd
│ │ └── gogs
│ ├── gentoo
│ │ └── gogs
│ ├── openbsd
│ │ └── gogs
│ └── suse
│ └── gogs
├── launchd
│ └── io.gogs.web.plist
├── mysql.sql
├── README
├── supervisor
│ └── gogs
├── systemd
│ └── gogs.service
└── windows
└── install-as-service.bat
以Ubuntu16、gogs-v0.11.34.1122为例:
复制脚本并赋予执行权限
cp scripts/init/debian/gogs /etc/init.d/
chmod +x /etc/init.d/gogs
cp scripts/systemd/gogs.service /lib/systemd/system/
chmod +x /lib/systemd/system/gogs.service
修改配置
/etc/init.d/gogs
/lib/systemd/system/gogs.service
启动
或者
2017-12-27
git模块文档
ansible 127.0.0.1 -m git -a "repo='https://github.com/ansible/ansible.git' dest='/tmp/ansible'"
通过用户名和密码拉取git代码
---
- hosts : all
gather_facts : no
become : yes
tasks :
- name : install git package
apt :
name : git
- name : Get updated files from git repository
git :
repo : "http://{{ githubuser | urlencode }}:{{ githubpassword | urlencode }}@github.com/dong4stop/hello.git"
dest : /tmp/git
version : v1.0
若密码中有特殊字符可以加上urlencode,{{ githubpassword | urlencode }}。
ansible-playbook git.yml -e "githubuser=*\*\\*\*" ; -e "githubpassword=\*\**" ;
2017-12-14
在使用wordpress时,发现一些目录及文件读写权限的问题。
目录已设置为755权限。
检查后,发现是nginx与php-fpm使用的用户和用户组不一致导致的。
PHP-FPM用户和用户组
vi /etc/php/5.6/fpm/pool.d/www.conf
/etc/init.d/php5.6-fpm restart
Nginx用户和用户组