专栏电商日志财经减肥爱情
投稿投诉
爱情常识
搭配分娩
减肥两性
孕期塑形
财经教案
论文美文
日志体育
养生学堂
电商科学
头戴业界
专栏星座
用品音乐

扛起英雄联盟S12千万在线哔哩哔哩直播架构演进史

  作者介绍
  赵海林,B端技术中心资深开发工程师。
  一、前言
  哔哩哔哩直播成立于2014年,经过8年时间的发展已经从最初的业务试水成长为公司重要的业务板块之一。技术架构也从一个单体服务演进为由数百个微服务组成的复杂系统。本文将回顾8年来哔哩哔哩直播架构演进中一步步的变化,带你了解它是如何从0开始逐渐成为能够承载千万在线的微服务系统。
  二、从0到1
  和大多数网站一样直播也是始于一套LAMP架构,即LinuxApacheMySQLPHP。前端、服务端、定时任务所有功能都集中在一个叫做liveappweb的项目中。
  直播系统架构
  一个典型直播后台架构由三部分组成:业务系统用于直播各种业务功能逻辑实现、推拉流系统用于主播推流和用户拉流观看、长连接系统用于在直播中的各类实时业务数据推送触达。而liveappweb即承担了applicationserver的角色。
  liveappweb的应用架构
  在liveappweb中既有通过PHP模板引擎Smarty渲染的页面,也有JS写的前端页面,还有常驻后台的PHP消息队列处理程序(通过RedisList实现的生产消费模型),这些功能被分别放在各自的代码目录中,分别由前后端开发人员进行代码开发,并最终部署到一台台物理机上。
  liveappweb最初的项目结构
  虽然现在看起来这套架构非常简陋,但在最初的2年里我们在liveappweb实现了每个直播平台所必备的各类业务系统,而这些系统也在后续的演进中也在不断发展壮大成为一个个重要且独立的业务系统。
  liveappweb
  像任何一个高速发展的业务一样,liveappweb的代码量也在急速增长,从2015年中的5W行PHP代码到年末的8W行,再到2016年中已经累计到了13W行。我们在这期间做了一定的前后端分离改造,将前端部分拆成一个个单独的前端应用,如直播首页、直播房间页、直播个人中心页等。但随着业务增长和人员扩充单体应用带来的问题也越来越多,并行项目带来的合并冲突、发布排队、某个子模块问题导致整站挂等问题日渐突出,而这些问题也终于在一个重要事件上集中爆发了。
  2016年某一时刻的git状态
  三、局座来了
  不了解局座B站直播梗的同学可以先通过这个链接了解一下事件背景:如何看待张召忠将军7月13日的b站直播?〔1〕,一句话总结就是:局座来了直播挂了,睿总在知乎公开道歉。
  当时的直播几乎受到全网的群嘲,微博、知乎各类吐槽的声音铺天盖地。回头来看一方面是对观看人数的预估不足,另一方面受到单体服务架构的制约,监控告警、资源弹性、限流降级、故障隔离等手段都非常缺乏。痛定思痛之后直播开启了微服务化的历程。
  四、微服务化
  如何做微服务?这是摆在当时团队的一大难题,由于当时团队成员主要是PHP背景,同时业务也在快速迭代,切换语言从0开始显然是不现实的。而当时正好有一款在国内很火的PHP高性能服务框架Swoole,通过进程常驻的方式显著提升了PHP服务的运行性能。经过一定的技术调研之后团队决定以Swoole为基础构建直播的微服务框架,并定义了以下原则:
  按业务领域进行微服务拆分每个微服务拥有自己独立的数据库、缓存每个微服务仅能访问自己的数据库、缓存,服务间只能通过RPC访问微服务负责人对自己的负责业务的服务稳定性负责
  服务框架:我们基于Swoole开发了我们自己的微服务框架,这套微服务框架实现服务进程管理、平滑重启、ORM、Cache、Logging等,业务只需要按照模板实现controller和对应service代码即可,能够比较快速地上手开发。
  通信协议:微服务间通信我们采用了基于TCP上自行封装的RPC协议并称之为liverpc,这个RPC协议非常简单直观,通过固定长度Header头变长JSONBody实现,服务间以TCP短连接进行服务调用。
  服务发现:引入微服务后还需要解决的一个问题是如何做服务发现?结合当时的背景我们选择了zookeeper作为服务发现组件,同时为了隔离服务注册、发现、健康检查的复杂性,我们专门开发了一个叫做Apollo的业务伴生程序用于服务配置拉取、服务注册、服务节点发现,业务框架通过文件监听的方式感知配置变化进行热加载。
  配置管理:同样地我们采用了zookeeper来保存每个服务的配置文件,并通过Apollo进行配置拉取和变更监控。
  消息队列:我们搭建专门的kafka机器作为消息队列,由于PHP直接跟Kafka交互较为复杂,我们搭建了专门的投递代理服务publisher和消息回调通知服务notify。
  统一网关:另一方面针对缺乏统一限流、降级能力的问题,我们单独开发了一个网关服务liveapi,并且要求所有外部的访问都需要经过liveapi转发到对应的业务服务。在这一层统一网关上我们实现了流量转发、URL重写、超时控制、限流、缓存、降级等能力。liveapi也是基于swoole实现的,不同的地方在于我们是通过swoole提供的纯异步client实现,在性能上有一定保证。
  至此一整套微服务系统的雏形已经显现出来。
  在这一套微服务系统上我们逐渐将liveappweb各自业务域的逻辑重构到对应的服务中。同时我们和DBA一起协作完成了直播的数据库在线拆分,将原来集中在一个库的业务表拆分到一个个独立的数据库中,实现了高速路上换轮子,也彻底解除了存储层混用的风险。
  2017年12月局座再次来到B站开直播,带来了比去年多得多的流量,但这一次我们稳了。
  五、容器化
  一直以来直播服务均采用物理机部署的方式,这种方式存在明显的缺陷:需要为每个服务分配独立的端口避免端口冲突、部署目录需要隔离、存在资源竞争、单个服务容量无法准确评估等等。而随着B站业务规模的扩大,公司的基建团队也提供了更为稳定的容器平台,在充分调研后我们启动了服务Docker化改造并在很短的时间内完成了全部服务的容器化部署。
  在Docker化部署中面临的一个问题是:如何选择CPU调度方式?
  我们知道在Docker中通常有两个方式:1、CFS(完全公平调度)即通过按比例的CPU时间分片进行调度,这种资源分配方式比较灵活,也可以通过资源超配来提升整体的资源使用率;2、CPUSET(绑核)这种方式通过设置CPU亲和性将POD绑定到指定的一个或多个CPU,实现资源上的独占。
  我们在将PHP服务迁移Docker时发现CFS模式下接口超时非常严重,已经达到了无法接受的程度,因此所有的PHP服务均采用了CPUSET的方式部署,同时PHP服务的工作进程数也通过压测的方式得到最佳配置,为分配的CPU数量的34倍表现最佳。
  在CPUSET模式下同样存在的突发流量的困扰,这类突发流量在Prometheus的监控图表中难以发现,因为监控数据通常是以30s周期采集拟合生成监控曲线。但在请求日志上我们可以清晰地看到一条条秒级的请求突刺存在,而这些请求量远远超过了我们为服务配置的CPUSET数量,而要满足这种突发流量而调高配额显然也是不现实的,因为这会造成极大的资源浪费。
  针对这种场景我们将应用资源池分成了两个分组:固定资源池和弹性资源池,固定资源池中的服务采用CPUSET固定分配好资源量,而弹性资源池采用多个服务混部的方式,单个服务不限制其资源使用量。并通过网关对突发流量进行分流,将突发流量引入到弹性资源池,以此来解决突发流量带来的容量瓶颈。
  网关服务liveapi会实时统计每个接口的QPS:当QPS小于X时流量全部转发到固定资源池分组,当QPSX时超出阈值的请求会被转发到弹性资源池。同时我们实现了请求打标功能,在弹性资源池内的请求会优先请求同在弹性资源池的服务。我们也可以通过观察弹性资源池的的利用率来判断固定资源池服务是否需要扩容,最终的目的是通过少量的混部弹性资源池来解决个别服务频繁的突发流量报错。
  关于CFS超时的问题后来在阿里云公开的文章中有了更详细的阐述,并通过CPUBurst技术将CFS调度导致的超时问题大大缓解,CPUBurst的核心是将我们常用的令牌桶限流算法引入到了Linux内核CPU调度上,当CPU使用率低于设定的配额时可以累计未使用的配额,并在后续的调度中允许使用累计的这部分配额来应对突出流量。随后内核团队通过内核升级、优化等方式解决了cgoup泄露、调度不均衡、超时等问题。同时在内核上通过调度算法优化,利用CPUBurst、GroupIdentity、SMTexpeller等技术实现了在离线业务混部互不影响、全站资源合池等重大技术特性,资源容量和利用率得到极大提升。业务应用也不再通过CPUSET这种相对固定的资源分配方式,而是在CFS调度模式下通过VPA、HPA这样的弹性资源管理策略,动态、按需地获得所需要的运行资源。
  六、Golang真香
  2018年是Golang大火的一年,毛老师作为Golang布道师在哔哩哔哩主站推进Golang服务化演进非常成功,并通过Golang开发出了一系列的微服务框架和中间件,如Kratos(Go微服务框架)、Discovery(服务发现)、Overload(缓存代理)等,相当一部分项目也同时在github上进行了开源。
  彼时的直播正面临着下一步技术演进的抉择,因为基于swoole构建的PHP微服务体系已经不能支撑更大的流量了,其主要问题集中在:
  1)PHP的多进程同步模型极易因为单个下游异常而导致整个服务挂掉,因为下游响应变慢PHPWorker不能及时释放,新的请求来了之后只能排队等待空闲Worker,这样的级联等待进而导致系统的雪崩。
  2)实现RPC并发调用较为困难,在一些业务复杂的场景由于只能串行调用下游接口,导致最终对外的接口耗时非常高。
  3)PHP服务扩容带来了数据库、缓存连接数的压力,当时还没有成熟的数据库代理,而是每个PHPWorker都会直连数据库,这直接导致了连接数的爆炸,进一步限制了PHP服务的扩容能力。
  而Golang的协程模型正好可以解决这些问题,毛老师在主站Golang服务化演进基本完成的情况下亲自来到直播指导Golang服务化演进。
  对于这次Golang服务化演进,我们将服务划分为了三种类型:
  业务网关(interface):业务网关按业务场景进行划分,如App、Web网关,在网关内完成对应场景的API接入,对下游业务服务的数据聚合、App版本差异处理、功能模块降级等。
  业务服务(service):业务服务按业务领域划分,如房间服务、礼物服务,不同的业务服务完成各自的业务逻辑。
  业务任务(job):业务JOB是依附于业务服务的,通常是用于定时任务处理、异步队列消费等场景。
  其中特别要提到业务网关的设计,在直播首页、房间页的场景中,由于业务逻辑复杂客户端通常需要调用十个甚至数十个接口,部分接口还存在时序依赖。不仅客户端代码实现复杂,还导致了客户端页面展现的延迟。因此在新的Golang网关实现中我们把单一场景的展示数据统一聚合到一个接口中,即打开一个页面只需要调用12的接口即可完成页面功能渲染。随后我们还在业务网关实现了热点数据主动缓存、下游服务异常的自动降级等特性。
  经过几个服务的试点后发现基于Golang的服务无论在接口耗时还是稳定性上均远超PHP服务,特别是网关需要聚合10几个下游的数据时,通过协程的并发处理接口平均耗时不到原来PHP服务的一半。在此后的一段时间越来越多的Golang服务创建,更多的API也通过Golang网关对外提供到哔哩哔哩Web、PC、Android、iOS等各种设备中。
  七、liveappweb的终结
  2019年直播最早的服务liveappweb终于完成了它的使命,所有线上功能全部完成重构迁移,实现了liveappweb服务整体下线。截止下线时liveappweb已累计了19W行代码、上百位contributers,感谢他们!
  八、新网关的诞生
  回到Goalng微服务演进过程中,我们并没有让曾经的liveapi网关承接Golang业务网关的流量,一方面是因为当时swoole没有成熟的异步httpclient,另一方面则是基于PHP的纯异步网关也逐渐显露出性能瓶颈。而问题在2019年也逐渐暴露出来了:
  1)Golang业务网关限流需要业务在各自服务内分别接入、配置修改后需要重启生效。某个紧急情况下甚至发现部分服务未接入限流组件。
  2)liveapi在更大的业务流量下表现不佳,已经成为一个瓶颈,而存量PHP服务在相当长一段时间还需要持续迭代和提供服务。
  对新网关的需求应运而生,在调研了Kong、Tyk、Envoy等多个开源网关,我们决定采用Envoy作为数据面,自研Golang服务作为控制面的方式来实现新网关。Envoy在servicemesh领域几乎是No。1的存在,其非常适合作为流量转发服务。我们将新网关命名为Ekango。
  为了进一步移除liveapi,我们将原有基于TCP的liverpc协议升级支持了HTTP调用,这样就可以将请求从Ekango直接转发到对应的PHP服务,同时也极大地便利了研发的开发、调试成本。
  在Ekango网关中我们实现了分布式限流、接口条件Rewrite、接口降级、统一鉴权、接口风控、多活可用区降级等特性,并提供单机15WQPS的服务能力。
  同时我们基于Ekango的设计开发经验,基于Envoy实现了servicemesh应用:Yuumi。Yuumi是解决PHP、JS等语言访问Golang开发的GRPC服务问题的解决方案,因为长期以来微服务建设围绕Golang生态展开,对于其他语言的支持却略显薄弱。对于直播而言我们希望PHP服务也一样能享受到Golang生态同等的服务治理能力,并且能够方便地调用GRPC服务。
  Yuumi的实现解决了这一问题,通过servicemesh的方式PHPJS进程以HTTP协议访问本地的sidecar进程,由sidecar再将请求转发到对应的HTTP或GRPC服务,并且业务服务无需关心服务节点发现、节点错误重试、节点负载均衡等等微服务治理问题。
  Ekango帮助直播支持了数个百万级、千万级的大型活动均有稳定的性能表现。但他也存在一些缺陷,如部署配置复杂、C代码难以二次开发,特别是流量治理和管控能力缺乏可视化的控制面,只有少数几个开发者才能正确配置。我们在之前的文章中有介绍过微服务团队开发了B站统一的网关,其在支持常规的流量治理能力外,还提供了全流程可视化的接入方式和管控面、API元数据管理、全链路灰度发布等高级特性。因此在充分评估之后直播也将网关流量全量迁移到统一网关上,由统一网关对全站的入口流量进行流量管控和治理。统一网关同时也作为Kratos开源项目之一在Github上同步更新。
  至此直播的架构演进基本告一段落,在此之后我们进行了消息队列和定时任务的角色拆分、分布式任务调度的引入彻底解决服务单点部署问题。同时积极推动业务多活落地以解决更大范围的可用性问题,服务好直播业务的快速发展。在架构演进过程中我们也碰到了一些典型问题,在这里也对这些问题的处理作一定的总结,希望能启发你的思考。
  九、关于热Key
  热点问题无处不在,抢购、秒杀、抽奖、一次大型活动、突发事件都会形成一个个热点,而最直接的影响就是产生热数据,进而导致单节点被打挂、服务雪崩等可怕结果。对于直播业务而言,最容易产生热Key的就是那些热门房间,即我们称之为高在线房间。随着直播架构的迭代,我们对于热Key的处理方式也在发生变化,但都围绕着多级缓存、分而治之的思路进行,同时也需要考虑数据一致性、时效性,不能盲目地通过加缓存的方式来解决热Key。
  1、PHP服务的高在线热点缓存
  在PHP微服务时代我们通过一个集中的monitorservice收集来自CDN和弹幕长连接数据,获得当前在线人数较高的房间,并将这些房间信息推送到消息队列中。由关心热门房间的服务job消费到这些热门房间信息,将各自业务可能涉及的热点数据主动推送到缓存中。而服务进程内也会有一个定时器监听这些热门缓存Key,并定时将这些数据直接拉到PHP进程的内存当中。这样热门房间的业务数据就会直接命中内存缓存。
  2、Golang服务的高在线热点缓存
  在Golang服务建设中我们简化了热门房间检测逻辑,直接提供了一个热门房间SDK,业务服务可以直接通过SDK判断特定的roomiduid是否属于热点,而由SDK内部定时拉取热门房间列表信息。业务再通过定时器将热点房间数据直接缓存到内存中。
  这样的好处是:
  1)热门的判断阈值可以由各个业务服务自行控制,如A服务认为1W在线属于热门,需要进行预热处理;B服务认为超过5W在线的属于热门数据才需要预热处理。这样对于非热门的数据提供较高的数据时效性和一致性、对于热门的数据通过牺牲一定的一致性来实现更高的可用性。
  2)热门的处理可模拟、可演练,通常在预期的大型活动中我们会提前将活动房间在后台标记为热门房间,再通过压测来验证热门房间处理逻辑是否生效、性能是否符合预期。
  3、热点数据主动探测
  随着直播在B站主站业务的融入,我们发现热点并非仅来自于热门直播房间这一种场景,热门稿件、热门评论同样会对部分直播服务造成热Key问题。因此我们设计了一个更通用的热点检测和处理SDK。
  业务在接收到用户请求后调用计数API,SDK异步通过滑动窗口LFU优先队列计算TopK,定时向业务回调统计到的热点数据ID,业务基于这些热点ID将数据源预加载到内存。这样对于热点的统计和判断完全取决于业务自身的QPS情况,而无需依赖外部数据。最终我们实现了热点数据的秒级感知和数据预热缓存能力。
  4、代理层的内存缓存
  Redis在6。0中实现了客户端缓存机制来解决热点数据问题。我们的中间件团队也在内部的缓存代理上实现了客户端数据缓存,通过中间件管理后台我们可以配置正则表达式匹配一类的缓存Key,符合规则的缓存Key会在代理层进行数据缓存,对该Key的下一次访问会直接命中本地缓存,不再需要访问缓存服务器,直到本地缓存失效。
  代理层缓存特别适合于已经发现热Key的紧急处理流程中,直接将发现的热Key设置为本地缓存可以极大缓解热Key风险。但其并不适合作为一种通用热Key处理方案进行提前配置,特别是针对一类Key的正则匹配这会影响这类Key的数据一致性。
  5、ProxylessRedisClient集成热点缓存
  热点探测SDK需要业务主动接入,代理层的缓存方案过于简单。在发生多次热Key触发告警后,我们与基础架构同学交流探索出了以RedisClient内嵌热点缓存SDK的方式来实现业务的透明接入。在该方案中基础架构同学借鉴了HeavyKeeper算法重新设计了热点探测SDK。HeavyKeeper用于在流式数据中以较小的内存开销获得非常精确的TopK计算结果,统计出的TopK即是我们想要知道的热Key。业务透明接入和缓存配置动态更新这两个特性的结合成了热Key的杀手级解决方案。
  6、热点写数据的处理
  在直播场景中除了读热点,还存在写热点的场景。通常是由于大量用户向同一个主播赠送礼物、发送弹幕等行为产生的写操作,进而对单条记录产生大量并发写场景。进一步分析这些并发写的场景我们发现通常是针对单条记录数值的增减操作,如经验值、积分、点赞数等,而这类场景天然是可以支持聚合的。因此我们开发了一个聚合写入SDK,其可以采用内存聚合或Redis聚合的方式,将业务对数据的变更操作按设定的周期进行聚合写入,比如1、2、1这样三个操作可以直接聚合成2一个操作。实现这个SDK需要考虑聚合窗口大小、下游DB压力、服务异常重启的数据一致性保证等。
  十、关于请求放大
  房间服务是直播流量最大也是最核心的服务之一,日常QPS维持在20W。在运营房间服务中我们发现了以下几种场景的请求放大:
  1、请求超出需要的数据
  在分析房间服务高QPS调用来源方时我们发现部分业务仅需要房间信息中的一部分数据却请求了整个房间信息,比如某些业务方仅需要判断用户是否拥有直播间却调用了完整的房间信息接口,本来一个字段能解决的问题接口返回了数十个字段,造成不必要的带宽消耗和接口耗时。我们参考FieldMask(关于FieldMask可参考NetflixAPI设计实践:使用FieldMask)的设计将房间信息拆分成不同的的模块,如播放相关、直播卡片展示相关等模块。业务方可根据场景需要组装API调用获取对应模块的数据实现按需请求。
  2、重复的请求
  直播间承载了直播近80的业务功能,用户在进入房间时会请求进房接口。在这个接口中网关会聚合多个下游的数据后统一返回给用户,我们发现这个场景存在重复请求房间信息的情况。
  上图所示除了roomgateway会请求房间信息外,giftpanel、dmservice也会分别再请求一次房间信息,直接导致了房间服务的请求放大。这样的下游服务越来越多后,用户一次进房将对房间服务产生10倍以上的流量放大。而这种流量放大显然是没有必要的。解决方案也很直接将dmservice、giftpanel依赖的房间信息通过接口直接传递给对应服务。调用时序调整为先调用房间服务获取房间信息,再并发调用业务服务获取业务模块数据,最后组装成业务需要的数据返回。
  3、业务服务的请求放大
  直播间承载了数十种业务功能,用户的一次进房会分别向这数十个下游服务进行请求。对每个下游都要求按照进房QPS进行备量,即承担至少2W的QPS。这对于一些小众的服务是难以承受的,从数据上看对下游的99请求都是查空的无效请求。为了降低接入房间场景业务的负载、减少资源浪费,我们在房间服务上实现了一个TAG机制,业务服务将数据TAG同步到房间服务,网关、客户端在请求房间信息后根据TAG标识状态决定是否请求对应的业务服务,这样就避免了大量业务需要承担用户进房级别的QPS。
  十一、关于活动保障
  一次大型活动的技术保障是一场技术盛宴,也是对所有研发同学的一次大考。直播技术在历年的活动保障中沉淀了一系列的工具和方法论。围绕场景梳理分析、服务容量预估、全链路压测、降级预案、现场保障等方面有一系列标准化方案、工具和平台支持。
  1、场景梳理
  场景梳理的目的是了解一场直播活动中涉及了哪些业务功能、服务和接口,以此针对涉及的业务模块开展后续的保障工作。通常活动直播间所使用的功能是普通直播间的子集,这就需要直播间内的功能都需要有控制开关,这里的控制开关一定是需要在终端实现的,即开关关闭后客户端不会对这一功能服务产生任何请求压力。场景梳理需要基于用户的真实操作路径进行请求录制,可以通过代理抓包的方式进行自动化的场景录制,再通过录制请求对应的Trace链路快速生成场景依赖关系图,这个关系图就明确了该场景下涉及的服务、资源等信息。
  2、容量评估
  容量评估用于确定活动所需要的资源,以进行采购备量和提前扩容。容量评估一定是基于历史数据和活动预估进行推算,其中针对不同的业务有不同的增长系数。
  3、服务压测
  服务压测通常是对线上服务真实容量进行摸底,一般在服务扩容前和服务扩容后都会进行压测以验证服务容量是否满足活动需求。特别地针对数据写的场景需要通过全链路压测的手段实现压测数据和真实数据的隔离,避免压测产生的脏数据影响线上业务。
  4、降级预案
  无预案不保障,针对可能出现的技术风险都需要有对应的SOP,且这些SOP都需要通过预演的方式验证方案有效性。
  5、现场保障
  现场值班保障时通常会遇到信息爆炸、协作难度大的问题,特别是突发的系统告警容易产生惊群效应。需要高效信息分发、实时协作,实现保障工作的有序流转、不重不漏、快速执行。基于保障场景的特殊性我们研发了活动实时保障平台。
  在实时保障平台中按照业务场景划分不同的场景负责人和保障值班,所有的线上服务告警、指标异常都会以实时推送的方式展示在对应保障人员的值班页面。针对常见的告警类型,如CPU过高、服务限流会直接关联到SOP手册,值班人员可以基于手册指导完成处理预案。在保障结束后我们也可以基于实时保障平台的数据记录生成保障报告,复盘保障过程中出现的问题、响应时效、执行结果和后续TODO。
  十二、高光时刻
  2021的《英雄联盟》全球总决赛哔哩哔哩直播实现了单平台超千万人同时在线的记录。整场比赛服务运行稳定、用户观看流畅,这是属于直播的高光时刻。
  十三、未来展望
  直播的技术架构仍在向前演进,持续围绕服务稳定性和高可用建设在业务架构治理、多活和单元化方向不断进化。期望在今年的LOLS12中在线人数再创新高。
  参考资料
  〔1〕https:www。zhihu。comquestion48457286〔2〕https:www。infoq。cnarticley2semvajjgxj9mbg9p00〔3〕https:www。redis。com。cntopicsclientsidecaching。html〔4〕https:www。computer。orgcsdljournalnt201905088094101cFUZDJL2OA〔5〕https:github。comgokratosgateway〔6〕https:zhuanlan。zhihu。comp436382314
  作者丨赵海林
  来源丨公众号:哔哩哔哩技术(ID:bilibiliTC)
  dbaplus社群欢迎广大技术人员投稿,投稿邮箱:editordbaplus。cn
  关于我们
  dbaplus社群是围绕Database、BigData、AIOps的企业级专业社群。资深大咖、技术干货,每天精品原创文章推送,每周线上技术分享,每月线下技术沙龙,每季度GdevopsDAMS行业大会。
  关注公众号【dbaplus社群】,获取更多原创技术文章和精选工具下载

带领中国男篮取得2连胜,但是乔帅真的比杜锋强吗?凭借着吴前第四节的爆发,中国男篮以86比74战胜没有哈达迪的伊朗队,加上此前战胜哈萨克斯坦,乔帅上任后取得2连胜。那么是否可以说乔帅比杜锋强了呢?看了球的球迷都知道,这两场比赛虽然伊布替补出场创纪录,AC米兰战胜亚特兰大文羊城晚报全媒体记者刘毅意甲亚军之争愈演愈烈,2月27日在第27轮比赛中,AC米兰主场以2比0击败亚特兰大,积47分追平排名第二的国际米兰,但仍落后领头羊那不勒斯18分之多。第74朱婷零失误全场最高效率!MVP旁落引争议,斯坎迪奇复仇32胜米兰随着伤病的恢复,朱婷在意甲联赛赛场的表现越来越稳定,状态也有所提升,女排意甲联赛第20轮斯坎迪奇对阵米兰,朱婷零失误打出全场最高的50的效率,助斯坎迪奇打破魔咒战胜宿敌米兰,也报了14连胜!又一个顶级后卫诞生!霍乐迪拿下3345!周一熬夜看完两场大战,神清气爽。第一战,凌晨两点,雄鹿主场104比101战胜太阳没有字母哥的雄鹿遇上没有杜兰特的太阳,各自让一张大王后,太阳队的布克艾顿保罗,雄鹿队的大洛佩斯都有不意甲综合米兰完胜亚特兰大国米负于博洛尼亚新华社罗马2月26日电(黎梦青)意大利足球甲级联赛第24轮26日继续进行,AC米兰主场20战胜亚特兰大,国际米兰客场01负于博洛尼亚。当地时间26日,梅西亚斯(右)在比赛中拼抢。新上帝归来喜提零封四连胜,梅西姆巴佩演绎个人里程碑伊布时隔9月归来,米兰2比0击败亚特兰大意甲第24轮上演一场事关欧冠资格的关键战役,AC米兰坐镇圣西罗迎战亚特兰大。上半场特奥制造穆索的乌龙,比赛尾声阶段梅西亚斯锁定胜局,红黑军团詹姆斯凭借我们的势头我觉得即使落后也能够逆转取胜直播吧2月27日讯今日NBA常规赛,湖人在客场以111108险胜独行侠,完成了27分大逆转。赛后,詹姆斯接受了记者采访。谈到自己的脚伤,他说道现在好多了。这是肯定的,受伤的时候我也英冠直播排名斯旺西vs罗瑟汉姆,前瞻录像APP比分热门体育在胜利斯旺西,现在在联赛中进球的队伍有13名选手。队伍有很多进攻点。斯旺西的攻击在允许范围内,他们的主场表现是平均的。在与罗萨勒姆的比赛中,他们取得了5胜3分2负的战绩,占优势。Swan范德比尔特我们投不进球,所以我和AD才有那么多篮板今日,湖人111108客场击败独行侠,迎来三连胜。赛后,湖人前锋贾里德范德比尔特接受了采访。谈到他和安东尼戴维斯合力抢到32个篮板,范德比尔特说当然,今晚出现了很多篮板,我们在比赛火箭或与篮网交易,五换二得到布里奇斯和西蒙斯,史密斯波特离队火箭本赛季表现非常糟糕,球队打到现在稳居联盟倒数第一的位置。虽然说其中有球队故意摆烂的原因,但是与整体实力不行有很大的关系。火箭队实力不行有很多原因,其中防守糟糕是表现得最明显的一斯奈德接受五年合同,成为老鹰新主帅据ESPN记者Woj报道,老鹰和前爵士主帅奎因斯奈德正式达成协议,对方接受了一份为期五年的合同(包含本赛季),成为球队新任主教练。斯奈德最早周三对奇才的比赛就可以临场执教。消息人士
心理学放下功利心,才能与美好的爱情相遇好的爱情关系大都是纯粹的,它不夹杂任何利益的考量,却可以直达人内心的最深处,使人感觉到温暖与快乐。爱情本就是深藏于人内心之中的一种情愫,爱情的产生,常在一瞬之间,它源于偶然的心动。被低估值5元以下潜力股被低估值5元以下潜力股,收藏研究分享。一002506协鑫集成公司的光伏产品制造产能及出货量均高居全球前十位,主要产品高效电池组件,能源工程,综合能源系统集成等相关产品的研发研发,设为什么会在睡觉时发生脚抽筋?有些人在晚上睡觉的时候,会被脚抽筋给疼醒,是什么原因导致经常会出现脚抽筋呢?脚抽筋可能是环境因素过度运动不良姿势缺钙等因素所导致。1。环境因素如果脚部保暖措施不到位,导致局部循环不大气男人刘一水刘一水是乡村爱情中最大气的男人,他也是象牙山村第一个办企业成功的男人,可是他的婚姻却没有他的事业那么顺利,他从来不和别人斤斤计较,感觉刘一水就是一位非常大度的大哥的形象。事业成功的百万保时捷卡宴追尾大众速腾,没想到差距这么大卡宴前脸撞报废大家都知道现在中国人对汽车的消费量很大,可是面对五花八门的汽车品牌,让很多人蒙圈,不知道如何选择。其实没有必要太纠结,看看路上跑的啥车最多,你就明白了。相信很多人都知道大众品牌,它一个退休5年,一个离职13年,两银监老同事同日被查金融监管领域反腐重拳频出!继7月第一个周末,两名银保监系统官员落马,这个周末,又有两名原银监会官员被查。7月17日14时,中央纪委国家监委网站同时公布两条消息原中国银行业监督管理委56岁大妈虽然搭伙老伴退休金9千,半年后,我还是和他分了手56岁大妈虽然搭伙老伴退休金9千,半年后,我还是和他分了手导语上了年纪还在单身的人不是离异就是老伴儿去世了,可是他们也渴望自己枕边有个知心人,所以很多中老年人都在找老伴儿的路上。虽醒都醒了,装什么晕?阳春三月,密林中草木成荫,莹白月色洒在山林间,野花随风轻舞,在地面上投出参差不齐的光影。踏踏踏脚步声匆匆。许不令横抱着陈思凝,来到稍微平整的空地,把她平放在花丛里,压倒了几束野花。重庆文科状元何川洋,高考659分被北大拒绝决不能录取这种学生重庆文科状元何川洋,高考659分被北大拒绝决不能录取这种学生重庆一考生以659的高分拿下文科状元,被北京大学录取。然而仅仅半个月就发生了一件事毁了他的名声,他被北大开除了。北大直言重庆文科状元何川洋,高考659分被北大拒收决不录取这样的学生重庆文科状元何川洋,高考659分被北大拒收决不能录取这样的学生被北大录取的学生肯定是很优秀的,毕竟清华北大作为国内最出色的大学,是无数的孩子梦想中的学堂,因此竞争也就更加的严重了。不懂纸币就不要收藏纸币,1960年2元纸币最新价格多少?你知道吗很多人都在收藏纸币,特别是一些比较特殊的纸币,更是收藏者想得到的藏品,就因为钟情于纸币收藏的人越来越多,所以纸币市场的交易也是异常地红火,为此一些商家媒体都加入了纸币宣传的行列,为
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网