问题描述:

rocketmq集群两个节点上的broker jvm进程突然每天整点不定时丢失

原因分析:

day1

进程丢失问题通常有两种原因:

1、系统物理内存耗尽(观察当时的内存使用情况、IO、CPU,并未发现异常)

2、应用运行的Java虚拟机进程异常退出(Crash)导致

  • 物理内存耗尽触发操作系统OOM Killer机制:

    1. 当操作系统物理内存和交换空间不够用时,操作系统的OOM Killer机制(默认打开)就会选择性地结束进程。

      说明:OOM Killer机制是如何知道要先结束哪个进程?其实Linux的每个进程都有一个oom_score值(位于/proc/XXX/oom_score),该值越大,越有可能会被OOM Killer机制选中并结束。

    2. 当一个进程被OOM Killer结束后,会向/var/log/messages操作系统日志写入结束进程的PID等信息,所以判断进程是否被OOM Killer,可以通过搜索操作系统日志来得知,执行以下任意一条命令,可以查看进程被结束的信息。

      grep -i 'killed process' /var/log/messages
      egrep "oom-killer|total-vm" /var/log/messages

      ECS实例进程被OOM Killer的具体日志如下。

      [Wed Aug 31 16:36:42 2017] Out of memory: Kill process 43805 (keystone-all) score 249 or sacrifice child[Wed Aug 31 16:36:42 2017] Killed process 43805 (keystone-all) total-vm:4446352kB, anon-rss:4053140kB, file-rss:68kB[Wed Aug 31 16:56:25 2017] keystone-all invoked oom-killer: gfp_mask=0x280da, order=0, oom_score_adj=0[Wed Aug 31 16:56:25 2017] keystone-all cpuset=/ mems_allowed=0[Wed Aug 31 16:56:25 2017] CPU: 2 PID: 88196 Comm: keystone-all Not tainted 3.10.0-327.13.1.el7.x86_64 #1
  • 应用运行的JVM进程异常退出(Crash)

    JVM进程通常会因为异常的JNI调用等原因在运行时异常退出,发生此问题时,会在当前JVM进程的工作目录(通过pwdx [$JVM_PID]命令可查)生成一个hs_err_[$JVM_PID].log文件。通常,从这个日志文件中即可查到JVM进程异常退出时执行的线程或原因(必要时可以通过生成coredump文件进一步分析)。

既然就这两种情况,开始排查我们服务器的日志 grep -i 'killed process' /var/log/messages 未发现相关信息,这就排除了第一种情况oom_killer;接着进入rocketMq的工作目录发现了确实生成了hs_err_1234.log,日志内容如下:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGBUS (0x7) at pc=0x00007f36e85ddaf6, pid=8489, tid=0x00007f352e3df700
#
# JRE version: Java(TM) SE Runtime Environment (8.0_201-b09) (build 1.8.0_201-b09)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.201-b09 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# v  ~StubRoutines::jlong_disjoint_arraycopy
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
#---------------  T H R E A D  ---------------Current thread (0x00007f36a0000cb0):  JavaThread "SendMessageThread_1" [_thread_in_Java, id=8603, stack(0x00007f352e2df000,0x00007f352e3e0000)]siginfo: si_signo: 7 (SIGBUS), si_code: 2 (BUS_ADRERR), si_addr: 0x00007f34f7d67000Registers:
RAX=0x00000005c01de018, RBX=0x0000000000000000, RCX=0x00007f34f7d670e0, RDX=0xffffffffffffffeb
RSP=0x00007f352e3de4f0, RBP=0x00007f352e3de4f0, RSI=0x00007f34f7d67000, RDI=0x00000005c01de010
R8 =0x0000000000000000, R9 =0x00007f34f7d67000, R10=0x00007f36e85de760, R11=0x00000005c01ddf20
R12=0x0000000000000000, R13=0x00000000000000e8, R14=0x000000077b8467c0, R15=0x00007f36a0000cb0
RIP=0x00007f36e85ddaf6, EFLAGS=0x0000000000010286, CSGSFS=0x0000000000000033, ERR=0x0000000000000006TRAPNO=0x000000000000000e

提取关键信息:

1、SIGBUS (0x7)

2、Problematic frame:# v  ~StubRoutines::jlong_disjoint_arraycopy

3、ulimit -c unlimited (备注此处通过这个可以生成 core dump文件,具体参考镜像FAQ - 云服务器 ECS - 阿里云)

4、JavaThread "SendMessageThread_1"

根据这些信息通过搜索引擎查找答案,查找到了相关文章说是JDK的bug(备注:jdk的bug概率极低,后来看也不是jdk的问题),开始升级jdk从1.8升级到Java10以上,又遇到Java9以后相关jvm参数的变更,启动mq报错,具体参考,修改runbroker 和 runnamesrv脚本jdk9 jdk10 jdk11启动rocketMQ的问题_Dissolute_的博客-CSDN博客

day2

最终MQ成功启动,但还时不时出问题,有一个新发现就是Java10以后hs_err_pid.log更详细了

内容如下:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGBUS (0x7) at pc=0x00007ff481c70304, pid=24249, tid=24426
#
# JRE version: Java(TM) SE Runtime Environment (10.0.2+13) (build 10.0.2+13)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (10.0.2+13, mixed mode, tiered, compressed oops, g1 gc, linux-amd64)
# Problematic frame:
# v  ~StubRoutines::jbyte_disjoint_arraycopy
#
# No core dump will be written. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
#---------------  S U M M A R Y ------------Command Line: -Xms8192m -Xmx8192m -Xmn4096m -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -XX:SoftRefLRUPolicyMSPerMB=0 -XX:SurvivorRatio=8 -XX:+DisableExplicitGC -verbose:gc -Xlog:gc:/dev/shm/mq_gc_%p.log -XX:-OmitStackTraceInFastThrow -XX:+AlwaysPreTouch -XX:MaxDirectMemorySize=8g -XX:-UseLargePages -XX:-UseBiasedLocking --add-exports=java.base/jdk.internal.ref=ALL-UNNAMED org.apache.rocketmq.broker.BrokerStartup -c ../conf/2m-2s-async/broker-a.propertiesHost: Intel(R) Xeon(R) Platinum 8163 CPU @ 2.50GHz, 8 cores, 31G, CentOS Linux release 7.4.1708 (Core)
Time: Fri Nov 19 10:00:37 2021 CST elapsed time: 2224 seconds (0d 0h 37m 4s)---------------  T H R E A D  ---------------Current thread (0x00007ff2c0010770):  JavaThread "SendMessageThread_1" [_thread_in_Java, id=24426, stack(0x00007ff2931c1000,0x00007ff2932c2000)]Stack: [0x00007ff2931c1000,0x00007ff2932c2000],  sp=0x00007ff2932c04f0,  free space=1021k
Native frames: (J=compiled Java code, A=aot compiled Java code, j=interpreted, Vv=VM code, C=native code)
v  ~StubRoutines::jbyte_disjoint_arraycopy
J 3585 c2 java.nio.DirectByteBuffer.put([BII)Ljava/nio/ByteBuffer; java.base@10.0.2 (135 bytes) @ 0x00007ff489909ab6 [0x00007ff4899099c0+0x00000000000000f6]
J 4655 c2 org.apache.rocketmq.store.CommitLog$DefaultAppendMessageCallback.doAppend(JLjava/nio/ByteBuffer;ILorg/apache/rocketmq/store/MessageExtBrokerInner;)Lorg/apache/rocketmq/store/AppendMessageResult; (939 bytes) @ 0x00007ff489bc4f24 [0x00007ff489bc2bc0+0x0000000000002364]
J 4593 c2 org.apache.rocketmq.store.MappedFile.appendMessage(Lorg/apache/rocketmq/store/MessageExtBrokerInner;Lorg/apache/rocketmq/store/AppendMessageCallback;)Lorg/apache/rocketmq/store/AppendMessageResult; (7 bytes) @ 0x00007ff489b778e8 [0x00007ff489b77680+0x0000000000000268]
J 4657 c2 org.apache.rocketmq.store.CommitLog.putMessage(Lorg/apache/rocketmq/store/MessageExtBrokerInner;)Lorg/apache/rocketmq/store/PutMessageResult; (742 bytes) @ 0x00007ff489bcd930 [0x00007ff489bcce80+0x0000000000000ab0]
J 4692 c2 org.apache.rocketmq.store.DefaultMessageStore.putMessage(Lorg/apache/rocketmq/store/MessageExtBrokerInner;)Lorg/apache/rocketmq/store/PutMessageResult; (402 bytes) @ 0x00007ff489bd9730 [0x00007ff489bd9600+0x0000000000000130]
J 4410 c2 org.apache.rocketmq.broker.processor.SendMessageProcessor.sendMessage(Lio/netty/channel/ChannelHandlerContext;Lorg/apache/rocketmq/remoting/protocol/RemotingCommand;Lorg/apache/rocketmq/broker/mqtrace/SendMessageContext;Lorg/apache/rocketmq/common/protocol/header/SendMessageRequestHeader;)Lorg/apache/rocketmq/remoting/protocol/RemotingCommand; (482 bytes) @ 0x00007ff489b091e4 [0x00007ff489b07d60+0x0000000000001484]
J 4136 c2 org.apache.rocketmq.broker.processor.SendMessageProcessor.processRequest(Lio/netty/channel/ChannelHandlerContext;Lorg/apache/rocketmq/remoting/protocol/RemotingCommand;)Lorg/apache/rocketmq/remoting/protocol/RemotingCommand; (103 bytes) @ 0x00007ff489a9b9b4 [0x00007ff489a9b800+0x00000000000001b4]
J 3931 c2 org.apache.rocketmq.remoting.netty.NettyRemotingAbstract$1.run()V (233 bytes) @ 0x00007ff48999e5e4 [0x00007ff48999e520+0x00000000000000c4]
J 3978 c2 org.apache.rocketmq.remoting.netty.RequestTask.run()V (17 bytes) @ 0x00007ff4899e2094 [0x00007ff4899e2040+0x0000000000000054]
J 3802 c2 java.util.concurrent.FutureTask.run()V java.base@10.0.2 (123 bytes) @ 0x00007ff489952308 [0x00007ff4899521e0+0x0000000000000128]
J 4495% c2 java.util.concurrent.ThreadPoolExecutor.runWorker(Ljava/util/concurrent/ThreadPoolExecutor$Worker;)V java.base@10.0.2 (187 bytes) @ 0x00007ff489b52464 [0x00007ff489b522c0+0x00000000000001a4]
j  java.util.concurrent.ThreadPoolExecutor$Worker.run()V+5 java.base@10.0.2
j  java.lang.Thread.run()V+11 java.base@10.0.2
v  ~StubRoutines::call_stub
V  [libjvm.so+0x8abc52]  JavaCalls::call_helper(JavaValue*, methodHandle const&, JavaCallArguments*, Thread*)+0x412
V  [libjvm.so+0x8aa170]  JavaCalls::call_virtual(JavaValue*, Handle, Klass*, Symbol*, Symbol*, Thread*)+0x1d0
V  [libjvm.so+0x95248a]  thread_entry(JavaThread*, Thread*)+0x8a
V  [libjvm.so+0xd94138]  JavaThread::thread_main_inner()+0x108
V  [libjvm.so+0xd942be]  JavaThread::run()+0x13e
V  [libjvm.so+0xc05392]  thread_native_entry(Thread*)+0xf2
C  [libpthread.so.0+0x7ea5]  start_thread+0xc5siginfo: si_signo: 7 (SIGBUS), si_code: 2 (BUS_ADRERR), si_addr: 0x00007ff277130000Register to memory mapping:RAX=0x00000006c146e0e5 is pointing into object: 0x00000006c146dee8
[B
{0x00000006c146dee8} - klass: {type array byte}- length: 4194312
RBX=0x00000000000001ed is an unknown value
RCX=0x00000000000001ed is an unknown value
RDX=0xffffffffffffffcb is an unknown value
RSP=0x00007ff2932c04f0 is pointing into the stack for thread: 0x00007ff2c0010770
RBP=0x00007ff2932c04f0 is pointing into the stack for thread: 0x00007ff2c0010770
RSI=0x00007ff2771301e0 is an unknown value
RDI=0x00000006c146e0d8 is pointing into object: 0x00000006c146dee8
[B
{0x00000006c146dee8} - klass: {type array byte}- length: 4194312
R8 =0x0000000000000010 is an unknown value
R9 =0x00000006c146dee8 is an oop
[B
{0x00000006c146dee8} - klass: {type array byte}- length: 4194312
R10=0x00007ff481c71400 is at begin+0 in a stub
StubRoutines::unsafe_arraycopy [0x00007ff481c71400, 0x00007ff481c7143b[ (59 bytes)
R11=0x00007ff277130000 is an unknown value
R12=0x0000000000000000 is an unknown value
R13=0x00000007380184d8 is an oop
java.nio.DirectByteBuffer
{0x00000007380184d8} - klass: 'java/nio/DirectByteBuffer'
R14=0x0000000000000000 is an unknown value
R15=0x00007ff2c0010770 is a thread

有了导致崩溃的线程堆栈信息,开始求助rocketmq开源社区,同时进行排查错误日志

通过“java.nio.DirectByteBuffer.put([BII)Ljava/nio/ByteBuffer”索引到关键点1(java.lang.InternalError: a fault occurred in a recent unsafe memory access operation in compiled Java code - Stack Overflow) 相关错误说明

public ByteBuffer put(byte x) {//通过unsafe 调用本地函数操作内存unsafe.putByte(ix(nextPutIndex()), ((x)));return this;}

stack overflow 上的重要信息摘录,谷歌翻译后:

更多细节:

sun.misc.Unsafe 是 JDK 私有 API,允许直接从 Java 访问本机内存。该 API 是 Direct ByteBuffers,尤其是 MappedByteBuffers 的基础。

在某些情况下,访问文件的内存映射区域可能会导致操作系统级异常,即 SIGBUS。典型的例子是:

(1)在底层文件被截断后访问内存映射缓冲区。

(2)网络驱动器上的文件已映射到内存,并在网络连接丢失后访问映射的缓冲区。
        (3)尝试写入映射到 tmpfs 文件系统上的文件的页面会导致内存不足(默认情况下,tmpfs 空间受总 RAM 的 50% 的限制)。

HotSpot JVM 无法有效地预先检测这些问题。它将 Unsafe.getX / putX 调用编译为简单的内存访问指令。额外的检查以查看内存区域是否有效将过于昂贵。

相反,JVM 处理 SIGBUG 信号。如果它看到错误发生在 Unsafe 调用中,它会将 InternalError 发布到当前线程并继续执行。
IOException 会更合适,但 JVM 不能抛出它或任何其他异常,因为 ByteBuffer 公共契约不允许其 get/put 方法抛出任何异常。
如果在 JIT 编译的方法中 Unsafe 内存访问失败,JVM 不会立即抛出异常(同样,对于如此热的 ByteBuffer API 来说成本太高了)。相反,它将异步 InternalError 发布到当前线程。这意味着错误实际上会在最近的本地方法或对 VM 运行时的最近调用处抛出。因此,错误消息中出现了“最近”一词。

后续会用到的关键信息已经标红

day3

得到mq开源社区的回复: jdk版本10并不是LTS版本,mq版本太低,使用ycrash进行分析。

这里简单说下ycrash,国外开发的一款分析服务器各项指标的工具,说是能分析出各项异常的原因,原理就是通过yc-agent采集服务器和应用产生的日志信息以及各项指标,传输到yc-server进行分析并给出分析报告,缺点是yc-agent需要手工触发采集或者集成下列监控工具(Promethus、AppDynamics、Grafana),等问题产生调用yc-agent API进行采集,还有一个测试版本的m3模式可以定时采集信息,为了不影响应用采集的信息少了一部分,总体来说比较鸡肋。

day4

前几天没有解决问题开始怀疑是ecs机器有问题,开始迁移新的ecs,迁移后过了两天消停日子,(当时部分不是特别依赖该MQ的应用未完全迁移过来),后来所有应用迁移完成又出现同样的问题,开始怀疑是不是其中的一个应用MQ使用不当造成的,强行停用了部分应用,然而还是出现同样问题,彻底崩溃......

day。。。

干了几碗心灵鸡汤后,我还没有放弃、我能行~

1、生成并分析core dump文件

Java Linux Core Dump分析 - 芥为之舟

2、翻查linux-log What are Linux Logs? How to View Them, Most Important Directories, and More – Stackify

3、电脑是不是中毒了,排查异常进程,了解每个进程的作用

Linux监控磁盘IO及线程读写状态 并用日志记录_TheRainManFSA的博客-CSDN博客

4、了解mq的消息存储设计

https://github.com/apache/rocketmq/blob/master/docs/cn/design.md

机缘巧合又排查了一遍/var/log/cron日志

0 * * * * find /data/rocketmq_data/*/store/commitlog -mtime +0 -type f |awk '{print "> "$1}'|bash

刚开始以为只是查看24小时前的日志,所以没关心,后来才知道是删除24小时前的commitlog

rocketmq生产者和消费者的日志分开存储:

commitlog主要是用来持久化存储producer生产的消息,只要不删,mq的消息就不会丢失,我们可以选择同步或者异步两种方式将PageCache中的数据持久化到磁盘文件

consumerQueue存储了commitlog当中消息的offset和tag和msgSize信息,相当于目录可以快速检索实体消息

indexFile索引文件主要用来存储消息的消费记录,可以通过topic/key和时间段快速检索消息,其中的索引数据包含了Key Hash/CommitLog Offset/Timestamp/NextIndex offset 这四个字段,通过commitlog offset从commitlog中读取消息实体

结合这个删除commitlog的定时任务、mq的消息存储原理、jvm崩溃的时间点(大多都是整点)

以及标红的报错关键点(1)在底层文件被截断后访问内存映射缓冲区。

分析得出是这个清除commitlog节省存储空间的定时任务导致的。建议使用mq自带的清空日志方式,修改broker配置文件:

Broker 配置

参数名 默认值 说明
listenPort 10911 接受客户端连接的监听端口
namesrvAddr null nameServer 地址
brokerIP1 网卡的 InetAddress 当前 broker 监听的 IP
brokerIP2 跟 brokerIP1 一样 存在主从 broker 时,如果在 broker 主节点上配置了 brokerIP2 属性,broker 从节点会连接主节点配置的 brokerIP2 进行同步
brokerName null broker 的名称
brokerClusterName DefaultCluster 本 broker 所属的 Cluser 名称
brokerId 0 broker id, 0 表示 master, 其他的正整数表示 slave
storePathRootDir $HOME/store/ 存储根路径
storePathCommitLog $HOME/store/commitlog/ 存储 commit log 的路径
mappedFileSizeCommitLog 1024 * 1024 * 1024(1G) commit log 的映射文件大小
deleteWhen 04 在每天的什么时间删除已经超过文件保留时间的 commit log
fileReservedTime 72 以小时计算的文件保留时间
brokerRole ASYNC_MASTER SYNC_MASTER/ASYNC_MASTER/SLAVE
flushDiskType ASYNC_FLUSH SYNC_FLUSH/ASYNC_FLUSH SYNC_FLUSH 模式下的 broker 保证在收到确认生产者之前将消息刷盘。ASYNC_FLUSH 模式下的 broker 则利用刷盘一组消息的模式,可以取得更好的性能。

至此该问题已经得到解决!

疑问点:为何会用到24小时前的消息?

记录排查rocketMQ-broker-JVM进程消失问题相关推荐

  1. linux java进程消失_Linux服务器Java进程消失问题解决

    Linux服务器Java进程消失问题解决 发布时间:2020-08-20 15:17:37 来源:脚本之家 阅读:65 作者:myseries 这篇文章主要介绍了Linux服务器Java进程消失问题解 ...

  2. JVM解惑:消失的异常堆栈,log中打印异常堆栈为空

    最近线上发现很多异常没有堆栈信息,只有一句描述,如下: java.lang.NullPointerException: null 排查问题时受到了一些阻碍.然后发现无论是在本地环境还是测试环境,堆栈信 ...

  3. 服务器流量异常排查步骤(查看进程的流量)

    服务器流量异常排查步骤(查看进程的流量) 参考文章: (1)服务器流量异常排查步骤(查看进程的流量) (2)https://www.cnblogs.com/pangguoping/p/5836725. ...

  4. RocketMQ Broker的最佳实践

    RocketMQ Broker的最佳实践 翻译自rocket官方文档 Broker Role Broker的方式有异步主,同步主,或者从.如果不能容忍消息丢失,建议以同步主从方式部署.如果对丢失没那么 ...

  5. Zabbix监控多个JVM进程

    一.场景说明:   我们这边的环境用的是微服务,每个程序都是有单独的进程及单独的端口号,但用jps查询出来的结果有些还会有重名的情况,所以某些脚本不太适用本场景: 二.需求说明: 需使用Zabbix- ...

  6. win10尘埃4点击开始游戏自动关闭没反应|dirt4.exe进程消失的解决方法

    win10尘埃4点击开始游戏自动关闭该怎么办?在win10系统中运行尘埃4的用户反应在打开游戏点击 [开始游戏]后没有任何反应的现象,在任务管理器中还能看到dirt4.exe进程,但是过一会就自动消失 ...

  7. HM-SpringCloud微服务系列11.1【多级缓存的意义JVM进程缓存】

    HM-SpringCloud微服务系列11:多级缓存-高级篇 1. 什么是多级缓存 多级缓存是亿级流量的缓存方案 浏览器访问静态资源时,优先读取浏览器本地缓存 访问非静态资源(ajax查询数据)时,访 ...

  8. rocketmq python 一个进程订阅多个topic_玩转不同业务场景,这些RabbitMQ特性会是得力助攻...

    原标题:玩转不同业务场景,这些RabbitMQ特性会是得力助攻 我是在解决分布式事务的一致性问题时了解到的RabbitMQ,当时主要是要基于RabbitMQ来实现我们分布式系统之间对有事务可靠性要求的 ...

  9. java 进程消失_Java进程诡异消失问题

    最新在Centos 7.6上起了一个新的Jboss,并在其中起了我们的server,但是在使用arthas的过程中发现一个问题. [root@tmsprod4 ~]# java -jar arthas ...

最新文章

  1. 【leetcode】Roman to Integer
  2. android摄像头代码,Android摄像头
  3. 2019年最后的一天_2019最后一天的说说 2019最后一条朋友圈再见2019
  4. ubuntu安装mysql,error: No curses/termcap library found报错
  5. mysql 安装盒子_Windows2008 装 MySQL 问题
  6. python判断_轻松python文本专题-判断对象里面是否是类字符串(推荐使用isinstance(obj,str))...
  7. idea解决编译时出现的未结束的字符文字等错误
  8. mysql 断言,mysql触发器模拟断言
  9. WCF从理论到实践(10):异常处理 (转)
  10. [Python] 关键字 assert
  11. android studio按键精灵,51模拟器怎么连接按键精灵 51安卓模拟器按键精灵连接教程...
  12. java怎么销毁session_java怎么销毁session?
  13. Git创建SSH命令
  14. 逆向之制作扫雷外挂——003
  15. AutoCAD启动缓慢
  16. http库三剑客:httpx
  17. 区块链是什么意思 如何简单明了的理解区块链
  18. 睡前做什么有助于睡眠,不妨试试这几个帮助睡眠小妙招
  19. 【从零建站3/n】错题集(已解决):服务器上再次进入有Echarts的页面,图表无法显示
  20. 【Visual C++】游戏开发笔记四十六 浅墨DirectX教程十四 模板测试与镜面特效专场

热门文章

  1. synchronized锁(方法锁, 代码块锁)
  2. 360的金刚不坏之身
  3. CSS 高级属性之 text-shadow 详解
  4. 图文详解:7000 字哈希表总结
  5. 快速入门运维:成为一名高效运维工程师的关键步骤
  6. html登陆成功后跳转页面跳转,怎么设置登录成功后跳转到相应的页面
  7. 部署Ambari 2.7.5 + HDP3.1.5
  8. P1936 【水晶灯火灵】
  9. ygo游戏王卡组_游戏王 WCS游戏王世界大会前三强卡组,淘气仙星成为比赛冠军卡组...
  10. 用计算机打青春不打烊,我们的青春不打烊散文