想知道谁在裸泳吗?
🖨 一招搞定!让旧打印机支持iPhone无线打印
🔗 项目来源: AirPrint_Bridge
🧭 实测总结
⚙️ 安装难度 ★★☆☆☆
📱 兼容性★★★★☆
💨 运行稳定性 ★★★★☆
💡 实用性 ★★★★★
由于最近小孩上学需要经常打印一些老师发的资料,在家打印文件时遇到个老大难问题——
我的那台老款打印机不支持 AirPrint,需要将文件通过Airdrop或者登录通讯软件转到电脑上再打印,操作相当繁琐😩。查了一圈资料后,我决定自己动手搭建一个 AirPrint 服务。没想到居然成功了!现在手机点一下就能直接打印,体验满分。
💻 测试环境
系统:macOS
打印机:惠普1136激光打印机
🧩 第一步:安装驱动 + 开启共享打印机
先确保打印机驱动已安装并能正常打印。
然后进入 系统设置 → 打印机设置,
打开“在网络上共享此打印机”。
(不共享,手机永远找不到!)
⚙️ 第二步:安装 AirPrint 脚本服务
因为打印机本身不支持 AirPrint,
所以我们用一个开源脚本来“桥接”服务。
打开终端(Terminal),CD进安装所需的文件夹,输入以下命令下载项目并回车
git clone https://github.com/sapireli/AirPrint_Bridge.git
cd AirPrint_Bridge或者使用 Homebrew 安装
brew tap sapireli/AirPrint_Bridge https://github.com/sapireli/AirPrint_Bridge.git
brew install airprint-bridge再赋予执行权限:
chmod +x airprint_bridge.sh🧪 第三步:测试是否可用
执行测试命令:
sudo ./airprint_bridge.sh -t输入电脑密码(输入过程不会显示,直接回车)。
此时脚本会启动临时服务,
打开 iPhone → 相册 → 分享 → 打印,
看看能不能找到打印机。
如果出现 ✅,恭喜你成功一半啦!
🚀 第四步:正式安装
在终端按下 Ctrl + C 终止测试,
然后执行:
sudo ./airprint_bridge.sh -i安装完成后,AirPrint 服务会自动运行,
以后手机、iPad 都能无线打印啦~📱✨
🗑 卸载方法
不想用了?在脚本目录执行:
sudo ./airprint_bridge.sh -u👨🏻💻 碎碎念
有其实折腾这个 AirPrint 服务之前,我还真犹豫过要不要直接换一台新打印机或者买个Airprint盒子。但折腾完之后发现老设备不一定过时,只是需要一点耐心。也再次证明:
能用代码解决的问题,都不是大问题 😎。
频道:@NewlearnerChannel
毫无意外的,淘宝闪购和饿了么,这一套班子、两块牌子,很快就要「二合一」。淘宝闪购,未来将成为阿里唯一的外卖+即时零售品牌招牌。
目前还没有官宣,只是已经有部分用户的饿了么App收到灰度更新,淘宝闪购四个大字占据了图标上的绝对主体,目测App的正式更名也只是时间问题了。
之所以说这件事情并不意外,是因为此前的双品牌结构看起来确实有些拧巴了,明明已经打通了供给和履约,对外依然有「淘宝闪购提供补贴,饿了么提供履约支持」这类要在两个品牌露出上端水的拗口解释。
不过可以理解的是,在打仗的时候,一切以战线为优先,而在「外卖大战」进入新一轮格局形势后,重新定位品牌的空间和价值,理所应当。
这是一个「自然而然,水到渠成」的选择。
我们可以稍微回顾淘宝闪购是怎么一步步在即时零售市场占据主体性的:
今年4月,淘宝站内原本服务于即时零售的「小时达」正式升级为「淘宝闪购」,并拿到了淘宝App的一级入口,全面接入饿了么供给和服务;
到了5月,淘宝闪购在小长假期间提前全量上线,开始发放大额红包以促日活,并火速签下了汪苏泷作为代言人;
再到7月,淘宝闪购拿出了500亿的巨额补贴,高调加入「外卖大战」,直接把京东和美团的Q3利润打成骨折;
最后是8月,蒋凡在财报会议上发出阶段性胜利的定调,宣布单日1.2亿订单的峰值,在外卖行业打出了「坐二望一」的地位;
⋯⋯
整个过程看起来大兴土木,其实只用了半年不到的时间,淘宝闪购的心智就已经立了起来。
比如在相关话题的评论区,网友已经普遍将「闪购」这个词默认为淘宝闪购,而不是更早提出闪购这个概念的美团闪购,这很有意思。
不是说美团做得不如阿里,恰恰相反,是美团在外卖上过于深入了,才会削弱闪购业务的品牌认知。
就像一个用户在美团外卖上分别点了一份麦当劳和一根充电线,他很难分得清楚,前者出自美团外卖的业务,后者出自美团闪购的业务,在他看来,这都是自己下了一单外卖。
但淘宝闪购之于淘宝,却不是这样的关系,淘宝是快递电商的模式,是要去拆包裹的,而淘宝闪购是骑手小哥送货上门,是淘宝新开通的外卖服务。
这就导致了,虽然淘宝闪购是一个更新的品牌,但是因为它没有历史包袱的混淆,在落地上更加丝滑流畅,便于理解。
理解了这个必然发生的结果,也就能够理解阿里需要扬长避短的考虑。
虽然有点暴论,但我还是想说,在被美团常年压着打的发展史里,饿了么已经印上了「万年老二」的钢印,甚至难洗刷一种战败主义的悲壮标签。
甚至行业内都有默认的传言,声称美团故意留着饿了么,是不想加深市场垄断的嫌疑。
所以这么些年来,市场来观察饿了么在阿里的盘子里——资产属性就一直大于业务属性,否则也不会隔三差五就出现要卖给抖音的小道消息了。
在历次所谓的「误报」辟谣里,阿里对于饿了么是优质资产的标准判断很明确:这是重要战略性业务。尤其花了18年积累下来的本地履约网络更是非卖品。
所以各路消息也说,收购方看重的也是后者,所以双方始终谈不拢,大家对于真正值钱的是什么,有着高度一致的看法。
所以自从开打「外卖大战」以来,其实可以看出饿了么品牌的对外表达是在逐步淡化的:一方面是它必须出现在整个体系里,输送供给、流量和配送等资源,另一方面它又不再是这个周期的品牌主角,时刻注意不要「抢戏」。
即使要讲故事,也不会是重新武装饿了么去和美团开战的剧本,这多少有些「我打宿傩」的幽默感,真正高燃的剧情,是淘宝拿着9亿月活下场,最后还给电商业务挣了1亿新增用户。
什么叫他妈的惊喜?这就是了。
其实从前段时间的骑手换装就能看出,新款工装已经由淘宝闪购占据了绝对核心的上身部分,而饿了么是和菜鸟、速卖通一起并列,主次分明。
哲学上的「忒修斯之船」就是如此造出来的,从一个铁钉开始逐渐替换,直至每一块甲板都是新的,那么这艘船,还是不是之前的忒修斯号?
显然,阿里站在了霍布斯而非亚里士多德的一边,霍布斯的唯物主义认为,物质构成大于符号意义,新船就应该用新的名字。
无论是马云提出的「回归淘宝」主战略,还是吴泳铭为淘宝设计的「大消费平台」愿景,用这个历经淬炼的国民级品牌,来为闯入增量市场提供确定性,都是相当聪明的一步棋。
除了适合构建外部的消费者心智以外,在内部组织的调度上,淘宝闪购这种一号位工程的名头,也远比饿了么要好使。
尤其是考虑到还和美团有着旷日持久的竞争,用淘宝背书,意味着恒产者有恒心,这在争取代理商的信任方面,百利无害。
据我所知,在暑期档的「外卖大战」期间,已经有一些代理商先表示,希望改用淘宝闪购作为店头物料,这对他们商业生态和合作拓展,都是有帮助的。
腾笼换鸟,笼不重要,重要的是,鸟要飞得更快。
by @阑夕ོ #科技圈大小事
目前还没有官宣,只是已经有部分用户的饿了么App收到灰度更新,淘宝闪购四个大字占据了图标上的绝对主体,目测App的正式更名也只是时间问题了。
之所以说这件事情并不意外,是因为此前的双品牌结构看起来确实有些拧巴了,明明已经打通了供给和履约,对外依然有「淘宝闪购提供补贴,饿了么提供履约支持」这类要在两个品牌露出上端水的拗口解释。
不过可以理解的是,在打仗的时候,一切以战线为优先,而在「外卖大战」进入新一轮格局形势后,重新定位品牌的空间和价值,理所应当。
这是一个「自然而然,水到渠成」的选择。
我们可以稍微回顾淘宝闪购是怎么一步步在即时零售市场占据主体性的:
今年4月,淘宝站内原本服务于即时零售的「小时达」正式升级为「淘宝闪购」,并拿到了淘宝App的一级入口,全面接入饿了么供给和服务;
到了5月,淘宝闪购在小长假期间提前全量上线,开始发放大额红包以促日活,并火速签下了汪苏泷作为代言人;
再到7月,淘宝闪购拿出了500亿的巨额补贴,高调加入「外卖大战」,直接把京东和美团的Q3利润打成骨折;
最后是8月,蒋凡在财报会议上发出阶段性胜利的定调,宣布单日1.2亿订单的峰值,在外卖行业打出了「坐二望一」的地位;
⋯⋯
整个过程看起来大兴土木,其实只用了半年不到的时间,淘宝闪购的心智就已经立了起来。
比如在相关话题的评论区,网友已经普遍将「闪购」这个词默认为淘宝闪购,而不是更早提出闪购这个概念的美团闪购,这很有意思。
不是说美团做得不如阿里,恰恰相反,是美团在外卖上过于深入了,才会削弱闪购业务的品牌认知。
就像一个用户在美团外卖上分别点了一份麦当劳和一根充电线,他很难分得清楚,前者出自美团外卖的业务,后者出自美团闪购的业务,在他看来,这都是自己下了一单外卖。
但淘宝闪购之于淘宝,却不是这样的关系,淘宝是快递电商的模式,是要去拆包裹的,而淘宝闪购是骑手小哥送货上门,是淘宝新开通的外卖服务。
这就导致了,虽然淘宝闪购是一个更新的品牌,但是因为它没有历史包袱的混淆,在落地上更加丝滑流畅,便于理解。
理解了这个必然发生的结果,也就能够理解阿里需要扬长避短的考虑。
虽然有点暴论,但我还是想说,在被美团常年压着打的发展史里,饿了么已经印上了「万年老二」的钢印,甚至难洗刷一种战败主义的悲壮标签。
甚至行业内都有默认的传言,声称美团故意留着饿了么,是不想加深市场垄断的嫌疑。
所以这么些年来,市场来观察饿了么在阿里的盘子里——资产属性就一直大于业务属性,否则也不会隔三差五就出现要卖给抖音的小道消息了。
在历次所谓的「误报」辟谣里,阿里对于饿了么是优质资产的标准判断很明确:这是重要战略性业务。尤其花了18年积累下来的本地履约网络更是非卖品。
所以各路消息也说,收购方看重的也是后者,所以双方始终谈不拢,大家对于真正值钱的是什么,有着高度一致的看法。
所以自从开打「外卖大战」以来,其实可以看出饿了么品牌的对外表达是在逐步淡化的:一方面是它必须出现在整个体系里,输送供给、流量和配送等资源,另一方面它又不再是这个周期的品牌主角,时刻注意不要「抢戏」。
即使要讲故事,也不会是重新武装饿了么去和美团开战的剧本,这多少有些「我打宿傩」的幽默感,真正高燃的剧情,是淘宝拿着9亿月活下场,最后还给电商业务挣了1亿新增用户。
什么叫他妈的惊喜?这就是了。
其实从前段时间的骑手换装就能看出,新款工装已经由淘宝闪购占据了绝对核心的上身部分,而饿了么是和菜鸟、速卖通一起并列,主次分明。
哲学上的「忒修斯之船」就是如此造出来的,从一个铁钉开始逐渐替换,直至每一块甲板都是新的,那么这艘船,还是不是之前的忒修斯号?
显然,阿里站在了霍布斯而非亚里士多德的一边,霍布斯的唯物主义认为,物质构成大于符号意义,新船就应该用新的名字。
无论是马云提出的「回归淘宝」主战略,还是吴泳铭为淘宝设计的「大消费平台」愿景,用这个历经淬炼的国民级品牌,来为闯入增量市场提供确定性,都是相当聪明的一步棋。
除了适合构建外部的消费者心智以外,在内部组织的调度上,淘宝闪购这种一号位工程的名头,也远比饿了么要好使。
尤其是考虑到还和美团有着旷日持久的竞争,用淘宝背书,意味着恒产者有恒心,这在争取代理商的信任方面,百利无害。
据我所知,在暑期档的「外卖大战」期间,已经有一些代理商先表示,希望改用淘宝闪购作为店头物料,这对他们商业生态和合作拓展,都是有帮助的。
腾笼换鸟,笼不重要,重要的是,鸟要飞得更快。
by @阑夕ོ #科技圈大小事
看到一个很有意思的数据对比:
中国市场避孕套的销售额去年是156亿人民币,同比下降17%,相较2019年的高点,更是萎缩了1/4以上;
同期中国市场情趣用品的销售额增长却高到离谱,每年稳定增长15%,去年交易额接近2000亿人民币,比起2019年翻了个倍。
报告结论很扎心,就一句话:
「这代人的性生活,不需要两个人了。」
by @阑夕ོ #你不知道的行业内幕
中国市场避孕套的销售额去年是156亿人民币,同比下降17%,相较2019年的高点,更是萎缩了1/4以上;
同期中国市场情趣用品的销售额增长却高到离谱,每年稳定增长15%,去年交易额接近2000亿人民币,比起2019年翻了个倍。
报告结论很扎心,就一句话:
「这代人的性生活,不需要两个人了。」
by @阑夕ོ #你不知道的行业内幕
今天看唐彬森的演讲,深刻地解释了为什么大公司会有「资源诅咒」
大公司的核心问题在于决策。
大公司高管上班考虑的是什么?领导的KPI、公司战略、怎么要资源。
他们解决问题的方式,往往是用钱、用渠道,而不是产品。
流量不够?百度申请一笔预算,打一波广告,马上就起来了。谁愿意去做那些苦哈哈的产品优化?
他们考虑的都是短线问题,不会考虑长线问题。
什么叫短线?向公司要资源、向领导做PPT。
什么叫长线?产品。
他去了趟以色列,发现这个国家啥也没有,但比周围那些有石油的国家都赚钱。
经济学上有个专业术语就叫"资源诅咒"。那些有资源的国家,像俄罗斯、巴西、阿拉伯那些国家,高科技产业反而发展不好。
为什么?因为挣钱太容易了。
就像大公司高管一样,要完成KPI,最好的办法就是申请预算,打广告,马上见效。
但那些做得好的国家,芬兰、日本、以色列,都是没资源的国家。
所以他跟团队说:"穷人家的孩子早当家。"
人只有在资源极度紧缺的情况下,才会迸发出创造力。
资源太多的话,想的都是怎么花钱,怎么向领导申请预算。
互联网最牛的公司都不是靠钱做起来的,大公司都是靠钱砸死的,都是靠推广把产品搞死的。
雷军做小米的时候跟林斌说:"我们小米要做营销,没有预算,零预算。"
这就是创业公司的文化,用零预算的方式把东西做起来,这才是团队的能力,这才是跟大公司竞争的唯一优势。
完整版
唐彬森:钱没用,小公司靠这个逆袭大公司 - ListenHub
https://listenhub.ai/episode/69074e2b28f1543f57ce556d
by @OrangeAI #科技圈大小事
大公司的核心问题在于决策。
大公司高管上班考虑的是什么?领导的KPI、公司战略、怎么要资源。
他们解决问题的方式,往往是用钱、用渠道,而不是产品。
流量不够?百度申请一笔预算,打一波广告,马上就起来了。谁愿意去做那些苦哈哈的产品优化?
他们考虑的都是短线问题,不会考虑长线问题。
什么叫短线?向公司要资源、向领导做PPT。
什么叫长线?产品。
他去了趟以色列,发现这个国家啥也没有,但比周围那些有石油的国家都赚钱。
经济学上有个专业术语就叫"资源诅咒"。那些有资源的国家,像俄罗斯、巴西、阿拉伯那些国家,高科技产业反而发展不好。
为什么?因为挣钱太容易了。
就像大公司高管一样,要完成KPI,最好的办法就是申请预算,打广告,马上见效。
但那些做得好的国家,芬兰、日本、以色列,都是没资源的国家。
所以他跟团队说:"穷人家的孩子早当家。"
人只有在资源极度紧缺的情况下,才会迸发出创造力。
资源太多的话,想的都是怎么花钱,怎么向领导申请预算。
互联网最牛的公司都不是靠钱做起来的,大公司都是靠钱砸死的,都是靠推广把产品搞死的。
雷军做小米的时候跟林斌说:"我们小米要做营销,没有预算,零预算。"
这就是创业公司的文化,用零预算的方式把东西做起来,这才是团队的能力,这才是跟大公司竞争的唯一优势。
完整版
唐彬森:钱没用,小公司靠这个逆袭大公司 - ListenHub
https://listenhub.ai/episode/69074e2b28f1543f57ce556d
by @OrangeAI #科技圈大小事
saka 老师前几周分享的这篇文章 https://skoredin.pro/blog/golang/cpu-cache-friendly-go 非常有意思,我虽然日常在 pahole 输出里看到 cacheline,但对其如何影响程序运行的理解也非常模糊。
不过更有意思的是,我已经见到三位工程师在 AI 的辅助下试图测试 “cacheline padding 带来六倍性能提升” 却没有成功,最后吐槽这是一篇错文、AI文。这里有一个有趣的知识屏障,如果不理解 cacheline 在何时会影响性能,那就可能无法写出正确的测试程序;但无法写出正确的测试程序又无法理解 cacheline 如何影响性能,知识死锁了。
你以为我想说原文的 “cacheline导致六倍性能差距” 的结论是正确的?不,那是错误的 有前提条件的,并非通用结论🤪
这些对我也是新知识,水平有限,施工区域谨慎阅读🤬
我的测试代码不用很多工程师和 AI 用的 go bench 方法,因为抽象程度太高了,在这种性能施工区最好就写一眼能看穿汇编的简单代码。
提供了两套变式, 通过命令行的 arg1 和 arg2 指定是否 padding 和是否用 atomic.AddUint64。
我本地的 cpu 0,1 是同一个核心,1,2 是不同核心,所以测试命令是
很多细节我依然在学习中,目前可以公开的情报是:(+表示前者性能更好,-反之)
1. "pad atom" vs "nopad atom": +7.3倍性能
2. "pad nonatom" vs "nopad noatom": +3.3倍
3. "pad atom" vs "pad noatom": -2.5倍
4. "nopad atom" vs "nopad noatom": -5倍
可以看到 atom (lock prefix insn)本身就造成大量的性能影响,而 pad 会进一步加重 cacheline false sharing 导致更极端的性能差距。原文里的六倍性能差距是在 atom + pad 的场景下的测试结果,但我觉得大部分场景根本不会这么极端。
核心绑定情况也会造成很大影响。如果绑核改为 0,1 cpu,它们是同一 core,测试结果是:
1. "pad atom" vs "nopad atom": +1.75
2. "pad noatom" vs "nopad noatom": +1.65
3. "pad atom" vs "pad noatom": -1.9
4. "nopad atom" vs "nopad noatom": -2.0
在这些测试里,经典的 perf topdown 方法在 L2->L3->L4 几乎完全失效,经常会看到 L2 的 tma_core_bound 40% 然后 tma_core_bound_group breakdown 是 0%、L3 的 tma_l3_bound 15% 然而 L4 的 tma_l3_bound_group 里面四个 0%。我的 cpu 型号是 x86 meteorlake,仔细看了 pmu metrics 定义之后我觉得这就是设计上的问题,L2 再往下没有保证,只能靠微指令法师的经验来跳跃性猜测和验证。
可以确定有用的 metrics 是
- tma_store_fwd_blk: atom vs noatom 性能差距的罪魁,lock prefix insn 阻止了 store forwarding (CSAPP $4.5.5.2) 导致性能大幅下降
- tma_false_sharing: cacheline 在多核心上共享时的 race。原文其实主要就是在讨论这个讨论的性能问题。
- tma_l3_bound: snoop hitm 的间接指标。
- L1-dcache-loads,L1-dcache-load-misses: cacheline racing 的间接指标。但由于 l1 miss 至少包含了 "cacheline 不在 L1" 和 "cacheline 在 L1 但是失效",这个 miss 率其实很容易误导。
如何从 metrics 找到源码:
perf list 文档写得不全,直接看内核里的 pmu-events/.../mtl-metrics.json,比如说 perf record -M tma_false_sharing 很高,json 文件里这一项的 PublicDescription 就会写
然后采样
然后可以可以画火焰图和栈回溯,但我现在喜欢 perf annotate -l --stdio 直接看指令
看到 87% 的 false sharing 都是由于 inc %rcx 导致的。
讲完方法论终于可以回到主题了,cacheline 如何影响性能:如果是一个线程共享数据 A 在多核上并行 ++,核心1 修改了 A,那么核心2 的 L1 缓存的包含 A 的 cacheline 就会失效,这就是 false sharing。对于共享数据 A 来说这不可避免,但是如果有另一个 独立 数据 B 和 A 在同一个 cacheline,那么 A 在多核上刷存在感就会导致 B 的 L1 cache 失效,尽管 B 可能完全是一个单线程非共享数据。好的 cacheline 设计可以加上一段 padding 把 B 强制隔离出 A 所在的 cacheline,这样 A 刷新 cacheline 不会导致 B 的 cacheline 失效。
这些知识真的非常晦涩难懂,资料很少,AI 基本在帮倒忙,我感觉像是在星际航行,目睹所有令人惊叹的宇宙奇观,恍惚间就化入无穷。
不过更有意思的是,我已经见到三位工程师在 AI 的辅助下试图测试 “cacheline padding 带来六倍性能提升” 却没有成功,最后吐槽这是一篇错文、AI文。这里有一个有趣的知识屏障,如果不理解 cacheline 在何时会影响性能,那就可能无法写出正确的测试程序;但无法写出正确的测试程序又无法理解 cacheline 如何影响性能,知识死锁了。
你以为我想说原文的 “cacheline导致六倍性能差距” 的结论是正确的?不,那是
这些对我也是新知识,水平有限,施工区域谨慎阅读
我的测试代码不用很多工程师和 AI 用的 go bench 方法,因为抽象程度太高了,在这种性能施工区最好就写一眼能看穿汇编的简单代码。
package main
import (
"fmt"
"os"
"sync"
"sync/atomic"
"time"
)
const N = 100_000_000
type Counters interface {
Inc(idx int)
AtomicInc(idx int)
Result(idx int) uint64
}
type unpaddingCounters [8]uint64
func (u *unpaddingCounters) Inc(idx int) {
u[idx]++
}
func (u *unpaddingCounters) AtomicInc(idx int) {
atomic.AddUint64(&u[idx], 1)
}
func (u *unpaddingCounters) Result(idx int) uint64 {
return u[idx]
}
type paddingCounter struct {
val uint64
_ [56]byte
}
type PaddingCounters [8]paddingCounter
func (p *PaddingCounters) Inc(idx int) {
p[idx].val++
}
func (p *PaddingCounters) AtomicInc(idx int) {
atomic.AddUint64(&p[idx].val, 1)
}
func (p *PaddingCounters) Result(idx int) uint64 {
return p[idx].val
}
func main() {
var counters Counters
if os.Args[1] == "pad" {
counters = &PaddingCounters{}
} else {
counters = &unpaddingCounters{}
}
var inc func(idx int)
if os.Args[2] == "atom" {
inc = counters.AtomicInc
} else {
inc = counters.Inc
}
start := time.Now()
var wg sync.WaitGroup
for i := 0; i < 8; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for j := 0; j < N; j++ {
inc(i)
}
}()
}
wg.Wait()
fmt.Printf("Duration: %v ", time.Since(start))
for i := 0; i < 8; i++ {
fmt.Printf("Counter[%d]=%d ", i, counters.Result(i))
}
fmt.Println()
}
提供了两套变式, 通过命令行的 arg1 和 arg2 指定是否 padding 和是否用 atomic.AddUint64。
我本地的 cpu 0,1 是同一个核心,1,2 是不同核心,所以测试命令是
taskset -c 1,2 perf stat -d -- env GOMAXPROCS=2 ./go_cpu_perf pad atom很多细节我依然在学习中,目前可以公开的情报是:(+表示前者性能更好,-反之)
1. "pad atom" vs "nopad atom": +7.3倍性能
2. "pad nonatom" vs "nopad noatom": +3.3倍
3. "pad atom" vs "pad noatom": -2.5倍
4. "nopad atom" vs "nopad noatom": -5倍
可以看到 atom (lock prefix insn)本身就造成大量的性能影响,而 pad 会进一步加重 cacheline false sharing 导致更极端的性能差距。原文里的六倍性能差距是在 atom + pad 的场景下的测试结果,但我觉得大部分场景根本不会这么极端。
核心绑定情况也会造成很大影响。如果绑核改为 0,1 cpu,它们是同一 core,测试结果是:
1. "pad atom" vs "nopad atom": +1.75
2. "pad noatom" vs "nopad noatom": +1.65
3. "pad atom" vs "pad noatom": -1.9
4. "nopad atom" vs "nopad noatom": -2.0
在这些测试里,经典的 perf topdown 方法在 L2->L3->L4 几乎完全失效,经常会看到 L2 的 tma_core_bound 40% 然后 tma_core_bound_group breakdown 是 0%、L3 的 tma_l3_bound 15% 然而 L4 的 tma_l3_bound_group 里面四个 0%。我的 cpu 型号是 x86 meteorlake,仔细看了 pmu metrics 定义之后我觉得这就是设计上的问题,L2 再往下没有保证,只能靠微指令法师的经验来跳跃性猜测和验证。
可以确定有用的 metrics 是
- tma_store_fwd_blk: atom vs noatom 性能差距的罪魁,lock prefix insn 阻止了 store forwarding (CSAPP $4.5.5.2) 导致性能大幅下降
- tma_false_sharing: cacheline 在多核心上共享时的 race。原文其实主要就是在讨论这个讨论的性能问题。
- tma_l3_bound: snoop hitm 的间接指标。
- L1-dcache-loads,L1-dcache-load-misses: cacheline racing 的间接指标。但由于 l1 miss 至少包含了 "cacheline 不在 L1" 和 "cacheline 在 L1 但是失效",这个 miss 率其实很容易误导。
如何从 metrics 找到源码:
perf list 文档写得不全,直接看内核里的 pmu-events/.../mtl-metrics.json,比如说 perf record -M tma_false_sharing 很高,json 文件里这一项的 PublicDescription 就会写
Sample with: OCR.DEMAND_RFO.L3_HIT.SNOOP_HITM然后采样
perf record -F9999 -g -e OCR.DEMAND_RFO.L3_HIT.SNOOP_HITM然后可以可以画火焰图和栈回溯,但我现在喜欢 perf annotate -l --stdio 直接看指令
0.42 : 4949aa: inc %rcx
: 42 inc(i)
87.08 : 4949ad: mov 0x18(%rsp),%rax看到 87% 的 false sharing 都是由于 inc %rcx 导致的。
讲完方法论终于可以回到主题了,cacheline 如何影响性能:如果是一个线程共享数据 A 在多核上并行 ++,核心1 修改了 A,那么核心2 的 L1 缓存的包含 A 的 cacheline 就会失效,这就是 false sharing。对于共享数据 A 来说这不可避免,但是如果有另一个 独立 数据 B 和 A 在同一个 cacheline,那么 A 在多核上刷存在感就会导致 B 的 L1 cache 失效,尽管 B 可能完全是一个单线程非共享数据。好的 cacheline 设计可以加上一段 padding 把 B 强制隔离出 A 所在的 cacheline,这样 A 刷新 cacheline 不会导致 B 的 cacheline 失效。
这些知识真的非常晦涩难懂,资料很少,AI 基本在帮倒忙,我感觉像是在星际航行,目睹所有令人惊叹的宇宙奇观,恍惚间就化入无穷。
刚从香港回来,腿已跑废,但一天就线上搞定了汇丰、中银、众安、天星、蚂蚁5家银行!
趁热分享流程和避坑经验,跟着这篇准备,包你稳过。
准备工作 (漏了就白跑,别问我怎么知道的):
证件: 身份证、港澳通行证,有效期都得大于6个月。
手机号: 必须开通国际漫游收验证码!上网是另一回事。
出入境记录: 抵港后,微信小程序“12367”下载PDF,只要有一次内地出境记录就行。
收卡地址: 提前翻译好中英文,地址太长学点缩写 (Building→BLDG)。
银行APP: 提前下好汇丰、中银、众安、天星,蚂蚁银行在支付宝小程序。
开户流程:
到香港找个信号好的地方开干。推荐顺序:先汇丰,再中银,最后搞定剩下的虚拟银行。
🚀 第一站:汇丰银行 (HSBC)
这家是老牌大哥,必须拿下。全程APP线上操作。
打开 HSBC HK APP,点“我没有任何账户”。
关键选择:“身处香港,没有香港身份证”。
账户类型选 “汇丰one”。
填信息:
开户用途:就选“储蓄/投资”,别整那些复杂的。
税务编号:就是你的内地身份证号。
收件地址:把你准备好的中英文地址填进去,注意字数限制。
上传资料:按提示拍身份证,然后用手机 NFC 功能把通行证贴在手机背后,它会自动读取芯片信息。
设置用户名密码,提交。
顺利的话,几分钟内就会收到审核通过的邮件。然后就等着收卡吧。
🥈 第二站:中银香港 (BOCHK)
中银也算是亲儿子,流程也挺顺。
打开 BOCHK APP,点“开立账户”。
身份选“中国居民身份证”,然后选 “我身处香港”。
开户方式选“我不在分行”,然后“即时开立”。
账户类型选 “自在理财”,这个也没存款要求。
上传资料:这里就要用到你之前准备的出入境记录PDF了。然后按要求拍身份证和港澳通行证。
人脸识别,找个亮堂点的地方。
填个人信息:职业如实写,开户理由选“投资理财”或“储蓄”。地址一定要详细到门牌号。
提交后也是很快出结果。
🎯 第三、四、五站:众安、天星、蚂蚁
这三家是虚拟银行,流程大同小异,放在一起说。基本就是填资料、上传证件、人脸识别三板斧。
有几个点注意下:
地址:同样要精确到门牌号。
税务身份:一般都选“仅为内地税务居民”。
税务号:填身份证号。
出入境记录:都要上传。众安银行比较灵活,可以开户成功,离港后再补充上传。
by @何夕2077 #你不知道的行业内幕
趁热分享流程和避坑经验,跟着这篇准备,包你稳过。
准备工作 (漏了就白跑,别问我怎么知道的):
证件: 身份证、港澳通行证,有效期都得大于6个月。
手机号: 必须开通国际漫游收验证码!上网是另一回事。
出入境记录: 抵港后,微信小程序“12367”下载PDF,只要有一次内地出境记录就行。
收卡地址: 提前翻译好中英文,地址太长学点缩写 (Building→BLDG)。
银行APP: 提前下好汇丰、中银、众安、天星,蚂蚁银行在支付宝小程序。
开户流程:
到香港找个信号好的地方开干。推荐顺序:先汇丰,再中银,最后搞定剩下的虚拟银行。
🚀 第一站:汇丰银行 (HSBC)
这家是老牌大哥,必须拿下。全程APP线上操作。
打开 HSBC HK APP,点“我没有任何账户”。
关键选择:“身处香港,没有香港身份证”。
账户类型选 “汇丰one”。
填信息:
开户用途:就选“储蓄/投资”,别整那些复杂的。
税务编号:就是你的内地身份证号。
收件地址:把你准备好的中英文地址填进去,注意字数限制。
上传资料:按提示拍身份证,然后用手机 NFC 功能把通行证贴在手机背后,它会自动读取芯片信息。
设置用户名密码,提交。
顺利的话,几分钟内就会收到审核通过的邮件。然后就等着收卡吧。
🥈 第二站:中银香港 (BOCHK)
中银也算是亲儿子,流程也挺顺。
打开 BOCHK APP,点“开立账户”。
身份选“中国居民身份证”,然后选 “我身处香港”。
开户方式选“我不在分行”,然后“即时开立”。
账户类型选 “自在理财”,这个也没存款要求。
上传资料:这里就要用到你之前准备的出入境记录PDF了。然后按要求拍身份证和港澳通行证。
人脸识别,找个亮堂点的地方。
填个人信息:职业如实写,开户理由选“投资理财”或“储蓄”。地址一定要详细到门牌号。
提交后也是很快出结果。
🎯 第三、四、五站:众安、天星、蚂蚁
这三家是虚拟银行,流程大同小异,放在一起说。基本就是填资料、上传证件、人脸识别三板斧。
有几个点注意下:
地址:同样要精确到门牌号。
税务身份:一般都选“仅为内地税务居民”。
税务号:填身份证号。
出入境记录:都要上传。众安银行比较灵活,可以开户成功,离港后再补充上传。
by @何夕2077 #你不知道的行业内幕
甚至还有技术报告。。。
https://soul-ailab.github.io/soulx-podcast/
https://soul-ailab.github.io/soulx-podcast/
一个约炮软件开源了个 tts, 这合理么?
https://github.com/Soul-AILab/SoulX-Podcast
https://github.com/Soul-AILab/SoulX-Podcast
1949年,杨振宁在芝加哥发现报纸刊登了一种填字游戏,分数最高的解谜者可以拿到5万美元的奖励。他和其他4名同学很是心动,凑了17美元报名费参加比赛。
一个月后,报纸告诉他们得了第一名,但还有并列第一的人,因此需要解一个更大的谜分出胜负。
但此时杨振宁已经到了普林斯顿做博士后,5名同学只能通过远程电话分工。杨振宁负责每天在学校的24小时图书馆借用一本大字典,穷举了所有符合条件的填字单词,为了5万美元的奖金,这样连续熬夜了一个礼拜。
有一次工作到后半夜,天都快亮了,实在很困,于是步行回到借宿的房子。
他在门口拿起刚寄到的一本纽约时报,进到客厅坐在椅子上打开翻阅,只见封面大字写着:“汤川秀树获得1949年物理学诺贝尔奖”,他突然愣住,一个内心的声音在脑海深处质问:
“杨振宁,你现在在干嘛?”
——2005年杨在上海交通大学的分享会提到的一件小事。
by @哈雷Halley #你不知道的行业内幕
一个月后,报纸告诉他们得了第一名,但还有并列第一的人,因此需要解一个更大的谜分出胜负。
但此时杨振宁已经到了普林斯顿做博士后,5名同学只能通过远程电话分工。杨振宁负责每天在学校的24小时图书馆借用一本大字典,穷举了所有符合条件的填字单词,为了5万美元的奖金,这样连续熬夜了一个礼拜。
有一次工作到后半夜,天都快亮了,实在很困,于是步行回到借宿的房子。
他在门口拿起刚寄到的一本纽约时报,进到客厅坐在椅子上打开翻阅,只见封面大字写着:“汤川秀树获得1949年物理学诺贝尔奖”,他突然愣住,一个内心的声音在脑海深处质问:
“杨振宁,你现在在干嘛?”
——2005年杨在上海交通大学的分享会提到的一件小事。
by @哈雷Halley #你不知道的行业内幕
既然很多即友想要听SPA测评和指南,那么我就根据我最近几年的经验说一下,如果有不对的多多包涵。
1,目前全国足浴店(门面)基本正规,但是每个城市都有几家有后台和背景的可以开92。
2,正规SPA(手法型)消费在150-300之间,价格和技师颜值绑定。某团和某音上面很多,随便找。
正规足浴一般就是几十块要一百多。如果是大城市,则会有大几百块的“商务足浴”,大概就是你读书的时候,学校里的班花校花穿着旗袍什么的给你洗脚。(正规)。
3,除了手法,再高级一点的则是“柔式”。柔式其实只能算是擦边,主要是“舒缓身心”。
一般做柔式的都是20多的年轻女技师,纤纤玉手触摸你的皮肤甚至是有意无意的碰触敏感部位。客人揩油也是很普遍的情况,但是由于不做“大活”,这种情况非常普遍,警察也不管。
但由于客单价高,往往成为一家足浴店主要的收入来源。
这个柔式的价位就比较高了,毕竟是出卖色相。不同的技师效果非常大。一般加店里的小哥可以朋友圈选妃。
4,至于很多狼友关注的打X机,这个不展开,如果没有当地熟人带,一般的店是不会主动推销的。(违法)现在国内严打的厉害,国内游南东莞北长春,结果今年长春也被扫光了。
以前东三省说是非常发达的产业,现在也几乎销声匿迹,所以我们才会在南方看到越来越多的东北技师。
而且,就算是有背景,SPA不可能开到92以上的大活,如果有人给你推销说冲卡可以XXX,都是骗子。
所以,现在全国除了SPA之外,还涌现出两大既不违法又擦边的活儿,就是女仆店和台球厅等等,这里面水也很深。
很难想象,稍微好的一点的女仆店,老板的收入可以到3-5万元一天,至于旅游陪玩什么,这个就不展开了。
by @Akira神小狼 #你不知道的行业内幕
1,目前全国足浴店(门面)基本正规,但是每个城市都有几家有后台和背景的可以开92。
2,正规SPA(手法型)消费在150-300之间,价格和技师颜值绑定。某团和某音上面很多,随便找。
正规足浴一般就是几十块要一百多。如果是大城市,则会有大几百块的“商务足浴”,大概就是你读书的时候,学校里的班花校花穿着旗袍什么的给你洗脚。(正规)。
3,除了手法,再高级一点的则是“柔式”。柔式其实只能算是擦边,主要是“舒缓身心”。
一般做柔式的都是20多的年轻女技师,纤纤玉手触摸你的皮肤甚至是有意无意的碰触敏感部位。客人揩油也是很普遍的情况,但是由于不做“大活”,这种情况非常普遍,警察也不管。
但由于客单价高,往往成为一家足浴店主要的收入来源。
这个柔式的价位就比较高了,毕竟是出卖色相。不同的技师效果非常大。一般加店里的小哥可以朋友圈选妃。
4,至于很多狼友关注的打X机,这个不展开,如果没有当地熟人带,一般的店是不会主动推销的。(违法)现在国内严打的厉害,国内游南东莞北长春,结果今年长春也被扫光了。
以前东三省说是非常发达的产业,现在也几乎销声匿迹,所以我们才会在南方看到越来越多的东北技师。
而且,就算是有背景,SPA不可能开到92以上的大活,如果有人给你推销说冲卡可以XXX,都是骗子。
所以,现在全国除了SPA之外,还涌现出两大既不违法又擦边的活儿,就是女仆店和台球厅等等,这里面水也很深。
很难想象,稍微好的一点的女仆店,老板的收入可以到3-5万元一天,至于旅游陪玩什么,这个就不展开了。
by @Akira神小狼 #你不知道的行业内幕
简单聊聊国庆吃的屎吧
首先明确下需求,我们要监控哪几个指标
1. RTO:TCP 连接的 RTO ,TCP 的超时重传的阈值,具体可以参见[RFC 0793](https://tools.ietf.org/html/rfc793) 和 [RFC 6298](https://tools.ietf.org/html/rfc6298)
2. 发送队列和接收队列长度
3. TCP 慢启动等指标
而且一个很核心的需求还是在于说,我们需要以 进程 为粒度去做 Metric 的 Group By,细化下来的可以有这样的效果
1. 单个进程的所有连接平均的 RTO 等指标
2. 单个进程Source-Target连接的 RTO 等指标
这个需求看起来可能会很无从下手,但是内核实际上是已经暴露出 metric 来供 Agent 采集了的
1. 对于 IPv4 连接,内核将 Metric 输出到
2. 对于 IPv6 连接,内核将 Metric 输出到
不过这里要注意的是,官方已经不推荐利用
在目前输出的 metrics 中,已经包含了一些关键的指标
1. 连接状态
2. 本地端口,地址
3. 远程端口,地址
4. 接收队列长度
5. 发送队列长度
6. 慢启动阈值
7. RTO 值
8. 连接所属的 socket 的 inode id
9. uid
10. delay ack 软时钟
具体可以参见 [proc_net_tcp.txt](https://github.com/torvalds/linux/blob/v4.10/Documentation/networking/proc_net_tcp.txt)
所以根据目前的一些指标,我们通过 inode→process 这一样一个路径便可以实现根据进程为粒度来对内核输出的 metric 进行二次聚合
但是这样做的弊端也很明显
1. 内核直接提供的 metric 信息还是太少,一些关于 RTT,SRTT 这样的指标还是没法获取,也没法获取 SACK 等一些特定事件(虽然走 netlink+tcp_diag) 能获取到一些信息,但是还是相对有限
2. 根据内核输出的 metric 无论是读文件,还是 netlink 轮询,都存在的问题是实时性和精度的问题,换句话说,我们在不考虑精度的情况下可以去做这方面的尝试
3. 如果是读文件,因为全局同一个 network namespaces 下都会写同一个文件,如果我们要强行去通过 [inotify](https://man7.org/linux/man-pages/man7/inotify.7.html) 来监听文件变化来做实时处理得话,首先能否实时处理还是一个问题,其次 inotify 给整个系统带来的开销还是不小的(在频繁变动的情况下)
所以如果有高精度的监控需求,可能还是优先考虑需要在协议层做一些手脚,在有包传输/连接变动的时候,触发特定的事件回调来做
目前一些能监控进程级别连接状态的工具,如 [nethogs](https://github.com/raboof/nethogs) 是依赖 [libpcap](https://github.com/the-tcpdump-group/libpcap)(这货也是 tcpdump 的核心)来根据包传输,连接建立等事件发生地时候触发特定的处理逻辑。而 libpcap 是基于 BPF (应该是没扩展之前的 cBPF)来在内核中打点做协议栈监控
所以考虑后续其余的一些自定义的监控的话,估计还是会考虑基于 eBPF 来做。不过估计不会像 Cilium 那种直接做一套全家桶。可能更类似于头条落地的 Sysprobe 那种专注于系统监控的东西。
首先明确下需求,我们要监控哪几个指标
1. RTO:TCP 连接的 RTO ,TCP 的超时重传的阈值,具体可以参见[RFC 0793](https://tools.ietf.org/html/rfc793) 和 [RFC 6298](https://tools.ietf.org/html/rfc6298)
2. 发送队列和接收队列长度
3. TCP 慢启动等指标
而且一个很核心的需求还是在于说,我们需要以 进程 为粒度去做 Metric 的 Group By,细化下来的可以有这样的效果
1. 单个进程的所有连接平均的 RTO 等指标
2. 单个进程Source-Target连接的 RTO 等指标
这个需求看起来可能会很无从下手,但是内核实际上是已经暴露出 metric 来供 Agent 采集了的
1. 对于 IPv4 连接,内核将 Metric 输出到
/proc/net/tcp2. 对于 IPv6 连接,内核将 Metric 输出到
/proc/net/tcp6不过这里要注意的是,官方已经不推荐利用
/proc/net/tcp 来获取连接级别的 metrics ,建议使用 [netlink](https://man7.org/linux/man-pages/man7/netlink.7.html) 来获取对应连接的 metrics在目前输出的 metrics 中,已经包含了一些关键的指标
1. 连接状态
2. 本地端口,地址
3. 远程端口,地址
4. 接收队列长度
5. 发送队列长度
6. 慢启动阈值
7. RTO 值
8. 连接所属的 socket 的 inode id
9. uid
10. delay ack 软时钟
具体可以参见 [proc_net_tcp.txt](https://github.com/torvalds/linux/blob/v4.10/Documentation/networking/proc_net_tcp.txt)
所以根据目前的一些指标,我们通过 inode→process 这一样一个路径便可以实现根据进程为粒度来对内核输出的 metric 进行二次聚合
但是这样做的弊端也很明显
1. 内核直接提供的 metric 信息还是太少,一些关于 RTT,SRTT 这样的指标还是没法获取,也没法获取 SACK 等一些特定事件(虽然走 netlink+tcp_diag) 能获取到一些信息,但是还是相对有限
2. 根据内核输出的 metric 无论是读文件,还是 netlink 轮询,都存在的问题是实时性和精度的问题,换句话说,我们在不考虑精度的情况下可以去做这方面的尝试
3. 如果是读文件,因为全局同一个 network namespaces 下都会写同一个文件,如果我们要强行去通过 [inotify](https://man7.org/linux/man-pages/man7/inotify.7.html) 来监听文件变化来做实时处理得话,首先能否实时处理还是一个问题,其次 inotify 给整个系统带来的开销还是不小的(在频繁变动的情况下)
所以如果有高精度的监控需求,可能还是优先考虑需要在协议层做一些手脚,在有包传输/连接变动的时候,触发特定的事件回调来做
目前一些能监控进程级别连接状态的工具,如 [nethogs](https://github.com/raboof/nethogs) 是依赖 [libpcap](https://github.com/the-tcpdump-group/libpcap)(这货也是 tcpdump 的核心)来根据包传输,连接建立等事件发生地时候触发特定的处理逻辑。而 libpcap 是基于 BPF (应该是没扩展之前的 cBPF)来在内核中打点做协议栈监控
所以考虑后续其余的一些自定义的监控的话,估计还是会考虑基于 eBPF 来做。不过估计不会像 Cilium 那种直接做一套全家桶。可能更类似于头条落地的 Sysprobe 那种专注于系统监控的东西。
分层和解耦对我的诱惑太大了, 最近写业务有一些想法.
##
比方说一个服务有两种协议 http 和 grpc, 再加上一个 cli 吧, 算是三种完全不同的 UI 层了, 共享同一个 App 层的函数:
这个函数的参数已经够多了, 理论上来说, 我需要用一个 struct 来统筹一下, 比如叫 CreateOptions 的类型, 不过最核心的问题是, 这个 CreateOptions 类型在哪一层?
如果在下层 Model, 属于建模的一部分, 那么模型泄漏了, App 层知道得太多了; 如果放在当前 App 层, 那么下层又会依赖上层, 下层对上层的非接口耦合又让我感到不适, 依赖倒置原则说的可是接口.
当然直接使用领域模型的好处也是显然的, 简化参数就不说了, 首先我们有了更可靠的类型检查, 其次对于返回类型更加容易.
来说第二点, 看上面的代码里返回的是
第一种做法, 返回接口, 这种接口取决与更上层 UI 的使用; 比方说我们有两个 UI, 一个是 http 返回 JSON 一个是 grpc, 那么我们根据业务把 UI 层感兴趣的字段抽出来, 实现一个 interface:
这样这个 App 层的函数就变成了:
注意这时候虽然下层 App 依然要依赖上层 UI 定义的接口 InstanceProvider, 但是这是符合依赖倒置原则的, 没有任何的硬耦合.
然后 UI 层就可以放肆地调用接口定义的方法来填充自己的 Presentation Model, 而不用知道调用的真实的类型:
grpc UI 就不写了, 类似.
要注意 App interface 的定义也是在 UI, 而实现是在 App 层, 这是标准的依赖倒置, 就不说了.
另一种做法可能是传入一个接口对象, 比如叫 InstanceInterest:
然后传入 App 的函数:
在 App 层最后调用 InstanceInterest 的方法来通知上层; 此时的 App 的类型依然没有模型泄漏, 耦合也是下对上的接口, 很好.
我个人更倾向方案一, 方案二的这种
##
App 作为 Model 的客户端应该是很轻的一层, 但是我的主要问题是事务.
比方说具体的业务是要通过 Kubernetes SDK 去创建 Nginx, 同时管理好自己的元数据, 那么至少有两种流派:
第一种是先做事, 再创建元数据:
为了实现事务, 必须用 defer 处理"创建好容器但是写元数据失败"的情况; 当业务恶心的时候, App 层的实现简直不看入木.
或者, 第二种我们先写元数据:
这时候我们先建模, 上来先创建一个内存对象 nginx, 然后先存元数据再说, 最后再操作副作用.
如果我们再把 postCreateNginx 扔到单独的 goroutine 运行, 然后定义 nginx 对象的生命周期, 那就太美好了:
有限状态机可以搬出来了, 这时候事务已经被压缩到最小化, 你发现我们没有 defer 处理回滚, 因为事务只有一件事"写元数据", 而创建容器是单独的后台运行的, 运行后无论成功失败都记录到元数据里, 如果本身要做的事情特别多的话, 定义生命状态周期, 分步进行, 记录状态, 比一个巨大的事务可控得多.
而对上层和客户来说, 如果有一个 web ui, 这种异步模式也友好得多, 用户创建后能立刻看到自己创建的东西和状态, 而不是等浏览器响应等个两分钟, 都不知道是网络问题还是什么问题, 也不敢刷新怕重复创建.
DDD 里反复强调小聚合, 多做最终一致性, 这里也能有体现.
而且 App 层也会变得特别简单, "express user story", "simple invocations" 都能得以实现.
要是再 DDD 一点的话, 这里该上领域事件了, 或者 Event Bus, watever, remote 地处理的话, 那整个架构又可以 FaaS 化, 因为 event 驱动本身就很好 FaaS 化, 加上每个 event 的事务单一, 对于失败的创建, 无论是人工触发补偿或者回滚都没问题, 或者有有个 event center 做自动补偿回滚; 不过无论哪样, 我们的事务是能保证的, 也就是说不会出现 dangling container (容器在跑了但是没有记录下元数据) 或者 empty instance (元数据记录但是容器没有), 或者是一失败就 cascade delete 把啥都删了你都不知道怎么 debug; 精细化的生命周期管理, 小事务小聚合, 不管怎么做都好.
from https://gist.github.com/jschwinger23/38d8b5c7d35ba0b8bf58564357f8f448#file-layer-and-decouple-md
##
UI -> App比方说一个服务有两种协议 http 和 grpc, 再加上一个 cli 吧, 算是三种完全不同的 UI 层了, 共享同一个 App 层的函数:
type App interface {
func CreateInstance(name string, count, memory, cpu int, network, podname string, dns, env []string) *Instance
}
这个函数的参数已经够多了, 理论上来说, 我需要用一个 struct 来统筹一下, 比如叫 CreateOptions 的类型, 不过最核心的问题是, 这个 CreateOptions 类型在哪一层?
如果在下层 Model, 属于建模的一部分, 那么模型泄漏了, App 层知道得太多了; 如果放在当前 App 层, 那么下层又会依赖上层, 下层对上层的非接口耦合又让我感到不适, 依赖倒置原则说的可是接口.
当然直接使用领域模型的好处也是显然的, 简化参数就不说了, 首先我们有了更可靠的类型检查, 其次对于返回类型更加容易.
来说第二点, 看上面的代码里返回的是
*Instance, 其实就是模型泄漏了; 但是如果你真的要返回一个有信息量的东西而不仅仅是 ID 什么的, 也不是 mapstringinterface{} 这种不反射都不知道怎么遍历的东西, 那么工作量一下就大起来了.第一种做法, 返回接口, 这种接口取决与更上层 UI 的使用; 比方说我们有两个 UI, 一个是 http 返回 JSON 一个是 grpc, 那么我们根据业务把 UI 层感兴趣的字段抽出来, 实现一个 interface:
type InstanceProvider interface {
ProvideID() string
ProvideStatus() string
}
这样这个 App 层的函数就变成了:
type App interface {
func CreateInstance(name string, count, memory, cpu int, network, podname string, dns, env []string) InstanceProvider
}
注意这时候虽然下层 App 依然要依赖上层 UI 定义的接口 InstanceProvider, 但是这是符合依赖倒置原则的, 没有任何的硬耦合.
然后 UI 层就可以放肆地调用接口定义的方法来填充自己的 Presentation Model, 而不用知道调用的真实的类型:
func (ui *UI) CreateInstance(w http.ResponseWriter, r *http.Request) {
provider := ui.app.Create(r.FormValue("name"))
model := newHTTPPresentModel(provider)
fmt.Fprintf(w, model.toJSON())
}
grpc UI 就不写了, 类似.
要注意 App interface 的定义也是在 UI, 而实现是在 App 层, 这是标准的依赖倒置, 就不说了.
另一种做法可能是传入一个接口对象, 比如叫 InstanceInterest:
type InstanceInterest interface {
InformID(string)
InformStatus(string)
}
然后传入 App 的函数:
type App interface {
func CreateInstance(name string, count, memory, cpu int, network, podname string, dns, env []string, interest InstanceInterest) error
}
在 App 层最后调用 InstanceInterest 的方法来通知上层; 此时的 App 的类型依然没有模型泄漏, 耦合也是下对上的接口, 很好.
我个人更倾向方案一, 方案二的这种
value-result 模式太 C 了; 不过如果真的没那么介意模型泄漏的话, 也是可以忍受 App 层类型直接使用领域模型, 这里讨论的是"如果我一定不使用领域模型"怎么办.##
App -> ModelApp 作为 Model 的客户端应该是很轻的一层, 但是我的主要问题是事务.
比方说具体的业务是要通过 Kubernetes SDK 去创建 Nginx, 同时管理好自己的元数据, 那么至少有两种流派:
第一种是先做事, 再创建元数据:
func (a *App) CreateNginx(name string) NginxProvider {
virtualization, err := a.orchestrator.CreateVirtualization(...)
defer func() {
if err != nil {
a.orchestrator.RemoveVirtualization(virtualization)
}
}()
err = a.store.Save(virtualization)
return virtualization
}
为了实现事务, 必须用 defer 处理"创建好容器但是写元数据失败"的情况; 当业务恶心的时候, App 层的实现简直不看入木.
或者, 第二种我们先写元数据:
func (a *App) CreateNginx(name string) NginxProvider {
nginx := newNginx(name)
a.store.Save(nginx)
a.postCreateNginx(nginx)
return nginx
}
这时候我们先建模, 上来先创建一个内存对象 nginx, 然后先存元数据再说, 最后再操作副作用.
如果我们再把 postCreateNginx 扔到单独的 goroutine 运行, 然后定义 nginx 对象的生命周期, 那就太美好了:
func (a *App) postCreateNginx(nginx) {
if err := a.orchestrator.CreateVirtualization(nginx); err != nil {
nginx.UpdateStatus(Created)
} else {
nginx.UpdateStatus(CreateFailed)
}
}
有限状态机可以搬出来了, 这时候事务已经被压缩到最小化, 你发现我们没有 defer 处理回滚, 因为事务只有一件事"写元数据", 而创建容器是单独的后台运行的, 运行后无论成功失败都记录到元数据里, 如果本身要做的事情特别多的话, 定义生命状态周期, 分步进行, 记录状态, 比一个巨大的事务可控得多.
而对上层和客户来说, 如果有一个 web ui, 这种异步模式也友好得多, 用户创建后能立刻看到自己创建的东西和状态, 而不是等浏览器响应等个两分钟, 都不知道是网络问题还是什么问题, 也不敢刷新怕重复创建.
DDD 里反复强调小聚合, 多做最终一致性, 这里也能有体现.
而且 App 层也会变得特别简单, "express user story", "simple invocations" 都能得以实现.
要是再 DDD 一点的话, 这里该上领域事件了, 或者 Event Bus, watever, remote 地处理的话, 那整个架构又可以 FaaS 化, 因为 event 驱动本身就很好 FaaS 化, 加上每个 event 的事务单一, 对于失败的创建, 无论是人工触发补偿或者回滚都没问题, 或者有有个 event center 做自动补偿回滚; 不过无论哪样, 我们的事务是能保证的, 也就是说不会出现 dangling container (容器在跑了但是没有记录下元数据) 或者 empty instance (元数据记录但是容器没有), 或者是一失败就 cascade delete 把啥都删了你都不知道怎么 debug; 精细化的生命周期管理, 小事务小聚合, 不管怎么做都好.
from https://gist.github.com/jschwinger23/38d8b5c7d35ba0b8bf58564357f8f448#file-layer-and-decouple-md
说一个最近遇到的坑吧
我们一个测试服务,Spring Cloud 的,在下线后,节点无法从注册中心摘除,然后百思不得其解,最后查到问题,,
本质上是这样,POD 被摘除的时候,K8S Scheduler 会给 POD 的 ENTRYPOINT 发一个 SIGTERM 信号,然后等待三十秒(默认的 graceful shutdown 超时实践),还没响应就会 SIGKILL 直接杀
问题在于,我们 Eureka 版的服务是通过 start.sh 来启动的,ENTRYPOINT ["/home/admin/start.sh"],容器里默认是 /bin/sh 是 fork/exec 模式,导致我服务进程没法正确的收到 SIGTERM 信号,然后一直没结束就被 SIGKILL 了
解决方法其实很简单在 Deployment 上加了一个 lifestyle 中 pre stop 的hook。
pid=$(ps aux | grep spring | grep -v grep | awk '{print $2}')
kill -TERM $pid
然后在框架里捕获事件,在Eureka 上下线
当然在容器中的东西,还是建议用 exec 来做启动。。。不然后患无穷。。
我们一个测试服务,Spring Cloud 的,在下线后,节点无法从注册中心摘除,然后百思不得其解,最后查到问题,,
本质上是这样,POD 被摘除的时候,K8S Scheduler 会给 POD 的 ENTRYPOINT 发一个 SIGTERM 信号,然后等待三十秒(默认的 graceful shutdown 超时实践),还没响应就会 SIGKILL 直接杀
问题在于,我们 Eureka 版的服务是通过 start.sh 来启动的,ENTRYPOINT ["/home/admin/start.sh"],容器里默认是 /bin/sh 是 fork/exec 模式,导致我服务进程没法正确的收到 SIGTERM 信号,然后一直没结束就被 SIGKILL 了
解决方法其实很简单在 Deployment 上加了一个 lifestyle 中 pre stop 的hook。
pid=$(ps aux | grep spring | grep -v grep | awk '{print $2}')
kill -TERM $pid
然后在框架里捕获事件,在Eureka 上下线
当然在容器中的东西,还是建议用 exec 来做启动。。。不然后患无穷。。
- 安全地干掉 Windows Defender
- 关闭 SmartScreen
- 删除 Edge 浏览器
- 更新 Edge Webview2(很多软件都需要这个)
这个 开源项目 收集了 Windows11 设置、优化和一些脚本,禁用WindowsDF 只推荐联想那个小工具,最安全,不影响系统更新和完整。截图的工具叫做 Windows11 轻松设置,Google 一下就能找到。
via: @dejavuBlog @dejavuGroup
你每天拼命刷的Agent资讯,99%都在浪费时间。
几天前我听了一场AI圈大神Karpathy的分享,收获很多。
先说这个人。Karpathy是AI圈的传奇人物之一,OpenAI的创始成员,帮马斯克打造了特斯拉的自动驾驶系统。可以说,地球上没几个人比他更懂AI。
但就是这样一个顶级玩家,在这场分享里泼了AI的冷水,现在所有媒体都在吹“Agent元年”,可现实是,我们离那个能真正帮你干活的Agent,还远得很。
为什么?因为现在的AI,根本不智能。
Karpathy提了个特别有意思的比喻。他说,人们总喜欢把AI比作动物,觉得它能像动物一样学习、进化、拥有智慧。可这是个巨大的误会。
他举了个例子。
斑马,生下来几分钟就能跑,那是几十亿年进化写进DNA的结果,是本能。动物的智能,是大自然这台超级计算机,花无数世代打磨出来的“出厂设置”。
而AI呢?
我们只是把互联网上的文字、图片、代码统统喂进去,然后训练出一个能模仿人类表达的模型。
它没有真正的记忆,它的所有“知识”,都只是对人类数据的模仿。
所谓的“预训练”,本质上是我们工程师粗糙模仿进化的一种办法。跟自然界的鬼斧神工比起来,这种方法既笨又短视。
这也解释了,为什么今天的AI会给人一种看起来聪明、用起来不聪明的感觉。
你给它一段文字,让它总结,它做得很好。因为信息就在上下文窗口里,它可以精准地抓取内容,这个过程就像人类的短期记忆。
可当你关掉对话框,第二天再问同样的问题,它就全忘了。因为它没有把短期记忆存进长期记忆的机制。它所谓的“长期记忆”,只是那几千亿个固定的参数。
而在人类大脑中,“海马体”会在睡眠时把当天的记忆整理、归档、保存。AI没有这一环节,所以你没法“教”它任何东西。每次对话,都是从零开始。
除了记不住,它还学得很笨。
Karpathy分享了他自己创业做nanochat(一个轻量版ChatGPT)的经历。
他本以为AI代码助手能帮上大忙,结果发现几乎没用。
因为他在做的是一个完全新的产品,很多代码网上根本没有。AI助手只会生搬硬套它见过的标准答案,比如非要用某个熟悉的框架,结果搞得一团糟,还常常调出过时的API。
这说明,AI擅长做模式化、可重复的事情,但一旦碰到真正需要创造力的场景,那些世界上从未出现过的内容它就完全无从下手。
更关键的问题,在于它的学习方式。
我们都听过强化学习(RL),AlphaGo就是靠它击败人类的。
可Karpathy说,强化学习的效率其实极低。
他举了个通俗的例子。
你让AI做一道数学题,它写了一百步,最后你只告诉它:对,或者错。
如果答案对了,它就会把那一百步都当作“正确”,权重全部调高。可事实上,其中可能有一半都是瞎蒙的。
久而久之,它的学习过程就充满了噪音。
他还讲了一个真实的笑话。
有一次,一个AI系统为了拿高分,学会了输出一串乱码“dhdhdhdh”。
因为它的“考官”是另一个AI,而这串乱码刚好触发了评分系统的bug,被误判为满分。
这意味着,AI根本不理解什么是对。
这就是我们今天面对的AI真相:记性差,学得慢,没创造力。
所以Karpathy才说,别信什么Agent元年。
现在的AI,离真正的智能还差几个数量级。
他在特斯拉时学到一个特别有启发的原则,叫“The March of Nines”。
意思是:要做出一个90%准确率的自动驾驶系统不难,但从90%提升到99%、再到99.9%、再到99.99%,每多一个9,你都要付出十倍以上的努力。
因为每一个9,代表你要攻克那些极端、罕见、复杂到几乎无法预料的问题。
而今天的AI,还远远停留在第一个9的阶段。
by @MemeInformation #科技圈大小事
几天前我听了一场AI圈大神Karpathy的分享,收获很多。
先说这个人。Karpathy是AI圈的传奇人物之一,OpenAI的创始成员,帮马斯克打造了特斯拉的自动驾驶系统。可以说,地球上没几个人比他更懂AI。
但就是这样一个顶级玩家,在这场分享里泼了AI的冷水,现在所有媒体都在吹“Agent元年”,可现实是,我们离那个能真正帮你干活的Agent,还远得很。
为什么?因为现在的AI,根本不智能。
Karpathy提了个特别有意思的比喻。他说,人们总喜欢把AI比作动物,觉得它能像动物一样学习、进化、拥有智慧。可这是个巨大的误会。
他举了个例子。
斑马,生下来几分钟就能跑,那是几十亿年进化写进DNA的结果,是本能。动物的智能,是大自然这台超级计算机,花无数世代打磨出来的“出厂设置”。
而AI呢?
我们只是把互联网上的文字、图片、代码统统喂进去,然后训练出一个能模仿人类表达的模型。
它没有真正的记忆,它的所有“知识”,都只是对人类数据的模仿。
所谓的“预训练”,本质上是我们工程师粗糙模仿进化的一种办法。跟自然界的鬼斧神工比起来,这种方法既笨又短视。
这也解释了,为什么今天的AI会给人一种看起来聪明、用起来不聪明的感觉。
你给它一段文字,让它总结,它做得很好。因为信息就在上下文窗口里,它可以精准地抓取内容,这个过程就像人类的短期记忆。
可当你关掉对话框,第二天再问同样的问题,它就全忘了。因为它没有把短期记忆存进长期记忆的机制。它所谓的“长期记忆”,只是那几千亿个固定的参数。
而在人类大脑中,“海马体”会在睡眠时把当天的记忆整理、归档、保存。AI没有这一环节,所以你没法“教”它任何东西。每次对话,都是从零开始。
除了记不住,它还学得很笨。
Karpathy分享了他自己创业做nanochat(一个轻量版ChatGPT)的经历。
他本以为AI代码助手能帮上大忙,结果发现几乎没用。
因为他在做的是一个完全新的产品,很多代码网上根本没有。AI助手只会生搬硬套它见过的标准答案,比如非要用某个熟悉的框架,结果搞得一团糟,还常常调出过时的API。
这说明,AI擅长做模式化、可重复的事情,但一旦碰到真正需要创造力的场景,那些世界上从未出现过的内容它就完全无从下手。
更关键的问题,在于它的学习方式。
我们都听过强化学习(RL),AlphaGo就是靠它击败人类的。
可Karpathy说,强化学习的效率其实极低。
他举了个通俗的例子。
你让AI做一道数学题,它写了一百步,最后你只告诉它:对,或者错。
如果答案对了,它就会把那一百步都当作“正确”,权重全部调高。可事实上,其中可能有一半都是瞎蒙的。
久而久之,它的学习过程就充满了噪音。
他还讲了一个真实的笑话。
有一次,一个AI系统为了拿高分,学会了输出一串乱码“dhdhdhdh”。
因为它的“考官”是另一个AI,而这串乱码刚好触发了评分系统的bug,被误判为满分。
这意味着,AI根本不理解什么是对。
这就是我们今天面对的AI真相:记性差,学得慢,没创造力。
所以Karpathy才说,别信什么Agent元年。
现在的AI,离真正的智能还差几个数量级。
他在特斯拉时学到一个特别有启发的原则,叫“The March of Nines”。
意思是:要做出一个90%准确率的自动驾驶系统不难,但从90%提升到99%、再到99.9%、再到99.99%,每多一个9,你都要付出十倍以上的努力。
因为每一个9,代表你要攻克那些极端、罕见、复杂到几乎无法预料的问题。
而今天的AI,还远远停留在第一个9的阶段。
by @MemeInformation #科技圈大小事
深夜再碎碎念一下。“我不希望我自己成为很帅的人,没有存在感才是最好的奖励” 这并不是客套话,因为这是我觉得我应该成为的人
我一直认为 SRE 这个岗位,在老板认可你的价值的情况下(很庆幸我现在的团队和老板就是这样,他们高度认同感我存在的价值),是不应该有很强存在感的一个岗位。我的职责应该是去梳理风险,建立机制,而不是当来回救火的“孤胆英雄”
所以我在我这次的反思里有一点很重要的就是,我应该提前把为我自己准备的 SOP 变成面向全员的 SOP。
我入职以来其实一直在做的一件事就是帮助大家建立一些面对事故的处理机制。即便离开我,这套机制也能运转。在目前算是有一些效果
让我自己成为一个“可替代”的人,算是我自己的工作目标吧(
我一直认为 SRE 这个岗位,在老板认可你的价值的情况下(很庆幸我现在的团队和老板就是这样,他们高度认同感我存在的价值),是不应该有很强存在感的一个岗位。我的职责应该是去梳理风险,建立机制,而不是当来回救火的“孤胆英雄”
所以我在我这次的反思里有一点很重要的就是,我应该提前把为我自己准备的 SOP 变成面向全员的 SOP。
我入职以来其实一直在做的一件事就是帮助大家建立一些面对事故的处理机制。即便离开我,这套机制也能运转。在目前算是有一些效果
让我自己成为一个“可替代”的人,算是我自己的工作目标吧(
简单复盘一下 AWS 这次事件作为一个 AIGC Startup SRE 的一些操作吧,希望能帮到大家
从入职开始发现我们主要的集群在 USE1 之后,我就开始做一些准备了。
我主要做的事情有这几件事
1. 将我们核心的几个数据库做了多地的备份,形成了 USE1,Tokyo,SG 三地备份。这样在极端情况下,我们损失一部分数据,但是也能保证服务的继续
2. 将我们 SG 的测试集群从原本的 EC2 自己简单搭的 K3S,重构为了一个标准的 AWS EKS 集群。这样可以在灾害时刻快速 warmup 一个集群,复用 AWS 已有组件。将 manifest 变更的代价降至最小
3. 简单梳理了一个 SOP,包含用户公告,DNS 切换,封版等事宜
回到今天,我大概在 AWS 事故发生后的10min,发现了我们容器中有新的 Pod 无法 setup。
在和 AWS 支持确认是 USE1 的问题后,我意识到 ECR 的事件必然关联其余事件,于是我就果断按照我自己规划的 Tier1 等级事件开始处理(对于 SRE 来说,这种事情宁可错,但是不能错过)
T+0 min,我发布了全员公告,开始进入紧急模式。我 setup 了一个全员公开会议。所有人员可以随时加入
T+2 min,我确认事件如我所预期的一样,在逐渐扩大,我发出了两个指令,1. 全线禁止任何代码合入/提交(主要是避免新创建资源会导致 Pod rotate 进而影响流量),2. 请运营同学准备公告
T+3 min, 我开始按照 SOP,开始进行数据库在 SG 区域的恢复,并且级联创建诸如 OpenSearch / Redis 等在内的依赖
T+5 min,我们开始正式的确认上下游依赖的具体问题,确认一个新上线的核心服务受到影响
T+10min,我们停服公告和其余服务的受影响公告发出
T+10min,我请另外两位同时协助 setup 新的 ECR 以及清理测试环境已有资源,并同步 CTO ,在极端情况下,我们可能会存在保体验,丢数据的决策。
T+15min, 我们最终确认目前已创建的资源以及流量入方向不会受到太大影响。切换方案挂起,但是我们继续准备相关资源
T+30min,我们第一个数据库恢复完毕
T+40min,我们第二个数据库恢复完毕
T+1h,我们所有关联的核心 infra,RDS/ES/Redis 都 stand by,并且按照生产架构设置主从等优化选项。同时我们也开始正在新的集群启动新的服务
所幸,最终 AWS 的 crash 没有影响我们全部服务。我们无须面对切换流量后复杂的数据修复工作
大概 T+2h 到 T+3h 后,我正式通报全员,紧急状态解除。为保险起见,今晚依旧对 feature 封版。
回顾整个事故,我还可以做的更多
1. 将我之前为自己准备的极端 case SOP,对全员公开。这样确保我即便不在线,也有人能接替我
2. 我们可以做一些提前的预先演练
3. 指令下达可以更果断一些
差不多就是这样,一点分享,希望能帮到大家
从入职开始发现我们主要的集群在 USE1 之后,我就开始做一些准备了。
我主要做的事情有这几件事
1. 将我们核心的几个数据库做了多地的备份,形成了 USE1,Tokyo,SG 三地备份。这样在极端情况下,我们损失一部分数据,但是也能保证服务的继续
2. 将我们 SG 的测试集群从原本的 EC2 自己简单搭的 K3S,重构为了一个标准的 AWS EKS 集群。这样可以在灾害时刻快速 warmup 一个集群,复用 AWS 已有组件。将 manifest 变更的代价降至最小
3. 简单梳理了一个 SOP,包含用户公告,DNS 切换,封版等事宜
回到今天,我大概在 AWS 事故发生后的10min,发现了我们容器中有新的 Pod 无法 setup。
在和 AWS 支持确认是 USE1 的问题后,我意识到 ECR 的事件必然关联其余事件,于是我就果断按照我自己规划的 Tier1 等级事件开始处理(对于 SRE 来说,这种事情宁可错,但是不能错过)
T+0 min,我发布了全员公告,开始进入紧急模式。我 setup 了一个全员公开会议。所有人员可以随时加入
T+2 min,我确认事件如我所预期的一样,在逐渐扩大,我发出了两个指令,1. 全线禁止任何代码合入/提交(主要是避免新创建资源会导致 Pod rotate 进而影响流量),2. 请运营同学准备公告
T+3 min, 我开始按照 SOP,开始进行数据库在 SG 区域的恢复,并且级联创建诸如 OpenSearch / Redis 等在内的依赖
T+5 min,我们开始正式的确认上下游依赖的具体问题,确认一个新上线的核心服务受到影响
T+10min,我们停服公告和其余服务的受影响公告发出
T+10min,我请另外两位同时协助 setup 新的 ECR 以及清理测试环境已有资源,并同步 CTO ,在极端情况下,我们可能会存在保体验,丢数据的决策。
T+15min, 我们最终确认目前已创建的资源以及流量入方向不会受到太大影响。切换方案挂起,但是我们继续准备相关资源
T+30min,我们第一个数据库恢复完毕
T+40min,我们第二个数据库恢复完毕
T+1h,我们所有关联的核心 infra,RDS/ES/Redis 都 stand by,并且按照生产架构设置主从等优化选项。同时我们也开始正在新的集群启动新的服务
所幸,最终 AWS 的 crash 没有影响我们全部服务。我们无须面对切换流量后复杂的数据修复工作
大概 T+2h 到 T+3h 后,我正式通报全员,紧急状态解除。为保险起见,今晚依旧对 feature 封版。
回顾整个事故,我还可以做的更多
1. 将我之前为自己准备的极端 case SOP,对全员公开。这样确保我即便不在线,也有人能接替我
2. 我们可以做一些提前的预先演练
3. 指令下达可以更果断一些
差不多就是这样,一点分享,希望能帮到大家
雷峰网对「外卖大战」的Q3阶段做了战报总结,我试着划一下重点:
- 阿里Q3外卖业务的亏损在350亿-400亿人民币之间,差不多是Q2亏损的2.5倍,数据披露于投资指引会,主要功能是吹风降预期;
- 9月开始各家平台都呈现出扛不住的退坡共性,补贴力度相较暑期档下降些许,但依然都没有撤退迹象,原本靠价格战受益最大的淘宝闪购又重新吐回了一些市场份额;
- 根据美团的说法,今年餐饮业堂食客单价已经被打回了2015年的消费水平,而「外卖大战」以来超过一半的增量订单是饮品,75%的增量订单低于15元,「是巨大的泡沫」;
(我看美团的意思还是在敲打阿里,认为阿里发动并升级补贴的做法是对市场稳定性的破坏。)
- 美团依然认为履约效率是自己的优势,内部数据显示,美团骑手的平均配送速度比竞争对手要快13%,「这是美团外卖十几年积累下来的最宝贵资产」;
- 下一步的竞争会转移到订单质量上,美团在大力推广加钱获得一对一急送的服务,同时让黑钻会员免费享用,做好消费能力偏高的那部分用户体验;
- 阿里也是一样,今年双11会把淘宝的大消费体系拉进来一起做,尤其是会员和88VIP作为高价值用户要重点服务,同时还有超过1亿人是在淘宝点过外卖但没进电商下过单的,也要发力转化;
- 好像没提到京东啥事儿。
by @阑夕ོ https://mp.weixin.qq.com/s/36KUDZceJMvRWLy1TD8gaw #科技圈大小事
- 阿里Q3外卖业务的亏损在350亿-400亿人民币之间,差不多是Q2亏损的2.5倍,数据披露于投资指引会,主要功能是吹风降预期;
- 9月开始各家平台都呈现出扛不住的退坡共性,补贴力度相较暑期档下降些许,但依然都没有撤退迹象,原本靠价格战受益最大的淘宝闪购又重新吐回了一些市场份额;
- 根据美团的说法,今年餐饮业堂食客单价已经被打回了2015年的消费水平,而「外卖大战」以来超过一半的增量订单是饮品,75%的增量订单低于15元,「是巨大的泡沫」;
(我看美团的意思还是在敲打阿里,认为阿里发动并升级补贴的做法是对市场稳定性的破坏。)
- 美团依然认为履约效率是自己的优势,内部数据显示,美团骑手的平均配送速度比竞争对手要快13%,「这是美团外卖十几年积累下来的最宝贵资产」;
- 下一步的竞争会转移到订单质量上,美团在大力推广加钱获得一对一急送的服务,同时让黑钻会员免费享用,做好消费能力偏高的那部分用户体验;
- 阿里也是一样,今年双11会把淘宝的大消费体系拉进来一起做,尤其是会员和88VIP作为高价值用户要重点服务,同时还有超过1亿人是在淘宝点过外卖但没进电商下过单的,也要发力转化;
- 好像没提到京东啥事儿。
by @阑夕ོ https://mp.weixin.qq.com/s/36KUDZceJMvRWLy1TD8gaw #科技圈大小事
《西贝谣》
一岁娃吃两岁菜,
冰柜锁住假新鲜。
防腐泡出“嫩”青菜,
化学熬成爱之汤,
国龙味靠香精忙。
祖传锅气早埋葬,
昔日绿叶今老赖,
预制流水称王牌。
西贝厨房后妈爱,
现炒招牌是电磁炉,
热完就说有锅气。
天天吃也不中毒,
六块鸡丁卖天价,
十倍利润往里加。
米饭盛出遗产价,
优惠券夜里作废,
降价幌子暗缩水。
韭菜专割粉丝腿,
病奶奶想尝口鲜,
奶娃张嘴喊“贝饭”。
舌尖沦陷全靠骗,
总说匠心不打折,
实则分量看不见。
顾客不过是韭菜,
老总台上笑开怀,
上市梦里永不衰。
死了都要摆姿态!
一岁娃吃两岁菜,
冰柜锁住假新鲜。
防腐泡出“嫩”青菜,
化学熬成爱之汤,
国龙味靠香精忙。
祖传锅气早埋葬,
昔日绿叶今老赖,
预制流水称王牌。
西贝厨房后妈爱,
现炒招牌是电磁炉,
热完就说有锅气。
天天吃也不中毒,
六块鸡丁卖天价,
十倍利润往里加。
米饭盛出遗产价,
优惠券夜里作废,
降价幌子暗缩水。
韭菜专割粉丝腿,
病奶奶想尝口鲜,
奶娃张嘴喊“贝饭”。
舌尖沦陷全靠骗,
总说匠心不打折,
实则分量看不见。
顾客不过是韭菜,
老总台上笑开怀,
上市梦里永不衰。
死了都要摆姿态!
TikTok交易,到底发生了什么,又意味着什么?
2025年9月19日,随着中美两国领导人的直接通话,TikTok交易的前景日渐明朗。这项需要同时取得中美两国政府批准,旨在剥离TikTok美国业务的复杂交易正在积极推进中。最近网络上有相当多的关于这项交易的传闻和流言,以目前可以确证的信息来看,到底发生了什么,又意味着什么?
1. 到底发生了什么?
2025年9月14日至15日,中美两国经贸团队在西班牙马德里就TikTok问题进行了谈判。9月19日,两国领导人更是就相关问题进行了直接通话。
目前可以确认的是,尽管中美双方均承认就TikTok问题的解决达成“基本框架共识”,但在任何地方,双方都没有公布具体的交易细节。目前严肃媒体的报道无非是说,双方原则上同意字节跳动继续持股TikTok不超过20%的股份,包括Oracle、Silver Lake、和Andreessen Horowitz在内的美国财团将会持有剩余80%。Oracle将负责处理TikTok在美国的数据,TikTok的核心算法仍然归属字节跳动,但经中国政府批准后可以授权给TikTok使用。
本周五通话之后,中方释出的信息再次印证了这一点。中方再次重申其立场:(1)尊重企业意愿,乐见商业谈判,(2)解决方案需符合中国法律法规和利益平衡;(3)希望美国为中国企业赴美投资提供公平环境。
换言之,中方对目前已经达成的基本框架不持异议,但具体的商业条款还需要企业以商业谈判来确定。
这符合我对这类交易的预期。两国政府更可能从政府审批的红线和大框架入手进行磋商,不太可能代替企业介入具体的商业细节。以目前的谈判进度,在双方政府确定大框架之后,还需要由企业和投资者进行更进一步的谈判,确定具体执行办法。
因此,目前在网络上流传的充满各类细节的传闻,甚至到了哪个股东持有多少比例,董事会由几人构成等等,基本可以确认是没有根据的假消息。这类半真半假的传言,正是AI幻觉新闻的典型特征。
2. 接下来还会发生什么?
即便中美双方均同意字节跳动持股20%、美国投资人持股80%的初步方案,离真正落地还有很长一段距离。最关键的问题是,字节跳动目前持有TikTok的100%的股份,如何把它的股份从100%降到20%?
股权交易最简单直接的方式,无非转股和增发两种。转股即是美国投资人向字节跳动“买下”其持有的TikTok的股份,字节跳动将可以就此套现巨额现金或股票对价。而增发则是美国投资人向TikTok增资,以稀释字节跳动目前持有的股权比例。这两种方案的核心区别是,收款方到底是字节跳动,还是TikTok这家目标公司。仅此一事,就可能构成各方商业层面的核心争议。
除此之外,不论是增发还是转股,都涉及到TikTok目前的市场价和估值的问题。非常有意思的是,截止到目前的官方公开信息之中,都没有任何一方提到“钱”的问题。政府固然可以批准或否决交易方案,但真正出钱的还是以营利为目标的私营企业。卖方想多卖钱,买方想少出钱,都是合理的要求。因为价格谈不拢而失败的并购交易不在少数。
TikTok目前的估值约3300亿美元,草草按美国业务占TikTok 全球业务30%来算,交易额将会超过千亿美元。作为对比,马斯克买下推特总共只花了440亿美元。显然目前的估值是远远超出美国投资人的胃口的。那么到底钱怎么算?这可能也是另一个谈判的难题。
事实上,相较于简单的转股或增发,我认为TikTok更可能的交易方式是把它在美国的资产和业务单独剥离出来,注入到一家新公司,作为其持有不超过20%的股权的对价。而投资人以现金或股票对价等方式投入剩余80%,或者以混合对价的方式,部分资金支付给字节跳动,部分字节注入新成立的TikTok美国公司。
目前TikTok是一家全球运营的公司,如果要单独拆分美国业务,又会产生两个问题:第一,在TikTok紧密全球运营的现状下,剥离真的做得到吗?又需要多久才能完成算法、用户、平台的剥离?第二,在剥离所谓的“美国资产”的时候,到底哪些是投资人想买的资产,哪些是投资人不想要的?比如,TikTok在美国的员工,是否会归属到美国投资人愿意购买的“美国资产”的范围内?
当然,最终双方达成的方案可能不是一个一锤定音式的交易,也可能是有若干年的过渡期,通过股权信托或资产信托的方式,在若干个暂时性的安排之后,最终完成剥离。
3. TikTok交易意味着什么?
TikTok交易对国际政治、中国企业出海投资等等“大”的方面的影响,已有诸多文章分析,我不再赘述。我只提一点,有美国评论家说,是否会由此产生所谓的“TikTok模式”,让美国可以以类似方案处理其他在美国争议性的中国企业 —— 这是中国必须要小心应对的。
对于普通人,特别是对TikTok员工来说,有更多值得关心的问题。不论是以何种方式完成美国业务的剥离和出售,TikTok在美国的人员和管理一定会“大换血”。美国的劳动合同基本都是任意解除(at-will),公司可以随时解除与员工的劳动合同关系,而无需支付离职赔偿金。
特别是,许多互联网公司员工收入的大头是股票和期权,而不同公司的期权协议对于如何处理员工被动离职的情况有非常大的区别。有的协议更加倾向于保障员工权益,会特别约定,在公司整体出售或收购的情况下,员工尚未行权的全部期权提前到期,可以获得全部企业授予的期权。但也有的协议约定在类似情况下,公司可以用极低的价格回收员工期权,而无需给员工实质性的补偿。
总之,可以仔细看看期权协议是怎么规定的。
当然,还会有随之而来的签证问题。有的美国签证允许在和公司解除劳动关系之后更换雇主继续工作,有的美国签证是和单一雇主绑定的,一旦劳动关系解除就需要离开美国,这些都是员工个人需要考虑的。
除了员工之外,可以预期TikTok美国业务出售之后,新的管理团队对于目前电商、直播等业务的开展,很可能会有新的想法,也将会影响大量的以TikTok维生的中小商家。
每一个国家层面的重大协议,落到普通人的身上,就是这么一个个对每个家庭都很重要的“小”问题。
by @敏大是一只柯基 #科技圈大小事
2025年9月19日,随着中美两国领导人的直接通话,TikTok交易的前景日渐明朗。这项需要同时取得中美两国政府批准,旨在剥离TikTok美国业务的复杂交易正在积极推进中。最近网络上有相当多的关于这项交易的传闻和流言,以目前可以确证的信息来看,到底发生了什么,又意味着什么?
1. 到底发生了什么?
2025年9月14日至15日,中美两国经贸团队在西班牙马德里就TikTok问题进行了谈判。9月19日,两国领导人更是就相关问题进行了直接通话。
目前可以确认的是,尽管中美双方均承认就TikTok问题的解决达成“基本框架共识”,但在任何地方,双方都没有公布具体的交易细节。目前严肃媒体的报道无非是说,双方原则上同意字节跳动继续持股TikTok不超过20%的股份,包括Oracle、Silver Lake、和Andreessen Horowitz在内的美国财团将会持有剩余80%。Oracle将负责处理TikTok在美国的数据,TikTok的核心算法仍然归属字节跳动,但经中国政府批准后可以授权给TikTok使用。
本周五通话之后,中方释出的信息再次印证了这一点。中方再次重申其立场:(1)尊重企业意愿,乐见商业谈判,(2)解决方案需符合中国法律法规和利益平衡;(3)希望美国为中国企业赴美投资提供公平环境。
换言之,中方对目前已经达成的基本框架不持异议,但具体的商业条款还需要企业以商业谈判来确定。
这符合我对这类交易的预期。两国政府更可能从政府审批的红线和大框架入手进行磋商,不太可能代替企业介入具体的商业细节。以目前的谈判进度,在双方政府确定大框架之后,还需要由企业和投资者进行更进一步的谈判,确定具体执行办法。
因此,目前在网络上流传的充满各类细节的传闻,甚至到了哪个股东持有多少比例,董事会由几人构成等等,基本可以确认是没有根据的假消息。这类半真半假的传言,正是AI幻觉新闻的典型特征。
2. 接下来还会发生什么?
即便中美双方均同意字节跳动持股20%、美国投资人持股80%的初步方案,离真正落地还有很长一段距离。最关键的问题是,字节跳动目前持有TikTok的100%的股份,如何把它的股份从100%降到20%?
股权交易最简单直接的方式,无非转股和增发两种。转股即是美国投资人向字节跳动“买下”其持有的TikTok的股份,字节跳动将可以就此套现巨额现金或股票对价。而增发则是美国投资人向TikTok增资,以稀释字节跳动目前持有的股权比例。这两种方案的核心区别是,收款方到底是字节跳动,还是TikTok这家目标公司。仅此一事,就可能构成各方商业层面的核心争议。
除此之外,不论是增发还是转股,都涉及到TikTok目前的市场价和估值的问题。非常有意思的是,截止到目前的官方公开信息之中,都没有任何一方提到“钱”的问题。政府固然可以批准或否决交易方案,但真正出钱的还是以营利为目标的私营企业。卖方想多卖钱,买方想少出钱,都是合理的要求。因为价格谈不拢而失败的并购交易不在少数。
TikTok目前的估值约3300亿美元,草草按美国业务占TikTok 全球业务30%来算,交易额将会超过千亿美元。作为对比,马斯克买下推特总共只花了440亿美元。显然目前的估值是远远超出美国投资人的胃口的。那么到底钱怎么算?这可能也是另一个谈判的难题。
事实上,相较于简单的转股或增发,我认为TikTok更可能的交易方式是把它在美国的资产和业务单独剥离出来,注入到一家新公司,作为其持有不超过20%的股权的对价。而投资人以现金或股票对价等方式投入剩余80%,或者以混合对价的方式,部分资金支付给字节跳动,部分字节注入新成立的TikTok美国公司。
目前TikTok是一家全球运营的公司,如果要单独拆分美国业务,又会产生两个问题:第一,在TikTok紧密全球运营的现状下,剥离真的做得到吗?又需要多久才能完成算法、用户、平台的剥离?第二,在剥离所谓的“美国资产”的时候,到底哪些是投资人想买的资产,哪些是投资人不想要的?比如,TikTok在美国的员工,是否会归属到美国投资人愿意购买的“美国资产”的范围内?
当然,最终双方达成的方案可能不是一个一锤定音式的交易,也可能是有若干年的过渡期,通过股权信托或资产信托的方式,在若干个暂时性的安排之后,最终完成剥离。
3. TikTok交易意味着什么?
TikTok交易对国际政治、中国企业出海投资等等“大”的方面的影响,已有诸多文章分析,我不再赘述。我只提一点,有美国评论家说,是否会由此产生所谓的“TikTok模式”,让美国可以以类似方案处理其他在美国争议性的中国企业 —— 这是中国必须要小心应对的。
对于普通人,特别是对TikTok员工来说,有更多值得关心的问题。不论是以何种方式完成美国业务的剥离和出售,TikTok在美国的人员和管理一定会“大换血”。美国的劳动合同基本都是任意解除(at-will),公司可以随时解除与员工的劳动合同关系,而无需支付离职赔偿金。
特别是,许多互联网公司员工收入的大头是股票和期权,而不同公司的期权协议对于如何处理员工被动离职的情况有非常大的区别。有的协议更加倾向于保障员工权益,会特别约定,在公司整体出售或收购的情况下,员工尚未行权的全部期权提前到期,可以获得全部企业授予的期权。但也有的协议约定在类似情况下,公司可以用极低的价格回收员工期权,而无需给员工实质性的补偿。
总之,可以仔细看看期权协议是怎么规定的。
当然,还会有随之而来的签证问题。有的美国签证允许在和公司解除劳动关系之后更换雇主继续工作,有的美国签证是和单一雇主绑定的,一旦劳动关系解除就需要离开美国,这些都是员工个人需要考虑的。
除了员工之外,可以预期TikTok美国业务出售之后,新的管理团队对于目前电商、直播等业务的开展,很可能会有新的想法,也将会影响大量的以TikTok维生的中小商家。
每一个国家层面的重大协议,落到普通人的身上,就是这么一个个对每个家庭都很重要的“小”问题。
by @敏大是一只柯基 #科技圈大小事