文章目录

  • 1 mino简介
  • 2 环境
  • 3 部署
    • 3.1 获取程序
    • 3.2 存储类别
    • 3.3 挂载硬盘
    • 3.4 单机部署
      • 3.4.1 部署及测试
      • 3.4.2 作为Linux Service启动
    • 3.5 分布式集群扩容方案
      • 3.5.1 部署及测试
      • 3.5.2 作为Linux Service启动
    • 3.6 多机部署,扩容支持
  • 4 客户端及演示
  • 5 Prometheus+Grafana 搭建监控系统监控minio集群
    • 5.1 搭建Prometheus 收集minio集群数据
    • 5.2 使用Grafana 优化监控界面
  • 6 参考

1 mino简介

MinIO 是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口,同时也支持本地磁盘、NAS、NFS、公有云存储、分布式云存储,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。MinIO是一个非常轻量的服务,可以很简单的和其他应用的结合,类似 NodeJS, Redis 或者 MySQL。

  • 高性能(读/写速度上高达183 GB / 秒 和 171 GB / 秒)
  • 云的原生支持(Kubernetes 、微服和多租户的的容器技术)
  • 可扩展性(集群模式)
  • 开放全部源代码 + 企业级支持(Apache V2 license )
  • 与Amazon S3 兼容

主要看重S3兼容,因为可以做S3的本地方案,应用程序不用做过多的修改

2 环境

minio支持单机单磁盘部署,单机多磁盘部署,多机多磁盘分布式部署。
同时也支持容器部署:MinIO是一个云原生的应用程序,旨在在多租户环境中以可持续的方式进行扩展。编排(orchestration)平台为MinIO的扩展提供了非常好的支撑。以下是各种编排平台的MinIO部署文档。

这里支持两种部署方式:
单机部署单磁盘(volume) 不支持后续拓展磁盘
分布式部署(volume > 4)支持拓展实例

分布式部署有以下优点:
数据保护:分布式Minio采用 纠删码来防范多个节点宕机和位衰减bit rot但分布式部署需要硬盘大于4
高可用:单机Minio服务存在单点故障,相反,如果是一个有N块硬盘的分布式Minio,只要有N/2硬盘在线,你的数据就是安全的。不过你需要至少有N/2+1个硬盘来创建新的对象。
一致性:Minio在分布式和单机模式下,所有读写操作都严格遵守read-after-write一致性模型。

已经存在的数据
当在单块磁盘上部署MinIO server,MinIO server允许客户端访问数据目录下已经存在的数据。比如,如果MinIO使用minio server /mnt/data启动,那么所有已经在/mnt/data目录下的数据都可以被客户端访问到。

3 部署

本文测试部署环境均为: AWS EC2
本文目标环境为离线局域网环境, 所有****没有采用容器编排部署方式,也没有采用nginx反向代理minio集群,直接将minio运行在80端口

3.1 获取程序

拉取minio Linux代码

wget http://dl.minio.org.cn/server/minio/release/darwin-amd64/minio

3.2 存储类别

MinIO服务器支持使用纠删码(erasure coding)模式实现存储。这允许每个对象配置数据和奇偶校验磁盘。纠删码erasure code和校验和checksum来保护数据免受硬件故障和无声数据损坏。 即便您丢失一半数量(N/2)的硬盘,您仍然可以恢复数据。

MinIO支持两个存储类,减少冗余类(Reduced Redundancy)和标准类(Standard)。这些类可以使用启动MinIO server之前设置的环境变量来定义。在使用环境变量为每个存储类定义了数据和同等值磁盘之后,可以通过请求元数据字段x- ams -storage-class设置对象的存储类。然后,MinIO服务器通过将对象保存在特定数量的数据和奇偶磁盘中来实现存储类。

为了了解数据和奇偶校验驱动器的不同组合如何影响存储使用,让我们以存储在16驱动器MinIO部署上的100mib文件为例。如果您使用8个数据和8个奇偶校验驱动器,文件空间使用将大约是2倍,即100 MiB文件将占用200 MiB空间。但是,如果使用10个数据和6个奇偶校验驱动器,同样的100mib文件大约需要160mib。如果你使用14个数据和两个奇偶校验驱动器,100 MiB文件只需要大约114 MiB。

标准存储
下面是16驱动器MinIO部署上的数据/奇偶校验驱动器和相应的近似存储空间使用情况。字段存储使用比率就是文件经过擦除编码后使用的驱动器空间除以实际文件大小。

大于或等于2,如果没有设置REDUCED_REDUNDANCY奇偶校验
大于REDUCED_REDUNDANCY奇偶校验(如果设置了)

奇偶校验块不能高于数据块,因此标准存储类奇偶校验不能高于N/2。(N为磁盘总数)
标准存储类的默认值是N/2 (N是驱动器总数)。

这里就都用标准存储吧
不同数据和奇偶校验驱动器的选择直接影响驱动器空间的使用。使用storage类,您可以优化为高冗余或更好的驱动器空间利用率。

默认情况下,将具有标准存储类的对象的奇偶校验设置为N/2,将具有减少的冗余存储类对象的对象的奇偶校验设置为2。在此处阅读有关MinIO服务器中存储类支持的更多信息。
MinIO server supports storage class in erasure coding mode. This allows configurable data and parity disks per object.
https://github.com/minio/minio/blob/master/docs/erasure/storage-class/README.md

奇偶校验位支持
http://docs.minio.org.cn/docs/master/minio-erasure-code-quickstart-guide
**

3.3 挂载硬盘

在linux上挂载4块硬盘用于测试单机部署和分布式部署。
在AWS EBS控制台上建立4块 1G 的EBS用于测试。然后挂在EC2上。
使用 lsblk 命令查看驱动器

可以看到多了xvdf xvdg xvdh xvdi 4块磁盘

请使用 mkfs -t 命令在该卷上创建一个文件系统。(如果要挂载已具有数据的卷(例如,从快照创建的卷),请勿使用此命令。否则,您会格式化卷并删除现有数据。)

sudo mkfs -t xfs /dev/xvdf

依次为四块磁盘创建对应文件系统

创建挂载点目录,并挂载卷

sudo mkdir /mnt/data1
sudo mkdir /mnt/data2
sudo mkdir /mnt/data3
sudo mkdir /mnt/data4
sudo mount /dev/xvdf /mnt/data1
sudo mount /dev/xvdg /mnt/data2
sudo mount /dev/xvdh /mnt/data3
sudo mount /dev/xvdi /mnt/data4

到这里四块磁盘就已经挂载到对应目录了
更改四块磁盘所有者:

sudo chown ubuntu /mnt/data1

配置开机挂载硬盘

3.4 单机部署

minio version RELEASE.2020-07-18T18-48-16Z
确认linux 有80端口访问且具有公网权限:

3.4.1 部署及测试

命令行测试:

wget http://dl.minio.org.cn/server/minio/release/linux-amd64/minio
chmod +x minio
sudo setcap cap_net_bind_service=+ep /home/ubuntu/minio
./minio server --address :80 /home/ubuntu/storage

以上命令行为:
1 下载minio程序 (注意 这里很扯, 拉下来的minio很可能会出现段错误Segmentation fault, 原因是从这个地址拉代码拉错了,这种情况就要去上诉地址找真正的minio的程序地址。我用wget拉下来的minio只有9M,而实际去该地址列表里面看到的49M的程序才是真正minio )
2 将minio更改为可执行
3 为minio配置Linux cap_net_bind_service能力可以绑定1024以下端口
4 单机执行minio 运行在80端口 volume绑定在/home/ubuntu/storage 路径

执行效果如下:

访问公网IP效果如下:(accessKey 和 SecretKey 密码均为默认值)

进入后台,使用就很简单了,界面非常简洁。和S3一样有存储桶,权限,对象的概念。熟悉S3上手速度很快的

3.4.2 作为Linux Service启动

https://github.com/minio/minio-service/tree/master/linux-systemd

1 将下载好的minio程序软连接到 usr/local/bin 路径下,可以在全局访问到minio程序

sudo ln minio /usr/local/bin/minio

2 创建 /etc/default/minio 配置

sudo vi /etc/default/minio

/etc/default/minio

# Volume to be used for MinIO server.
MINIO_VOLUMES="/home/ubuntu/storage"
# Use if you want to run MinIO on a custom port.
MINIO_OPTS="--address :80"
# Access Key of the server.
MINIO_ACCESS_KEY="minioubuntu"
# Secret key of the server.
MINIO_SECRET_KEY="minioubuntu"

配置存储路径
配置运行ip及端口
配置minio AccessKey和SecretKey

3 配置Systemctl
下载minio.service 在这个文件中 /etc/systemd/system/

cd /etc/systemd/system
sudo wget https://raw.githubusercontent.com/minio/minio-service/master/linux-systemd/minio.service

minio.service内容如下:

[Unit]
Description=MinIO
Documentation=https://docs.min.io
Wants=network-online.target
After=network-online.target
AssertFileIsExecutable=/usr/local/bin/minio[Service]
WorkingDirectory=/usr/local/User=minio-user
Group=minio-userEnvironmentFile=/etc/default/minio
ExecStartPre=/bin/bash -c "if [ -z \"${MINIO_VOLUMES}\" ]; then echo \"Variable MINIO_VOLUMES not set in /etc/default/minio\"; exit 1; fi"ExecStart=/usr/local/bin/minio server $MINIO_OPTS $MINIO_VOLUMES# Let systemd restart this service always
Restart=always# Specifies the maximum file descriptor number that can be opened by this process
LimitNOFILE=65536# Disable timeout logic and wait until process is stopped
TimeoutStopSec=infinity
SendSIGKILL=no[Install]
WantedBy=multi-user.target# Built for ${project.name}-${project.version} (${project.name})

如果要以普通用户身份运行服务时绑定到<1024端口,则需要通过minio.service文件中的AmbientCapabilities指令添加绑定功能:
sudo vi minio.service

更改[Service]中的内容

[Service]
WorkingDirectory=/usr/local/
AmbientCapabilities=CAP_NET_BIND_SERVICEUser=ubuntu
Group=ubuntu

4 启动minio

sudo service minio start
sudo service minio stop
systemctl status minio.service

使用ps -aux | grep “minio” 查看确实为ubuntu启动的minio

5 使能开机启动

sudo systemctl enable minio.service

6 禁用minio Service服务

sudo systemctl disable minio.service

可以是用下列命令查看service启动报错

journalctl -u minio.service
journalctl -f

3.5 分布式集群扩容方案

http://docs.minio.org.cn/docs/master/distributed-minio-quickstart-guide

分布式Minio可以让你将多块硬盘(甚至在不同的机器上)组成一个对象存储服务。由于硬盘分布在不同的节点上,分布式Minio避免了单点故障。
在大数据领域,通常的设计理念都是无中心和分布式。Minio分布式模式可以帮助你搭建一个高可用的对象存储服务,你可以使用这些存储设备,而不用考虑其真实物理位置。

分布式Minio至少需要4个硬盘,使用分布式Minio自动引入了纠删码功能。

验证是否部署成功,使用浏览器访问Minio服务或者使用 mc。多个节点的存储容量和就是分布式Minio的存储容量。
如果你了解Minio单机模式的搭建的话,分布式搭建的流程基本一样,Minio服务基于命令行传入的参数自动切换成单机模式还是分布式模式。
启动一个分布式Minio实例,你只需要把硬盘位置做为参数传给minio server命令即可,然后,你需要在所有其它节点运行同样的命令。

3.5.1 部署及测试

本次部署目标 单节点四块盘
用户目录:/home/ubuntu
内网IP: 172.31.21.207

这里使用在3.3 中挂载的四块硬盘

wget http://dl.minio.org.cn/server/minio/release/linux-amd64/minio
chmod +x minio
sudo setcap cap_net_bind_service=+ep /home/ubuntu/minio
sudo ln minio /usr/local/bin/minio
export MINIO_ACCESS_KEY=minioubuntu
export MINIO_SECRET_KEY=minioubuntu
minio server --address :80 http://172.31.21.207/mnt/data1 http://172.31.21.207/mnt/data2  http://172.31.21.207/mnt/data3  http://172.31.21.207/mnt/data4

和单机部署主要差别即为将 文件路径换成 IP + 文件路径的方式。且需要将需要挂载的磁盘均加入。

启动成功:

同3.4.2中一样进入后台, 创建一个test 桶并上传一张图片

我们去挂载四块磁盘看看实际存储情况

可以看到每块磁盘内都存储了对应这个文件信息。如果使用分布式部署之后我们不用太关心文件物理存储方式。 默认纠错码N/2 。即4G容量只有2G用于存储物理数据。

3.5.2 作为Linux Service启动

分布式部署作为服务启动。唯一差别就是将3.4.2 中第二步配置替换掉即可。即更新磁盘路径和监听端口。

2 创建 /etc/default/minio 配置

sudo vi /etc/default/minio

/etc/default/minio 将多块磁盘配置其中

# Volume to be used for MinIO server.
MINIO_VOLUMES="http://172.31.21.207/mnt/data1 http://172.31.21.207/mnt/data2  http://172.31.21.207/mnt/data3  http://172.31.21.207/mnt/data4"
# Use if you want to run MinIO on a custom port.
MINIO_OPTS="--address :80"
# Access Key of the server.
MINIO_ACCESS_KEY="minioubuntu"
# Secret key of the server.
MINIO_SECRET_KEY="minioubuntu"

配置存储路径
配置运行ip及端口
配置minio AccessKey和SecretKey

3.6 多机部署,扩容支持

如果3.5 中单节点多磁盘容量不够,我们可以新增主机minio进行分布式集群进行扩容。

**新的对象上传请求会自动分配到最少使用的集群上。通过以上扩展策略,您就可以按需扩展您的集群。**重新配置后重启集群,会立即在集群中生效,并对现有集群无影响。如上命令中,我们可以把原来的集群看做一个区,新增集群看做另一个区,新对象按每个区域中的可用空间比例放置在区域中。在每个区域内,基于确定性哈希算法确定位置。

AWS EC2新增一台主机(minio2) 附带四块磁盘
内网IP:172.31.31.30

原AWS EC2主机(minio1) 已运行过minio 且存在一个存储桶test 及 一张图片
内网IP: 172.31.21.207

按照3.5 的方式在新主机上搭建环境。
停止minio1 EC2服务,在两台主机上均运行以下命令 {1…4} 语法是重复4次,从1到4

export MINIO_ACCESS_KEY=minioubuntu
export MINIO_SECRET_KEY=minioubuntu
minio server --address :80 http://172.31.21.207/mnt/data{1...4}   http://172.31.31.30/mnt/data{1...4}

原主机启动后效果

新主机执行:

可以在新主机80端口也访问到对应对应的test 存储桶及图片,在新主机上传文件后,在原主机耶可以看到新的文件。

可以看到新主机下挂载磁盘内容为

并没有将原集群的图片复制过来 仅有存储桶

也可以将上诉操作部署为linux service
**

4 客户端及演示

MinIO Client (mc)为ls,cat,cp,mirror,diff,find等UNIX命令提供了一种替代方案。它支持文件系统和兼容Amazon S3的云存储服务(AWS Signature v2和v4)。

ls       列出文件和文件夹。
mb       创建一个存储桶或一个文件夹。
cat      显示文件和对象内容。
pipe     将一个STDIN重定向到一个对象或者文件或者STDOUT。
share    生成用于共享的URL。
cp       拷贝文件和对象。
mirror   给存储桶和文件夹做镜像。
find     基于参数查找文件。
diff     对两个文件夹或者存储桶比较差异。
rm       删除文件和对象。
events   管理对象通知。
watch    监听文件和对象的事件。
policy   管理访问策略。
session  为cp命令管理保存的会话。
config   管理mc配置文件。
update   检查软件更新。
version  输出版本信息。

下面演示如何下载一个客户并创建存储桶 且将存储桶配置为公开访问。在3.6 集群部署的基础上进行

wget  http://dl.minio.org.cn/client/mc/release/linux-amd64/mc &&
chmod +x mc &&
sudo ./mc config host add minio http://127.0.0.1:80 minioubuntu minioubuntu --api s3v4 &&
sudo ./mc mb minio/testclient &&
sudo ./mc policy set public minio/testclient &&

执行效果:

5 Prometheus+Grafana 搭建监控系统监控minio集群

https://www.jianshu.com/p/8d2c020313f0

指导文档:
http://docs.minio.org.cn/docs/master/how-to-monitor-minio-using-prometheus#1-download-prometheus

5.1 搭建Prometheus 收集minio集群数据

下载最新版本prometheus
https://prometheus.io/download/

wget https://github.com/prometheus/prometheus/releases/download/v2.20.0/prometheus-2.20.0.linux-amd64.tar.gz
tar xvfz prometheus-*.tar.gz
cd prometheus-2.20.0.linux-amd64/
export MINIO_PROMETHEUS_AUTH_TYPE="public"

这里配置环境变量要重启一下minio集群:

MinIO服务器在/ minio / prometheus / metrics端点上公开以下指标 配置为public之后访问该路由可以拿到prometheus 格式的监控数据

2 配置prometheus
在Promethus中 更改Promethus.yml 添加minio job

- job_name: minio-jobmetrics_path: /minio/prometheus/metricsscheme: httpstatic_configs:- targets: ['172.31.21.207:80', '172.31.31.30 :80']

启动prometheus

./prometheus --config.file=prometheus.yml  --web.listen-address=:443

访问promeprprootheus status-targets 发现两个节点被获取到

访问: 443端口即可看到以下界面

以上界面并不好看且不够直观

shell

 sudo ln prometheus-2.20.0.linux-amd64/prometheus /usr/local/bin/prometheussudo cp -a prometheus-2.20.0.linux-amd64/prometheus.yml /etc/default/sudo cp prometheus.service /etc/systemd/system/sudo systemctl daemon-reloadsudo systemctl enable prometheus.servicesudo systemctl start prometheussudo systemctl status prometheus

作为service 代码:

[Unit]
Description=Prometheus
Wants=network-online.target
After=network-online.target[Service]
User=eagleeye
Group=eagleeye
Type=simple
AmbientCapabilities=CAP_NET_BIND_SERVICEExecStart=/usr/local/bin/prometheus \--config.file /etc/default/prometheus.yml \--storage.tsdb.path /home/ubuntu/minioservice/prometheus/[Install]
WantedBy=multi-user.target

5.2 使用Grafana 优化监控界面

下载Grafana

wget https://dl.grafana.com/oss/release/grafana-7.1.1.linux-amd64.tar.gz
tar -zxvf grafana-7.1.1.linux-amd64.tar.gz
$ cd grafana-7.1.1
$ ./bin/grafana-server web

修改 conf/defaults.ini port然后修改自己想要修改自己想要的端口

http://161.189.186.14:443/login

安装并启动Grafana后,浏览器输入 IP:3000 来访问Grafana,管理员账号密码默认是admin/admin。首次登陆会让你修改管理员密码,然后就可以登录查看了。

填入prometheus 参数 对应IP及端口。
出现Data source is working 工作后即表示参数接入成功。

现在导入minio监控界面:

https://grafana.com/grafana/dashboards/12063
模板界面可以填入上诉这个模板

导入grafana 模板:

集群总容量和集群已使用空间需要进入到具体界面编辑,把instant标志位置位。

监控指标:

参考该文档下载了一个模板
https://blog.csdn.net/shykevin/article/details/107196450

作为linux service启动
Shell

sudo ln grafana-7.1.1/bin/grafana-server  /usr/local/bin/grafana-server
sudo cp grafana.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable grafana.service
sudo systemctl start grafana

grafana.service 代码:

[Unit]
Description=Prometheus
Wants=network-online.target
After=network-online.target[Service]
User=eagleeye
Group=eagleeye
Type=simple
AmbientCapabilities=CAP_NET_BIND_SERVICEExecStart=/usr/local/bin/grafana-server \-homepath /home/ubuntu/minioservice/grafana-7.1.1[Install]
WantedBy=multi-user.target

6 参考

https://blog.csdn.net/shykevin/article/details/107196450
https://blog.csdn.net/shykevin/article/details/107196450
http://docs.minio.org.cn/docs/master/how-to-monitor-minio-using-prometheus

Minio 搭建对象存储服务相关推荐

  1. minio搭建文件存储服务

    文件存储是必不可少的.目前市场上有许多提供对象存储服务的厂商,但是这些存储服务往往是收费或者有存储空间限制的.现在可使用minio搭建自己的文件存储服务器,因为minio新版和旧版有一定的区别,所以今 ...

  2. SpringBoot 搭建基于 minio 的高性能存储服务

    欢迎关注方志朋的博客,回复"666"获面试宝典 什么是minio 引用官网: MinIO是根据GNU Affero通用公共许可证v3.0发布的高性能对象存储.它与Amazon S3 ...

  3. 自己搭建个对象存储服务难不难?

    今天小编就在欢快的编码,来了一个刚毕业的小嫩青,虚心求教到 对象存储服务到底有啥用? 说起这个对象存储服务,那家伙,那场面,那可是锣鼓喧天.鞭炮齐鸣 打住,打住,其实小编对于对象存储服务的理解是,为了 ...

  4. 如何简单快速搭建自己的云对象存储服务(OSS)

    简单来说,其实我们只需要有一台服务器,利用服务器的各种资源,搭配其它厂商开发的软件,就能很轻易拥有自己的云对象存储服务.不需要在阿里云上花钱买什么服务,甚至还能自己给别人提供服务,真的是太爽了. 云对 ...

  5. MinIO可视化的对象存储服务

    一.简介 平时做项目的时候,文件存储是个很常见的需求.这时候就会用到对象存储服务,平时可能会选择 OSS.AWS S3 这类第三方服务.今天带大家搭建一款自己的对象存储服务,带可视化管理,用起来也挺简 ...

  6. 对象存储搭建文件服务器,搭建分布式对象存储服务MinIO-单点模式

    # 搭建分布式对象存储服务 MinIO-单点模式 本文介绍开源的分布式对象存储服务 MinIO 的单点模式的搭建步骤.对象存储系统相比于传统的 NAS 文件系统有很多的优势,访问效率高.方便扩容,支持 ...

  7. 九、Swift对象存储服务(双节点搭建)

    九.Swift对象存储服务(双节点搭建) 要求:Controoler节点需要2块空盘 Compute节点需要再加2块空盘 本次搭建采用Controller 和 Compute双节点节点做swift组件 ...

  8. openstack-r版(rocky)搭建基于centos7.4 的openstack swift对象存储服务 四

    openstack-r版(rocky)搭建基于centos7.4 的openstack swift对象存储服务 一 openstack-r版(rocky)搭建基于centos7.4 的openstac ...

  9. MiniO对象存储服务 磁盘缓存快速入门 ​​​​​​​

    MiniO对象存储服务 磁盘缓存快速入门 这里的磁盘缓存功能是指使用缓存磁盘来存储租户常用的一些数据.例如,假设你通过gateway azure设置访问一个对象并下载下来进行缓存,那接下来的请求都会直 ...

最新文章

  1. android中实现view的更新有两组方法
  2. HDU2089——不要62 (数位DP)
  3. 如何提高后台服务应用问题的排查效率?日志 VS 远程调试
  4. leetcode343. 整数拆分(思路+详解)
  5. 15. 三数之和 golang
  6. ftp与sftp及sftp和scp的区别
  7. [Swift]扩展String类:实现find()查找子字符串在父字符串中的位置
  8. php载入内存的是本地代码吗,常量和静态变量会先载入内存后在进行执行php代码...
  9. 新浪微博开放平台链接耗尽的情况分析
  10. 故障解决-CPU超频问题解决
  11. mysql 右模糊_面试小知识:MySQL索引相关
  12. 全国各省市区城市编码SQL
  13. 软考之系统架构师考试经验分享
  14. 让zheng支持activiti工作流
  15. [转载] 胡锡进:5000亿买一包爆米花 我不想让我的国家这样
  16. sql中exist与in 的区别
  17. python打印古诗_python教程:利用python基础知识取出对应诗句
  18. re匹配截至到第一个中文_Python正则表达式:re模块常用方法详解
  19. YGG 与 Thirdverse 达成合作,将《足球小将》IP 带入 Web3
  20. 实现全球同服,保障业务出海——腾讯云跨域加速解决方案

热门文章

  1. 《Nodejs开发加密货币》之十九:签名和多重签名
  2. Sonar问题(一)Multi-threading - Call to static DateFormat
  3. 微服务如何限制接口调用次数
  4. 云原生 - 2、Openstack架构
  5. SAP中如何合并会计凭证(Summarizing FI documents)
  6. 韩国:大连 IT产业国际合作的新舞台
  7. 字符串算法总结——KMP算法
  8. java泛型之自限定类型和参数协变
  9. DTL with变量
  10. 怎样规划自己的一生?