All Posts

从Google Fuchsia理解“天然无root”

"a dream job is not about dreaming, it's all job all work all reality all blood all sweat no tears. i work a lot and i love it.

特斯拉智能化路上的左脑+右脑

“种一棵树,最好的时间是十年前,其次是现在。” 特斯拉于去年3月份发布了基于Intel Atom(Apollo Lake)芯片的新版本多媒体控制器MCU2(MCU, Media Controller Unit),今年4月份 发布了其自研SOC (System On Chip) 的Autopilot硬件HW3(FSD,Full Self Driving)以支持将来实现全自动驾驶所需要的算力。多媒体控制器MCU与Autopilot ECU共同构成了特斯拉的大脑,最新版本的两个硬件开始在今年4月份下旬生产的Model 3和5月下旬生产的Model S/X中使用。 在Model 3中,特斯拉将MCU与Autopilot ECU两个板子分为两层装进了同一个外壳中(如下图),使得原本娱乐域和自动驾驶域的两个零部件就像左脑和右脑的关系一样,物理上组合在一起形成了一个车载大脑零部件。 如上图,其中上层的板子为媒体控制器,使用Intel Atom E3950的4核2.

从TDengine的开源说起技术选型

如果一艘快艇足够承载下你的所有货物到达彼岸,那么你不需要使用一艘轮船出行。产品设计和技术选型也是一样,我们经常会说:“我需要一个能够处理百万规模并发读写操作的,低延时,高可用的系统。” 如果按照这样的需求去设计系统,你可能得到的是一个设计复杂,代价昂贵的通用方案。但是如果仔细分析一下需求,你可能省略了需求背后的一些前提条件,比如真实的需求可能是这样的:“我需要一个能够处理百万规模的并发(只是理论峰值,平均情况小于10万并发)读写操作(读写比例1:9,只有追加写,没有修改操作)的低延时,高可用的(可以接受一定程度数据不一致性的)系统。” 那么你可能可以为这个特定的需求设计一个简单的,高效又低成本的系统。 做技术选型时,我们不会单纯的说A方案比B方案好,只是在解决特定的问题上,A方案比B方案更合适,选择了A方案的同时也意味着接受A方案里那些不如B方案的地方。在特定领域问题上的优化和定制方案往往能够取胜于解决更多领域问题的通用方案。最近涛思数据开源的TDengine也是这样一个针对专用领域的优化方案,TDengine的官方介绍如下: “TDengine是一个针对物联网,车联网和工业物联网领域优化的开源大数据平台。除了是一个速度快10倍的时序数据库,它还提供了缓存,流式计算,消息队列和其他以减少开发和运维的复杂度和成本的功能。” 在TDengine的官网文档上我们可以了解到这是一个针对IOT领域数据特性优化的强大的大数据计算平台。最近花了一些时间去熟悉这个开源项目的文档和代码,聊聊在做IOT时序数据库这方面的技术选型时使用TDengine或者其他产品一些可能需要考虑的点。 版本的选择 TDengine提供了三个版本的产品:社区版,企业版以及云版本。 其中社区版是本次开源的 单机版本 ,根据官方的介绍社区版拥有TDengine的大部分核心功能,是 处理中小规模数据 的理想平台。 企业版 在社区版的基础上新增了 高可用、横行扩展 等集群功能,内置 异地副本复制 功能,可用性达运营商级服务等级,提供 更强大的运维管理工具 。 而云版本则为运行在AWS/阿里云上托管的企业版,按月付费省掉了你自己部署和系统运维的工作。 类似的,行业里另一个比较流行的开源时序数据库InfluxDB也同样提供了三个版本的选择: 开源的单机版,商业的集群版以及云版本,功能对比如下图。 开源协议的考虑 TDengine的社区版本 基于AGPL 3.

那个上传的通讯录有毒!

近期,一则智联招聘员工倒卖个人简历信息的新闻在网上传播《5元一份!16万份简历被盗卖,“智联招聘”多名员工涉案》,个人隐私保护和网络信息安全的话题又一次被拾起。随着越来越多的个人信息电子化,信息安全的保护愈加重要,信息泄漏背后有人为的因素,也有信息系统建设安全设施不健全的因素。 前段时间看到一个黑产界在抖音进行精准营销的例子:抖音的推荐机制里,会经常请求用户手机的通讯录发现新用户或者把自己发布的视频推荐给通讯录里的新用户。黑产大佬呢,这时候,手握无数用户手机号码,做好手机号码归类,就可以尝试进行营销。举个例子,黑产手上有一批打着家长标签的手机号码,把这些号码导入到手机通讯录,用这个手机注册一个抖音用户,只发布育儿商品视频,那么这些视频会被精准的推荐给通讯录里的抖音用户(那些打着家长标签的号码),转化率也是可想而知。 现如今传说中的黑产界流通着各种不同线上线下渠道收集到的数据。你通过中介卖了一个房子,可能后面几年时不时会有电话打过来跟你说在哪有个新楼盘要不要考虑一下。你在汽车APP上尝试对车辆进行一次二手车估价,可能后面几个月你会不断收到不同地方打来的,询问你是否要卖车的电话。据网上消息报道,2018年年中,华住酒店集团有5亿条用户信息疑似遭到泄露,来自圆通和顺丰的总计十几亿条个人信息在暗网被出售。2019年央视3·15晚会也介绍了个人隐私信息通过手机App泄露的案例。 那么手机号都是怎么被泄漏的呢?除了一部分内部人员利益因素的有意售卖,或者不慎使用了恶意APP之外,有相当一部分数据是因为系统的信息安全建设不到位导致的数据泄漏。有存在系统漏洞被完整拖库的,也有接口保护不完善被恶意利用的,这里面也不乏拥有数亿用户的大平台产品。 举个大家熟悉的微博的例子。很久很久以前,国家刚开始执行社交网络实名制,各大社交网络平台的解决方案是让用户绑定手机号,通过运营商对手机号的实名登记完成。于是乎短时间各个人的微博账号都关联上了手机号。另一方面,为了进一步拓展社交关系网络,微博开始收集用户的通讯录数据,向用户推荐他还没有在微博上建立联系的通讯录里的好友。这个功能出发点挺好,然而刚刚上线那会,接口保护不完善遇到了可能产品设计者也没想到的功能滥用: 简单的,比如你有个陌生的未接来电,你想查一下是谁,利用微博这个功能可以这么查:你把这个手机号在通讯录里存一下,走一遍微博的上传通讯录&推荐通讯录好友功能,如果这个手机号也绑定了微博,微博就会给你找出来对应的微博账号。 再进一步呢,这是个通讯录的上传功能,天生就自带了批量查询属性,加上早期接口防范机制不健全(现已修复),于是乎前几年存着一种批量爬取微博手机号的漏洞: 如下图,我们知道运营商的手机号是分地区分配的,知道一个前缀可以查运营商和归属地,比如1817823这个前缀是中国电信分配给了广西柳州的手机号,符合这个前缀号段的号有1万个(手机号共11位),把这1万个号分成10个通讯录,每个通讯录1000个联系人,做十次通讯录上传&推荐通讯录好友的功能,便可以找出这1万个号码里对应的微博账号。在接口保护机制不健全的情况下,一个每秒只发10个请求的脚本(10 QPS对于微博这个体量的访问量来说是非常不可见的),相当于每秒完成1万个手机号的查询,跑一个小时便是3千多万个手机号,数量非常可观。 老实的微博大哥看着乐观的运营数据以为收集了好多用户通讯录,殊不知自己因为这种有毒的通讯录在一次次的往外吐着自己的用户数据。 系统漏洞并不偏好于产品的核心功能,实际上往往一些不起眼的地方的漏洞也会带来很大的损失,而这些不起眼的地方经常会是开发过程中最容易被忽视的地方。一些新的APP开发有时候为了赶时间上线,容易忽视这些不可见的安全方面加固的工作投入,以至于后期出现严重的问题。 防止接口被滥用的方法主要有几个方面: 通过接口签名和密钥保护(比如,白盒加密)的方法尽可能的防止签名方法和密钥泄漏被脚本实现调用; 加强输入参数的有效性校验,拒绝不符合期望的输入请求; 频次控制,对单个来源IP单个接口在短时间内的访问次数限制; 人机挑战,当检测到异常访问时,可以通过人机挑战的方式(比如输入滑块验证码,做基本算数题等)来要求调用方证明自身不是机器; 接口设计上仅输出必要的信息,避免过多的暴露信息而被利用; 线上无小事,防范于未然。

服务网格(Service Mesh)与Kubernetes的服务发现

伴随着微服务架构, 容器编排技术 和云原生(Cloud Native)应用的发展,William Morgan 两年前一篇《 What's a service mesh? And why do I need one? 》把服务网格(Service Mesh)带入到更多人的视野,近两年服务网格软件Linkerd,Istio等在 越来越多的公司生产环境中有所应用 。 在微服务架构里,服务网格是一个负责专门处理服务到服务之间通讯的基础设施层。 服务网格有两个主要目标,一个是将原先不可见的服务间通讯可视化; 另一个是对服务间的通讯进行一定控制(在路由/跟踪/安全等方面); 实践中, 服务网格通常被设计成轻量的 网络代理 程序,通过无侵入式的方式与应用集成,接管服务所有 入口和出口的网络流量,作为微服务之间网络拓扑中的通讯管道。 Kubernetes提供了服务抽象及服务发现机制,支持微服务之间的相互通讯,为什么我们还需要服务网格呢?我们先来看看Kubernetes的服务发现。 Kubernetes通过抽象出Service对象来支持微服务架构,运行应用的多个Pod实例通过定义Service对象对外提供服务。应用之间通过Service名来相互访问,通过Service名的DNS解析完成服务发现。 具体的,Pod实例运行时会将实例的地址端口等信息注册到kube-apiserver,与相关的Service建立关联(数据存储于背后的etcd存储),同时K8S节点会监听到该Service与Pod实例节点映射关系的变化。对于通常的一个Service名(非Headless Service),它会被DNS服务解析到一个虚拟IP(Virtual IP),而K8S节点上的kube-proxy进程会根据Service的信息建立这个虚拟IP的iptables转发规则:将发送到该虚拟IP的数据均衡的转发到若干个提供该服务的Pod实例所在的节点,以提供L4层的负载均衡功能。 类似于iptables代理模式,Kubernetes也提供了另一种基于哈希表的IPVS代理模式,以解决当服务数量达到上万级别的场景下iptables查找记录性能低下的问题,IPVS模式也提供了基于连接数,期望时延,加权选择等更多的负载均衡算法。 相对于Kubernetes工作在第4层的负载均衡,服务网格通过接管服务的出入口流量,可以提供更多对流量的路由控制,加工和可视化能力: 统一提供安全的双向认证加密通道; 支持7层协议检测,支持HTTP,HTTP/2和gRPC代理; 提供请求重试和超时功能; 自动 熔断机制; 支持基于就近/端到端请求时延的负载均衡; 服务请求的指标监控和可视化; 在应用服务网格之前,我们通常需要在各个服务程序内部实现以上的各个功能:服务的指标监控,请求重试及超时设定,熔断机制处理等跟服务业务逻辑代码混杂在一起存在于多个微服务之中。 以Linkerd为例,如下图,在集成了服务网格后,服务指标如请求成功率,延时及每秒请求数等会被自动记录并可以方便的集成到Prometheus和Grafana报表中展示。 服务网格使得服务运维所需要的代码逻辑与业务逻辑相分离,服务可以专注于业务逻辑的开发。 对于访问在Kubernetes中定义的Service,Linkerd会从K8S中读到Service对应的后台Pod节点信息用做负载均衡而不依赖于服务DNS。基于就近策略的负载均衡使得当Kubernetes在同城多机房部署时,可以优先路由到同机房的服务节点,减少跨机房访问。 服务网格在Kubernetes中有两种常见的部署方式: Sidecar容器的模式及主机共享代理模式。 Sidecar容器模式下linkerd-proxy被部署为每个pod里的一个容器实例,该模式下各个pod的linkerd独立,单个linkerd的故障不会影响其他pod,缺点是服务网格对系统资源的占用随着pod数量增长。 在主机共享代理模式下,同节点上的pod共用一个linkerd代理,这种方式可以减少linkerd的集群资源占用,也能够通过共享连接池的方式一定程度上提高吞吐量,缺点是当linkerd故障时同节点里的所有pod都会被影响到。 最后,服务网格跟API网关有什么联系和区别?API网关的主要职责在于为你的服务提供API接口,而服务网格的主要职责在于从服务实现里解偶出底层网络通讯及其相关的运维需求。两者在路由等部分功能上有一定的重合,但定位不同。微服务之间的内部依赖调用,如果都通过一个中心的内网网关来完成,那么所有服务形成一个中心化的星状网络。服务网格去中心化的架构使得拓扑中不存在一个可能影响所有微服务的中心网关节点存在,另一方面每次内部请求调用也少了网关这一跳的网络节点。 面向外部的API网关和面向内部的服务网格这样的分工通常会是一种推荐的部署方式。

琐言:团队带领者的知识覆盖模型

无论是刚毕业时作为团队的初级员工,还是若干年后初步接手团队带领工作,一直以来我脑海里有着一个团队带领者的知识覆盖模型。一方面作为督促自身不断学习新技术的指导,另一方面也作为在职场选择时选择自己的leader的一些准则。 在知识的深度和广度两个维度上,我们可以把团队带领者的知识/能力覆盖看成一个树形结构(如下图): 每一层的团队带领者能够 较大比例的覆盖 下一层的团队带领者的知识广度。 每一层的团队带领者在 一定程度上覆盖 下一层团队带领者的知识深度。 在这个模型下,不同类型的团队带领者区别在于自己所在的这个三角形的形状: 有呈细长形状三角形的某方面专家覆盖团队部分成员的全部技能,通过招聘另外一些方面的专家来补全团队的专业性和完整性。 有呈非常扁宽形状三角形的团队带领者,团队里每个人做的事情都知道一点,但并不深入了解。 处于每一层团队带领者的理想三角形形状各不一样,越接近底层对深度的覆盖会越大。 每个人心中都有自己理想的三角形,你期望的会是怎样? 最后,为什么是团队带领者而不是管理者? 高科技行业里,团队的成员大多是具备自驱动能力的高智商人士,拥有这样特征的团队需要的是能带队打胜战的带领者而不需要过多的被管理。