首页>会议文档 >

滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成

page:
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成
滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成

滴滴出行平台技术部 王涛 - 滴滴出行跨地域 iOS 构建优化与持续集成

所属会议:ArchSummit全球架构师峰会北京站2017会议地点:北京


下载

手机看
活动家APP客户端

扫二维码下载
或点击下载
Android iOS

6077次
浏览次数
ArchSummit全球架构师峰会北京站2017所有文档 宜信 张军 - 信贷业务持续创新当中的大数据风控架构_部分1 宜信 张军 - 信贷业务持续创新当中的大数据风控架构_部分2 翼启云 孙鹰 - 守住Fintech这扇门 — 高可用测试平台演进之路 优酷 张云锋 - 优酷广告投放引擎优化实践_部分1 优酷 张云锋 - 优酷广告投放引擎优化实践_部分2 优酷 李玉 - 视频推荐中用户兴趣建模、识别的挑战和解法 郑建军 - PaxosStore:微信高可用、强一致存储系统 知乎 姚钢强 - 知乎 feed 流架构演进 中兴通讯首席架构师 钱煜明 - 打造金融级分布式数据库服务_部分1 中兴 钱煜明 - 打造金融级分布式数据库服务_部分2 诸葛越 - 算法无处不在 转转 张相於 - C2C电商平台推荐系统架构演进 亚马逊 代闻 - Cloud Native 架构的演进之路 亚马逊 郑斌 - 工程师文化与文化中的工程师 腾讯 陈宁国 - 腾讯海外计费系统架构演进 腾讯 黄斯亮 - 全民K歌从零到千万在线后台服务的演进之路与黑产对抗 腾讯 王旻 - 腾讯云大规模任务调度系统的架构蜕变 腾讯 闫二辉 - 腾讯企业级消息中间件DevOps实践 王秀刚 - 京东金融多业务集成解决方案 微博 崔建兴 - 微博社交广告系统架构实践 微博 胡忠想 - 微博应对突发热点事件的弹性调度实践 吴惠君 - 实时流系统Heron的异常检测和恢复 清华大学 张宇韬 - 大规模异构网络数据融合 趣店 尹茂君 - 砥砺前行:趣店同城双活高可用架构实践 沈悦时 - 超高密度游戏直播转码架构 滴滴出行 李培龙 - 滴滴出行海量数据场景下的智能监控与故障定位实践 丁宇 - 阿里巴巴云化架构创新之路 饿了么 胡彪 - 饿了么移动性能可视化之路 付钱拉 石伟 - 从零到一,构建灵活、高性能的金融账务系统 复旦大学 邱锡鹏 - 深度学习在自然语言处理中的应用 瓜子二手车 魏旋 - 机器学习中的人机互动 杭州谐云 苌程 - 容器环境下基于APM的海量日志全链路跟踪分析 恒丰银行 赵宏伟 - 恒丰银行基于大数据技术重塑数据仓库及应用的探索_部分1 恒丰银行 赵宏伟 - 恒丰银行基于大数据技术重塑数据仓库及应用的探索_部分2 恒丰银行 赵宏伟 - 恒丰银行基于大数据技术重塑数据仓库及应用的探索_部分3 京东 李维 - 自动深度语法分析是自然语言应用的核武器 京东 周光 - 京东虚拟业务系统高可用性设计 京东 刘峻桦 - 京东国际独立站系统演进 陆金 卢峻 - 凤凰涅磐:陆金所金融平台的架构大升级 美丽联合 张振华 - 美丽联合容器云平台建设的实战分享 美丽联合 赵懿 - 时尚的产品化和商业化_部分1 美丽联合 赵懿 - 时尚的产品化和商业化_部分2 美团点评 孙业锐 - 美团点评用户行为分析系统的构建与优化 美团点评 梁士兴 - 从分层复用到自动化测试—看美团客户端架构的演变_部分1 美团点评 梁士兴 - 从分层复用到自动化测试—看美团客户端架构的演变_部分2 摩拜 范同祥 - 摩拜国际化架构演进_部分1 摩拜 范同祥 - 摩拜国际化架构演进_部分2 拍拍贷 杨波 - 拍拍贷基础架构的DevOps演进之路 青云 张雁飞 - RadonDB:新一代分布式关系型数据库 滴滴出行 陈宜明 - 滴滴出行平台的高可用实践 百度 牟宇航 - 百度MPP数据仓库Palo开源架构解读与应用 百度 马艳军 - 人工智能驱动的内容生产与分发_部分1 百度 马艳军 - 人工智能驱动的内容生产与分发_部分2 百度 马晋 - 成就成长-工程师团队前进的驱动力 百度 于洋 - PaddlePaddle:Towards a Deep Learning Compiler for the Cloud 北京木仓科技(驾考宝典) 谢呈 - 技术人转身创业的坑和坡 菜鸟网络 朱君标 - 菜鸟技术团队全栈化(开发全栈前端)之路 Reddit 陈晨 - 从Instagram到Reddit,浅谈西方工程师文化和管理 tutorabc 张明 - tutorabc微服务平台架构实践_部分1 tutorabc 张明 - tutorabc微服务平台架构实践_部分2 Yuanchi Ning - UberEats Discovery:Food Recommendation 阿里UC 顾辉 - UC浏览器客户端容器化架构演进 阿里巴巴 吕奇 - 阿里混部技术最佳实践 阿里巴巴 张瓅玶 - 阿里巴巴调度与集群管理系统Sigma 阿里巴巴 林轩 - Pouch和阿里容器技术演进 阿里巴巴 余锋 - MySQL数据库架构的演化观察 阿里巴巴 张佶 - 阿里小蜜中的机器阅读理解技术揭秘_部分1 阿里巴巴 张佶 - 阿里小蜜中的机器阅读理解技术揭秘_部分2 阿里巴巴 张娟 - 弹性容量管理探索 爱奇艺 邢常亮 - 与狼共舞 - 爱奇艺移动业务后台系统架构设计与优化实践 爱因互动 王守崑 - 创业,永远在路上 Tumblr 李北涛 - 相关性反馈在推荐系统中的应用 PayPal 曹若沈 - 高可用低延时的PayPal风控数据平台 TalkingData 宋净超 - 从Kubernetes到Cloud Native——云原生应用之路_部分1 TalkingData 宋净超 - 从Kubernetes到Cloud Native——云原生应用之路_部分2 TalkingData 宋净超 - 从Kubernetes到Cloud Native——云原生应用之路_部分3 58速运 沈剑 - 分还是合?58到家订单中心架构演进 bilibili 王昊 - 技术、产品、管理,选择和平衡 FreeWheel 宋一玮 - FreeWheel在微服务架构下的前端改造实践 FreeWheel 姜冰 - FreeWheel OLAP实践 musical-ly 杜鹏 - musical-ly基于社交关系的Smart Feed架构 OnVideo 刘歧 - 大闹天宫:悟空在FFmpeg社区从入门到出家

文档介绍

随着滴滴出行业务的不断拓展,客户端开发团队人数激增,代码量急剧膨胀,开发人员物理地域不同(北京、上海、杭州),人员间的协同开发成本,代码维护成本成指数型增加。在如此前提下,如何保证稳定高效的协同开发? 滴滴业务的高速发展对滴滴客户端的组织架构提出了新的挑战,如何才能高效的进行代码复用,持续集成和按需集成? 工程涵盖业务组件繁多,代码量巨大,单次构建耗时长,一个组件出错就要重新再来。如何避免这种情况?

演讲实录

随着滴滴出行业务的不断拓展,客户端开发团队人数激增,代码量急剧膨胀,同时开发人员存在物理地域的不同(北京、上海、杭州),在如此前提下,如何保证稳定高效的协同开发?如何才能高效的进行代码复用,持续集成和按需集成?工程涵盖业务组件繁多,代码量巨大,单次构建耗时长,一个组件出错就要重新再来,如何避免这种情况?
滴滴出行 APP架构组架构师王涛根据滴滴出行乘客端架构演进历程以及实践经验,在 2017年 ArchSummit全球架构师峰会北京站上分享了滴滴出行对以上问题的解决方案,并介绍了滴滴出行主推的构建平台的设计思路、现状和未来的规划,以下是分享的全部内容。
滴滴出行乘客端架构演进历程
1.0版本
滴滴出行 1.0版本功能比较简单,就是一个供需的匹配工具,业务比较单一,开发者也比较少,所有代码都在一个工程里面。
2.0版本
到了 2.0版本,功能上仍然只有出租车一条业务线,但是产品形态发生了一个变化,变成一个交易平台,而代码仍然是以大锅饭的方式进行开发和集成。
3.0版本
到了 3.0版本,产品出现多元化,新增了专车业务线,代码出现了初步的膨胀,但是因为这个时期只有两个业务线,集成构建仍然不是什么大问题。
4.0版本
在 4.0版本,我们遇到了很多挑战和痛点,这个阶段被定义为平台化整合阶段,由于在这个时期竞争对手的出现导致应用需求需很快上线。时间短、业务重,快速上线造成了工程代码极度膨胀,高度冗余。在这个时间段滴滴出行和快的打车又进行了合并,开发者出现跨地域分布,因此跨地域的团队协作,资源分散在各地,团队间沟通和交流都出现了很大的问题。
对此,在每次发布新版本之前,我们都会预留一周时间进行代码合并。在这个时期我们成立了一个交流群,叫协同发版群,大家都在群里沟通代码要怎么合并的问题,而且这个时期的 QA测试遇到了很多的灾难性问题,因为代码是高度耦合的,任何人只要修改了任何一条代码,都要进行一次回归测试,这个时期让我们很头疼,效率很低。
5.0版本
随着业务线增加,代码功能开发时间和代码合并时间的关系如下图的柱状图,功能开发时间的曲线是稳步上升的,但是代码合并所需时间出现了指数级的上升,这是失衡的。因此在架构上我们向组件化迁移,针对每个组件推进了组件工程化,使每一个组件都有一个自己独立的工程,解决了协同合作的问题,提升了开发效率,此时的架构也升级到了 5.0阶段。
在平台组件化的阶段,随着后续的业务迭代和功能开发,乘客端里的组件有了高达 140多个,同时出现了新问题,我们集成了这么多的组件,如何进行有效管理上升为一个很大的问题。组件越多,原代码越多,编译就需要很长的时间,这对于开发者来说,体验是非常不好的。
然后我们对构建系统进行了再次升级,推出了OneTool工具,标准化壳工程改造,是我们的壳工程经历了合久必分,分久必合的过程,以及基于 Cocoapods的预编译优化。
这个是我们目前的基本架构图,大家可以看到下面是基础平台的部分,包括了一些通用的运行时组件,一些基础组件还有业务组件,在平台之上会有不同的 APP,每个不同的 APP加入自己的个性化组件,包装成一个 APP。
标准化的壳工程
由于滴滴出行有十多条业务线,构建系统面临一个最复杂的环境。因此我们首先要做的就是标准化壳工程。
项目背景
在 4.0阶段,我们推进了组件工程化,在当时很好地解决了我们的问题,提升了开发效率,但随着版本迭代,也出现了一些不适应的问题:
由于每个组件都有独立的工程,各自就会加入自己的配置,以及加入自己特异性的脚本,这样就会出现一个问题,组件在自己的工程里面可以正常使用,但是集中到总工程里面就无法使用了,导致无法集成。
组件工程化对新入职的开发者并不是十分友好,任何一个开发者加入一个公司之后可能负责 4-5个组件进行开发,每个组件都有独立的工程,他们要同时接触 5个不同的工程的创建和管理,对他们来说初始的挑战很大。
还有 Debug的问题, Pods文件夹下的代码是没有版本控制的,因此在我们修改了一些代码之后,这些修改的代码没有办法直接提交到组件仓库里的,如果 BUG比较严重的话,修改的代码可能比较多,某一个开发者可能花了一天时间把错误解决了,但是他想把修改的代码往自己的组件库导入的时候,可能已经把修改过的部分给忘了。
因此,我们推翻了组件工程化,开始创建一个标准化的壳工程。
上图是标准壳工程的大概模型图,可以看到它分为两部分:一是本地的部分,这一部分开发者可以进行自由改造,还有一部分是同步的Workspace,这是不允许开发者进行修改的。
如果组件的开发者要想开发组件也很简单,只需把自己的组件克隆到 Workspace里面,将自己的组件以 LOCAL PODS方式加载进来就可以了。
标准壳工程的创建过程
标准壳工程的创建过程分为六个步骤:创建一个本地的 Workspace,克隆同步的 Workspace到本地的 Workspace里面,创建一个基本的配置文件 ,第四步从 Workspace里面拷贝一些文件到本地的 Workspace里面,生成 Podfile,执行 pod install,最终生成如图所示的本地的目录结构。
上图中间这一部分就是本地的 Workspace,然后选中的右边是同步的 Workspace,这其中有一些文件和文件夹是相同的,这就是第四步操作的结果。
以上的步骤还是很烦琐的,因为创建这样一个工程需要六步,每一步都有很小的细节,如果有程序员自己一步一步手工操作的话,非常容易出错,但这却是我们进行工具自动化的基础。
OneTool
对于工具自动化,我们自研了 OneTool,这是一套命令行工具,最初目的是使iOS开发构建更加简单快捷。下图就是基本的命令,其中就包括了前面的创建一个标准壳工程。
OneTool这个工具已经是整个构建系统的桥梁,目前整个构建系统中任何一个环节都离不开 OneTool的存在。
OneTool包括两个部分,第一部分是 One Commands,这是由开发者主动调用的。还有另外一个部分是 OnePods,它是由 Cocoapods主动调用的。
OneTool很好地解决了开发者使用繁琐步骤创建工程的问题,减少了操作,但它毕竟是一个命令行的工具,所以它并不是很友好,同时每一个开发者的电脑环境是不能保证相同,在使用过程中就会出现各种各样的问题。
所以,我们基于 OneTool开发了一个 GUI工具,就是 OneApp,它把所有 OneTool的命令都集中到这个界面上,降低了使用门槛。OneApp除了基本功能以外还提供了对所有的 Workspace统一管理的功能,图中左侧展示出了所有的 Workspace,右面的主要区域是展示选则的 Workspace的 Pods的基本情况,它可以对任何一个 pod进行任何信息的修改。
OneApp的工具推出之后,在公司内部将成本基本降低到了零,在最初我们没有工具,仍然是以原始创建工程的方式创建工程时,曾经发生过这样的事情,公司一个新同学入职的时候,第一件事就是配个可以编译的 Workspace,由于我们的 Workspace非常复杂,他配置了一个星期也没能将工程 run起来,最后那个同学直接离职了,但是现在这样的问题已经不存在了。使用这个工具之后,新同学在入职十分钟之内就可以创建出一个可以运行的Workspace,目前除了 iOS开发者在使用它以外,QA和 PM也在使用用,PM为什么会用?前一阵 iPhoneX出来之后,我们要做适配,PM可以拿出这个工具,通过简单操作配出一个工程,就可以看到适配之后的结果。
实践经验
如果使用组件化的架构体系,首先尽早建立标准化壳工程,这样会减少很多的负担。其次要统一组件库配置文件规范,也就是podspec文件,还要善于使用 xcconfig文件。最后依赖配置文件的权限要控制好,一旦一个开发者误操作将文件进行了修改提交上去,可能就会造成灾难性后果。自动化和工具化是以上工作最好的实现方案,因为手工去做的话很可能会出现一些问题。
预编译优化
滴滴出行的工程初次编译时间有着将近一个小时,假设有 300多个开发者,每个人编一次工程,就需要 300小时,所以编译时间优化是势在必行的任务。相同的工程在使用预编译优化之后,一次编译时间缩短到 5分钟,带来了效率上的极大提升。
预编译优化的实现方案,第一步使用一个纯源码的工程,编译出静态库文件,通过 vendored_libraries加载静态库文件,找到 podspec文件修改一些参数,以及文件的地址,最后将修改之后的文件与静态库放在一起打包,就制作好了预编译包,将这个包上传到服务器,使用时根据需要将这个预编译包下载下来,集成到工程中,就完成预编译包的创建和使用。
我们的预编译包也有自己的发布流程,每个组件的开发者开发好以及本地测试 OK之后他们会将预编译包进行提交触发一下的流程。
踩过的坑
当源码中有预编译宏的话就会出现问题,预编译是将代码提前进行编译,最后是使用静态包的,由于我们编译的环境和运行环境很可能是不一样的。比如 if_has_include宏,我们在编译的时候有某个头文件,实际运行中没有头文件,这样会直接造成功能的缺失或者crash。
如果组件中定义了 subspec,前面的预编译包的创建流程是不 ok的,做出来的包是不能使用的。滴滴出行最早是不支持 subspec的,一旦遇到 subspec这个库只能以源码方式进行集成,后来经过不断的踩坑填坑过程,如今完美的完成了 subspec的支持。
使用结构体和联合体,这种在使用预编译的时候也会有一个隐讳的问题,举个例子有两个库:地图库、依赖地图的导航库,地图库里面定义了 C语言的结构体,导航库在刚开始使用时,可以完美地运行,当在某个版本地图库将结构体进行修改,新增一个字段,没有通知导航库,这时候在编译阶段因为可以正常编译通过,因为导航库并没有使用这个字段,但是一旦到了线上就会直接造成crash。因为线上运行的时候内存结构不一致,就会造成错误。在这里有一个避免的方式,大家可以参考一下系统库的结构体的实现方式,由库自身提供创建结构体的方法,比如 CGRectMake,使用这些方法创建结构体就可以解决使用时内存结构不一致的问题,还有如果podspec编写不规范,随意写的话,修改出来的包也可能不能正常使用。
持续集成
最开始的时候用的方法比较低端,人肉 merge效率极低、错误后置,之后我们接入了jenkins,在每个开发者提交了一个 tag之后,会进行一次编译检查,如果检查失败的话就不提交 tag。因为 Jenkins每次只能添加一个组件,每个组件都要创建单独的 job,最后 Jenkins job数量就爆炸了。如果多个库相互之间有依赖的话,一次需要集成三到四个库,而 Jenkins自身一个 job只支持修改一个组件库,这时候 Jenkins就处理不了,又会回到手工修改这种方式。由于人肉手工修改没有检查的保证,很可能出现错误。
那么有没有更好的方式进行持续构建和集成呢?有!那就是集成构建平台,首先集成构建平台和 Jenkins相比有着更加友好的用户界面,另一个是集成构建平台支持各种自定义方式去集成构建,开发者可以想集成几个组件就集成几个,针对任何一个组件库都可以进行自定义的设置,包括预编译包的属性设置等。
另外集成构建平台相比 Jenkins会增加一个统一管理所有组件的功能,借助这个功能,在基础平台上通过不同的组件的集成就会包装出不同的 APP,即支持多 APP的集成,集成构建平台还有一个功能就是会对每次集成构建创建快照,根据需要的时候能进行恢复,如果一个历史线上的包出现问题的话,可以快速恢复那个包的代码状态,进行调试,集成构建平台的投入使用是人肉手工效率的 3倍左右。
任何一个开发者提交了代码之后,会触发集成、创建工程、克隆 pod、打新 tag、更新依赖、集成工程、编译、集成失败,会修改,如果成功:
预编译流程;
将修改之后的依赖配置文件提交到仓库里,最后通知给用户告诉他这次集成是成功的。
目前我们持续集成的过程就是在不停地跑这样的循环,完成整个公司所有 APP的持续集成过程。
集成构建平台

上图是集成构建平台的界面,他有着比 Jenkins更友好的界面,左面是支持的不同端和不同的 APP,右面是每次集成构建的历史,上面还有一些 APP的管理和组件的管理等功能。
我们集成构建平台的设计思路,主要是为了解决 Jenkins的一些问题才推出的,首先它支持各种自定义的需求,以及要支撑多 APP的集成,还要统一管理公司内部所有的 SDK,不能只针对 iOS一个端使用,一定要多端通用。最后集成构建平台的各个用户权限一定要有明确的划分。
公司内部除了集成构建平台之外还有其他的平台,比如说测试、发版、数据统计平台,这些平台都是相互独立的状态,我们推出集成构建平台之后会将这些平台全部打通,从最初的构建情况,到最后直接上线、数据收集,完全都是打通的。目前,集成构建平台已经上线一个多月,已经有数次稳定发版,已经接入了滴滴出行乘客端和企业端,打通平台的有发版平台和OneTool。
未来要实现 iOS和Android一致性开发
未来要做的就是要流量全切,现在仍是灰度发布状态。一部分使用集成构建平台,另外一部分做老的Jenkins方式,未来要接入公司内所有端,以及和其他平台进行打通,未来开发的重点是要做 iOS和安卓的一致性开发,目前在这两个端上,整体开发流程是一致的,但在某些细节上 iOS和安卓还有些区别,比如说 iOS天生是支持源码的,经过修改之后才支持了预编译的包,而安卓天生是支持预编译的包,在修改了之后才支持了源码的编译,未来我们就要做到一致性开发。

×

打开微信扫一扫,分享到朋友圈