Patch Notes
- Create patch file:
diff -u file1 file2 > name.patch
, orgit diff > name.patch
- Apply path file:
patch [-u] < name.patch
- Backup before apply patch:
patch -b < name.patch
- Validate patch without apply:
patch --dry-run < name.patch
- Reverse applied path:
patch -R < name.patch
8:24
R.I.P. KOBE
audit.sh
Use PROMPT_COMMAND for bash, and precmd for zsh.
mkdir -p /var/log/.audit
touch /var/log/.audit/audit.log
chown nobody:nobody /var/log/.audit/audit.log
chmod 002 /var/log/.audit/audit.log
chattr +a /var/log/.audit/audit.log
Save to /etc/profile.d/audit.sh
:
HISTSIZE=500000
HISTTIMEFORMAT=" "
export HISTTIMEFORMAT
export HISTORY_FILE=/var/log/.audit/audit.log
export PROMPT_COMMAND='{ curr_hist=`history 1|awk "{print \\$1}"`;last_command=`history 1| awk "{\\$1=\"\" ;print}"`;user=`id -un`;user_info=(`who -u am i`);real_user=${user_info[0]};login_date=${user_info[2]};login_time=${user_info[3]};curr_path=`pwd`;login_ip=`echo $SSH_CONNECTION | awk "{print \\$1}"`;if [ ${login_ip}x == x ];then login_ip=- ; fi ;if [ ${curr_hist}x != ${last_hist}x ];then echo -E `date "+%Y-%m-%d %H:%M:%S"` $user\($real_user\) $login_ip [$login_date $login_time] [$curr_path] $last_command ;last_hist=$curr_hist;fi; } >> $HISTORY_FILE'
echo "local6.* /var/log/commands.log" > /etc/rsyslog.d/commands.conf
systemctl restart rsyslog.service
precmd() { eval 'RETRN_VAL=$?;logger -p local6.debug "$(whoami) [$$]: $(history | tail -n1 | sed "s/^[ ]*[0-9]\+[ ]*//" ) [$RETRN_VAL]"' }
GitHub Actions Canceled Unexpectedly
By default, GitHub will cancel all in-progress jobs if if any matrix
job fails. Set fail-fast: false
to fix this.
How to Activate Noise Cancellation with One AirPod
Settings
- Accessibility
- AirPods
, toggle on Noise Cancellation with One AirPod
.
AirPods Pro 开启单只降噪:设置 - 辅助功能 - AirPods,打开 一只 AirPod 入耳时使用降噪
。
[转]服务端高并发分布式架构演进之路
原文 服务端高并发分布式架构演进之路,本文以淘宝作为例子,介绍从一百个并发到千万级并发情况下服务端的架构的演进过程,同时列举出每个演进阶段会遇到的相关技术,让大家对架构的演进有一个整体的认知,文章最后汇总了一些架构设计的原则。
架构设计的原则:
- N+1设计。系统中的每个组件都应做到没有单点故障;
- 回滚设计。确保系统可以向前兼容,在系统升级时应能有办法回滚版本;
- 禁用设计。应该提供控制具体功能是否可用的配置,在系统出现故障时能够快速下线功能;
- 监控设计。在设计阶段就要考虑监控的手段;
- 多活数据中心设计。若系统需要极高的高可用,应考虑在多地实施数据中心进行多活,至少在一个机房断电的情况下系统依然可用;
- 采用成熟的技术。刚开发的或开源的技术往往存在很多隐藏的bug,出了问题没有商业支持可能会是一个灾难;
- 资源隔离设计。应避免单一业务占用全部资源;
- 架构应能水平扩展。系统只有做到能水平扩展,才能有效避免瓶颈问题;
- 非核心则购买。非核心功能若需要占用大量的研发资源才能解决,则考虑购买成熟的产品;
- 使用商用硬件。商用硬件能有效降低硬件故障的机率;
- 快速迭代。系统应该快速开发小功能模块,尽快上线进行验证,早日发现问题大大降低系统交付的风险;
- 无状态设计。服务接口应该做成无状态的,当前接口的访问不依赖于接口上次访问的状态。
Google Code Review Guide
- 原则:给出技术上的建议,而不是个人偏好
- 写一个好的 commit:
- 第一行,改动的简短摘要
- 空行
- 详细提交信息
- 小修改,多提交
- 方便 review/merge/roll back
- 利于好的代码设计,减少 bug
- Code review 看什么?
- 设计
- 功能实现是否正确,以及复杂度
- 测试
- 命名,注释,代码风格,文档等
- 尽早 review,尽快 review
- 好的 code review comment
- Be kind
- 只指出问题,让开发人员自己决定怎么修改
- Encourage developers to simplify code
如何写出优雅的 Golang 代码
原文是一篇非常赞的工程总结,推荐。这里记录一些笔记
- 代码规范,
gofmt
,goimports
,golangci-lint
等,配合 CI 自动化 - 目录结构 Standard Go Project Layout
/pkg
可以被外部使用包模块/internal
私有模块,不可被外部使用- 不要有
/src
目录 /cmd
生成可执行文件/api
对外提供的 API 模块- 不要有
model/controller
这样的模块,按照职责拆分,面向接口开发
- 不要在
init
做资源初始化,比如 rpc/DB/Redis 等,因为 init 会被隐式执行,会默默初始化资源连接 - 推荐的做法是 Client + NewClient,显式初始化连接
- init 阶段适合做一些简单、轻量的前置条件判断,比如
flag
设置 - 使用 GoMock/sqlmock/httpmock/monkey 做 mock + 测试
Simple techniques to optimise Go programs 介绍了一些简单却非常高效的性能提升方法:
- Avoid using structures containing pointers as map keys for large maps, use ints or bytes
- Use strings.Builder to build up strings
- Use strconv instead of
fmt.Sprintf
Power of g in Vim
:[range]g[!]/pattern/cmd
!
means do not match pattern, cmd list:
d
: deletem
: movet
: copy, orco
s
: replace
for more info:
:help ex-cmd
- Power of g
动态添加/删除 Hadoop DataNode
添加节点
- NameNode 添加节点
etc/hadoop/slaves
- 同步
etc/hadoop
配置 - 在新节点
./sbin/hadoop-daemon.sh start datanode
- 在 NameNode 刷新
hdfs dfsadmin -refreshNodes
删除节点
- 在
etc/hadoop/excludes
写入要删掉的节点地址 - 修改
etc/hadoop/hdfs-site.xml
:
<property>
<name>dfs.hosts.exclude</name>
<value>/home/web/hadoop/etc/hadoop/excludes</value>
</property>
- 修改
etc/hadoop/mapred-site.xml
, 这个是下线 nodemanager
<property>
<name>mapred.hosts.exclude</name>
<value>/home/web/hadoop/etc/hadoop/excludes</value>
<final>true</final>
</property>
- 修改
etc/hadoop/slaves
,去掉要删除的节点 - 同步
etc/hadoop/excludes
和etc/hadoop/slaves
到所有 NameNode - 在 NameNode 执行
hdfs dfsadmin -refreshNodes
hdfs dfsadmin -report
查看要删除的节点状态变化Normal -> Decommission in progress -> Decommissioned
- 在要删除的节点
./sbin/hadoop-daemon.sh stop datanode
,等待 Admin State 变更为 Dead
检查节点
hdfs fsck /
检查文件系统信息,正常是 Status: HEALTHY
,如果 Status: CORRUPT
说明 blocks 有损坏,其中 Missing blocks
表示有丢失,但有备份,Missing blocks (with replication factor 1)
表示 block 损坏丢失也没有备份,不可恢复。
可以用 hdfs fsck / -delete
来检查并删除有损坏的 blocks.
调整 JournalNode
- 修改
etc/hadoop/hdfs-site.xml
:
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://hadoop01:8485;hadoop02:8485;hadoop03:8485/cluster</value>
</property>
- 同步到所有节点
- 如果是新增节点,要同步
dfs.journalnode.edits.dir
下 edits 文件 - 在调整的 journalnode 节点启动/关停:
./sbin/hadoop-daemon.sh start journalnode
- 重启 standby NameNode:
sbin/hadoop-daemon.sh stop|start namenode
- 切换节点为 active:
hdfs haadmin -failover nn1 nn2
,重启其他 namenode - 检查 NN 状态
hdfs haadmin -getServiceState nn1
调整 NodeManager
- 修改
etc/hadoop/yarn-site.xml
<property>
<name>yarn.resourcemanager.nodes.exclude-path</name>
<value>/home/pubsrv/hadoop/etc/hadoop/excludes</value>
</property>
- 同步到 ResourceManager
- 重启 ResourceManager,
sbin/yarn-daemon.sh stop|start resourcemanager
- 修改 excludes,添加要删除的节点地址
yarn rmadmin -refreshNodes
yarn node -list -all
检查
调整 Spark 节点
- 新增:在 worker 上
./sbin/start-slave.sh spark://master:7077
- 删除: 在 worker 上
./sbin/stop-slave.sh
,需要注意的是如果$SPARK_PID_DIR
没有指定的话,默认是在/tmp
,类似/tmp/spark-hadoop-org.apache.spark.deploy.worker.Worker-1.pid
-
在 master 节点修改
conf/slaves
- https://www.jianshu.com/p/727da7ba438a
- https://www.iteye.com/blog/shift-alt-ctrl-2102571