范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

阿里二面RockeMQ是如何通过mmap大幅提升单机吞吐量的?

  今天抽空给大家整理了一份关于RocketMQ的高性能知识点文章总结。希望能对各位读者有所帮助。
  关于RockeMQ的基本介绍
  简介
  RocketMQ是一个纯Java、分布式、队列模型的开源消息中间件,前身是MetaQ,是阿里参考Kafka特点研发的一个队列模型的消息中间件,后开源给apache基金会成为了apache顶级开源项目,具有高性能、高可靠、高实时、分布式特点。
  发展背景 2011年:业界出现了现在被很多大数据领域所推崇的Kafka消息引擎,阿里巴巴在研究了Kafka的整体机制和架构设计之后,基于Kafka的设计使用Java进行了完全重写并推出了MetaQ 1.0版本,主要是用于解决顺序消息和海量堆积的问题。 2012年:阿里巴巴开源其自研的第三代分布式消息中间件——RocketMQ。 2016年11月:阿里将RocketMQ捐献给Apache软件基金会,正式成为孵化项目。 2017年2月20日:RocketMQ正式发布4.0版本,专家称新版本适用于电商领域,金融领域,大数据领域,兼有物联网领域的编程模型。 2022年:RocketMQ正式发布5.0版本,这也是目前最新版本。
  RocketMQ的各个特点 单机吞吐量:10w/s。 可用性:支持双主双从的分布式架构,具备高可用特性。支持使用topic,tag,SQL来对消息进行筛选。底层结构通过多队列来承载消息存储等特性。可靠的FIFO和严格有序的消息队列中间件。支持多种消息传递协议,例如grpc,Mqtt,Jms.... 源码实现:Java语言。
  PageCache和Mmap
  RocketMQ这款中间件具有着单机10w+的吞吐量,其底层原因,实际上得从操作系统原理开始和大家讲起。
  顺序写入
  磁盘的写步骤通常是:CPU发送一个写信号给到磁盘磁头,接着磁头需要进行寻道操作,找到对应的磁道后,定位对应的位置进行数据写入。所以如果数据是随机写入的话,磁头就需要频繁地切换盘道进行数据的写入,整体耗时会有所提升。
  顺序写,其实是一种非常常见的提升IO写性能的方式,利用连续的写入地址,从而减少磁头的切换次数,提升性能。
  PageCache
  为了提升对文件的读写效率,Linux 内核会以页大小(4KB)为单位,将文件划分为多数据块。当用户对文件中的某个数据块进行读写操作时,内核首先会申请一个内存页(称为 页缓存)与文件中的数据块进行绑定。
  例如下边这张图,当我们发起一次系统调用的write方法,想要将用户态中的数据写入磁盘的时候,其实是需要发生以下操作的:
  首先,将用户地址空间的数据通过CPU拷贝,放入到内核空间中,并且写入一个PageCache里面,然后通过DMA去将PageCache的数据写入到磁盘。
  这里面由于有CPU拷贝这样的重操作,所以想要提升吞吐量,必须解决这个问题。而RocketMQ的创作团队,则是通过mmap技术来解决了它。
  什么是mmap
  mmap系统调用,让用户地址空间,跟文件做映射(实际是指向不存在的物理内存)。将内核态的一段空间地址映射到了用户态中,这样数据只需要写入到用户态的这段虚拟地址中,接着内核空间的DMA会将这段数据写入到磁盘中。这样之后,整体的写入流程就如下图所示:
  使用mmap技术之后,可以减少一次的CPU拷贝次数,提升性能。
  这里补充一些说明,其实DMA本质上是一块访问独立的芯片。由于每次访问磁盘进行IO操作都会导致CPU大量的空闲时间,而DMA则是用于提升IO操作效率的一个角色,主要用于IO的数据传输,降低CPU等待时间。
  Java里面如何使用mmap技术
  在Java语言中,其实很早就有提供mmap方面的api了,下边是一段简单的mmap使用案例。 public class MmapUtils {     public File commitLogFile;     public MappedByteBuffer mappedByteBuffer;     public int mappedSize = 0;     public int writePos = 0;       public MmapUtils(String commitLogPath, int mappedSize) {         this.commitLogFile = new File(commitLogPath);         if(!commitLogFile.exists()){             try {                 commitLogFile.createNewFile();             } catch (IOException e) {                 e.printStackTrace();             }         }         this.mappedSize = mappedSize;         try {             mappedByteBuffer = new RandomAccessFile(commitLogFile, "rw").getChannel().map(FileChannel.MapMode.READ_WRITE, 0, mappedSize);         } catch (IOException e) {             e.printStackTrace();         }     }       /**      * 往磁盘写数据      *      * @param content      * @return      */     public int writeFile(String content) {         mappedByteBuffer.put(content.getBytes());         //强制刷盘         mappedByteBuffer.force();         writePos = mappedByteBuffer.position();         return 1;     }       /**      * 从磁盘中读取数据      *      * @param len      * @return      */     public byte[] readContent(int len) {         mappedByteBuffer.position(0);         byte[] dest = new byte[len];         int j = 0;         for (int i = 0; i < mappedSize; i++) {             byte b = mappedByteBuffer.get();             if (b != 0) {                 dest[j++] = b;             }         }         return dest;     } }
  mmap存在的缺陷
  其实使用mmap技术还是存在一些缺陷的。
  导致缺页中断问题
  我们知道,在操作系统的中,数据通常都是被放在磁盘中的,只有在需要计算的时候,才会将数据加载到内存中,而每次加载的单位都是以"页"作为基础,假设我们需要访问一块存在于磁盘,但是没有被加载到内存中的数据,这种情况,我们称之为  "软性的缺页中断"  。 如果数据是存在于内存,但是该页的地址没有被注册到MMU中,我们则称之为  "硬性的缺页中断"  。
  总之不管是软性还是硬性的中断,都需要重新建立一次数据的内存映射,比较消耗性能。
  mmap对于文件的大小有一定要求
  使用mmap技术之后,我们不可以使用2gb大小以上的文件去做映射,同时文件的长度也不建议做变长,最好是固定的大小。最后对于小文件而言,使用mmap可能性能还不如直接的原始IO操作。
  RocketMQ对mmap的优化
  好了,现在我们了解了mmap存在的缺陷之后,来看看RocketMQ是如何解决这些不足点的。
  预映射
  在RocketMQ的源代码里,可以看到这样一份代码,它的名字叫做:org.apache.rocketmq.store.AllocateMappedFileService。这个类负责在rocketmq启动时,预先分配mmap的文件映射。
  文件预热
  调用mmap进行内存映射后,OS只是建立虚拟内存地址至物理地址的映射表,没有实际加载任何文件至内存。依靠一次缺页加载4K,1G的commitLog需要发生256次缺页中断。而在RocketMQ的源代码中,进行了madvise系统调用,其目的是使操作系统做一次内存映射后对应的文件数据尽可能多地预加载进内存,从而实现预热。
  内存锁定
  将进程使用的部分或者全部的地址空间锁定在物理内存中,并会先写入一些随机值到mmap映射出的内存空间里,防止其被交换到swap空间。基于mlock系统调用。
  堆外缓存
  到这里,我们了解了RocketMQ内部通过使用PageCache去让我们的数据写入如写入内存般轻松,但是这在极端情况下,可能会有出现频繁出现缺页中断的情况,以及PageCache阻塞,这种情况下,Broker节点会返回一个SYSTEM_BUSY的信号给到客户端,不过这类场景在实际生产中很少会出现。为了避免这种情况,RocketMQ底层增加了一套堆外缓存来优化这类场景。当PageCache写入阻塞的时候,可以选择写入到堆外缓存中,之后再从堆外缓存  (DirectByteBuffer)  写入到PageCache。
  RocketMQ中的mmap预分配实现分析
  下边让我们来看看RocketMQ底层是如何进行mmap的文件映射预分配的。在RocketMQ的源代码中,当服务启动之后,AllocateMappedFileService这个线程类便会开始执行。
  线程启动之后,便会执行mmapOperation方法,这个方法的大致步骤如下: 从优先级队列中获取AllocateRequest 创建MappedFile 根据配置是否预热MappedFile(填充0字节),将MappedFile放入到AllocateRequest 如果出现IOException将AllocateRequest重新放入优先级队列 调用AllocateRequest的CountDownLatch#countDown方法通知putRequestAndReturnMappedFile线程
  整体执行目的总结起来就是:初始化+预热mappedFile。
  关于mmapOperation的源代码和其含义,我列了一份出来给各位读者查看: /**  * Only interrupted by the external thread, will return false  */ private boolean mmapOperation() {     boolean isSuccess = false;     AllocateRequest req = null;     try {         // 从优先级队列里获取AllocateRequest         req = this.requestQueue.take();         //从Map里获取AllocateRequest         AllocateRequest expectedRequest = this.requestTable.get(req.getFilePath());         if (null == expectedRequest) {             log.warn("this mmap request expired, maybe cause timeout " + req.getFilePath() + " "                 + req.getFileSize());             return true;         }         //putRequestAndReturnMappedFile里map与优先级队列并不是强一致,是最终一致的         if (expectedRequest != req) {             log.warn("never expected here,  maybe cause timeout " + req.getFilePath() + " "                 + req.getFileSize() + ", req:" + req + ", expectedRequest:" + expectedRequest);             return true;         }           if (req.getMappedFile() == null) {             long beginTime = System.currentTimeMillis();               MappedFile mappedFile;             //堆外内存             if (messageStore.getMessageStoreConfig().isTransientStorePoolEnable()) {                 try {                     mappedFile = ServiceLoader.load(MappedFile.class).iterator().next();                     mappedFile.init(req.getFilePath(), req.getFileSize(), messageStore.getTransientStorePool());                 } catch (RuntimeException e) {                     log.warn("Use default implementation.");                     mappedFile = new MappedFile(req.getFilePath(), req.getFileSize(), messageStore.getTransientStorePool());                 }             } else {                 mappedFile = new MappedFile(req.getFilePath(), req.getFileSize());             }               long eclipseTime = UtilAll.computeEclipseTimeMilliseconds(beginTime);             //创建MappedFile 花费大于10ms打印日志             if (eclipseTime > 10) {                 int queueSize = this.requestQueue.size();                 log.warn("create mappedFile spent time(ms) " + eclipseTime + " queue size " + queueSize                     + " " + req.getFilePath() + " " + req.getFileSize());             }               // pre write mappedFile 默认warmMapedFileEnable=false,即默认不预热             if (mappedFile.getFileSize() >= this.messageStore.getMessageStoreConfig()                 .getMapedFileSizeCommitLog()                 &&                 this.messageStore.getMessageStoreConfig().isWarmMapedFileEnable()) {                 // 文件预热                 mappedFile.warmMappedFile(this.messageStore.getMessageStoreConfig().getFlushDiskType(),                     this.messageStore.getMessageStoreConfig().getFlushLeastPagesWhenWarmMapedFile());             }               req.setMappedFile(mappedFile);             this.hasException = false;             isSuccess = true;         }     } catch (InterruptedException e) {         log.warn(this.getServiceName() + " interrupted, possibly by shutdown.");         this.hasException = true;         return false;     } catch (IOException e) {         log.warn(this.getServiceName() + " service has exception. ", e);         this.hasException = true;         if (null != req) {             //重新插入请求到队列             requestQueue.offer(req);             try {                 Thread.sleep(1);             } catch (InterruptedException ignored) {             }         }     } finally {         //AllocateRequest计数器减一,表示MappedFile已经创建完成         if (req != null && isSuccess)             req.getCountDownLatch().countDown();     }     return true; }
  在这段代码里头,我们可以看到有个文件预热的方法,叫做:warmMappedFile,该方法内部最后发出了一次系统调用,mlock方法。  public void warmMappedFile(FlushDiskType type, int pages) {         long beginTime = System.currentTimeMillis();         ByteBuffer byteBuffer = this.mappedByteBuffer.slice();         int flush = 0;         long time = System.currentTimeMillis();         for (int i = 0, j = 0; i < this.fileSize; i += MappedFile.OS_PAGE_SIZE, j++) {             byteBuffer.put(i, (byte) 0);             // force flush when flush disk type is sync             if (type == FlushDiskType.SYNC_FLUSH) {                 if ((i / OS_PAGE_SIZE) - (flush / OS_PAGE_SIZE) >= pages) {                     flush = i;                     mappedByteBuffer.force();                 }             }               // prevent gc             if (j % 1000 == 0) {                 log.info("j={}, costTime={}", j, System.currentTimeMillis() - time);                 time = System.currentTimeMillis();                 try {                     Thread.sleep(0);                 } catch (InterruptedException e) {                     log.error("Interrupted", e);                 }             }         }           // force flush when prepare load finished         if (type == FlushDiskType.SYNC_FLUSH) {             log.info("mapped file warm-up done, force to disk, mappedFile={}, costTime={}",                 this.getFileName(), System.currentTimeMillis() - beginTime);             mappedByteBuffer.force();         }         log.info("mapped file warm-up done. mappedFile={}, costTime={}", this.getFileName(),             System.currentTimeMillis() - beginTime);         // 这里是一个系统调用         this.mlock();     }
  这段代码的末尾处调用的mlock函数,它的内部是利用了Java的JNI机制,去进行系统调用。
  JNA的本质就是将大多数native的方法封装到jar包中的动态库中,并且提供了一系列的机制来自动加载这个动态库。例如下边这个例子就是基于JNI去调用c lib中的print方法: public class JNAUsage {       public interface CLibrary extends Library {         CLibrary INSTANCE = (CLibrary)                 Native.load((Platform.isWindows() ? "msvcrt" : "c"),                         CLibrary.class);           void printf(String format, Object... args);     }       public static void main(String[] args) {         CLibrary.INSTANCE.printf("Hello, World ");         for (int i=0;i < args.length;i++) {             CLibrary.INSTANCE.printf("Argument %d: %s ", i, args[i]);         }     } }
  这个例子中,我们想要加载系统的c lib,从而使用c lib中的printf方法。
  具体做法就是创建一个CLibrary interface,这个interface继承自Library,然后使用Native.load方法来加载c lib,最后在这个interface中定义要使用的lib中的方法即可。
  那么在RocketMQ中,底层又是如何通过JNI来实现mlock的调用呢,来看源代码:  public void mlock() {         final long beginTime = System.currentTimeMillis();         final long address = ((DirectBuffer) (this.mappedByteBuffer)).address();         Pointer pointer = new Pointer(address);         {             int ret = LibC.INSTANCE.mlock(pointer, new NativeLong(this.fileSize));             log.info("mlock {} {} {} ret = {} time consuming = {}", address, this.fileName, this.fileSize, ret, System.currentTimeMillis() - beginTime);         }           {             int ret = LibC.INSTANCE.madvise(pointer, new NativeLong(this.fileSize), LibC.MADV_WILLNEED);             log.info("madvise {} {} {} ret = {} time consuming = {}", address, this.fileName, this.fileSize, ret, System.currentTimeMillis() - beginTime);         }     }
  上边代码中的LIbC是一个作者封装的系统调用接口文件,里面正好是映射了操作系统的mlock方法。 package org.apache.rocketmq.store.util;   import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.NativeLong; import com.sun.jna.Platform; import com.sun.jna.Pointer;   public interface LibC extends Library {     LibC INSTANCE = (LibC) Native.loadLibrary(Platform.isWindows() ? "msvcrt" : "c", LibC.class);       int MADV_WILLNEED = 3;     int MADV_DONTNEED = 4;       int MCL_CURRENT = 1;     int MCL_FUTURE = 2;     int MCL_ONFAULT = 4;       /* sync memory asynchronously */     int MS_ASYNC = 0x0001;     /* invalidate mappings & caches */     int MS_INVALIDATE = 0x0002;     /* synchronous memory sync */     int MS_SYNC = 0x0004;       int mlock(Pointer var1, NativeLong var2);       int munlock(Pointer var1, NativeLong var2);       int madvise(Pointer var1, NativeLong var2, int var3);       Pointer memset(Pointer p, int v, long len);       int mlockall(int flags);       int msync(Pointer p, NativeLong length, int flags); }
  通过调用mlock可以将进程使用的部分或者全部的地址空间锁定在物理内存中,防止其被交换到 swap 空间。对时间敏感的应用会希望全部使用物理内存,提高数据访问和操作的效率。例如, memcached 就提供锁定内存的选项,保证memcached使用内存全部在物理内存中。
  通过mlock锁定对应的地址空间,防止被swap出去,这样的效果 ,也正是RocketMQ所需要的。
  来源:https://mp.weixin.qq.com/s/Qrf8fCvBbNGEbqsLf3lRvA

企业微信如何实现定时群发消息?如何解除限制?企业微信突破了普通个人微信群的功能限制,能够帮助企业实现更自动化更智能化的客户管理和私域运营。而很多企业的客户基数过大,往往同时拥有多个企微社群,如何高效运营社群?比如如何定时群发油价调整消息今天8月26日,调整后9295号汽油柴油售价今天是2022年8月26日,油价调整计价周期正常运行中,而整个原油市场的反应处于持续向上的趋势。根据最细腻的数据显示,国内汽柴油价格调整幅度随着原油价格不断地上涨,油价调整幅度持续一分钟资讯苹果华为三星华硕,最新消息哈喽,我是毛小毛。关注我,每日带你了解最新数码资讯!一分钟资讯第411篇,感谢你的阅读。苹果已经启动M3芯片开发计划,代号Palma中国台湾工商时报报道,苹果M3芯片的核心设计已经国产品牌重磅消息!OPPO红米新品惊艳亮相,蔚来手机再爆料这个八月,手机圈为我们带来了多个品牌的最新消息,其中有我们非常熟悉的OPPO和红米,还有之前官宣说要进军手机圈的蔚来汽车,下面就跟着小编一起来吃瓜吧!OPPOWatch3系列正式官一夜3消息!郭艾伦开撕辽篮,宏远官宣13人大名单,书豪深情发声郭艾伦去哪儿?周琦去哪儿?赵睿去哪儿?这恐怕是这个休赛季大家最关心的三个问题。其中,郭艾伦本人最近亲自下场,就媒体人刘宝杰的虚假消息进行了有力反击,表示自己已经与其他CBA球队进行婆媳风波争议不断,小贝大儿子表态立忠心,自曝为老婆纹70个纹身近日,贝克汉姆的大儿子透露身上拥有一百个纹身,还表示其中有七十个是献给老婆妮可拉的,还直言每次纹上一个关于妮可拉的纹身,她都会感动的哭出来,所以大布经常会为了给老婆送惊喜而纹身,网家庭日常分享搬家推荐小米空气净化器4Pro除甲醛除菌除异味最近搬了离上班更近的公寓,工作生活上便捷了很多,下班再晚也不用担心末班车时间问题,但是美中不足的是公寓由于是新装修的,虽然通知说通风了半年以上了,但是房间里的味道还是很重,尤其是担最好的蛋仔派对Q弹好玩,给你带来欢乐可爱的游戏画风总是更容易吸引玩家,更容易被他们接受。看着可爱的角色陪你冒险,似乎更容易获得治愈感。这样一来,很多画风可爱的游戏受到大家的欢迎。这次给大家介绍一款风格可爱的社交游戏蛋拥有高端设计的入门款,日常体验出人意料,乐视Y2Pro上手评测今天要给大家分享的产品是乐视Y2Pro,你没看错,这是一部乐视手机。在今年的7月份,乐视发布了这款Y2Pro手机,乐视品牌本身的知名度,加上这部手机独特的外观设计,让它的市场关注度体验服23号更新亲儿子赵云终加强,海月获得免伤,双龙调整新版本将至,王者荣耀体验服的更新频次变多,比如23号的更新除了对峡谷进行二次优化外,还涉及4位英雄的平衡调整,一起随小编来分析一二吧!首先赵云双喜临门,官方才曝光赵云还有一款新皮肤郑智全盘否定了前任主帅的战术,并提高了球员的自信心前十场比赛刘智宇主打控制(多场控球场面占优,但不赢球),并让韦世豪甚至杨立瑜回撤太深,在中场进行组织,远离禁区,进攻机会寥寥,这不是韦世豪擅长的工作。完全不能发挥他的进攻特点。在前
iQOOZ6Z6x开卖三星GalaxyA04s发布云鲸J3小鲸灵发售电动狗iQOOZ6和iQOOZ6x两款新机将于今日10点首销,分别搭载骁龙778GPlus和天玑810处理器,售价1199元起。iQOOZ6分为三个版本,8128GB8256GB1拓宽线下体验,三星快闪店落地北京三里屯蓝色港湾科技前线三星Galaxy折叠屏新品快闪体验蓝色港湾店钛媒体App9月1日消息,近日国内40家三星Galaxy折叠屏新品快闪体验店已陆续在上海沈阳广州成都等30余座城市开业,8月30日,三星成本900多元售价过万?慕思床垫因价格问题冲上热搜近日,慕思床垫因价格问题登上微博热搜,将单位成本不到1000元的床垫卖到数千元甚至上万元,又因其在研发上三年投入的费用总和不及一年投入的广告费用,被网友质疑通过砸钱营销,树立中高端03!中超最新排名诞生广州惨败黑马,海港跌出前7,榜首无悬念比赛瞬息万变,因而才有爆冷逆转甚至是追平的情况发生,强如梅西和C罗,也无法左右结局,因为足球是需要彼此默契配合,1日晚,升班马浙江队就为球迷带来了一场激动人心的比赛,浙江队的对手正KD和蔡崇信是最大的LOSER?恰恰相反!对手们已悄然被他们搅翻天从7。1日交易大门开启,KD即请求离队。很多人都在看蔡老板的热闹,想看看这位华裔老板怎么被球员拿捏。一个多月间,篮网不断收到各队优质报价,正准备优中选优狠敲一笔时,KD留队了。很多华为Mate50系列续航黑科技碾压iphone关闭低电量9月1日,随着华为Mate50的持续预热,华为手机产品线副总裁李小龙发文称长续航是Mate系列最重要的DNA之一,这次我们在续航技术上又进行了一个独特的创新,缓解大家的电量焦虑。电苹果,拜拜?马斯克进军智能手机领域,代号pi,能打败iphone?想不到吧,特斯拉作为世界最大的电动汽车制造商,却传出正在研发智能手机的重大消息,或许亿万富翁埃隆马斯克真的会用这款新的特斯拉手机占领苹果的庞大市场。据了解,早在去年就已经传出特斯拉国产化替代号角已吹响,操作系统先拔头筹科技强国作为首要的强国目标,在强国的工程中发挥着决定性作用,所以必须以建设科技强国助推中国梦的实现。在信息技术领域发展方面,我国大部分都是跟随着欧美的,所以无论是产品或是技术都长时华为Mate50Pro售价曝光起售价49999月10日开售中关村在线消息华为Mate50系列将于9月6日正式发布,今日Mate50Pro的售价信息被曝光,起售价为4999元,12GB256GB5499元,顶配12GB512GB5999元。探讨9月6日发布的华为Mate50,售价会高过iPhone14吗?我们现在对于9月6号和9月8号发布的华为Mate50系列以及iPhone14系列应该都非常的期待。这两款手机可以说在这个阶段,完全出现一种正面竞争的局面!所以,我们现在想猜测一下,华为副总要正视美国的强大,坚定向美国学习最近,深圳消息人士透露,网传号称任正非一号大弟子现任华为副总陈黎芳,在华为内部的一次高管会议上,向全体华为管理层大声疾地呼任何一个华为员工,都必须要正视美国的强大,都必须毫不犹豫地国内适合一个人散心旅行的九个目的地给大家整理了一下国内适合一个人散心旅行的九个地方收藏起来不用谢一。大理风花雪月地山光水色城静静感受洱海的风看月升日落二。阳朔天上人间水墨山水风光桂林山水甲天下,阳朔山水甲桂林乘着一传承草原地区红色基因助推草原资源保护修复第一批12处红色草原名单公布来源中央纪委国家监委网站中央纪委国家监委网站侯颗近日,为传承草原地区红色基因助推草原资源保护修复,促进红色文化与绿色生态融合发展,国家文物局国家林业和草原局确定并公布了第一批红色草全胜战绩打出最佳首发,中国女排亚洲杯有惊喜,将全力冲冠女排亚洲杯小组赛已经结束,虽然这样的比赛没有多大的含金量,但是对于中国女排年轻的小将来说,绝对是珍贵的锻炼机会,起码说这样的赛事要比直接打国内联赛要更加紧张刺激,毕竟这代表的是国家U18男篮亚锦赛杨瀚森空砍1711中国遭韩国19分逆转无缘决赛北京时间8月26日,U18男篮亚锦赛半决赛,中国以8589不敌韩国无缘决赛,只能进行季军战。中国队在最多领先19分的情况下,惨遭对手逆转。中国队刘礼嘉19分5篮板,杨瀚森17分118589!中国男篮耻辱一败,惨遭韩国19分大逆转,无缘亚锦赛冠军北京时间8月26日,U18男篮亚锦赛半决赛打响,中国U18男篮时隔3天再度交手韩国U18男篮,双方争夺一张决赛门票。这场比赛,中国队在最多领先19分的情况下惨遭大逆转。经过4节鏖战15亿英镑!英超夏季转会窗引援创纪录文羊城晚报全媒体记者徐扬扬尽管离夏季转会窗关闭还有一周,但据德勤会计师事务所8月25日发布的最新统计,英超俱乐部引援已狂砸15亿英镑,比过往最高的2017年投入14亿英镑还多。未来中国亚轨道运载器重复飞行成功,此前美国放弃,这技术难在哪?我国亚轨道运载器重复使用试验成功关于载人航天一直以来有种说法当年苏联宇航员尤里加加林第一次进入太空,那只是一次亚轨道飞行。1961年4月12日苏联东方1号的轨道近地点高度为181公意大利品牌4US与演员张明明主持人陈翩翩洽谈代言合作今日头条意大利品牌4US与演员张明明主持人陈翩翩洽谈代言合作。演员张明明与浙里有约栏目主持人陈翩翩CesarePaciotti是意大利的著名设计师品牌,与意大利其他顶级设计师品牌G什么人不适合双眼皮手术?双眼皮手术成为时下比较风靡的眼部整形项目,皆在于它可以从视觉上有增大双眼轮廓的效果,增添了眼睛的立体感,使眼睛显得较大。但是双眼皮手术也不是适合于任何人,也是有一些禁忌症,有些特殊罗马诺切尔西为中场扎哈里安报价1500万欧,接近达成协议直播吧8月26日讯记者罗马诺报道,切尔西已经为莫斯科迪纳摩中场阿尔森扎哈里安提交了1500万欧元的报价,球员经纪人帕维尔安德烈夫已对RBSPORT确认这是真的,协议已接近达成。报道罗马诺尤文已签下米利克,并将在未来几小时内完成帕雷德斯转会直播吧8月26日讯昨晚,罗马诺已经用标志性的Herewego确认,米利克将加盟尤文,租借费为100万欧元100万欧元浮动,合同中包含选择性买断条款800万欧元。据名记罗马诺跟进,尤