siege模拟并发

今天遇到一个并发的场景,因为代码不严谨,座位被重复预定了。为了模拟并发请求,学习了一下 siege 这个工具:

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
$ siege --help
SIEGE 4.0.4
Usage: siege [options]
siege [options] URL
siege -g URL
Options:
-V, --version 版本号
-h, --help 帮助文档
-C, --config 在屏幕上打印显示出当前的配置,配置是包括在他的配置文件$HOME/.siegerc中,
可以编辑里面的参数,这样每次siege 都会按照它运行
-v, --verbose 运行时能看到详细的运行信息
-q, --quiet 关闭输出运行信息
-g, --get 获取请求的headers信息并打印出来,debug专用
-c, --concurrent=NUM 模拟有n个用户在同时访问,默认是10,不要设得太大,因为越大,siege 消耗本地机器的资源越多
-i, --internet 随机访问urls.txt中的url列表项
-b, --benchmark BENCHMARK: no delays between requests.
-t, --time=NUMm 持续运行siege n秒(如10S),分钟(10M),小时(10H)
-r, --reps=NUM 重复运行测试n次,不能与-t同时存在
-f, --file=FILE 指定用urls文件,默认为siege安装目录下的etc/urls.txt
urls.txt文件:是很多行待测试URL的列表以换行符断开,格式为:
[protocol://]host.domain.com[:port][path/to/file]
-R, --rc=FILE 指定用特定的siege配置文件来运行,默认的为$HOME/.siegerc
-l, --log[=FILE] 运行结束,将统计数据保存到日志文件siege.log中,可在.siegerc中自定义日志文件
默认位置是: PREFIX/var/siege.log
-m, --mark="text" MARK, mark the log file with a string.
-d, --delay=NUM 每个url在0-n之间进行的延迟
-H, --header="text" 添加header,可以添加多个
-A, --user-agent="text" 设置User-Agent
-T, --content-type="text" 设置Content-Type

Read More

MongoDB定容集合

MongoDB定容集合(capped collection) 用于定义一个大小固定的集合:

1
db.createCollection("coll_name", {capped: true, size:100000})

当插入新的数据导致存储空间超出预设大小时,旧的数据会被清除。但这个表里面的文档是不能被手动删除的,只有 drop 整个表才行。不许删除的原因是为了保持每个文档在磁盘上的位置不变。另外,文档的更新是有限制的,即必须在不增加文档占用空间的前提下才能生效,比如减少字段或减少值的长度,如果更新后的文档比原文档占据更多的空间,就会更新失败。Capped Collection主要用于存储日志信息和缓存一些少用的文档。

Flutter.h file not found

今天打包到 iPhone 上的时候,提示报错:

1
2
'Flutter/Flutter.h' file not found
#import <Flutter/Flutter.h>

意思是说插件中的 Flutter 找不到,网上查了一下说是 cocoapods 的问题,解决办法就是:

flutter create my_app 创建一个新的项目,然后用这个新项目中的 ios/Flutter 文件夹替换报错项目即可。

unit8array转换为字符串

unit8array 格式是8字节无符号整数数组,如果把它转换为 string 类型呢?

  1. 如果不是 utf8 编码的话,可以用下面的方法:

    1
    2
    3
    function uint8arrToStr(uint8arr){
    return String.fromCharCode.apply(null, uint8arr)
    }
  2. 如果使用了 utf8 编码,在浏览器上可以用下面的方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    // 把 Uint8Array 转换为 String
    function uint8arrToStr(uint8arr){
    return new TextDecoder("utf-8").decode(uint8arr)
    }

    // 把 String 转换为 Uint8Array
    function str2Uint8arr(str){
    return new TextEncoder("utf-8").encode(str)
    }

Read More

yarn安装node-sass太慢

Yarn 安装 node-sass 太慢了,可以尝试用更改镜像源或者使用离线镜像的方式:

  1. 在项目目录下新建 .yarnrc 文件,并添加以下代码

    1
    2
    registry "https://registry.npm.taobao.org"
    sass_binary_site "https://npm.taobao.org/mirrors/node-sass/"
  2. 全局修改 yarn 的配置

    1
    2
    yarn config set registry https://registry.npm.taobao.org
    yarn config set sass_binary_site https://npm.taobao.org/mirrors/node-sass/
  3. 使用离线镜像

    离线镜像的使用可以参考这篇文章

utf16转换为utf8

如何把 utf16 编码的字符串转换为 utf8 呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function utf16to8(str) {
var out, i, len, c;

out = "";
len = str.length;
for(i = 0; i < len; i++) {
c = str.charCodeAt(i);
if ((c >= 0x0001) && (c <= 0x007F)) {
out += str.charAt(i);
} else if (c > 0x07FF) {
out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
} else {
out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F));
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
}
}
return out;
}

Read More

react登录认证

用 react 框架做项目时,如何实现登录认证呢?即登录成功加载当前页,否则跳转至登录页。可以写一个高阶函数来实现这个目的:

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
import React, { Component } from 'react'
import { connect } from 'react-redux'

export default function(ComposedComponent) {
class Auth extends Component {
componentWillMount() {
if (!this.props.auth.authorized) {
this.props.history.push('/login')
}
}

componentWillUpdate(nextProps) {
if (!nextProps.auth.authorized) {
this.props.history.push('/login')
}
}

render() {
return <ComposedComponent {...this.props} />
}
}

const mapStateToProps = state => ({
auth: state.auth
})

return connect(mapStateToProps)(Auth)
}

Read More

adb学习笔记

adb 相关命令可以方便我们在电脑上安装和调试apk,在此学习和记录如下:

查看所有设备:

1
adb devices

安装apk到设备:

1
2
adb install xxx.apk
adb -s emulator-5555 install xxx.apk # 指定序列号安装

如果有多个可用设备,但只有一个是模拟器,可以使用 -e 选项将命令发送至该模拟器。
如果有多个设备,但只连接了一个硬件设备,可以使用 -d 选项将命令发送至该硬件设备。

进入到 shell:

1
2
adb -s emulator-5554 shell
run-as app.package.name # 例如 com.example.demo

Read More

package.json中的resolution

开发过程中经常会遇到下面两个场景:

  1. 项目依赖一个不常更新的包,但这个包又依赖另一个包,而这个包由于各种原因需要立即升级,例如紧急安全更新等。
  2. 项目的直接依赖定义了过于宽泛的子依赖版本范围,恰巧这其中的某个版本有问题,需要把子依赖限制在某些正常工作的版本范围里。

这个时候就很头疼,因为项目 package.json 不能指定依赖的依赖的版本,它是在依赖的 package.json 中指定的,要么坐等作者升级,要么手动编辑 package-lock.json。如果用 yarn 作为包管理工具的话,就好办了,只需要在 package.json 文件里添加 resolutions 字段,就能覆盖版本定义,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"name": "project",
"version": "1.0.0",
"dependencies": {
"left-pad": "1.0.0",
"c": "file:../c-1",
"d2": "file:../d2-1"
},
"resolutions": {
"d2/left-pad": "1.1.1",
"c/**/left-pad": "1.1.2"
}
}

意思是说可以直接指定依赖 d2 所依赖的 left-pad 版本为 1.1.1。可惜 npm 官方并不支持这个参数,不过 github 上有一个第三方库支持了这个功能。

用docker申请letsencrypt通配符证书

用 docker 申请 letsencrypt 证书的好处就是不需要在宿主机上安装依赖,只要用下面的命令即可:

1
2
3
4
5
6
docker run -it --rm \
--name certbot \
-v /mnt/letsencrypt:/etc/letsencrypt \
-v /mnt/bak/letsencrypt:/var/lib/letsencrypt \
certbot/certbot \
certonly --manual --agree-tos --server https://acme-v02.api.letsencrypt.org/directory --preferred-challenges dns -d *.YOUR-DOMAIN.com -d YOUR-DOMAIN.com

具体的命令释义如下:

1
2
3
4
5
6
-v /mnt/letsencrypt:/etc/letsencrypt -v /mnt/bak/letsencrypt:/var/lib/letsencrypt # 挂载目录,certbot申请到的或备份的证书会放在这两个目录
--manual # 交互模式
--agree-tos # 同意服务协议
--server https://acme-v02.api.letsencrypt.org/directory # 指定使用acmev2协议的服务器,因为通配符证书的申请需要这个协议
–preferred-challenges dns # 使用dns检验来证明你拥有这个域名
-d *.YOUR-DOMAIN.com -d YOUR-DOMAIN.com # 指定了需要申请证书的通配符域名,根域名要额外再写一次

Read More