我们要对 Newsletter 说不(吗?)
刚看了 diygod 发布的这篇文章 对 Newsletter 说不,对其中的一部分观点不是很认同,但是没有钱包的我没有办法去进行留言评论,索性就借此机会水一篇博客吧 这些问题让我觉得 Newsletter 就像一个没有能力但却拼命想证明自己的暴君,无法很好达到发布者期望的效果,又过分侵犯了用户的选择和效率。 没有一种技术是想要证明自己的,想要证明自己的永远是在技术后面的人。 相比之下,RSS 更加简洁高效。订阅源可以集中管理,分类、收藏、订阅和取消订阅的过程也非常简单。而 Newsletter 则会将各种各样的邮件混合在一起,非常分散且难以管理。你很难知道自己到底订阅了哪些内容,它们什么时候会突然出现。而且,内容格式也是各种各样的,查看和阅读起来非常混乱,所以你也不能将一篇文章进行收藏,更不用说方便的第三方集成了。 Newsletter 很难对内容进行有效分类和过滤,又与所有正常邮件混合在一起,需要花费精力手动整理。这很容易导致信息过载和垃圾邮件的问题。 而 RSS 可以很方便地进行分类和过滤,对于不重要的内容,你也可以一键全部标记为已读瞬间解脱,完全没有压力。 在我使用过的大部分邮件客户端或者说网页端的邮件管理页面来说都有自动归类以及一键已读的功能。 对于 RSS 的更新虽然不算实时,但一般以小时计,类似 RSSHub 等自建服务,甚至可以做到每分钟更新。相比之下,Newsletter 的更新周期,以天甚至周月计,明显滞后了许多。 明显的概念混淆,在上面的一段话中 RSS的更新==RSS主动拉取新内容的时间 但是 newsletter更新时间==newsletter发送者更新的时间 这两者并不等同,而且就算RSS每隔五分钟去拉取一次更新,但是RSS提供者不更新的情况就算你拉得再快也没有用,反观 newsletter 在一般情况下一有新文章更新则会立即推送到读者手中,这不是更新更加及时吗? RSS 的开放性体现在它不需要用户提供个人信息,从而确保了更好的隐私性和安全性。然而,Newsletter 至少需要提供一个邮箱地址,这增加了数据泄露或滥用的风险。更有甚者,电子邮件可能包含恶意链接或附件。 电子邮件可能包含恶意链接或者附件,那 RSS 返回的数据就不会有任何风险了吗? 总结 总的来说,其实 RSS 和 Newsletter 更像是在同一条内容分发赛道上面的不同方向的技术解决方案,RSS 更倾向于面对公众群体的公告板式的内容分发,Newsletter 更倾向于向特定群体提供及时的内容推送服务,两种技术解决方案各有优劣,RSS 代表的是 pull,Newsletter 代表的是 push,一概而论的进行讨论真的很奇怪。 我在这里提出一些 我没有数据支持的观点 Newsletter 的打开率要比 RSS 要高 Newsletter 一般情况下来说平均质量要高 Newsletter 在付费领域比 RSS 更有优势
使用 logstash 采集来自腾讯云 tke 的日志
前提 好久没有给博客除草了,正好最近折腾了下 logstash,记录一下。 为啥要用 logstash 呢,其实是因为在测试环境上面腾讯云 tke 的日志没有开启日志收集,所以在排查问题的时候会十分的痛苦,正好有空了就想着将日志抽出来放进 es 里面,方便以后排查问题,正好看到腾讯云的日志规则是允许将 pod 的 stdout 日志进行采集之后投递到 kafka 的,就小试了一下。 部署 logstash logstash 我选择使用 docker-compose 来进行快速的部署。 以下是部署流程,参考自 deviantony/docker-elk 项目 创建目录 mkdir logstash/config logstash/pipeline -p 创建环境变量 路径 .env ELASTIC_VERSION=8.7.1 LOGSTASH_INTERNAL_PASSWORD='changeme' 创建 Dockerfile 路径 logstasg/Dockerfile ARG ELASTIC_VERSION # https://www.docker.elastic.co/ FROM docker.elastic.co/logstash/logstash:${ELASTIC_VERSION} 配置文件 路径 logstash/config/logstash.yml --- ## Default Logstash configuration from Logstash base image. ## https://github.com/elastic/logstash/blob/main/docker/data/logstash/config/logstash-full.yml # http.host: 0.0.0.0 node.name: logstash 路径 logstash/pipeline/logstash.conf input { beats { port => 5044 } tcp { port => 50000 } } ## Add your filters / logstash plugins configuration here output { elasticsearch { hosts => "elasticsearch:9200" user => "logstash_internal" password => "${LOGSTASH_INTERNAL_PASSWORD}" index => "logstash-%{+YYYY-MM-dd}" } } 启动服务 version: '3....
2022 年度总结
来了来了,晚到了几天的年度总结,但是总算是没有鸽掉 ~ ...
使用 headscale 异地组网
很久之前看过柠檬大佬的使用 N2N 进行异地组网的文章,大受震撼,但是 N2N 的部署体验很难说得上令人愉悦。 然后就听说了 wireguard 被加入 linux 内核,以下是 wireguard 的介绍: WireGuard是由Jason A. Donenfeld开发的开放源代码VPN程序及协议[1],基于Linux内核实现,利用Curve25519进行密钥交换,ChaCha20用于加密,Poly1305用于数据认证,BLAKE2用于散列函数运算[1],支持IPv4和IPv6的第3层。[2]WireGuard旨在获得比IPsec和OpenVPN更好的性能[3]。 确实,wireguard 性能十分不错,但是配置实在是过于繁琐了,如果要往 wireguard 网络中加入一台设备,则需要修改几乎所有连入网络设备的配置文件,实在是太麻烦了,好在现在已经有了 tailscale 这个服务提供商提供了基于 wireguard 的 0 配置的 VPN 组网方案。 而 headscale 就是 tailscale 中控服务端的开源版本,开源版本支持自己部署,同时没有连入设备的数量限制,于是我花了一点时间将 headscale 部署了一下。 使用到的项目 Github:juanfont/headscale Github:gurucomputing/headscale-ui 部署 headscale 这里我使用 docker-componse 进行部署 version: '3.5' services: headscale: image: headscale/headscale:latest-alpine container_name: headscale volumes: - ./container-config:/etc/headscale - ./container-data/data:/var/lib/headscale ports: - 27896:8080 command: headscale serve restart: unless-stopped headscale-ui: image: ghcr.io/gurucomputing/headscale-ui:latest restart: unless-stopped container_name: headscale-ui ports: - 9443:443 同时我还使用了nginx来进行反向代理,将 headscale-ui 和 headscale 分别部署在了不同的域名下面,因此要做一些 CORS 的处理,Nginx 配置文件参考如下...
使用 ssh 密钥签名 git commit
在 Github commit添加verified标识 这篇文章中,配置好了 gpg 密钥签名作为标识 git commit 是否值得信任带凭证,但是载后面使用签名的过程中渐渐感到了一丝丝的麻烦,因为 gpg 密钥在我日常的生活中并没有很多其他的用处。最近 github 支持了显示通过 ssh 密钥签名的 commit 的功能。ssh 密钥在日常用起来要比 gpg 密钥要多得多,所以配置了一下,顺便写个文章记录操作流程。 git config --global gpg.format ssh git config --global user.signingKey ~/.ssh/id_ed25519.pub git config --global commit.gpgsign true git config --global tag.gpgsign true 一般来说,配置好了这几个选项,就可以顺利的把签名加上了,要是 git commit 的时候提示你 ssh是不支持的格式 那么就意味着当前版本的 git 并不支持通过 ssh 密钥签名 commit,这时候就要自己更新下系统上面的 git 了。
使用 docker-compose 搭建 clickhouse 集群
Docker Compose 配置 version: '3' services: clickhouse-server-ck1: restart: on-failure:10 # 退出非0重启,尝试10次 image: yandex/clickhouse-server container_name: ck1 networks: - ck-network ports: - "8124:8123" - "9001:9000" - "9010:9004" volumes: - `pwd`/clickhouse/:/var/lib/clickhouse/ - `pwd`/clickhouse-server/:/etc/clickhouse-server/ - `pwd`/log/clickhouse-server/:/var/log/clickhouse-server/ ulimits: nofile: soft: "262144" hard: "262144" depends_on: - zookeeper-1 clickhouse-server-ck2: restart: on-failure:10 # 退出非0重启,尝试10次 image: yandex/clickhouse-server container_name: ck2 networks: - ck-network ports: - "8125:8123" - "9002:9000" - "9011:9004" volumes: - `pwd`/clickhouse2/:/var/lib/clickhouse/ - `pwd`/clickhouse-server2/:/etc/clickhouse-server/ - `pwd`/log/clickhouse-server2/:/var/log/clickhouse-server/ ulimits: nofile: soft: "262144" hard: "262144" depends_on: - zookeeper-1 clickhouse-server-ck3: restart: on-failure:10 # 退出非0重启,尝试10次 image: yandex/clickhouse-server container_name: ck3 networks: - ck-network ports: - "8126:8123" - "9003:9000" - "9012:9004" volumes: - `pwd`/clickhouse3/:/var/lib/clickhouse/ - `pwd`/clickhouse-server3/:/etc/clickhouse-server/ - `pwd`/log/clickhouse-server3/:/var/log/clickhouse-server/ ulimits: nofile: soft: "262144" hard: "262144" depends_on: - zookeeper-1 zookeeper-1: restart: on-failure:10 # 退出非0重启,尝试10次 image: zookeeper:3....
Go 实现瑞士轮排列算法
工作原因接触到了瑞士轮这种赛制,记录一下瑞士轮比赛对手编排的算法 瑞士轮有两个规则 选择积分相近的对手进行比赛 不会重复比赛 写出来的算法如下: type player struct { Id int64 Score int64 Opponent map[int64]struct{} // 曾经遇到过的对手 } // pickTablePlayer 计算瑞士轮比赛排列 func pickTablePlayer(players []int64, playerOpponentMap map[int64]map[int64]struct{}) ([]int64, bool) { if len(players) < 2 { return players, true } whitePlayer := players[0] opponentMap, _ := playerOpponentMap[whitePlayer] for i := range players { if i != 0 { // 判断是否已经比过 if _, has := opponentMap[players[i]]; !has { // 选中 res := make([]int64, 2) res[0] = whitePlayer res[1] = players[i] // 组装剩下排序的数据 var nextRound []int64 nextRound = append(nextRound, players[1:i]....
Oneplus 8T 刷入 LineageOS
劳动节来给博客除除草! 自从一加手机社区发布了官方公告说 Android 12 正式版本出来了之后我就一直在等系统更新的推送,谁知道从4月12日公告出来到今天我都没有收到推送,再加上一加的在 Android 12 后 HOS 会切换成 ColorOS,类原生的特点就没有了,OOS 虽说还会持续维护,但是我既然都用 OOS 了我为啥不自己刷个更加原生的系统呢?比如说 LineageOS。 前期准备 说干就干,先去官网看下有没有支持,芜湖,有支持而且看了下文档还蛮完善的,备份好微信(这个手机里面唯一没有同步功能的app)的数据就打算开始刷机了。 开刷 刷机的过程官方文档已经非常完善了,在这里不重复赘述。 一些要注意的小问题 GAPPS GAPPS 一定要在首次启动系统之前刷入,不然就要双清,之前辛苦配置的东西都无了 SafetyNet 在刷好系统之后,我自然是想打开 ingress 玩下,然后折腾了半天,一直在提醒 ”ingress 需要安全登录“,一开始还以为是代理的问题,疯狂切换代理都没有用,后来查到这个讨论发现是 SafetyNet 的问题,于是 Magisk 刷入了 MagiskHide Props Config、Universal SafetyNet Fix 两个模块解决了这个问题 Universal SafetyNet Fix 这个模块无需任何配置,直接刷入即可生效 MagiskHide Props Config 这个则需要在shell执行指令 props 按照提示选择即可。 相机 自带的相机 app 太拉了,直接停用,在 Google Camera Port 下载了个最新版本的相机,以及挑了个推荐的配置文件。 使用感受 原生的系统真是舒服啊,没有了一些有的没有的app,动画啥的感觉要比HOS要好。高帧率、AOD、蓝牙HD音频编码、屏下指纹这些都没有啥大问题。 甚至有些之前在HOS上面没有体验过的特性,比如说锁屏音乐可视化 总的来说挺满意的,再看看后续使用的过程中有没有啥坑了,就这样。