分类: 云计算

云计算

利用Docker构建开发环境

*近接触PAAS相关的知识,在研发过程中开始使用Docker搭建了自己完整的开发环境,感觉生活在PAAS时代的程序员真是幸福,本文会简要介绍下Docker是什么,如何利用Docker来搭建自己的开发环境(本文主要是面向Mac OS X),以及期间所遇到的一些坑和解决方案。(本文会要求你对PAAS、LXC、CGroup、AUFS有一定的了解基础,请自行Google )

大背景–虚拟化技术历史

计算机虚拟化技术由来已久,从硬件仿真到全虚拟化,再到准虚拟化和操作系统虚拟化,各种技术粉墨登场,种类繁多,说实在的有点眼花缭乱和复杂;但用户的核心诉求一直是比较简单的,降低信息技术(IT)的运营成本,提高资源利用率,提高安全性和可靠性等等;虽说用户的核心诉求比较简单,但每个时代的需求场景却是不同的。在大型机时代,虚拟化技术被用来支持多个用户能够同时使用大型机,在x86架构时代,随着企业服务的大规模部署,虚拟化技术主要是用来提高企业资源的利用率,而现如今,随着云计算时代的到来,人们对应用的安全性、隔离性越来越高,对于部署的标准化以及虚拟机的性能要求越来越高。现如今,一种叫Linux容器的虚拟化技术逐渐得到广泛的应用,它的优点有许多,本文不一一赘述,有太多的文章可以参考。

什么是Docker?

docker的英文本意是码头工人,也就是搬运工,这种搬运工搬运的是集装箱(Container),集装箱里面装的可不是商品货物,而是任意类型的App,Docker把App(叫Payload)装在Container内,通过Linux Container技术的包装将App变成一种标准化的、可移植的、自管理的组件,这种组件可以在你的latop上开发、调试、运行,*终非常方便和一致地运行在production环境下。

Docker的核心底层技术是LXC(Linux Container),Docker在其上面加了薄薄的一层,添加了许多有用的功能。这篇stackoverflow上的问题和答案很好地诠释了Docker和LXC的区别,能够让你更好的了解什么是Docker, 简单翻译下就是以下几点:

  • Docker提供了一种可移植的配置标准化机制,允许你一致性地在不同的机器上运行同一个Container;而LXC本身可能因为不同机器的不同配置而无法方便地移植运行;
  • Docker以App为中心,为应用的部署做了很多优化,而LXC的帮助脚本主要是聚焦于如何机器启动地更快和耗更少的内存;
  • Docker为App提供了一种自动化构建机制(Dockerfile),包括打包,基础设施依赖管理和安装等等;
  • Docker提供了一种类似git的Container版本化的机制,允许你对你创建过的容器进行版本管理,依靠这种机制,你还可以下载别人创建的Container,甚至像git那样进行合并;
  • Docker Container是可重用的,依赖于版本化机制,你很容易重用别人的Container(叫Image),作为基础版本进行扩展;
  • Docker Container是可共享的,有点类似github一样,Docker有自己的INDEX,你可以创建自己的Docker用户并上传和下载Docker Image;
  • Docker提供了很多的工具链,形成了一个生态系统;这些工具的目标是自动化、个性化和集成化,包括对PAAS平台的支持等;

那么Docker有什么用呢?对于运维来说,Docker提供了一种可移植的标准化部署过程,使得规模化、自动化、异构化的部署成为可能甚至是轻松简单的事情;而对于开发者来说,Docker提供了一种开发环境的管理方法,包括映像、构建、共享等功能,而后者是本文的主题。

Docker的安装和构成

Docker官方本身提供了非常具体的安装教程,这里不说具体的安装过程,请参考Docker安装(Mac系统),重要的是描述下原理和安装完成后的结构,好对Docker更好的了解。 由于LXC本身不支持Mac内核,因此需要跑一个VirtualBox虚拟机(TinyCoreLinux)来安装,幸好Docker社区提供了一个非常方便的工具boot2docker(其实就是一个VBoxManage的包装shell脚本),用于安装Mac下的整个Docker环境。具体的结构如下:

docker-install

如图所示,安装完成后,具体情况如下:

  • 在Mac的home目录~/.boot2docker下创建了虚拟机所需要的文件,其中boot2docker.iso是虚拟机映像,这是一个由CD-ROM引导的TinyCoreLinux系统;而boot2docker-vm.vmdk文件则是你的虚拟机磁盘,你所有的持久化数据都存放在这里,包括docker创建的lxc容器等文件。
  • 在Mac下,docker被分为客户端docker-client和服务端docker-daemon两部分,如果是在linux(比如ubuntu),实际上则是同一个可执行文件同时充当客户端和服务端。docker-daemon可以监听unix scoket,也可以在tcp socket(默认端口为4234),docker-client会通过一个叫DOCKER_HOST的环境变量读取服务地址和端口,因此你应该在你的bash_profile文件里面添加这么一行:

docker-daemon跑在虚拟机上,这个程序实际上就是接收docker-client发送过来的消息命令,创建、启动和销毁lxc容器,以及docker本身的版本管理、映像存储等等 运行你的*个docker容器 安装完成后,就差不多可以开始创建和运行docker容器了,在这之前,你首先得下载一个Image,什么是Image?我们先来了解docker的2个基础概念:Image和Container。

Container和Image 在Docker的世界里,Image是指一个只读的层(Layer),这里的层是AUFS里的概念,*直观的方式就是看一下docker官方给出的图:

docker-filesystems-multilayer

Docker使用了一种叫AUFS的文件系统,这种文件系统可以让你一层一层地叠加修改你的文件,*底下的文件系统是只读的,如果需要修改文件,AUFS会增加一个可写的层(Layer),这样有很多好处,例如不同的Container可以共享底层的只读文件系统(同一个Kernel),使得你可以跑N多个Container而不至于你的硬盘被挤爆了!这个只读的层就是Image!而如你所看到的,一个可写的层就是Container。

那Image和Container的区别是什么?很简单,他们的区别仅仅是一个是只读的层,一个是可写的层,你可以使用docker commit 命令,将你的Container变成一个Image,也就是提交你所运行的Container的修改内容,变成一个新的只读的Image,这非常类似于git commit命令,感觉真棒!

实际上这就是Docker对Container映像的版本管理基石,AUFS文件系统实在是太美妙了,更多细节可以参考DotCloud的这篇文章

运行和退出

在了解了Image和Container的概念后,我们可以开始下载一个Image,Docker的好处就是提供了一个类似github的Image仓库管理,你可以非常方便pull别人的Image下来运行,例如,我们可以下载一个ubuntu Image:

这里的13.10是一个Tag,类似于git的tag,这里的tag可以为你制定一个ubuntu的版本。下载完成后,执行docker images命令可以列出你已经下载或者自己构建的image:(请允许我使用可爱的马赛克 🙂 )

QQ20140322-1

你可以看到ubuntu:13.10的大小为178MB,以及它的IMAGE ID。 现在我们开始运行一个Container,命令很简单,例如我们想运行一个执行Shell终端的Container:

QQ20140322-2

如你看到的,你已经进入到一个Shell里面,可以执行你想执行的任何命令,就和在ubuntu里面一样,进去后默认是在根目录/下,可以看到经典的unix/linux目录结构,以及你所运行的bash版本等信息。你可以给你的Container定一个名字,通过–name选项,例如这里命名了shell,日后你就可以直接用这个名字引用Contanier。

退出一个Container也很简单,你直接exit就好了。 其他更多的命令这里不做赘述,因为官方的文档已经非常全面,这里只是给一个直观的初步印象。下面进入主题。

利用Docker搭建开发环境

我们先看看程序员在搭建开发环境时遇到的一些问题:

  • 软件安装麻烦,比如很多公司都使用redhat,一般开发人员又不给root,安装一个nginx或者是mysql都得自己下载编译安装 权限问题,没有root,一些软件无法运行,例如dnsmasq;
  • 没有root,无法修改hosts,无法netstat -nptl,无法tcpdump,无法iptable
  • 隔离性差,例如不同的开发人员如果在同一台主机环境下共享开发,虽然是用户隔离,但端口如果不规范可能会冲突;同一个Mysql如果权限管理不好很有可能误删别人的数据
  • 可移植性差,例如和生产环境不一致,开发人员之间也无法共享;更严重的情况是当有新人入职时,通常需要又折腾一遍开发环境,无法快速搭建

这些问题可以通过在本地搭建虚拟机来解决,但虚拟机是一个很笨重的解决方案,Docker是一个非常轻量级的方案,而且还拥有虚拟机没有的一些功能,例如标准化Image,Image共享等,更重要的是,利用Docker,你可以运行非常多的容器,在你的Mac下搭建一个分布式的开发环境根本不是什么大的问题,而且对内存、磁盘和cpu的消耗相比传统的虚拟机要低许多,这些都要归功于AUFS和LXC这两大神奇的技术。

构建基础Image

想要搭建一个节省磁盘空间和扩展性良好的开发环境,*重要的*步就是构建一个基础性的Image,比如你的主要开发语言是Ruby,那么你肯定需要一个已经安装好以下工具的基础Image:

  • ruby
  • bundler
  • gem

然后在此基础上,你可以扩展这个基础的Image(下面叫base)为不同的开发环境,例如rails,或者是nats。当然,你的这个base也可以从别人的Image扩展而来,还记得我们刚刚pull下来的ubuntu:13.10这个Image吗?你可以从这个Image扩展开始构建你的base,如何做呢?Docker提供了一种标准化的DSL方式,你只需要编写一个Dockerfile,运行docker build指令,就可以构建你自己的Image,这有点像Makefile和make命令一样,只是大家要构建的内容和构建语言不同。

Dockerfile的语法请参考Dockerfile Reference,这里给出上面提到的Ruby开发的base Dockerfile示例:

这里只用到了很简单的2个指令:FROM和RUN,FROM指定了我们要扩展的Image,RUN指定我们要运行的命令,这里是安装ruby,gem、bundler等软件。写好Dockerfile后,运行以下指令就可以创建你的base image了:

-t 选项是你要构建的base image的tag,就好比ubuntu:13.10一样 –rm 选项是告诉Docker在构建完成后删除临时的Container,Dockerfile的每一行指令都会创建一个临时的Container,一般你是不需要这些临时生成的Container的 如你所想,我们可以像运行ubuntu:13.10那样运行我们的base了:

这里我们使用dev:base这个Image运行了一个irb解释器(Ruby的交互式解释器)。 在构建完base之后,你可以依样画葫芦构建你的rails环境,很简单,只需要FROM dev:base,然后RUN安装你的rails组件就可以了,不再赘述。*终你可能构建的开发环境是这样的:

docker-dev

如上图所示,base和service都是从ubutnu:13.10继承而来,他们作为不同的基础开发环境,base是ruby开发环境(也许命名为dev:ruby更为合适?),而service是一些基础数据服务,例如mysql,memcache,我建议将这些第三方组件集中在一个Container中,因为他们的环境不经常修改,可以作为一种底层服务Container运行,除非你需要构建分布式的服务,例如memcache集群,那可以继续拆分。

指定Image入口

当你构建完你的base Image和其他应用的Image之后,你就可以启动这些Image了,还记得前面我们给出的运行命令吗?

这里我们运行了一个bash,这样你就可以在shell里面执行你所想要执行的任何命令了,但是我们有时候并不想每次都启动一个shell,接着再在shell里面启动我们的程序,比如一个mysql,而是想一启动一个容器,mysql服务就自动运行了,这很简单,Dockerfile提供了CMD和ENTRYPOINT这2个指令,允许你指定一个Image启动时的默认命令。CMD和ENTRYPOINT的区别是CMD的参数可以由docker run指令指定的参数覆盖,而ENTRYPOINT则不可以。例如我们想运行一个memcached服务,可以这么写Dockerfile:

或者可以这么写:

注意不要把memcached启动为后台进程,即加上-d选项,否则docker启动的container会马上stop掉,这点我也觉得比较意外。 接着我们build这个Image:

这样,当你build完你的Image后,你可以直接将该Image运行为一个容器,它会自动启动mysql服务:

注意使用-d (detach) 选项,这样这个container就会作为后台进程运行了,接着你可以使用docker ps命令查看是否有在运行。

磁盘映射

大部分时候你会需要把你host主机(宿主)上的目录映射到Container里面,这样你就非常方便地在host主机上编辑代码,然后直接就可以在Container里面运行它们,而不用手动copy到Container里面再重启Container。按理将host的目录映射到guest(指Container)上应该是一件很容易的事情,就好像VMWare那样,但可惜的是,由于Mac上的Docker多了一层虚拟机,因此多了一层周折,你必须先VM上的目录通过sshfs mount到host(指Mac)上,然后再将你的目录或文件copy到这个mount的目录,再将VM上的这个目录映射到Container里,听起来比较拗口,画个图会清晰很多。

docker-disk-map

如上图所示,VM里面的/mnt/sda1/dev/目录(你需要自己创建)通过sshfs命令mount到了host主机(Mac)的~/workspace/dev/目录 ,而VM里的/mnt/sda1/dev/目录又被映射到了Container的/src/目录下,这样你就可以在Container里面的/src/目录下访问你的host文件了。具体如何做呢?首先你需要安装sshfs命令,然后将VM的password写到一个文件中,例如~/.boot2docker/b2d-passwd,在用sshfs命令mount起VM的/mnt/sda1/dev目录:

接着你在run一个Container的时候需要通过-v选项来将/mnt/sda1/dev/映射到/src目录:

这样你就可以在你的Container的/src目录下看到你host里的文件了。 磁盘映射还有2个地方需要注意:

  • 你的文件实际上是存储在VM里面的,也就是说你需要将你的目录或者文件copy到VM里面,你sshfs之后,就是copy到~/workspace/dev目录下
  • 千万不要sshfs mount非/mnt/sda1下的目录,因为VM里面跑的是TinyCoreLinux,这个OS的rootfs是临时性的(放在内存的,实际上就是boot2docker.iso文件里面的一个rootfs),因此其根目录/下的东西(包括/home)根本不会持久化,只有/mnt/sda1这个目录下的才能持久化。如果你放在/home目录下,只要VM一重启,就会丢失的,/mnt/sda1则不会,实际上就是那个~/.boot2docker-vm.vmdk文件挂载到了/mnt/sda1目录下

端口映射

和磁盘映射一样,你有时候会需要将Container的端口映射到host主机上,同样蛋疼的是,由于多了一层VM,端口映射也显得比较麻烦。首先你需要设置VirtualBox的端口映射,然后再将Container的端口映射到你的VM里面:

docker-port-map

具体是这么做的,通过2条命令:

也就是说在docker run的时候通过-p选项指定要映射的端口到VM,而boot2docker ssh命令则是将VM的8000端口映射到了host(Mac)的8000端口,这样你就可以通过Mac的localhost:8000访问Container的8000端口了。 其实,有另一种解决方案就是你不用映射到host(Mac),而是直接登录到VM里面进行访问就好了,boot2docker ssh就可以登录到VM,这样就类似于你的host是ubuntu,但这种解决方案的问题是这个ubuntu太弱了(TinyCoreLinux),如果你在这个ubuntu里面开发代码,或者是运行浏览器,是非常蛋疼的事情,关键还是这个ubuntu是每次重启都会复原的!所以我建议还是做多一层映射好了。 *后,实际上在VM里面,你是可以直接访问所有的Container的端口的,因为VM到Container的网络都是桥接的。

其他的一些坑

在使用的过程中,还遇到一些不少的坑:

  1. /etc/hosts文件无法修改,这样你就不能自己做域名解析
  2. VM的系统时间是UTC +0000的,而且貌似无法修改
  3. Container的IP无法指定为静态IP,因此每次重启Container时,IP可能会变化

第1个问题的解决方案是通过安装dnsmasq软件来做域名解析:

第2个问题的解决方案就稍微麻烦些,起码我没有找到更好的解决方案,我是将boot2docker.iso文件重新制作一次来解决这个问题的:

第三个问题暂时无法解决(可能需要编辑底层的LXC配置文件)。

docker的限制以及后续的一些想法

docker其实还是有一些限制的:

  • 要求你的环境是Linux的,而且内核必须很新(>= 2.6.27 (29)),这其实是LXC本身的限制,和docker无关
  • docker的Container目前host是不能修改的,当然有解决方案(dnsmasq)
  • docker的Container也暂时无法指定静态IP

用docker作为开发环境甚至是生产环境其实还有很多地方值得尝试:

  • 在团队内部构建本地的仓库,标准化所有的开发环境,使得团队的新人可以快速上手
  • 在生产环境部署docker,这其实是PAAS的虚拟化和自动化的一种方式,利用LXC和Docker能够更便捷地实施PAAS
  • 尝试用docker做分布式集群模拟和测试,成本会更加低廉,更加容器维

关于自定义 redis session 的自动延期问题

一般情况下,用户 30 分钟没操作就会过期,那问题来了,我需要怎么自动延期呢?用户每次访问,我都到 redis 更新一下过期时间?这样的话对 redis 写操作会不会太频繁了点?
各位大佬认为什么方案比较好?
Redis 过期 延期 Session6 条回复 • 2021-06-18 10:18:09 +08:00
yeqizhang 1
yeqizhang 12 小时 17 分钟前 via Android
我觉得可以折中,不一定严格要求每次操作后半小时,你可以判断过期时间还剩下十几二十分钟的话再更新,超过 20 分钟就不更新,一般用户登陆后那几分钟操作才会比较频繁,然后实际*后操作时间到过期时间只有二十几分钟比半小时差几分钟,用户感知也不强。

话说回来,一般采用 session 方案的会有多大的用户量呢,redis 还怕这点写操作?
polyang 2
polyang 12 小时 3 分钟前
@yeqizhang 嗯,这个方案不错,我觉得可以考虑,比如设定有效时间超过 25 分钟就不更新,小于等于 25 分钟时重新更新回 30 分钟,只差 5 分钟感知也不强。
不过按照你说的,正常的用户量不是特别高的情况下,每次都更新过期时间也没什么,只不过我有点强迫症,觉得每次都更新的话有点……
vibbow 3
vibbow 10 小时 44 分钟前
那就在 redis 里把超时时间设为 1 个小时

然后应用层判断有没有半个小时,再和 1 楼的方案结合一下。
Oktfolio 4
Oktfolio 9 小时 38 分钟前
Spring Session 每次请求更新过期时间。
gaius 5
gaius 3 小时 20 分钟前
鉴权接口给 session 续期
ChoateYao 6
ChoateYao 2 小时 56 分钟前
你有多少用户?这么快担忧到 redis 性能不够用?你没有实际因为 session 频繁写导致性能不够的场景,一切都是凭空想象出来的,那么你的优化也是凭空想象的。

想咨询一下大家关于云计算特别是 iaas 这块的看法, 感觉正在逐渐消退

目前楼主在从事这个工作, 但是这几年感觉 iaas 这块儿正在逐渐失去热度, 取而代之的是 k8s 这种 paas, 不知道大家怎么看

尤其是让我感觉有点焦虑的就是,不知道 iaas 会不会逐渐被淘汰

说了这么多其实就是有点焦虑不知道 iaas 这碗饭还能吃几年, 希望行业内的老哥们能畅所欲言, 一起讨论一下

IaaS 不知道 焦虑 k8s9 条回复 • 2021-06-17 14:53:48 +08:00
janxin 1
janxin 1 天前 ❤️ 2
IaaS 市场格局在固定,新入场玩家的空间在被挤压

每个企业在发展过程中逃不过 PaaS 的落地,这套东西无法被公有服务完全替代
wellsc 2
wellsc 1 天前 ❤️ 1
paas 不是还得依赖 iaas,不过市场肯定是要被压缩的,打不过就加入呗,k8s 学起来
my3157 3
my3157 1 天前 ❤️ 1
k8s+分布式存储, 对于 iaas 来说是釜底抽薪
不过感觉公有云 iaas 受影响不大, k8s 不能很好的租户隔离对于公有云客户来说是天然的风险, 私有云就不好说了
www5070504 4
www5070504 1 天前
@wellsc 感谢回复 [笑哭] 现在的问题就是 没有 k8s 的经验 人家不让我加入, 但是不加入怎么能获得 k8s 的经验呢 难啊太苦逼了
libook 5
libook 1 天前 ❤️ 2
商业项目上通常会以多种角度综合评估是否使用一项技术,技术火不火反而是相对低优先级的因素。

有一些系统在不使用 k8s 的情况下性价比可能更高,比如非分布式计算或几乎不需要调度和更新的系统。

没必要焦虑旧的技术会不会被淘汰,但新技术肯定是要学的。
Rocketer 6
Rocketer 1 天前 via iPhone ❤️ 1
你是 iaas 的用户还是开发者(开发云计算平台的)?

如果是用户,那 AWS 目前一家独大,做 AWS 还是有市场的。而且由于迁移困难,iaas 必须走向垄断,否则大家都不好过。

如果是开发者,那真得准备点其他技能了,除非你是 AWS 的
onion83 7
onion83 1 天前 ❤️ 1
IaaS 更底层的投入门槛其实很高,网络、存储、计算,每块的研发投入都是巨大,涉及软件、硬件,技术含量也是很高。前期投入大,单一旦形成市场和规模效应,后期的边际成本会越来越高。

反观 k8s 我的理解只是 IaaS 的一个上层应用,利益冲突不大。如果项目不大,跑跑网页应用、做一点边缘计算,其实函数计算更省钱、更省心。
julyclyde 8
julyclyde 23 小时 6 分钟前 ❤️ 1
当年 IaaS 流行并不是因为 IaaS 好,而是因为当年的 PaaS 没办法做好
kitthsu 9
kitthsu 22 小时 17 分钟前 via iPhone ❤️ 1
从产品和市场看,k8s 的定位是作为 web service 的 OS 存在,也势必会越来越流行,用户不需要再直接面对 IaaS 产品。但是各大云供应商的套路并不是用托管 k8s 产品取代其他已有产品,而是把其他产品接入 k8s,再一并卖给用户,其中包括 IaaS 产品,那么 k8s 的流行对于其他产品也是好处更多。如果从技术角度看,那就没什么好讨论的了,基础架构不可能消亡。

利用服务器剩余的磁盘空间的小方法(大佬们别喷我

前言:随着服务器越来越多,我们在部署服务后可能服务器硬盘存在许多空间,现在我就教大家如何优秀地利用(榨干)服务器硬盘。

服务器这里我选用了腾讯云轻量应用服务器,现在有无忧计划哦!续费超便宜,大家可以试试!

先介绍一下本次所利用的开源项目

Minio

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

引用自官网介绍链接为 http://docs.minio.org.cn/docs/

minio 官网 现在我们来部署一下 minio (其实这东西可以集群啦但是没有必要,官方的集群方法太麻烦啦,也太耗费资源!

推荐使用 docker 部署的方法!

docker 部署

安装 docker (这里可以选择腾讯云轻量应用服务器 docker 镜像,已经默认安装了 docker 并且已经更换为腾讯云的源了)

1.宝塔版本

应用商店-docker 管理器

宝塔安装 docker 2.自行安装(若服务器基于 LXC,openvz 虚拟化无法安装 docker 哦,请看下一种安装方法!

推荐使用 daocloud 一键脚本安装

curl -sSL https://get.daocloud.io/docker | sh

docker 如果提示 curl command not found

请使用 apt-get install curl ( unbutu,debian

centos 使用 yum install curl -y

下面开始部署 minio

docker pull minio/minio (pull 镜像) docker run -p 9000:9000 minio/minio server /data. (可以部署其他端口修改前面的 9000 即可,后面这个命令是数据持久化储存的命令)

注意:防火墙开放 9000 端口!!!!

接下来就可以访问 server-ip:9000 来进入啦!

minio 界面 默认用户名密码为 minioadmin

手动拉取部署

wget https://dl.min.io/server/minio/release/linux-amd64/minio chmod +x minio ./minio server /data ( data 可以改为服务器任意目录) 配置守护(不然 ssh 断掉网页端也会断开!) nohup /opt/minio/minio server –address “${MINIO_HOST}:${MINIO_PORT}” /opt/minio-data > /opt/minio/minio.log 2>&1 & 部署完后我们进入 server-ip:9000

进入 minio

这里和云服务厂商一样点击➕号

1.创建自己的储存桶

2.创建好后点击上传可以上传自己的文件

3.点击可以获取临时访问链接

4.修改可见性使用公共可见

创建好后*关键的来啦!我们可以 s3fs 让另一个服务器挂载这一台服务器的 minio,也可以使用支持 s3 通用协议的储存!

sudo yum install epel-releasesudo

yum install s3fs-fuse (安装 s3fs centos )

ubuntu,debian

1

curl https://downloads.plex.tv/plex-keys/PlexSign.key | apt-key add -echo deb https://downloads.plex.tv/repo/deb public main | tee /etc/apt/sources.list.d/plexmediaserver.list

2.apt update && apt install -y plexmediaserver s3fs echo “你的访问 key:你的密钥” > /root/.passwd-s3fs && chmod 600 /root/.passwd-s3fs

3.挂载到本地磁盘

s3fs -o passwd_file=/root/.passwd-s3fs -o url=http://server-ip:9000 -o allow_other -o nonempty -o no_check_certificate -o use_path_request_style -o umask=000 pic /pic

现在使用

df -h 查看是否挂载成功

minio Docker 服务器 curl4 条回复 • 2021-06-18 12:04:59 +08:00
FreeEx 1
FreeEx 4 小时 47 分钟前 via iPhone
学习了
fkname 2
fkname 3 小时 31 分钟前
国内服务器带宽都很小,意义不大
aiz 3
aiz 3 小时 9 分钟前 via Android
@fkname 国内服务器下行网带宽都很大的,这个在利用 cos 还是有一定可行性的
u011631336 4
u011631336 1 小时 4 分钟前
对生产环境要有敬畏之心

前端如何获取当前用户名和其他用户信息 需要一个 单独的 api 吗

1
chaleaoch 3 小时 18 分钟前
登录成功之后会返回当前用户信息.

但是切到别的 component 或者关掉浏览器之后在打开. 前端如何处理呢?

session 是有效的,但是前端不知道当前用户是谁了.

local storage?
wotemelon 2
wotemelon 3 小时 16 分钟前 ❤️ 1
需要一个获取用户信息的接口。如果是 ssr 更好,直接写到 store
Vegetable 3
Vegetable 3 小时 11 分钟前 ❤️ 1
常见的系统设计中,一般是以下 3 个情况

– 登录返回信息
– 登录不返回+独立获取信息接口
– 登录返回+独立获取信息接口

前端通常会将用户的信息持久化到本地,方案如 cookie 或者 local storage,至少也是使用 redux 之类的工具在内存里留一份,避免需要的时候只能再次请求接口
keepeye 4
keepeye 3 小时 8 分钟前 ❤️ 1
GET /profile
keepeye 5
keepeye 3 小时 8 分钟前 ❤️ 1
一般是需要一个单独的接口的,登录返回的不靠谱,万一数据变了呢?
chenluo0429 6
chenluo0429 3 小时 4 分钟前 ❤️ 1
用户信息肯定需要提供查询接口的,如果用户信息是静态不变的情况下,可以合并给登录接口来返回,但是只要用户信息可变动,那就一定需要独立的查询接口。
chaleaoch 7
chaleaoch 3 小时 2 分钟前
@chenluo0429
@keepeye
@keepeye
@Vegetable
@wotemelon

谢谢大佬们的热心解答.
Rocketer 8
Rocketer 2 小时 44 分钟前 via iPhone
jwt 里直接读就好啊
liyang5945 9
liyang5945 2 小时 37 分钟前
前端存储 token 到 cookie 或 local storage 里,用这个 cookie 调一个接口获取用户信息,保存到 store 里,这样切到别的 component 或者关掉浏览器之后再打开也没问题了
leven87 10
leven87 2 小时 20 分钟前
以上大佬说的都对

samin 11
samin 2 小时 15 分钟前
JWT 了解一下
skypyb 12
skypyb 2 小时 5 分钟前
按照楼上几位的说法, 要是用户的权限在关闭浏览器时变动了。再次打开浏览器直接拿 localStore 里的信息就有问题了吧。

我还是倾向于每次打开都要去请求一下
lybcyd 13
lybcyd 1 小时 7 分钟前
我习惯用单独接口,每次打开页面请求一下。单独的接口合理一点,因为不一定能保证当前用户和登录时返回的信息一致。
IvanLi127 14
IvanLi127 41 分钟前 via Android
倾向于从接口拿 。除了是小玩具或者登录不登录区别的大的网页。毕竟这个接口还承担着踢用户下线的功能呐
walpurgis 15
walpurgis 17 分钟前 via Android
功能独立较好,方便复用,登录只返回 token

Oracle中复杂数据类型–集合

集合是用来处理多行单列的数据,记录是用来处理单行多列,变量处理单行单列数据,PL/SQL记录表处理多行多列数据
1.索引表
下标可以为负数,并且元素的个数没有限制,只能作为PL/SQL复合数据类型使用.
TYPE type_name IS TABLE OF element_type
[NOT NULL] INDEX BY key_type;
identifier type_name;

type_name用于指定用户自定义数据类型的名称(IS TABLE .. INDEX表示索引表),element_type用于指定索引表元素的数据类型.NOT NULL表示不能引用NULL元素.
key_type用于指定索引表下标的数据类型(BINARY_INTEGER, PLS_INTEGER, VARCHAR2),identifier定义索引表变量
DECLARE
TYPE ename_table_type IS TABLE OF emp.ename%TYPE
INDEX BY BINARY_INTEGER;
ename_table ename_table_type;
BEGIN
SELECT ename INTO ename_table(-1) FROM emp
WHERE empno=&no;
dbms_output.put_line(‘雇员名:’||ename_table(-1));
END;
其中ename_table(-1)表示下标是-1的元素.

DECLARE
TYPE ename_table_type IS TABLE OF NUMBER
INDEX BY VARCHAR2(10);
ename_table ename_table_type;
BEGIN
ename_table(‘北京’) := 1;
END;

2.嵌套表
元素下标从1开始,元素个数没有限制,值可以是稀疏的.可以作为表列的数据类型使用.
TYPE type_name IS TABLE OF element_type
identifier type_name;
type_name用于指定嵌套表的名字,element_type指定嵌套表元素的数据类型.在使用时,必须先使用构造方法先初始化构造表
(1)在PL/SQL块中使用嵌套表
DECLARE
TYPE ename_table_type IS TABLE OF emp.ename%TYPE;
ename_table ename_table_type
BEGIN
ename_table:=ename_table_type(‘MARY’,’MARY’,’MARY’);
SELECT enmae INTO ename_table(2) FROM emp
WHERE emp_no=&no;
dbms_output.put_line(‘雇员名:’||ename_table(2));
END;
(2)在表列中使用嵌套表
必须先使用CREATE TYPE命令来建立嵌套表类型,当使用嵌套表类型作为表列的数据类型时,必须为嵌套表指定专门的存储表
CREATE TYPE phone_type IS TABLE OF VARCHAR2(20);

CREATE TABLE employee(
id NUMBER(4), name VARCHAR2(10),sal NUMBER(6,2),
phone phone_type)NESTED TABLE phone STORE AS phone_type;

经过上面的定义后,就可以在建立employee的时间使用这个嵌套类型了.
BEGIN
INSERT INTO employee VALUES(1, ‘SCOTT’, 800, phone_type(‘123456′,’13245641234’));
END;

3.变长数组(VARRAY)
下标从1开始,元素的*大个数是有限制的.
TYPE type_name, IS VARRAY(size_limit) OF element_type[NOT NULL];
identifier type_name;
使用的时间必须要用构造方法进行初始化,例如:
DECLARE
TYPE ename_table_type IS VARRAY(20) OF emp.ename%TYPE;
ename_table ename_table_type:=ename_table_type(‘A’,’A’);
BEGIN
SELECT ename INTO ename_table(1) FROM emp
WHERE empno=&no;
dbms_output.put_line(‘雇员姓名:’||ename_table(1));
END;

VARRAY也可以作为列的数据类型使用,在表中引用此数据类型必须先create type
CREATE TYPE phone_type IS VARRAY(20) OF VARCHAR2(20);
CREATE TABLE employee(
id NUMBER(4),
name VARCHAR2(20),
sal NUMBER(6,2),
phone phone_type);

搜索引擎收录提交链接大全

谷歌网站收录提交http://www.google.com/intl/zh-CN/add_url.html

谷歌新闻源收录提交http://www.google.com/support/news_pub/bin/request.py?contact_type=suggest_content&hl=cn

谷歌博客收录提交http://blogsearch.google.com/ping?hl=zh-CN

谷歌网站管理员工具http://www.google.com.hk/intl/zh-CN/webmasters/点击这里查看详细操作步骤。

百度网站收录提交http://www.baidu.com/search/url_submit.html

百度博客收录提交http://utility.baidu.com/blogsearch/submit.php

百度站长平台http://sitemap.baidu.com/

百度搜索开放平台http://open.baidu.com/

微软bing网站收录提交http://cn.bing.com/docs/submit.aspx

微软bing站长工具http://cn.bing.com/toolbox/webmasters/

搜狗网站收录提交 http://www.sogou.com/feedback/urlfeedback.php

搜狗博客收录提交 http://www.sogou.com/feedback/blogfeedback.php

SOSO网站收录提交http://www.soso.com/help/usb/urlsubmit.shtml

SOSO博客收录提交 http://blog.soso.com/join.html

有道网站收录提交 http://tellbot.yodao.com/report?type=web

有道博客收录提交 http://tellbot.yodao.com/report?type=BLOG

雅虎中国网站收录提交 http://search.help.cn.yahoo.com/h4_4.html

Dmoz网站登录入口 http://www.dmoz.com/World/Chinese_Simplified

Alexa网站登录入口 http://www.alexa.com/help/webmasters

 

Tips:

如何知道自己的网站是否已经被搜索引擎收录?只要在搜索引擎中输入“site:yoursite”然后搜索(注:yoursite是网站域名,例如site:xxx.net是查询博客是否已经被收录),如果有搜索结果则证明已经成功收录了。

[poll id=”2″]

数据库PL/SQL快捷键设置

Oracle数据库中,PL/SQL设置快捷键的方法是本文我们主要要介绍的内容,了解了这些设置可以是我们更效率地使用Oracle数据库,接下来就让我们一起来了解一下这部分内容吧。

1、登录后默认自动选中My Objects

默认情况下,PLSQL Developer登录后,Brower里会选择All objects,如果你登录的用户是dba,要展开tables目录,正常情况都需要Wait几秒钟,而选择My Objects后响应速率则是以毫秒计算的。

设置方法:

Tools菜单 –> Brower Filters,会打开Brower Folders的定单窗口,把”My Objects”设为默认即可。

Tools菜单–Brower Folders,中把你经常点的几个目录(比如:Tables Views Seq Functions Procedures)移得靠上一点,并加上颜色区分,这样你的平均寻表时间会大大缩短,试试看。

 2、记住密码

这是个有争议的功能,因为记住密码会给带来数据安全的问题。 但假如是开发用的库,密码甚至可以和用户名相同,每次输入密码实在没什么意义,可以考虑让PLSQL Developer记住密码。

设置方法:菜单Tools –> Preferences –> Oracle –> Logon History –> Store With Password

3、双击即显示表数据

鼠标双击表或者视图时的默认响应实在让我感到失望,因为我*关心的是表结构和数据,但是双击后这两件事情都没有发生,也许默认响应是高手们需要的,但对我来说查看数据和表结构是*主要的,其他的我不关心。不过好的是这是可以设置的,你可以给鼠标双击和拖放绑定需要的事件,比如:双击编辑数据,拖放显示表结构,Yeah!

设置方法:菜单Tools –> Preferences –> Browser,在右侧,为不同的Object Type绑定双击和拖放操作。

4、SQL语句字符全部大写

自认为这是个好习惯,信息系统的核心是数据库,系统出问题时*先要查的就是SQL语句,怎样在浩瀚的日志中快速找到那条SQL语句是件比较痛苦的事情。 SQL语句全部大写并不能彻底解决这一问题,但在一堆代码中间找一行全部大写的字符相对容易些,你的眼睛会感谢你。

设置方法:菜单Tools –> Preferences –> Editor –> Keyword Case –> Uppercase

5、特殊Copy

在SQL Window里写好的SQL语句通常需要放到Java或者别的语言内,就需要转成字符串并上加上相应的连字符,这一个事不需要再重复做了,在写好的SQL上点右键,使用特殊Copy即OK!

设置方法:鼠标右键 –> Special Copy

6、自定义快捷键

PLSQL Developer里预留了很多键让用户自定义,这是件很Hight的事情。不像霸道的Word,基本上所有的键都已预定义了功能,修改起来很是头疼。 通常情况下,打开PLSQL Developer后,*经常干的事就是打开SQL Window和Command Window,就给这两个操作定义了快捷键,ALT+S和ALT+ C,这样拿鼠标点三下的事情只需要按一下键。

设置方法:菜单Tools –> Preferences –> Key Configuration

7、SQL Window中根据光标位置自动选择语句

设置方法:Preferences –> Window Types –> SQL Window,将AutoSelect statement选中即可。注意,每条语句后面要加分号。

8、自动替换

快捷输入SQL语句,例如输入s,按下空格,自动替换成SELECT;再例如,输入sf,按下空格,自动替换成SELECT * FROM,非常方便,节省了大量的时间去编写重复的SQL语句。

设置方法:菜单Tools –> Preferences –> Editor –> AutoReplace. –> Edit

关于Oracle数据库PL/SQL设置快捷键的方法就介绍到这里了,希望本次的介绍能够对您有所收获!

如何查看端口号是否被占用

在网络程序的调试过程中,经常发生一些出乎意料的事情,比如创建一个TCP服务失败,这时候往往需要查看系统的网络情况,*常用的网络抓包当然非WireShark模式。但往往很多时候只需要查看某个端口的使用情况,它到底被那个进程(对应PID)占用了,或者你还需要把它Kill掉。如果你在Windows操作系统,你可以使用netstat命令来查询PID,然后可以打开任务管理器,查看这个PID对应的进程名;如果PID没有显示,菜单》查看》选择列》选中PID即可;得知进程后,我们可以将进程杀掉。下面我简单描述一下我所了解的在Windows和Linux系统下处理方式。(假如我们需要确定谁占用了我们的9010端口)

1、Windows平台
在windows控制台窗口下执行:
netstat -nao | findstr “9010”
TCP 127.0.0.1:9010 0.0.0.0:0 LISTENING 3017

你看到是PID为3017的进程占用了9010端口,如果进一步你想知道它的进程名称,你可以使用如下命令:

tasklist | findstr “3017”

如果你想杀死这个进程,你当然可以用前面描述的那种方法,在任务管理器里把它KILL了,但如果你喜欢高效一点,那么用taskkill命令就可以了。

taskkill /pid 3017

那么这个进程就灰灰湮灭了:)

2、Linux

如果你是个Linux爱好者,那个这个命令你应该很熟了,

netstat -pan | grep 9010

如果你稍微仔细一点,你会发现,用的都是netsta命令,事实上,netstat是一个比较通用的网络统计命令,几乎适用于所有现在流行的操作系统,无论是Linux,Window,还是其他Unix,或者Unix-like操作系统,而且用法基本一致。

下面是一个对Windows系统中netstat命令行参数的详细解释。

格式:

netstat [-a] [-e] [-n] [-o] [-p Protocol] [-b] [-r] [-s] [-v] [Interval]

参数说明:

-a 显示所有连接和监听端口。
-n 以数字形式显示地址和端口号。

-o 显示与每个连接相关的所属进程 ID。

-p 在Windows系统中,该选项用于指定默认情况的子集。proto 显示 proto 指定的协议的连接;proto 可以是下列协议之一: TCP、UDP、TCPv6 或 UDPv6。

如果与 -s 选项一起使用以显示按协议统计信息,proto 可以是下列协议之一:
IP、IPv6、ICMP、ICMPv6、TCP、TCPv6、UDP 或 UDPv6。

-b 显示包含于创建每个连接或监听端口的可执行组件。在某些情况下已知可执行组件拥有多个独立组件,并且在这些情况下;包含于创建连接或监听端口的组件序列被显示。这种情况下,可执行组件名在底部的 [] 中,顶部是其调用的组件,等等,直到 TCP/IP 部分。注意此选项
可能需要很长时间,如果没有足够权限可能失败。

-e 显示以太网统计信息。此选项可以与 -s选项组合使用。

-s 显示按协议统计信息。默认地,显示 IP、IPv6、ICMP、ICMPv6、TCP、TCPv6、UDP 和 UDPv6 的统计信息。

-r 显示路由表。

-v 与 -b 选项一起使用时将显示包含于为所有可执行组件创建连接或监听端口的组件。

interval 重新显示选定统计信息,每次显示之间暂停时间间隔(以秒计)。按 CTRL+C 停止重新显示统计信息。如果省略,netstat 显示当前
配置信息(只显示一次)。

Oralce如何选择合适的索引类型

索引就好象一本字典的目录。凭借字典的目录,我们可以非常迅速的找到我们所需要的条目。数据库也是如此。凭借Oracle数据库的索引,相关语句可以迅速的定位记录的位置,而不必去定位整个表。

虽然说,在表中是否创建索引,不会影响到Oracle数据库的使用,也不会影响数据库语句的使用。这就好像即使字典没有目录的话,用户仍然可以使用它一样。可是,若字典没有目录,那么可想而知,用户要查某个条目的话,其不得不翻遍整本字典。数据库也是如此。若没有建立相关索引的话,则数据库在查询记录的时候,不得不去查询整个表。当表中的记录比较多的时候,其查询效率就会很低。所以,合适的索引,是提高数据库运行效率的一个很好的工具。

不过,并不是说表上的索引越多越好。过之而不及。故在数据库设计过程中,还是需要为表选择一些合适的索引。宁缺勿烂,这是建立索引时的一个具体选择。在理论上,虽然一个表可以设置无限的索引。但是,数据库管理员需要知道,表中的索引越多,维护索引所需要的开销也就越大。每当数据表中记录有增加、删除、更新变化的时候,数据库系统都需要对所有索引进行更新。故数据库表中的索引*对不是多多益善。具体来说,在索引建立上,笔者对大家有如下建议。

  建议一:在基数小的字段上要善于使用位图索引。

基数是位图索引中的一个基本的定义,它是指数据库表中某个字段内容中不重复的数值。如在员工信息表中的性别字段,一般就只有男跟女两个值,所以,其基数为2;婚姻状况字段的话,则其只有已婚、未婚、离婚三种状态,其基数就为3;民族一览内也是只有有限的几个值。

对于要查询基数小的字段,如现在用户想查找所有婚姻状况为“已婚”的“女性”时,利用位图索引可以提高查询的效率。这主要是因为标准索引是通过在索引中保存排序过的索引列以及对应的ROWID来实现的。若我们在基数小的列上建立标准索引的话,则其会返回大量的记录。

而当我们在创建位图索引的时候,在Oracle会对整个表进行扫描,并且会为索引列的每个取值建立一个位图。若内容相同,则在位图上会以一个相同的数字表示。此时,若这个字段的基数比较小的话,则若需要实现对整个字段的查询的话,效率就会非常的高。因为此时,数据库只要位图中数字相同的内容找出来即可。

除了在数据表某列基数比较小的情况下,采用位图索引外,我们往往在一些特殊的情况下,也会建议采用位图索引。*常见的情况是,在Where限制条件中,若我们多次采用AND或者OR条件时,也建议采用位图索引。因为当一个查询饮用了一些部署了位图索引的列的时候,这些位图可以很方便的与AND或者Or 运算符操作结合以快速的找出用户所需要的记录。

但是,这里要注意,不是在条件语句中包含运算符的时候,采用位图索引都能够提供比较高的效率。一般来说,只有AND 或者OR运算符的时候,位图索引才会比较具有优势。若此时用户采用大于号或者不等于号作为条件语句中的限制条件的时候,则往往采用标准索引具有更大的优势。

所以,笔者在数据库设置中,一般只有在三种情况下才采用位图索引。一是列的基数比较小,而有可能需要根据这些字段的内容查找相关的记录;二是在条件语句中,用到了AND或者OR运算符的时候。除了这两种情况外,*好能够采用其他适合的索引。第三种情况是,需要用到NULL作为查询的限制条件。因为标准查询一般情况下,会忽略所有的NULL值列。也就是说,若需要查询“所有没有身份证号码”的员工的信息的时候,标准索引并不能够起到加速查询速度的作用。此时,就需要采用位图索引。因为位图索引会记录相关的NULL值列信息。

  建议二:创建索引的一些限制条件。

并不说,表或者列建立的索引越多越好。相反,索引建的越多,有时会反而会影响数据库运行的整体性能。所以,在建立索引的时候,仍然会有一些限制条件。

一是不要对一些记录内容比较少的表建立索引。在一个应用系统设计的时候,如设计一个ERP系统的数据库,其虽然有几千张表。但是,并不是每张表都有大量记录的。相反,其中有近一半左右的数据表,可能其存储的数据不会超过百条。如员工登陆帐户密码表、企业部门信息表等等。对于这些记录内容比较少的表,我们建立*好不要为其建立索引。无论是表上的,还是字段上,都不要建立索引。

二是若表中的内容比较大,但是,这个表基本上不怎么查询的时候,则只需要在表上建立索引即可;而不需要在字段上建立索引。如现在在ERP系统中,有一张表是“AD_Table”。其存储的是这个数据库中相关表的信息。这张表只有在数据库设计的时候才会用到。故这张表中的记录虽然比较多,但是由于用户用的比较少,所以,一般没有必要为这张表建立列级别上的索引。而直接用表索引来代替。

三是在一些NULL字段上,要根据实际情况来判断是否要建立索引。如现在有一张人事档案的表格,其上面有两个字段,分别为“身份证号码”与“地区”。有时会为了某个原因,企业需要所有员工都在系统中登记他们的身份证号码,以方便他们办工资卡、社会保险等等。所以人事管理可能需要经常的查询系统,看看有没有没有身份证号码的员工信息。此时,就需要利用条件“IS NULL”来查询我们所需要的记录。故为了提高查询效率,若某个记录可能为空,并且经常需要以NULL为条件进行查询的时候,则*好给这个字段添加一个索引,并且*好建立位图索引。相反,若虽然可能会以NULL这个条件作为查询的限制语句,但是,用的不是很多的时候,则就没有必要为其建立索引。

  建议三:多表连接查询的索引设计。

如现在有一个人事管理系统。人事经理想知道员工的社保缴纳情况。他需要知道员工的姓名、职务、户籍性质(农民户口跟居民户口费用不一样)、缴纳的情况等等。但是,这些信息包含在不同的表中。因为为了提高数据库的性能,在表中存储的可能只是某些序号,而不是具体的内容。如在社保表中,存储的是员工对应的编号,而不是员工的名字。所以,要得到这份报表的话,就可能需要关联员工基本信息表、公司组织结构表等表格,才能够查询到用户所需要的内容。

为此,就需要利用Join语句,把这些表格关联起来。为了提高数据库的查询效率,这些用来关联的字段,*好能够建立索引。这可以显著的提高查询的速度。

  建议四:在表的更新速度与查询速度之间寻求一个平衡点。

众所周知,索引本身并不影响数据库的使用,其主要是为了提高数据库的查询效率。但是,由于当数据库的表中的数据更新的时候,包括记录的增加、删除、更改等等,都会对虽有的索引进行更新。

很明显,索引虽然可以提高查询速度。但是,也会对一些表的更新操作产生不良的影响。当在表中建立的索引越多,这个不利影响也会越大。故数据库管理员在设置索引的时候,还需要注意,在这两个之间需要一个均衡点。

按照一般的理论来说,当某个表多数用来查询、更新相对来说比较上的话,则要多多采用索引。相反,当某个表记录更新居主导,查询相对来说比较少的话,则不要建立太多的索引,避免对更新的速度差生不利影响。

在实际工作中,若某个表频繁的被视图所调用的话,则*好就好设置比较多的索引了。

友情链接: SITEMAP | 旋风加速器官网 | 旋风软件中心 | textarea | 黑洞加速器 | jiaohess | 老王加速器 | 烧饼哥加速器 | 小蓝鸟 | tiktok加速器 | 旋风加速度器 | 旋风加速 | quickq加速器 | 飞驰加速器 | 飞鸟加速器 | 狗急加速器 | hammer加速器 | trafficace | 原子加速器 | 葫芦加速器 | 麦旋风 | 油管加速器 | anycastly | INS加速器 | INS加速器免费版 | 免费vqn加速外网 | 旋风加速器 | 快橙加速器 | 啊哈加速器 | 迷雾通 | 优途加速器 | 海外播 | 坚果加速器 | 海外vqn加速 | 蘑菇加速器 | 毛豆加速器 | 接码平台 | 接码S | 西柚加速器 | 快柠檬加速器 | 黑洞加速 | falemon | 快橙加速器 | anycast加速器 | ibaidu | moneytreeblog | 坚果加速器 | 派币加速器 | 飞鸟加速器 | 毛豆APP | PIKPAK | 安卓vqn免费 | 一元机场加速器 | 一元机场 | 老王加速器 | 黑洞加速器 | 白石山 | 小牛加速器 | 黑洞加速 | 迷雾通官网 | 迷雾通 | 迷雾通加速器 | 十大免费加速神器 | 猎豹加速器 | 蚂蚁加速器 | 坚果加速器 | 黑洞加速 | 银河加速器 | 猎豹加速器 | 海鸥加速器 | 芒果加速器 | 小牛加速器 | 极光加速器 | 黑洞加速 | movabletype中文网 | 猎豹加速器官网 | 烧饼哥加速器官网 | 旋风加速器度器 | 哔咔漫画 | PicACG | 雷霆加速