内容来源:DevOps案例深度研究第4期 – B站 DevOps实践研究战队(本文只展示部分PPT及研究成果,全程视频请移步文末)转载请注明出处。
本案例内容贡献者:曹坤良,董沙莎,过佳昱,廖定,李晶晶,李思源,欧美玲,任广印,Ruth,姚丹,张楠
IDCF指导老师:徐磊、姚冬、王立杰、许舟平
原文首发于「老广的印记」
一、文化和历史
徐逸:创始人,意见领袖,重度动漫迷。曾任执行董事。2019年卸任法人代表和执行董事,目前负责社区运营。 陈睿:董事长兼CEO。曾任中国最早的互联网软件企业之一金山软件联合创始人。2011年,陈睿以天使投资人的身份加入B站;2014年,正式加入B站担任董事长。 李旎:首席运营官。
为用户构建好的社区。 为创作者搭建施展才华的舞台。
二、社区运营生态
三、用户价值为导向的需求管理
二次元用户(核心目标用户):可以追番剧,了解二次元文化,希望能认识更多同好。 UGC创作者(核心目标用户):希望有一个大平台可以让自己作品被看到,收到大家认同。 直播爱好者:希望有平台能展示自己的才能。 非二次元用户:只是单纯地希望能找到有序的视频,或跟随喜欢的UP主或主播而来。
视频内容主要包括番剧、原创视频及UP主自制类视频功能,加上以用户为中心的页面布局、交互等用户体验设计,这两类需求针对核心用户占比会比较大,也呼应了前面的注重核心用户价值和体验。 社区文化类主要包括会员管理及支撑圈层的需求;氛围环境类包括弹幕和交流环境以及相关审核的需求,这两块为共同爱好者持续的交流分享营造一个良好的氛围,为核心功能提供支撑,这是B站重点响应的部分。
一方面通过全面分析商业价值、用户价值、分解转换为具体实现的需求; 另一方面在快速响应需求上线以后,收集用户反馈来持续完善产品的需求。
首先它是基于用户及商业价值的分析,基于核心用户的诉求和用户画像,优先考虑需求的迫切程度,通过良好的用户体验既维持老用户的粘度。对于系统运行稳定的一些非功能性的需求,也作为重点的排序考虑。 另外基于商业价值考量,针对付费用户,用付费情况来衡量需求价值,更量化且与商业接轨。 考虑用户与商业价值分析的同时,B站也会使用四象限法来进行需求的筛选和排序,通过需求的用户范围、发生频率和成本、效益,进行综合分析排序,确保用户价值价值较高的需求能够优先、快速地进入迭代循环,快速地上线并得到用户的反馈。
B站采用多种方式来收集用户的反馈,不仅包括了线下渠道的主动收集,而且还通过日志采集、设置埋点等多种手段,线上自动采集运营数据。对于线上的采集,采取了收集用户行为和用户数据的方式,首先与业务方一起绘制需采集业务场景涉及的系统链路,然后系统分布分别在客户端和服务端设置埋点,采集用户行为数据,记录日志。通过新功能灰度上线后目标用户数据采集和分析,形成对需求的快速反馈,持续打磨完善产品。
四、高性能微服务实践
文档缺失,上手难度大。 理解业务逻辑很耗时。
基于织梦CMS,一个开源的内容管理系统。 系统做了深度定制,底层逻辑没几个人能搞定。 业务聚合在一起,不易被扩展和拆分。 运行环境基本上只能通过创始人来扩展。
线上配置很复杂,代码层面没有设计路由系统。 运维已经不堪重负,已经禁止添加重写规则。
4.1 服务化/微服务化
各个服务独立开发。 分工明确,各自迭代。 单独模块独立部署。 可独立进行测试。
依赖链条长,测试常常遇阻,影响测试结果。 各服务的一致性难以保证。 运维成本高,错误难定位。 基础设施,网络等要求都比较高。
4.2 RPC框架
强大的标准库,解决了B站在视频方面的问题。 和Docker容器化良好的支持。 二进制发布,优秀的执行效率和开发效率。 易学易用上手快。 背靠Google大厂,丰富的开发者生态。 支持几乎所有主流的框架。
基于Go原生的网络库“net/rpc”。 Gob进行struct的序列化,不需要拷贝额外的代码,使用较为方便。 方法级的超时控制。 上下文context的支持。
及时同步服务上下线事件。 服务发现节点自我发现。 CP模式:依赖ZK的心跳进行广播(ZK心跳遇到抖动时候,容易出现全服务下线 ,所以B站会根据服务节点变化数进行判断是否放弃本次变更,进行容错)。 AP模式:polling + ping(优先保证高可用,牺牲部分一致性,但最终达到一致)。
利用mysql做存储管理相关配置信息。 通过http long polling来检查配置变更确保及时生效。 获取服务ip和版本,记录meta信息,实现服务发现的功能。
4.3 高性能
动态配置 协议装载 业务拦截 限流保护 缓存加速 鉴权 反作弊 业务服务 统计&监控
4.4 可用性
服务隔离:压力分流,稳定性高,物理隔离。 轻重隔离:核心稳定,快慢分离,流量迁移。 物理隔离:进程隔离,集群隔离,机房隔离。e.g. 机器隔离,容器隔离
设置超时:连接超时,读取超时,写入超时。e.g. 避免挤压,防止雪崩 合理超时:避免过短,避免过长,动态设置。
流量限流:accept,connection,thread。 资源限流:连接池,线程池。 请求限流:总数,时间窗口,平滑限流。 分布式限流:redis + lua,nginx + lua。 接入层限流:nginx limit_req,nginx limit_conn
重试容错:简单重试,主备重试,成功率重试,快速失败。 熔断容错:动态剔除,异常恢复。
调用链路:UI降级,UI异步请求降级,功能降级,读/写降级,接入层降级,应用层降级。 自动降级:超时降级,统计失败降级,服务故障降级,限流降级。 手动降级:功能开关,只读缓存,写异步化降级。
依赖的接口,必须加上熔断。 当接口出现故障,自动熔断,普罗米修斯出熔断数据曲线图,并且报警。 当超过N分钟,服务仍然不恢复,可以使用配置中心的推送功能,打开强制熔断,不再依赖接口。 当依赖方告知服务恢复,重新关闭熔断开关,变成自动熔断状态。
4.5 一致性
MySQL本地事务 本地事务+消息队列 Binlog
消息队列 幂等 努力送达 事务补偿
4.6 微服务部署发布
在PaaS平台上选择灰度发布-染色,定义染色标签。 在IaaS平台上开启“环境代理”虚拟机。 镜像选择环境代理hasson-base最小配置即可。 在hasson的虚拟机录入染色标签,按需配置测试接口。 DNS指向hasson IP,即可开始测试。
尽早的进入主干,可以跟灰度发布结合使用(金丝雀发布),需要使用统一的flag机制。 需要清理不再需要的flags,需要开发者养成良好习惯,正确使用flags,否则容易显得很乱。
4.7 代码管理
随着业务发展,基础库变更频繁,推进困难。 虽然重视代码质量,但流程不够自动化,完全靠自觉。 测试都积压在发版前,质量难保证,发版风险大。 版本管理非常复杂,代码复用率低下,维护成本高。
统一版本控制 广泛的代码共享和重用 简化依赖管理,避免菱形依赖 原子修改 大规模重构 跨团队协作 灵活的团队边界和代码所有权 代码可见性以及清晰的树形结构提供了隐含的团队命名空间
支持多种开发语言。 依赖分析增量编译。 可按需进行扩展。
统一的代码规范,便于协作。 单元测试覆盖率,高质量传承。
保证业务逻辑代码质量。 信息传递,扩充人员备份。 buildup competence,提升集体战斗力。 Ownership机制,责任到人。
五、数据运营
5.1 日志平台
5.2 监控平台
5.3 数据平台
六、结尾
“一代人终将老去,但总有人正在年轻。”
本文部分配图来源于网络,内容来源于网络和B站分享内容。