Octotree for Safari

brew install [email protected]
export PATH="/usr/local/opt/[email protected]/bin:$PATH"
# make sure node and npm is v10, cause octotree used gulp 3, which is not working with node 12.

git clone https://github.com/ovity/octotree.git ~/src/octotree
cd ~/src/octotree
git checkout master

npm i
npm install [email protected]
npm run dist
# extension locate in ~/src/octotree/tmp/safari/octotree.safariextension/

cd ~/Library/Safari/Extensions
mv ~/src/octotree/tmp/safari/octotree.safariextension .
  1. Enable Developer menu in Safari
  2. Developer - Show Extension Builder
  3. Add octotree.safariextension and Run

MySQL Prefix Index

CREATE TABLE `t1` (
  `bundle` varchar(300) DEFAULT '' COMMENT 'pkg name',
  `domain` varchar(200) DEFAULT '',
  UNIQUE KEY `idx_bundle_domain` (`bundle`(100),`domain`(100))
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4;

关键部分 bundle(100) 来解决组合索引可能会出现的 Specified key was too long; max key length is 767 bytes 错误。

Deployment with git

#!/bin/sh

set -uex

PATH=$PATH:$HOME/bin
export PATH

DIR=/home/serv/project
cd ${DIR}

REV1=$(git rev-parse --verify HEAD)
git pull origin master
REV2=$(git rev-parse --verify HEAD)
test ${REV1} = ${REV2} && echo "Already updated" && exit

make
test $? -ne 0 && echo "make error" && exit

kill -HUP $(cat logs/run.pid)

主要是通过 git rev-parse --verify HEAD 来获取当前 rev hash,前后对比是否一致,以此来决定是否继续。

logrotate

logrotate - rotates, compresses, and mails system logs

# 0 0 * * * /usr/sbin/logrotate --state=/home/serv/logrotate.state /home/serv/logrotate.log.conf
/home/serv/logs/dev.log
/home/serv/logs/access.log {
    rotate 10
    daily
    compress
    create
    copytruncate
    missingok
    dateext
    dateformat -%Y-%m-%d
    dateyesterday

    sharedscripts
    postrotate
        kill -USR1 `cat /var/run/nginx.pid`
    endscript
}
  1. 要么保存到 /etc 配置,由系统调度。也可以自己通过 crontab 调度控制,这种情况要注意加 --state 来保存状态
  2. 像 nginx 可以通过 kill -USR1 来重新打开日志文件,如果服务不支持可以用 copytruncate,先拷贝再清空

Druid Query in JSON

Druid 可以在 Superset SQL 查询,除此之外可以通过 HTTP+JSON 查询:

curl -X POST '<host:<port>/druid/v2/?pretty' -H 'Content-Type:application/json' -H 'Accept:application/json' -d @query.json
{
  "queryType": "timeseries",
  "dataSource": "cpm_log",
  "granularity": "hour",
  "aggregations": [
    {
      "type": "longSum",
      "name": "requests",
      "fieldName": "req_count_raw"
    },
    {
      "type": "longSum",
      "name": "impressions",
      "fieldName": "win_count"
    },
    {
      "type": "floatSum",
      "name": "revenues",
      "fieldName": "win_price"
    }
  ],
  "postAggregations": [
    {
      "type":"arithmetic",
      "name": "ecpm",
      "fn": "/",
      "fields": [
        {
          "type": "fieldAccess",
          "name": "postAgg_rev",
          "fieldName": "revenues"
        },
        {
          "type": "fieldAccess",
          "name": "postAgg_imps",
          "fieldName": "impressions"
        }
      ]
    }
  ],
  "filter": {
    "type": "and",
    "fields": [
      {
        "type": "selector",
        "dimension": "device_os",
        "value": "android"
      },
      {
        "type": "in",
        "dimension": "req_ad_type",
        "values": ["banner"]
      }
    ]
  },
  "context": {
    "grandTotal": true
  },
  "intervals": [
    "2019-04-09T00:00:00+08:00/2019-04-09T23:00:00+08:00"
  ]
}
  1. queryType 有 timeseries, topN, groupBy, search, timeBoundary
  2. 尽量少用 groupBy 查询,效率不高
  3. topN 查询是通过 metric 来排序
  4. context 可以指定 queryId,这样可以通过 DELETE /druid/v2/{queryId} 取消查询
  5. 去重: {"type": "cardinality", "name": "distinct_pid", "fields": ["ad_pid"]}

RTFM, godruid

To Appwill

昨天梦到了 AW。

不是现在的 AW,是几年前的,很多人都还在,一起讨论某个产品。

那时的 AW 很小,但有凝聚力,有战斗力,很 nice。后来有好几个人都跟我说过,那时的 AW 是大家最棒的经历。

什么时候是个转折呢?大概就是 15年吧,Z 移民澳洲后产品上一直没有太好的 Lead,之后日活下降收入走低,产品开始往下走。16年后 L 对现有产品兴趣不大,改组内部项目制,效果也不好。

再后来,17年初 L 组建新公司,Z&Z 言明不可从原公司挖人,结果就是一起拼搏走过来的人,跟着已经死去的旧产品沉没,之后相继离职,包括我。

我个人对 AW 的感情很深,但说实话,最后创始人分家+限制挖人,让我心里很不舒服,本身我们还可以一起用彼此都信任的方式做事,结果却似有欺骗,维护着注定要死去的产品,费劲心力,却无成长。

R.I.P.

Nginx proxy_next_upstream non_idempotent

在 Nginx 做反向代理的时候,我们一般会配置 proxy_next_upstream,如果某个 upstream 超时或出错,自动切换到下一个 upstram。

upstream backend{
  server 192.168.0.1;
  server 192.168.0.2;
}
location /example/ {
   proxy_pass http://backend;

   proxy_next_upstream error timeout http_500 non_idempotent;
}

这里有一个地方需要注意,non_idempotent,Nginx 默认对 non-idempotent 请求,比如 POST/LOCK/PATCH,是不进行重试。常见的情况就是 POST 请求出错后不会重试,需要加上该设置。

normally, requests with a non-idempotent method (POST, LOCK, PATCH) are not passed to the next server if a request has been sent to an upstream server (1.9.13); enabling this option explicitly allows retrying such requests;

Homebrew Speedup

通过修改 Homebrew git repo 来加速:

cd "$(brew --repo)"
git remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/brew.git
// 中科大 git remote set-url origin https://mirrors.ustc.edu.cn/brew.git

cd "$(brew --repo)/Library/Taps/homebrew/homebrew-core"
git remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-core.git
// 中科大 git remote set-url origin https://mirrors.ustc.edu.cn/homebrew-core.git

// homebrew-cask
cd "$(brew --repo)/Library/Taps/homebrew/homebrew-cask"
git remote set-url origin https://mirrors.ustc.edu.cn/homebrew-cask.git

// homebrew-bottles
export HOMEBREW_BOTTLE_DOMAIN=https://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles
// export HOMEBREW_BOTTLE_DOMAIN=https://mirrors.ustc.edu.cn/homebrew-bottles
// export HOMEBREW_BOTTLE_DOMAIN=http://7xkcej.dl1.z0.glb.clouddn.com

重置为官方源:

cd "$(brew --repo)"
git remote set-url origin https://github.com/Homebrew/brew.git

cd "$(brew --repo)/Library/Taps/homebrew/homebrew-core"
git remote set-url origin https://github.com/Homebrew/homebrew-core

cd "$(brew --repo)/Library/Taps/homebrew/homebrew-cask"
git remote set-url origin https://github.com/Homebrew/homebrew-cask

Python Development Environment 2019

macOS

  1. brew install python to install python 3
  2. python3 -m venv .venv or virtualenv -p $(which python3) .venv
  3. source .venv/bin/activate
  4. pip install 'python-language-server[all]' to install pyls, will switch to MSPyls.
  5. coding
  6. deactivate to leave

No more pyenv, pipenv, use pipsi to install utils written in Python.

AWS Services List (2018)

一句话说清楚 AWS X 是什么

计算:

  • EC2
    • Amazon Elastic Compute Cloud,或者叫亚马逊的虚拟机服务
    • 一台托管在 AWS 的电脑/服务器
  • ECS
    • Amazon Elastic Container Service
    • 亚马逊 Docker 服务,配合内部 Elastic Container Registry(ECR) 做服务容器化
    • 还有 EKS(ECS for Kubernetes)
  • Lambda
    • AWS App Scripts
    • 只跑代码,不需要考虑服务器问题
    • 可访问其他服务资源

存储:

  • S3
    • Amazon Simple Storage Service,或者叫亚马逊无限量 FTP 服务器
    • 存储网站图片、视频、备份等
    • 不同服务间文件共享
  • EFS
    • Amazon Elastic File System
  • EBS
    • Amazon Elastic Block Store
    • EFS 和 EBS 很像,简单理解就是 EBS 是一个可以挂载到 EC2 的硬件磁盘,EFS 是一个网络文件系统
  • Glacier
    • 云归档服务
    • 成本极低的数据存储和长期备份

数据库:

  • RDS
    • Amazon Relational Database Service
    • 亚马逊数据库服务,帮你做好备份、扩容等
  • Aurora
    • 兼容 MySQL/PostgreSQL 的分布式关系型数据库
  • Elasticache
    • 亚马逊 Redis/Memcached 服务
  • DynamoDB
    • 亚马逊 NoSQL 服务
    • KV 存储服务
  • RedShift
    • PB 级数据仓库

网关和内容分发:

  • Cloudfront
    • 亚马逊 CDN 服务
  • Route53
    • 域名注册,DNS 服务
  • ELB
    • Elastic Load Balancing,负载均衡
  • API Gateway
    • API 网关代理
    • 管理后端 API,比如流量控制,监控,版本切换,A/B 测试分流等

开发者工具:

  • CodeCommit
    • 私有 Git 服务器
  • CodeBuild
    • CI 系统
  • CodePipeline
    • 持续交付发布
  • Code Deploy
    • 自动化部署
    • 尤其适用于同时部署到多个 EC2
  • Cloud9
    • 云端 IDE

移动应用服务:

  • Cognito
    • 亚马逊 OAuth 服务
    • 让用户使用社交网站信息注册、登录
  • Device Farm
    • 在真实设备上做应用测试
    • 提供视频、截图、日志等信息
  • Mobile Analytics
    • 收集、查看应用分析数据
    • 类似 Flurry、Google Analytics

Web 基础服务:

  • SES
    • Amazon Simple Email Service
    • 亚马逊邮件发送服务,包括邮件通知、订阅等
  • SNS
    • Amazon Simple Notification Service
    • 向用户发 push、邮件、短信
  • SQS
    • Amazon Simple Queue Service
    • 亚马逊消息队列服务
  • WAF
    • Web 应用防火墙
  • CloudSearch
    • 或者叫亚马逊全文搜索服务
  • Elastic Transcoder
    • 亚马逊视频转码服务

其他,包括 AWS 安全,管理,监控等:

  • IAM
    • AWS Identity and Access Management
    • 管理用户组,管理资源访问权限
  • CloudTrail
    • 跟踪 AWS 用户活动和 API 使用状况
  • CloudWatch
    • AWS 服务监控
  • Config
    • 记录、评估 AWS 资源配置
  • OpsWorks
    • 用 Chef 和 Puppet 实现操作自动化
  • Trusted Advisor
    • 对使用的 AWS 资源进行成本分析、安全建议等
  • Inspector
    • 自动安全评估服务,评估应用程序风险、漏洞