0x11 高效SQL原则

高效SQL原则

通用SQL原则

1. 子查询中禁止使用order by

2. 禁止使用select * from

3. 不使用%前导的查询,例如like “%xxx”

4. 不使用方向查询,例如not in/not like

5. 禁止应用使用IP直连数据,使用域名进行连接

MySQL原则

0x09 正则

^~ 标识符后面跟一个字符串。Nginx将在这个字符串匹配后停止进行正则表达式的匹配(location指令中正则表达式的匹配的结果优先使用),如:location ^~ /images/,你希望对/images/这个目录进行一些特别的操作,如增加expires头,防盗链等,但是你又想把除了这个目录的图片外的所有图片只进行增加expires头的操作,这个操作可能会用到另外一个location,例如:location * .(gif|jpg|jpeg)$,这样,如果有请求/images/1.jpg,nginx如何决定去进行哪个location中的操作呢?结果取决于标识符^,如果你这样写:location /images/,这样nginx会将1.jpg匹配到location * .(gif|jpg|jpeg)$这个location中,这并不是你需要的结果,而增加了^这个标识符后,它在匹配了/images/这个字符串后就停止搜索其它带正则的location。
= 表示精确的查找地址,如location = /它只会匹配uri为/的请求,如果请求为/index.html,将查找另外的location,而不会匹配这个,当然可以写两个location,location = /和location /,这样/index.html将匹配到后者,如果你的站点对/的请求量较大,可以使用这个方法来加快请求的响应速度。
@ 表示为一个location进行命名,即自定义一个location,这个location不能被外界所访问,只能用于Nginx产生的子请求,主要为error_page和try_files。

~ 为区分大小写的匹配。
* 不区分大小写的匹配(匹配firefox的正则同时匹配FireFox)。
!
不匹配的
!~* 不匹配的

. 匹配除换行符以外的任意字符
\w 匹配字母或数字或下划线或汉字
\s 匹配任意的空白符
\d 匹配数字
\b 匹配单词的开始或结束
^ 匹配字符串的开始
$ 匹配字符串的结束

  • 重复零次或更多次
    
  • 重复一次或更多次
    
    ? 重复零次或一次
    {n} 重复n次
    {n,} 重复n次或更多次
    {n,m} 重复n到m次
    *? 重复任意次,但尽可能少重复
    +? 重复1次或更多次,但尽可能少重复
    ?? 重复0次或1次,但尽可能少重复
    {n,m}? 重复n到m次,但尽可能少重复
    {n,}? 重复n次以上,但尽可能少重复

\W 匹配任意不是字母,数字,下划线,汉字的字符
\S 匹配任意不是空白符的字符
\D 匹配任意非数字的字符
\B 匹配不是单词开头或结束的位置
[^x] 匹配除了x以外的任意字符
[^aeiou] 匹配除了aeiou这几个字母以外的任意字符

捕获 (exp) 匹配exp,并捕获文本到自动命名的组里
(?exp) 匹配exp,并捕获文本到名称为name的组里,也可以写成(?’name’exp)
(?:exp) 匹配exp,不捕获匹配的文本,也不给此分组分配组号
零宽断言 (?=exp) 匹配exp前面的位置
(?<=exp) 匹配exp后面的位置
(?!exp) 匹配后面跟的不是exp的位置
(?<!exp) 匹配前面不是exp的位置
注释 (?#comment) 这种类型的分组不对正则表达式的处理产生任何影响,用于提供注释让人阅读

0x08 redis手记

目录

  • 01.redis配置认证密码
    • a.修改配置文件修改密码
    • b.通过命令修改密码
    • c.master配置了密码,slave如何配置

01.redis配置认证密码

a.修改配置文件修改密码

修改redis配置文件中的密码(e.g.:/etc/redis/redis.conf),去掉行前的注释,并修改密码为所需的密码,保存文件:

1
requirepass password

重启redis

1
sudo service redis-server restart

尝试用密码登录

1
redis-cli -h 127.0.0.1 -p 6379 -a password

b.通过命令修改密码

1
2
3
4
5
redis 127.0.0.1:6379[1]> config set requirepass my_redis
OK
redis 127.0.0.1:6379[1]> config get requirepass
1) "requirepass"
2) "my_redis"

尝试重启一下redis,用新配置的密码登录redis执行操作,发现新的密码失效,redis重新使用了配置文件中的密码。

除了在登录时通过 -a 参数制定密码外,还可以登录时不指定密码,而在执行操作前进行认证。

1
2
3
4
5
6
7
8
redis-cli -h 127.0.0.1 -p 6379
redis 127.0.0.1:6379> config get requirepass
(error) ERR operation not permitted
redis 127.0.0.1:6379> auth myRedis
OK
redis 127.0.0.1:6379> config get requirepass
1) "requirepass"
2) "myRedis"

c.master配置了密码,slave如何配置

若master配置了密码则slave也要配置相应的密码参数否则无法进行正常复制的。
slave中配置文件内找到如下行,移除注释,修改密码即可

1
#masterauth  mstpassword

0x07 nginx杂记

目录

1. nginx返回头包含服务器相关信息,在分布式环境定位问题


1
2
3
4
5
6
7
server{
...
if ($server_addr ~* "((\d+)\.(\d+))$") {
set $server_addr_tail $1;
}
add_header ser $server_addr_tail;
}

效果如下:
2016-06-01_170233.png

2.给nginx开启文件目录模式,用于文件下载

1
2
3
4
5
6
location /download{
root /zen/data/;
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
}

3.给nginx开启简单加密模式

  1. 修改nginx配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
location /download/ {
# 下载目录为 /home/myname/download
root /home/myname;

# 设置目录浏览
autoindex on;

# 默认为on,显示出文件的确切大小,单位是bytes。
# 改为off后,显示出文件的大概大小,单位是kB或者MB或者GB
autoindex_exact_size off;

# 默认为off,显示的文件时间为GMT时间
# 注意:改为on后,显示的文件时间为文件的服务器时间
autoindex_localtime on;

# 在第一次访问目录时,会弹出输入验证框
auth_basic "Restricted";

# 存放密码的文件,/etc/nginx/passwd/download
auth_basic_user_file passwd/download;

# 设置charset,解决中文乱码问题
charset utf-8,gbk;
}

2)修改密码配置文件
输入用户名和密码(密码会在第三步被替换)

vi /etc/nginx/passwd/download

1
admin:admin
  1. 设置 admin 的密码(apt-get install apache2-utils):
1
htpasswd /etc/nginx/passwd/download admin

4)重启nginx

1
service nginx restart

参考:http://wenzhixin.net.cn/2013/10/19/nginx_http_auth

4.查看nginx安装了哪些模块

1
nginx -V

5.nginx中获取自定义header

如果自定义header为CUSTOM_HEAD则,在nginx中的变量http_custom_head对应它的值。也就是:http_header小写变量

6.设置请求头

proxy_set_header Host $http_host;
proxy_set_header X-Forward-For $remote_addr;

7.nginx黑白名单

1
2
3
4
5
6
7
8
deny IP; 
deny subnet;
allow IP;
allow subnet;
# block all ips
deny all;
# allow all ips
allow all;

这样设置以后,该服务器上所有的网站都会按照这个设置来拒绝或允许访问。如果想只针对某个网站,可以在具体的网站的配置中加入:

1
2
3
4
location / { 
allow 192.168.0.0/24;
deny all;
}

这样就只允许192.168.0.0网段的ip访问,其他ip访问会返回一个403错误。

还可以自定义一个403错误的页面,可以在/usr/local/nginx/html下新建个error403.html文件,里面按照html的语法写个文档,写上一些说明文字。
然后编辑nginx.conf,加入:

1
2
3
4
error_page   403  /error403.html; 
location = /error403.html {
root html;
}

8.window版本nginx

启动:nginx.exe 或者 start nginx.exe

重载:nginx.exe -s reload

关闭:nginx -s stop 或taskkill /F /IM nginx.exe > nul

window下 nginx http concat模块的版本: http://pan.baidu.com/s/1hrAdm0c

参考:http://www.cnblogs.com/chuncn/archive/2011/10/14/2212291.html

9.cors

方式一:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
location ^~ /api  {
set $cors "";
if ($http_origin ~* (\.eagleon\.id|\.eagleon\.com)) {
set $cors "true";
}

proxy_set_header Cookie $http_cookie;
proxy_pass http://tomcat.eagleon;

if ($cors = "true") {
add_header 'Access-Control-Allow-Origin' "$http_origin";
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, DELETE, PUT';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Headers' 'User-Agent,Keep-Alive,Content-Type';
}
if ($request_method = OPTIONS) {
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
add_header Access-Control-Allow-Credentials true;
add_header Access-Control-Allow-Headers DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type;
add_header Access-Control-Allow-Headers Content-Type;
add_header Access-Control-Max-Age 1728000;
return 204;
}
}

方式二:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#跨域访问
map $http_origin $corsHost {
default 0;
"~http://www.123admin.com" http://www.123admin.com;
"~https://www.123admin.com" https://www.123admin.com;
"~http://m.123admin.com" http://m.123admin.com;
"~http://wap.123admin.com" http://wap.123admin.com;
}

server {
listen 80;
server_name search.123admin.com;
root /nginx;
location / {
add_header Access-Control-Allow-Origin $corsHost;
add_header Access-Control-Allow-Headers Content-Type;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
add_header Access-Control-Allow-Credentials true;
# 其他逻辑
}
}

0x06 MySQL手札

MySQL手札

01 MYSQL获取自增ID方法

1
SHOW TABLE STATUS;

得出的结果里边对应表名记录中有个Auto_increment字段,里边有下一个自增ID的数值就是当前该表的最大自增ID.

02 mysql字符集

1
2
SHOW VARIABLES LIKE 'collation_%';
SHOW VARIABLES LIKE 'character%';

03 修改字段长度

1
2
3
4
5
6
7
alter table vender_info_ext  
MODIFY COLUMN vender_en_info varchar(300) comment '英文店铺描述',
MODIFY COLUMN vender_ru_info varchar(300) comment '俄文店铺描述',
MODIFY COLUMN vender_cn_info varchar(300) comment '中文店铺描述',
MODIFY COLUMN vender_en_notice varchar(300) comment '英文站公告',
MODIFY COLUMN vender_ru_notice varchar(300) comment '俄文站公告',
MODIFY COLUMN vender_cn_notice varchar(300) comment '中文公告';

03 查看表结构

1
2
show full fields from vender_info
show create table vender_info

0x22 读《火球-UML大战需求分析》

读《火球-UML大战需求分析》

公司请了潘加宇给大家培训UML,开始以为是讲各类UML图怎么画,自己也没有进行过系统培训,就去参加了。听完之后,很有收获,当然收获主要是第一天上午。

下来买了《火球-UML大战需求分析》

0x05用Python监控网站web服务质量

temp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# -*- coding: utf-8 -*-
import os,sys
import time
import sys
import pycurl

URL="http://www.google.com.hk"
c = pycurl.Curl()
c.setopt(pycurl.URL, URL)

#连接超时时间,5秒
c.setopt(pycurl.CONNECTTIMEOUT, 5)

#下载超时时间,5秒
c.setopt(pycurl.TIMEOUT, 5)
c.setopt(pycurl.FORBID_REUSE, 1)
c.setopt(pycurl.MAXREDIRS, 1)
c.setopt(pycurl.NOPROGRESS, 1)
c.setopt(pycurl.DNS_CACHE_TIMEOUT,30)
indexfile = open(os.path.dirname(os.path.realpath(__file__))+"/content.txt", "wb")
c.setopt(pycurl.WRITEHEADER, indexfile)
c.setopt(pycurl.WRITEDATA, indexfile)
try:
c.perform()
except Exception,e:
print "connecion error:"+str(e)
indexfile.close()
c.close()
sys.exit()

NAMELOOKUP_TIME = c.getinfo(c.NAMELOOKUP_TIME)
CONNECT_TIME = c.getinfo(c.CONNECT_TIME)
PRETRANSFER_TIME = c.getinfo(c.PRETRANSFER_TIME)
STARTTRANSFER_TIME = c.getinfo(c.STARTTRANSFER_TIME)
TOTAL_TIME = c.getinfo(c.TOTAL_TIME)
HTTP_CODE = c.getinfo(c.HTTP_CODE)
SIZE_DOWNLOAD = c.getinfo(c.SIZE_DOWNLOAD)
HEADER_SIZE = c.getinfo(c.HEADER_SIZE)
SPEED_DOWNLOAD=c.getinfo(c.SPEED_DOWNLOAD)

print "HTTP状态码:%s" %(HTTP_CODE)
print "DNS解析时间:%.2f ms"%(NAMELOOKUP_TIME*1000)
print "建立连接时间:%.2f ms" %(CONNECT_TIME*1000)
print "准备传输时间:%.2f ms" %(PRETRANSFER_TIME*1000)
print "传输开始时间:%.2f ms" %(STARTTRANSFER_TIME*1000)
print "传输结束总时间:%.2f ms" %(TOTAL_TIME*1000)

print "下载数据包大小:%d bytes/s" %(SIZE_DOWNLOAD)
print "HTTP头部大小:%d byte" %(HEADER_SIZE)
print "平均下载速度:%d bytes/s" %(SPEED_DOWNLOAD)

indexfile.close()
c.close()

0x04ruby环境搭建

ruby环境搭建

1.rvm

1
2
gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
\curl -sSL https://get.rvm.io | bash -s stable

2. 试用淘宝源替代原生

FOR LINUX

1
sed -i -E 's!https?://cache.ruby-lang.org/pub/ruby!https://ruby.taobao.org/mirrors/ruby!' $rvm_path/config/db

FOR MAC

1
sed -i .bak -E 's!https?://cache.ruby-lang.org/pub/ruby!https://ruby.taobao.org/mirrors/ruby!' $rvm_path/config/db

0x03git 使用小记

1. 下载:

windows版
Mac版
Linux版
当然对于linux和Mac来说,通过apt-get install git 或者 mac下通过brew install git 来安装是最方便的。

2. 基本配置

1
2
git config --global user.name "Your Name Here"                   
git config --global user.email "your_email@youremail.com"

3. 生成SSH Keys

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
cd ~/.ssh      
ssh-keygen -t rsa -C "your_email@youremail.com"
# Creates a new ssh key using the provided email

# Generating public/private rsa key pair.
# Enter file in which to save the key (/Users/you/.ssh/id_rsa): [Press enter]

#Enter passphrase (empty for no passphrase): [Type a passphrase]
# Enter same passphrase again: [Type passphrase again]
#然后应该类似:
#Your identification has been saved in /Users/you/.ssh/id_rsa.
# Your public key has been saved in /Users/you/.ssh/id_rsa.pub.
# The key fingerprint is:
#01:0f:f4:3b:ca:85:d6:17:a1:7d:f0:68:9d:f0:a2:db your_email@youremail.com

Windows Command Line:

1
type %userprofile%\.ssh\id_rsa.pub | clip

Windows PowerShell:

1
cat ~/.ssh/id_rsa.pub | clip

Mac:

1
pbcopy < ~/.ssh/id_rsa.pub

GNU/Linux (requires xclip):

1
xclip -sel clip < ~/.ssh/id_rsa.pub

4. 添加SSH KEYS到github或者bitbucket相关账户配置

1
pbcopy < ~/.ssh/id_rsa.pub

打开id_rsa.pub把其中内容复制过去。

5. git clone

1
git clone git@bitbucket.org:eagleon/acrm.git

6. git remote

1
git remote add remote_name git@bitbucket.org:eagleon/acrm.git

7. git push,pull,fetch

1
2
3
4
5
git pull remote_name branch_name               
git push remote_name branch_name
git pull origin master #从远程拉取到本地master分支
git fetch remote_name branch_name
git fetch origin master # 从远程拉取到本地的origin/master分支,但是不合并到master

8. 打tag,branch

1
2
3
4
git tag v0.1
git branch new_branch
git checkout -b dev origin/dev
git checkout -t origin/dev

9. add,commit相关

1
2
3
4
git status
git add .
git commit -a
git commit --amend #覆盖上次添加

10. merge

1
2
git merge <branch>  #把某个分支合并到现有分支
git merge --no-ff develop # 默认情况下,Git执行"快进式合并"(fast-farward merge),会直接将Master分支指向Develop分支。使用--no-ff参数后,会执行正常合并,在Master分支上生成一个新节点。为了保证版本演进的清晰,我们希望采用这种做法。

11. 缓存SSH密码

1
2
3
4
5
6
7
git config credential.helper store  #缓存到文件中,永久储存
git config credential.helper cache # linux 缓存到内存中
git config --global credential.helper wincred# windows 缓存到内存中,需要安装https://github.com/Microsoft/Git-Credential-Manager-for-Windows
git config --global credential.helper osxkeychain # mac 缓存到keychain中
git config --global credential.helper osxkeychain #linux mac windows都可以添加global参数
git config credential.helper 'cache --timeout=3600' #数字为保存的时间(秒,默认900) 在这个时间内输入的密码都是有效的,

12.丢弃本地修改

1
git checkout . && git clean -xdf

13. 把其他分支切换为master分支

1
git push origin +dev:master
1
2
3
4
5
6
7
8
9
10
Update the origin repository’s master branch with the dev branch, allowing non-fast-forward updates. This can leave unreferenced commits dangling in the origin repository. Consider the following situation, where a fast-forward is not possible:

o---o---o---A---B origin/master
\
X---Y---Z dev
The above command would change the origin repository to

A---B (unnamed branch)
/
o---o---o---X---Y---Z master

14. git alias

1
2
3
4
5
6
7
[alias]
lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
last = log -1
co = checkout
ci = commit
br = branch
st = status

15. git push一次到多个仓库

方法一:

1
git remote set-url --add origin git@github.com:ehlxr/ehlxr-Hexo.git

方法二:

1
2
3
4
5
vim .git/config
[remote "origin"]
url = https://github.com/zxbetter/test.git
fetch = +refs/heads/*:refs/remotes/github/*
url = https://git.oschina.net/zxbetter/test.git

参考:
https://segmentfault.com/a/1190000011294144
https://ehlxr.me/2016/07/24/Git-%E5%90%8C%E6%97%B6-push-%E5%88%B0%E5%A4%9A%E4%B8%AA%E8%BF%9C%E7%A8%8B%E4%BB%93%E5%BA%93/

Ref:

Set Up Git
Caching your GitHub password in Git
git-credential-winstore
Generating SSH keys
git - 简明指南
Git分支管理策略
Git远程操作详解