0%

今天发现某网站在chrome的dev tool里面没法用jquery调试,原因未知。搜了下发现重新导入一下jquery就可以。

1
2
3
4
var importJs=document.createElement('script')  //在页面新建一个script标签
importJs.setAttribute("type","text/javascript") //给script标签增加type属性
importJs.setAttribute("src", 'https://code.jquery.com/jquery-3.3.1.min.js') //给script标签增加src属性, url地址为cdn公共库里的
document.getElementsByTagName("head")[0].appendChild(importJs) //把importJs标签添加在页面

-s Squeeze multiple occurrences of the characters listed in the last operand (either string1 or string2) in the input into a single instance of the character. This occurs after all deletion and translation is completed.

我自己的理解:“针对参数中的最后一个字符集(只有一个字符集参数时就是string1,有两个字符集参数时就是string2)的每个字母,如果出现多个连续的就只保留一个。这个操作在转换和删除操作完成之后进行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ echo 'baaabccc'|tr -d 'ac'
只删除,输出 bb
$ echo 'baaabccc'|tr -s 'ac'
只压缩,输出 babc
$ echo 'baaabccc'|tr 'ac' 'gf'
只转换,输出 bgggbfff
$ echo 'baaabccc'|tr -s 'ac' 'gf'
转换后压缩,输出 bgbf
$ echo 'baaabccc'|tr 'ac' 'g'
只转换,输出 bgggbggg
$ echo 'baaabccc'|tr -s 'ac' 'g'
转换后压缩,输出 bgbg
$ echo 'baarcteejjgfa'|tr -sd 'acj' 'ef'
第一步acj会被删掉,第二步ef被压缩。最后输出 brtegf

Tutorial

Bitbucket tutorial

廖雪峰

git-recipes tutorial

Extract

Command Scope Common use cases
git reset Commit-level Discard commits in a private branch or throw away uncommited changes
git reset File-level Unstage a file
git checkout Commit-level Switch between branches or inspect old snapshots
git checkout File-level Discard changes in the working directory
git revert Commit-level Undo commits in a public branch
git revert File-level (N/A)

git reset to alter the staged snapshot and/or the working directory by passing it one of the following flags:

  • --soft – The staged snapshot and working directory are not altered in any way.
  • --mixed – The staged snapshot is updated to match the specified commit, but the working directory is not affected. This is the default option.
  • --hard – The staged snapshot and the working directory are both updated to match the specified commit.

一个比较好的学习postgres的站点

http://www.postgresqltutorial.com

显示当前连接数

1
2
3
select sum(numbackends) FROM pg_stat_database;
select datname,numbackends from pg_stat_database;
select * from pg_stat_activity;
1
2
3
4
5
6
7
8
9
10
--切换数据库
\c database_name;
--显示所有数据库
\l
--显示当前数据库的表
\dt
--显示user_info开头的表
\dt user_info*
--展示表结构
\d+ table_name;
重建主键
1
2
3
4
5
6
-- Firstly, remove PRIMARY KEY attribute of former PRIMARY KEY
ALTER TABLE <table_name> DROP CONSTRAINT <table_name>_pkey;
-- Then change column name of your PRIMARY KEY and PRIMARY KEY candidates properly.
ALTER TABLE <table_name> RENAME COLUMN <primary_key_candidate> TO id;
-- Lastly set your new PRIMARY KEY
ALTER TABLE <table_name> ADD PRIMARY KEY (id);
让主键自增
1
2
3
4
5
6
7
create sequence <table_name_primary_id_seq>;
--设定序列从1开始自增
select setval('<table_name_primary_id_seq>', 1,false);
--等同于以上语句
alter sequence <table_name_primary_id_seq> restart with 1;

alter table <table_name> alter <primary_id> set default nextval('<table_name_primary_id_seq>');

导出insert语句

1
pg_dump --column-inserts --data-only -d <database> -t <table>  > ./export.sql

计算百分比

1
2
select count(*) as item,(count(*)::decimal / (select count(*) from <table>)::decimal) * 100  as percent
from <table> where ....;

postgis应用

http://www.gonjay.com/blog/2015/05/15/postgis-cha-xun-fu-jin-de-ren/

今天折腾了下用iptables中转流量的事情,先把命令记录在这里,以后再来精简

首先开启ip转发(在中转服务器上面操作)

  • 编辑/etc/sysctl.conf,设置或打开net.ipv4.ip_forward=1
    • $ sudo sysctl -p使修改文件后设置生效
  • 或者 $ sudo sysctl -w net.ipv4.ip_forward=1,重启后无效
  • 或者 echo "1" > /proc/sys/net/ipv4/ip_forward,这种直接修改内核方式重启后无效

流量中转,在中转服务器上执行下面规则

1
2
3
4
sudo iptables -t nat -A PREROUTING  -p tcp --dport 中转端口 -j DNAT --to-destination 目标服务器:目标端口
sudo iptables -t nat -A PREROUTING -p udp --dport 中转端口 -j DNAT --to-destination 目标服务器:目标端口
sudo iptables -t nat -A POSTROUTING -p tcp -d 目标服务器 --dport 目标端口 -j MASQUERADE
sudo iptables -t nat -A POSTROUTING -p udp -d 目标服务器 --dport 目标端口 -j MASQUERADE

ipsec vpn服务器需要中转500,4500两个端口的udp流量

情景:只对某一个ip开放端口,其他ip访问此端口拒绝

1
2
iptables -A INPUT -s 开放的ip -p tcp --dport 端口 -j ACCEPT
iptables -A INPUT -p tcp --dport 端口 -j DROP

关于这两条的执行顺序,容易弄混。经测试发现,一定要先ACCEPT这个ip,再DROP掉其他ip,才能达到预期效果。

Each rule in a chain contains the specification of which packets it matches. It may also contain a target (used for extensions) or verdict (one of the built-in decisions). As a packet traverses a chain, each rule in turn is examined. If a rule does not match the packet, the packet is passed to the next rule. If a rule does match the packet, the rule takes the action indicated by the target/verdict, which may result in the packet being allowed to continue along the chain or it may not

可以理解一下为:按顺序匹配,只要匹配中一条就采用这一条。不再往下匹配。以此例,如果先DROP,就不会有ACCEPT了。

1
2
3
4
5
6
~     #正则匹配,区分大小写
~* #正则匹配,不区分大小写
空 #普通字符匹配,
^~ #普通字符匹配,
= #普通字符匹配, 精确匹配
@ #"@" 定义一个命名的 location,使用在内部定向时,例如 error_page, try_files

匹配规则

  1. 精确匹配到=定义的loacation,使用这个location,停止搜索;
  2. 匹配最长普通字符,如果这个最长prefix string带有^~修饰符,使用这个location,停止搜索,否则往下
  3. 存储这个最长匹配;
  4. 然后匹配正则表达式(按配置顺序);
  5. 匹配到第一条正则表达式,使用该正则表达式的这个location,停止搜索;
  6. 没有匹配到正则表达式,使用第3步存储的prefix string的location。

参考链接

背景

从nginx配置上防止恶意请求

nginx处理方式

HttpLimitReqModule配置来限制ip在同一时间段的访问次数来防cc攻击。
HttpLimitConnModul用来限制单个ip的并发连接数
网友总结     nginx文档

实例(见上面网友总结)

https://www.nginx.com/blog/rate-limiting-nginx/

http://blog.nkhost.net/notes/nginx-limit-the-request-processing-rate/

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
http{
...

#定义一个名为allips的limit_req_zone用来存储session,大小是10M内存,
#以$binary_remote_addr 为key,限制平均每秒的请求为20个,
#1M能存储16000个状态,rete的值必须为整数,
#如果限制2秒钟处理一个请求,可以设置成30r/m

limit_req_zone $binary_remote_addr zone=allips:10m rate=20r/s;
...
server{
...
location { #也可以不用放在location这一级
...

#限制每ip每秒不超过20个请求,漏桶数burst为5
#brust的意思就是,如果第1秒、2,3,4秒请求为19个,
#第5秒的请求为25个是被允许的。
#但是如果你第1秒就25个请求,第2秒超过20的请求返回503错误。
#nodelay,如果不设置该选项,严格使用平均速率限制请求数,
#第1秒25个请求时,5个请求放到第2秒执行,
#设置nodelay,25个请求将在第1秒执行。

limit_req zone=allips burst=5 nodelay; #也可以直接放在server这一级下面
...
}
...
}
...
}

测试

ab -n 1000 -c 50 http://testweb.com/index.html #1000个请求,50个并发测试

观察nginx访问日志可以看到,很快就限制返回503了
nginx503
观察nginx error日志可以看到请求受限
nginx_err

优化返回

云服务器会统计5xx错误,5xx错误可能引发报警。有时需要把这种错误自定义,例如把这种503自定义成403错误。http错误码

nginx配置 stackoverflow

1
2
limit_req zone=allips burst=2 nodelay;
limit_req_status 403;

自定义错误返回页 stackoverflow

1
2
3
4
error_page  403  /403.html;
location /403.html {
internal;
}

进一步优化

在webapi项目中,想用json返回错误提示,并且状态码设为200 github

1
2
3
4
5
6
7
limit_req zone=allips burst=2 nodelay;
limit_req_status 403;
error_page 403 =200 @403.json;
location @403.json {
default_type application/json;
return 200 '{"limit":"request is too fast"}';
}
测试效果

先用ab命令发起并发请求,引发连接限制。同时访问可以发现,服务器返回json格式数据,同时状态码200
自定义json测试

docker基本概念

镜像 容器 仓库 参考链接

用docker file创建docker镜像

1
2
cd dockerfile所在目录
docker build -t image_name .

docker启动镜像时端口映射

1
docker run -p [ip:]hostPort:containerPort image_name

docker run命令参数及其使用

常用

1
2
-i: 以交互模式运行容器,通常与 -t 同时使用;
-t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;

使用镜像nginx:latest以交互模式启动一个容器,在容器内执行/bin/bash命令

1
2
docker run -it nginx:latest /bin/bash 
docker run -it -p 80:80 nginx_image /bin/bash

docker容器相关

1
2
3
4
5
docker ps #列出正在运行的容器
docker ps -a #列出所有容器
docker run -d image_name #守护态启动一个容器
docker start container_id_or_name #运行停止的容器
docker exec -it container_id_or_name /bin/bash #进入容器里面

container_id_or_name: 如果是id可以只取前面几位,能区分就好,如果用name就要全称

宿主机往容器中拷贝文件

1
docker cp /data/tmp/test.txt container:/data/tmp

docker从容器创建新镜像

1
docker commit -m "message" -a "author" container_id_or_name new_image_name

参考链接