实测有效方法:压缩你的镜像

方法:试着用命令或工具压缩你的镜像。

docker 自带的一些命令还能协助压缩镜像,比如 export 和 import

$ docker run -d redis:lab-3
$ docker export 71b1c0ad0a2b | docker import - redis:lab-4

但麻烦的是需要先将容器运行起来,而且这个过程中你会丢失镜像原有的一些信息,比如:导出端口,环境变量,默认指令。

 

20161027203227data-tag="bdshare" />

介绍

前段时间网易蜂巢曾经推出蜂巢 Logo T恤,用的正是 Docker 镜像制作,最神奇的是,它最终的镜像大小只有 585字节。

$ docker images | grep hub.c.163.com/public/logo

REPOSITORY                          TAG     IMAGE ID           CREATED      SIZE

hub.c.163.com/public/logo  latest  6fbdd13cd204  11 days ago  585 B

这其中就用到了不少精简镜像的技术,尤其是针对 C 程序的优化和精简。但我们平常开发肯定不止用 C 语言,甚至有些镜像都不是我们自己来打包的(比如下载公共镜像),那是否有一些通用的精简 Docker 镜像的手段呢? 答案是肯定的 ,甚至有的镜像可以精简 98%。精简镜像大小的好处不言而喻,既节省了存储空间,又能节省带宽,加快传输。那好,接下来就请跟随我来学习怎么一步步精简 Docker 镜像吧。

镜像层(Layers)

在开始制作镜像之前,首先了解下镜像的原理,而这其中最重要的概念就是镜像层(Layers)。镜像层依赖于一系列的底层技术,比如文件系统(filesystems)、写时复制(copy-on-write)、联合挂载(union mounts)等,幸运的是你可以在很多地方学习到这些技术,这里就不再赘述技术细节。

 

20161027203243data-tag="bdshare" />

 

总的来说,你最需要记住这点:

在 Dockerfile 中, 每一条指令都会创建一个镜像层,继而会增加整体镜像的大小。

举例来说:

FROM busybox

RUN mkdir /tmp/foo

RUN dd if=/dev/zero of=/tmp/foo/bar bs=1048576 count=100

RUN rm /tmp/foo/bar

以上 Dockerfile 干了这几件事:

  • 基于一个官方的基础镜像 busybox(只有1M多)
  • 创建一个文件夹(/tmp/foo)和一个文件(bar)
  • 为该文件分配了100M大小
  • 再把这个大文件删除

事实上,它最终什么也没做,我们把它构建成镜像看看(构建可以参考一期):

docker build -t busybox:test .

再让我们来对比下原生的 busybox 镜像大小和我们生成的镜像大小:

$ docker images | grep

busyboxbusybox    test     896c63dbdb96    2 seconds ago    106 MB

busybox    latest   2b8fd9751c4c    9 weeks ago      1.093 MB

出乎意料的是,却生成了 106 MB 的镜像。

多出了 100 M,这是为何?这点和 git 类似(都用到了Copy-On-Write技术),我用 git 做了如下两次提交(添加了又删除),请问 A_VERY_LARGE_FILE 还在 git 仓库中吗?

$ git add  A_VERY_LARGE_FILE

$ git commit

$ git rm  A_VERY_LARGE_FILE

$ git commit

答案是: 在的 ,并且会占用仓库的大小。Git 会保存每一次提交的文件版本,而 Dockerfile 中每一条指令都可能增加整体镜像的大小,即使它最终什么事情都没做。

精简步骤

了解了镜像层知识,有助于我们接下来制作精简镜像。这里开始,以最常用的开源缓存软件 Redis 为例,从一步步试验,来介绍如何制作更精简的 Docker 镜像

步骤 1:初始化构建 Redis 镜像

直接上 Dockerfile :

FROM ubuntu:trusty

ENV VER     3.0.0

ENV TARBALL http://download.redis.io/releases/redis-$VER.tar.gz

# ==> Install curl and helper tools...

RUN apt-get update

RUN apt-get install -y  curl make gcc

# ==> Download, compile, and install...

RUN curl -L $TARBALL | tar zxv

WORKDIR  redis-$VER

RUN make

RUN make install

#...

# ==> Clean up...

WORKDIR /

RUN apt-get remove -y --auto-remove curl make gcc

RUN apt-get clean

RUN rm -rf /var/lib/apt/lists/*  /redis-$VER

#...

CMD ["redis-server"]

结合注释,读起来并不困难,用到的都是常规的几个命令,简要介绍如下:

  • FROM:顶头写,指定一个基础镜像,此处基于 ubuntu:trusty
  • ENV:设置环境变量,这里设置了 VER 和 TARBALL 两个环境变量
  • RUN:最常用的 Dockerfile 指令,用于运行各种命令,这里调用了 8 次 RUN 指令
  • WORKDIR:指定工作目录,相当于指令 cd
  • CMD:指定镜像默认执行的命令,此处默认执行 redis-server 命令来启动 redis

执行构建:

$ docker build  -t redis:lab-1  .

注:国内网络,更新下载可能会较慢

查看大小:

 

20161027203303data-tag="bdshare" />

 

动辄就有 300多 M 的大小,不能忍,下面我们开始一步步优化。

步骤 2: 优化基础镜像

方法:选用更小的基础镜像。

常用的 Linux 系统镜像一般有 ubuntu、centos、debian,其中debian 更轻量,而且够用,对比如下:

REPOSITORY     TAG        IMAGE ID           VIRTUAL SIZE

---------------           ------          ------------                ------------

centos              7               214a4932132a     215.7 MB

centos              6               f6808a3e4d9e      202.6 MB

ubuntu              trusty       d0955f21bf24      188.3 MB

ubuntu              precise    9c5e4be642b7     131.9 MB

debian              jessie       65688f7c61c4      122.8 MB

debian              wheezy    1265e16d0c28      84.96 MB

替换 debian:jessie 作为我们的基础镜像。

优化 Dockerfile:

FROM debian:jessie

#...

执行构建:

$ docker build  -t redis:lab-2  .

查看大小:

 

20161027203254data-tag="bdshare" />

 

减少了42M,稍有成效,但并不明显。细心的同学应该发现,只有 122 MB 的 debian 基础镜像,构建后增加到了 305 MB,看来这里面肯定有优化的空间,如何优化就要用到我们开头说到的 Image Layer 知识了。

步骤 3:串联 Dockerfile 指令

方法: 串联你的 Dockerfile 指令(一般是 RUN 指令)。

Dockerfile 中的 RUN 指令通过 && 和 / 支持将命令串联在一起,有时能达到意想不到的精简效果。

优化 Dockerfile:

FROM debian:jessie

ENV VER     3.0.0

ENV TARBALL http://download.redis.io/releases/redis-$VER.tar.gz




RUN echo "==> Install curl and helper tools..."  && \     apt-get update                      && \   

  apt-get install -y  curl make gcc   && \  

  \   

  echo "==> Download, compile, and install..."  && \  

  curl -L $TARBALL | tar zxv  && \   

  cd redis-$VER               && \   

  make                        && \   

  make install                && \   

  ...   

  echo "==> Clean up..."  && \   

  apt-get remove -y --auto-remove curl make gcc  && \

  apt-get clean                                  && \   

  rm -rf /var/lib/apt/lists/*  /redis-$VER




#...

CMD ["redis-server"]

构建:

$ docker build  -t redis:lab-3  .

查看大小:

 

20161027203318data-tag="bdshare" />

 

哇!一下子减少了 50%,效果明显啊!这是最常用的一个精简手段了。

步骤 4:压缩你的镜像

方法:试着用命令或工具压缩你的镜像。

docker 自带的一些命令还能协助压缩镜像,比如 export 和 import

$ docker run -d redis:lab-3

$ docker export 71b1c0ad0a2b | docker import - redis:lab-4

但麻烦的是需要先将容器运行起来,而且这个过程中你会丢失镜像原有的一些信息,比如:导出端口,环境变量,默认指令。

所以一般通过命令行来精简镜像都是实验性的,那么这里再推荐一个小工具: docker-squash。用起来更简单方便,并且不会丢失原有镜像的自带信息。

下载安装:

https://github.com/jwilder/docker-squash#installation(复制此链接到浏览器打开)

压缩操作:

$ docker save redis:lab-3 \ 

  | sudo docker-squash -verbose -t redis:lab-4  \ 

  | docker load

注: 该工具在 Mac 下并不好使,请在 Linux 下使用

对比大小:

 

20161027203328data-tag="bdshare" />

 

好吧,从这里看起来并没有太大作用,所以我只能说试着,而不要报太大期望。

总结

本期我们介绍了镜像层的知识,并且通过实验,介绍三种如何精简镜像的技巧(下期还有更强大的技巧)。这里主要介绍了三种精简方法:选用更精小的镜像,串联 Dockerfile 运行指令,以及试着压缩你的镜像。通过这几个技巧,已经可以将 300M 大小的镜像压缩到 150M,压缩率50%,效果还是不错。但这还远远不够,下篇我们将介绍一些终极手段,压缩效果可以达到 98%哦!

转:http://www.senra.me/remove-proxmox-ve-dont-have-valid-subscription-notice/

一.问

最近把我的OVH独服重装了下,打算用Proxmox开点VM来用,省得一直吃灰(雾,安装很简单,毕竟是OVH提供的模板,但是,这玩意每次登陆都会有个蛋疼的提示(You do not have a valid subscription for this server. Please visit www.proxmox.com to get a list of available options.),而且找了半天没找到有关的地方,然后去官网看了下订阅的价格,呵呵呵,我还是自己想办法吧……

二.解

对于一个网页,要明白它到底发生了什么,那当然是直接F12怼一波,看了下控制台发现有个pvemanagerlib.js,看看名字就觉得很像是这玩意在搞事啊,右击在新页面打开,看看内容,首先根据之前的提示文字来搜索

data-data-originalset="http://cdn.senra.me/wp-content/uploads/2017/04/pve_warn_text.png 1589w, http://cdn.senra.me/wp-content/uploads/2017/04/pve_warn_text-768x100.png 768w" />

很好,找到目标,然后再次搜索noSubKeyHtml

一切顺利,找到了执行订阅检测的地方,现在简单了,直接改判断条件或者怼掉show操作都行,问题来了,这个文件在浏览器里又不能改,它到底在哪?

其实很简单,随便locate一下就找到了,我们先用cp备份一下,然后开始修改这个文件

然后注销重新登录,一切OK,世界清静

转:http://www.senra.me/add-internal-adapter-for-proxmox-to-secure-intranet-communication/

一.锲子

最近在配置hadoop过程中为了让各节点使用内网通信,研究了下怎么在proxmox下添加内网地址,一开始觉得挺容易,然后发现有点小坑,记录下。

二.Here We Go

首先需要在宿主机上添加个内网网卡,可以使用Proxmox添加,也可以直接改配置文件,效果一样,面板如下,vlan aware随意

编辑文件的话需要修改/etc/network/interfaces ,添加如下,同样vlan aware 随意

之后我们便为宿主机添加了一个内网网卡,地址为10.10.10.254

之后我们在创建的容器或是虚拟机上同样添加一个网卡,mac地址会自动生成,网关就写宿主机的,桥接写我们添加的那个网卡,然后就可以了

PS.需要注意的有一点,先加内网地址后加外网地址,否则默认路由会是内网,这个是个坑,我一开始没在意然后发现怎么也访问不了

转:http://www.senra.me/add-tun-tap-support-for-proxmox-ve-4-lxc-containers/

一.为什么

Proxmox VE 4将3代的OpenVZ支持去除换成了LXC,算是跟随趋势吧,但是LXC和OpenVZ还是有挺多不同的,在权限上更是如此,而网上最多的还是OVZ相关的教程,LXC的是真的少,不过一直以来没需求,所以没怎么折腾,最近在搞内网,所以为了用Tunnel还是得把TUN/TAP支持打开。

二.怎么办

首先当然是谷歌咯,关键词选得好马上出结果,proxmox官方论坛讨论贴 https://forum.proxmox.com/threads/tun-devices-in-ve-4-lxc.23473

总结一下

①.如果需要对所有(之后创建的)LXC容器全部开启tun/tap

那么需要修改/etc/lxc/default.conf,添加lxc.cgroup.devices.allow = c 10:200 rwm

当然,也可以创建/usr/share/lxc/config/common.conf.d/02-tuntap.conf 这样的配置文件来取得同样的效果

②.而如果只要对指定容器有效,则需要修改/etc/pve/lxc/[ID].conf , [ID]为你的容器编号

还没完,这样只是给了权限,实际上还没好,需要在容器的/etc/rc.local 自启动文件中添加如下

这样你执行需要tun/tap的程序时就不会出问题了

三.附录(记如何在v3版本的ovz下开启tun/tap)

a. 编辑vz.conf文件,添加iptable_nat ipt_state这2个东西

b. 手动关闭所有小鸡,重启openvz模块
/etc/init.d/vz restart

c. 对小鸡进行必要的设置(这里以小鸡100为例,100是指PID,WEB控制面板里可以看到)

d. 母鸡加载一次这些

e. 启动小鸡输入以下命令

Hbase hbck

[plain] view plaindata-mod="popu_168">data-mod="popu_168"> copy

data-mod="popu_167">在CODE上查看代码片data-mod="popu_170">派生到我的代码片

  1. 新版本的 hbck 可以修复各种错误,修复选项是:
  2. (1)-fix,向下兼容用,被-fixAssignments替代
  3. (2)-fixAssignments,用于修复region assignments错误
  4. (3)-fixMeta,用于修复meta表的问题,前提是HDFS上面的region info信息有并且正确。
  5. (4)-fixHdfsHoles,修复region holes(空洞,某个区间没有region)问题
  6. (5)-fixHdfsOrphans,修复Orphan region(hdfs上面没有.regioninfo的region)
  7. (6)-fixHdfsOverlaps,修复region overlaps(区间重叠)问题
  8. (7)-fixVersionFile,修复缺失hbase.version文件的问题
  9. (8)-maxMerge <n> (n默认是5),当region有重叠是,需要合并region,一次合并的region数最大不超过这个值。
  10. (9)-sidelineBigOverlaps ,当修复region overlaps问题时,允许跟其他region重叠次数最多的一些region不参与(修复后,可以把没有参与的数据通过bulk load加载到相应的region)
  11. (10)-maxOverlapsToSideline <n> (n默认是2),当修复region overlaps问题时,一组里最多允许多少个region不参与
  12. 由于选项较多,所以有两个简写的选项
  13. (11) -repair,相当于-fixAssignments -fixMeta -fixHdfsHoles -fixHdfsOrphans -fixHdfsOverlaps -fixVersionFile -sidelineBigOverlaps
  14. (12)-repairHoles,相当于-fixAssignments -fixMeta -fixHdfsHoles -fixHdfsOrphans
  15. 新版本的 hbck
  16. (1)缺失hbase.version文件
  17.  加上选项 -fixVersionFile 解决
  18. (2)如果一个region即不在META表中,又不在hdfs上面,但是在regionserver的online region集合中
  19.  加上选项 -fixAssignments 解决
  20. (3)如果一个region在META表中,并且在regionserver的online region集合中,但是在hdfs上面没有
  21.  加上选项 -fixAssignments -fixMeta 解决,( -fixAssignments告诉regionserver close region),( -fixMeta删除META表中region的记录)
  22. (4)如果一个region在META表中没有记录,没有被regionserver服务,但是在hdfs上面有
  23. 加上选项 -fixMeta -fixAssignments 解决,( -fixAssignments 用于assign region),( -fixMeta用于在META表中添加region的记录)
  24. (5)如果一个region在META表中没有记录,在hdfs上面有,被regionserver服务了
  25. 加上选项 -fixMeta 解决,在META表中添加这个region的记录,先undeploy region,后assign
  26. (6)如果一个region在META表中有记录,但是在hdfs上面没有,并且没有被regionserver服务
  27. 加上选项 -fixMeta 解决,删除META表中的记录
  28. (7)如果一个region在META表中有记录,在hdfs上面也有,table不是disabled的,但是这个region没有被服务
  29. 加上选项 -fixAssignments 解决,assign这个region
  30. (8)如果一个region在META表中有记录,在hdfs上面也有,table是disabled的,但是这个region被某个regionserver服务了
  31. 加上选项 -fixAssignments 解决,undeploy这个region
  32. (9)如果一个region在META表中有记录,在hdfs上面也有,table不是disabled的,但是这个region被多个regionserver服务了
  33. 加上选项 -fixAssignments 解决,通知所有regionserver close region,然后assign region
  34. (10)如果一个region在META表中,在hdfs上面也有,也应该被服务,但是META表中记录的regionserver和实际所在的regionserver不相符
  35. 加上选项 -fixAssignments 解决
  36. (11)region holes
  37. 需要加上 -fixHdfsHoles ,创建一个新的空region,填补空洞,但是不assign 这个 region,也不在META表中添加这个region的相关信息
  38. (12)region在hdfs上面没有.regioninfo文件
  39. -fixHdfsOrphans 解决
  40. (13)region overlaps
  41. 需要加上 -fixHdfsOverlaps
  42. 说明:
  43. (1)修复region holes时,-fixHdfsHoles 选项只是创建了一个新的空region,填补上了这个区间,还需要加上-fixAssignments -fixMeta 来解决问题,( -fixAssignments 用于assign region),( -fixMeta用于在META表中添加region的记录),所以有了组合拳 -repairHoles 修复region holes,相当于-fixAssignments -fixMeta -fixHdfsHoles -fixHdfsOrphans
  44. (2) -fixAssignments,用于修复region没有assign、不应该assign、assign了多次的问题
  45. (3)-fixMeta,如果hdfs上面没有,那么从META表中删除相应的记录,如果hdfs上面有,在META表中添加上相应的记录信息
  46. (4)-repair 打开所有的修复选项,相当于-fixAssignments -fixMeta -fixHdfsHoles -fixHdfsOrphans -fixHdfsOverlaps -fixVersionFile -sidelineBigOverlaps
  47. 新版本的hbck从(1)hdfs目录(2)META(3)RegionServer这三处获得region的Table和Region的相关信息,根据这些信息判断并repair

示例:

[plain] view plaindata-mod="popu_168">data-mod="popu_168"> copy

data-mod="popu_167">在CODE上查看代码片data-mod="popu_170">派生到我的代码片

  1. 查看hbasemeta情况
  2. hbase hbck
  3. 1.重新修复hbase meta表(根据hdfs上的regioninfo文件,生成meta表)
  4. hbase hbck -fixMeta
  5. 2.重新将hbase meta表分给regionserver(根据meta表,将meta表上的region分给regionservere)
  6. hbase hbck -fixAssignments

文章来源:科通社

在去年的央视315晚会上,工程师现场演示了如何通过公共WiFi获取用户手机上的隐私信息。而今年的315晚会上,现场观众连上一个免费WiFi后,只要打开消费类软件,订单和消费记录统统被一览无余!连续两年登陆我国最高打假平台,还能不能让人愉快地连接公共WiFi了?别急,其实只要养成好的习惯,远没有我们看到的那么夸张。

data-link="" />

免费“蹭网”,小心因小失大!

场景一:

央视“315”晚会上,上演了令人惊讶的一幕:现场观众的手机都连上无线网络,然后打开自己常用的一两个消费类软件,比如打车、订餐、购物的软件,浏览一下过去下的订单和消费记录。而现场的大屏幕上,各种地址、姓名、身份证号、银行卡号都显示了出来。

data-link="" />

在试验过程中,不仅搜集到了大家的各种信息。屏幕的左边显示了搜集到的姓名、电话号码、地址。现场随机抽取了观众验证了这些信息的准确性,结果无论是订餐APP、定电影票、打车软件,还是购物软件,你消费的所有信息都可以看到,截取了这些信息进行组合,一个人衣食住行的生活习惯甚至个人隐私,都可能被不法分子一点一点摸透。

解读:

据北京邮电大学网络技术研究院马严教授介绍,无论是家里的WiFi还是公共WiFi,都存在信息被截获的可能,但显然一些没有密码保护的公共WIFI更加危险。用手机在WiFi环境下收发信息,这个环境是开放的,就像在办公室里喊一声,周围和隔壁的人都能听到。黑客就是进入你这个开放的环境中,轻易截获下来重要的信息。

黑客的成本很低,甚至一台手机就能制作一个和你所在公共WiFi环境里相似度极高的WiFi,通常来说,黑客窃取信息的方式有两种,一种是假WiFi,克隆域名;另一种是直接监听。

比如饭店的WiFi名称是hotel123,而黑客制作一个hotell23,英文大写的i(I)和小写的L(l)一模一样,o和0也很相似,从名称上就容易选错。域名是可以克隆的,黑客克隆了假域名后,无线信号常常会不稳定,当信号不好的时候,信号波段就会自己“波”到信号强的一方去,就会挂到黑客的WiFi上去。另外,一般旅馆的WiFi或商家的WiFi都需要手机号码和注册验证码等等,而且一家饭店往往有几个WiFi,所以黑客WiFi会把信号做强、且稳定,并且不需要繁琐的验证信息,消费者的手机会自动连接上稳定的信号,很容易连上假WiFi。黑客可以自己编写这些程序,甚至还会有人去卖这些。

data-link="" />

防护措施:

不能选择来路不明的WiFi,尤其是免费、不需要密码的WiFi。免费的“蹭网”确实可以省下一些流量费用,但不需要验证、不需要密码的公共WiFi风险系数很高,背后有可能是钓鱼陷阱。一旦用户通过蹭网应用自动连接上了钓鱼WiFi,造成财产损失,那可就真是因小失大了。

手机很傻,不要自动连接WIFI

场景二:

小王曾经连过中移动的CMCC网络上网,一次他在地铁上发现,手机居然自动连上了“CMCC”的WiFi,但平常这列地铁上没有CMCC信号呀?而且还可以上网,他感觉很奇怪,马上把WiFi关掉,不过手机上装着的各类软件在后台都连过网了。回家登陆百度网盘一看,里边多了一份“Hacking by Helen”的txt文档。

data-link="" />

解读:

听起来很神奇对吧?原理可很简单呢。自带3G路由,做一个“CMCC”的无密码WiFi,在里边配置将所有流量都经过你的监控软件,接下来的事情就和前边一样了。这里利用了一个小漏洞,你的手机/电脑会自动连接以前连接过的所有WiFi,刚好CMCC又是无密码的,伪造特方便。

至于百度网盘,App主动联网同步,很多都是用cookies值和一些特定值做验证,拿到这些数据就可以在电脑上伪造成这个App ID登陆,其他应用也基本类似。

据360网络攻防实验室负责人林伟介绍,还有一种叫做诱捕连接。手机平时处于待机状态的时候,WiFi按钮是打开的,所以每到一个曾经连过的无线网地带都会自动再度连接上,手机信号就会像广播一样在信号区域寻找自己曾经认识的信号。此时,黑客就会捕捉到手机的“广播”,黑客所设定的程序就能自动伪造出一个手机正在寻找的,并且这个WiFi是以前连接过的WiFi。这时,所连接的WiFi就不是你所处环境中的WiFi,而是其他地点的WiFi,如果不打开网络设置查看,用户无法发现自己连上了这个不在这里的无线网。连上之后,手机的流量就会被黑客监听了,就可以进一步对手机发起攻击。而这个伪造的过程通过程序可以直接实现,不需要人工操作。

data-link="" />

防护措施:

手机会把使用过的WiFi热点都记录下来,如果WiFi开关处于打开状态,手机就会不断向周边进行搜寻,一旦遇到同名的热点就会自动进行连接,存在被钓鱼风险。所以我们要养成良好的WiFi使用习惯,尽量不要将WiFi设置成自动连接。手机很傻,我们只能自己麻烦一下了。

连接公共WIFI进行网络支付?no zuo no die啊

场景三:

为了调查公共WiFi到底有多不安全,《消费质量报》记者请专家做了一组现场验证。

在成都IFS 大食代餐厅,由于是饭点,坐满了人。云擎信息技术(深圳)有限公司技术专家张沛打开电脑,搭建WiFi热点。IFS提供的WiFi热点为:IFS,记者通过电脑连接上以后,专家告诉记者,其实连接的是他刚才建立的与IFS一样名称的WiFi。

当记者打开淘宝网页时,在键盘上的操作与黑客电脑是同步的。记者输入第一个字母时,黑客电脑就开始显示;当记者敲击删除键盘,“黑客”电脑上也马上显示记者敲击删除键盘,相当于完全同步操作。“黑客”的电脑上随后显示出记者刚刚录入的信息。

随后,有顾客已经连上了黑客提供的WiFi。“有人在看MSN”“有人输入QQ密码了”,张沛说到。记者在“黑客”电脑上看到,随时会出现这样的程序语言“qq.com”“weixin”“alipay”,张沛说,这是他们有人在上QQ,有人在用微信,还有人在使用支付宝。

data-link="" />

解读:

黑客的手段不止是在现场盗取信息那么简单,只要你连接上他的WiFi,他可以将你的操作内容存盘,之后再慢慢研究。

我们在打开淘宝网页时,很多时候都不需要输入用户名,直接输入密码就行,或者是用户名和密码都不用输入,直接登录。但是,这样也不能逃过黑客的“魔爪”,你的信息是被缓存在手机里,他能够通过缓存来盗取你的信息,或者是,设计一个程序,让你在登录时弹出“账号过期需重输用户名或密码”的信息,甚至是让你在登录时受阻,不得不手动再次输入账号和密码。

当然,黑客能看见的远不止此,他还能看见用户上传的朋友圈内容,包括上传的图片,文字等等,甚至是登录支付宝,微信的支付过程,支付密码轻而易举就能知道。

北京邮电大学网络技术研究院马严教授指出,即使不选择黑客的WiFi,黑客也可以轻易进入没经过处理的非加密网站中截获你的信息,再通过他们自己编写代码的软件分析出你的密码、身份证号、银行卡号等信息。如果他们盯上了你微信聊天的过程中传输的图片,这些也是可以被截获下来的,方法一样。例如打电话,信号会通过电话线传输到对方,网络也有传递途径,如果黑客在你的信息传递中间伪造中转站,就可以接听到你此时正在传输的信息。

data-link="" />

防护措施:

在不确定绝对安全的WiFi下,重要的操作比如网购时,最好关闭WiFi,通过数据网络进行,保障资金安全。现在运营商的各种数据套餐已经很便宜了,如果还不能实现全部行为使用数据网络,至少在重要行为如网购支付、理财、邮箱等操作时切换到数据网络。要切换为数据网络只要关闭WiFi,一般就会自动切换为数据网络了。安卓和苹果系统都可以从快捷下拉(上拉)菜单,或者设置界面里面关闭WiFi。(马严 北京邮电大学网络技术研究院教授;林伟 网络攻防实验室负责人;文/记者 白竞楠 图文编辑/刘昭 新

转:http://toutiao.com/a6265193054686707970/

树莓派,作为极客们的玩具,对大众而言还很陌生,它大小仅如一枚信用卡,虽说是一台迷你“电脑”,配置还不如主流的手机。但如果你有一颗好奇的心,它会迸发出无限可能。有人用它酿酒、有人把它做成游戏机。在移动互联飞速发展的时代,这一科技产品显然无法在大众人群中造成影响,然而它却让无数极客欢欣鼓舞,所谓一千个树莓派,就有一千个世界。

1. 数字时钟

用大号的晶体管和树莓派搭载一款颇具后现代风格的数字始终并不是什么苦难的事情,你还可以将它接入到网络中以便随时校正时间。当然,只需要几行代码,就可以在有线和无线的方式之中切换。

看看极客们怎么玩树莓派

2. 微型气象站

体积小、造价低、能耗少,用树莓派建立自己的气象站就不必依靠并不太靠谱的天气预报了。通过额外的传感器和硬件,组装起来并不算太难,在Dragon Tail上有更多的设置建议。

看看极客们怎么玩树莓派

3. 复古游戏机

老式怀旧游戏机很有市场,而利用树莓派作为游戏机运算中心,绝对有不一样的乐趣。最简单的办法就是在SD卡上安装一些模拟器软件,然后通过USB连接器插到书没派上,整个过程差不多一个小时就能结束。

看看极客们怎么玩树莓派

4. 游戏摇杆

来自伦敦的Jason Birch把树莓派打造成了一台小型游戏机,配合SD卡这台MAME游戏机可以在任何有显示器的场合发挥它的作用。而在控制手柄的选择这个问题上,我们可以在下图中形象的了解到Jason是怎样一次解决了树莓派的保护壳以及游戏手柄两个问题的。

看看极客们怎么玩树莓派

5. 飞行器

树莓派在各个方面的可拓展能力,可用来做为飞行器的飞控。Matthew Watson用树莓派打造的飞控除了控制他的四旋翼飞行器,同时他还用树莓派充当“黑匣子”,利用一张SD卡记录下每次飞行所涉及到的约200M大小的数据。

看看极客们怎么玩树莓派

6. 远程发送微博

气象爱好者把它绑在检测气球上,还用它在平流层发了一条微博。这绝对是个实在的工具,就是不知道用电问题怎么解决。

看看极客们怎么玩树莓派

7. 机器人管家

如果你有一个很久不用的任天堂Wiimote控制器,那么可以通过它来控制用树莓派组装的机器人,而这个机器人的外型则完全由你自己决定。另外,你还需要购买一个可以让机器人移动的底盘及电机,完整的指令可以到树莓派官网查看。

看看极客们怎么玩树莓派

8. 偷拍利器

利用树莓派并结合 3D 打印技术可以轻松打造一款“偷拍神器”,这个“偷拍神器”外表看上去是个毫无侵略性的(或者傻傻的)3D 打印领结,但实际上领结下方隐藏了小型摄像头。

看看极客们怎么玩树莓派

9. 电力控制

树莓派可以成为你家里强大的自动化控制终端,但最实用的应该是控制家用电器以及灯的打开关闭了。那就意味着小派应该能够安全的控制110V电力。
看看极客们怎么玩树莓派

data-groupid="6265193054686707970">

 

从我大二的时候,大概六年前开始写技术博客,到现在已经有540+了,大概每年会写一百篇左右。

这篇文章由四部分组成:

  1. 博客的流量来源
  2. 不同文章类型的写作要点
  3. 如何写博客
  4. 如何收集写作的灵感

流量来源

首先,我将技术博客分为下面几种类型:

  1. 技术细节型。频率: 每天几次,15~30分钟可以写完。
  2. 干货型。频率: 每月几次,1~2小时可以搞定。
  3. 实践总结型。频率: 每周1~2次,2+小时以上的时间。
  4. 杂谈与鸡汤型。频率: 每季度几次,少则几小时,动则上月。

接着,奉献上一章我的博客的用户来源图,分析完大概如下:

程序员怎样才能写出一篇好的博客或者技术文章

前三者可以带来很多的流量,后者可以带来大量的评论啦。

前三者可以让你在Google上有一个好位置~~,后者可以让你在用户心中有个好位置。

通过社交媒体可以让第四种类型的文章,有大量的评论和转载。

干货型和实践总结型的文章通过聚合网站来传播的效果最好。

在Google中有个好位置意味着——第一的位置会有50%以上的用户访问,这一点很重要哦~~。再放出神图:

程序员怎样才能写出一篇好的博客或者技术文章

首先作为一个专业的程序员,我们会用某个关键词去搜索,如“InsecurePlatformWarning: A true SSLContext object is not available.” :如果这时你的标题就是《Python 解决 InsecurePlatformWarning: A true SSLContext object is not available》,那么你就找到了你的用户了。

这是我之前用了5分钟不到的文章写的一篇文章,它在半年的时间里带来了6,599个访问量。它在Google的搜索结果中排第一:

程序员怎样才能写出一篇好的博客或者技术文章

虽然很不情愿地被排名第二的文章抄袭了——但是我还是第一,这该死的伪原创

而用户不会只访问你的一个页面的:

程序员怎样才能写出一篇好的博客或者技术文章

一般来说,前三种类型的用户获取到他们想要的信息就走了,不会留下评论。至于第四种类型,没有大V的光环,偶尔文章被转企业V转转也能多个几十个粉丝。所以我没有第四种类型的文章太多的经验哈。

不同文章类型的写作要点

接着, 让我们再看看上面的几种类型:

技术细节型

在我的博客里很大一部分文章都是这一类,主要是原自早先对SEO的研究。对于先这种没有光环的人来说,这是我博客的主要流量来源。这也是让我坚持下去的动力,每天有大概三百个用户来自搜索引擎。

这种类型主要来自于日常工作,但是好像写这一类的人不多。每天我们都会遇到不同的技术问题——如某个第三库更新,某个浏览器bug,如何使用某个技术。因此,我们就会用这样的关键字和词去搜索,反正大部分教程序员使用Google的文章就是这么写的。

既然你想要这样的搜索,那我就直接把搜索结果放前面好了,如:

如果你也擅长用Google的话,我想你就懂了奥秘。标题的前半部分是关键字,后半部分指名意图。

接着,就是贴解决方案和代码咯~~。在这时候需要注意几点:

  • 试着去表达一些技术上的细节,也会省去一些技术上的细节。
  • 以自己学习的角度去想怎样写可以一步步下来。
  • 加入一点点自己的情感,博客和文档是不一样的。
  • 编写更简洁的内容,因为技术博客与此文不同的是,技术博客是面向寻找信息的人。

干货型

一般来说,这种类型的文章更类似于GitHub上的那些Awesome类型的Repo。说说几个标题,大概可能就会有点感觉了:

  • 每个程序员必知之SEO
  • 作为一个前端工程师你了解你的小伙伴么 - chrome
  • App 上架相关事宜、解决技巧
  • 20 个非常有用的 Java 程序片段
  • Java 开发者不容错过的 12 种高效工具

通常来说,这一类型的文章都是作者一段时间对于某一个东西的总结,非常有收藏价值。故而,这种类型的文章会在GitHub或者聚合网站上比较受欢迎。所以,它也更容易传播。

但是写起来的难度比较大,这依赖于你的使用经验。所以,也不是一天、两天就能搞定的。

实践总结型

看看标题,可能大家都知道这一类文章要怎么写了:

这通常是一系列的文章,而这一系列的文章一般是连续写出来的。也因此,我们可以发现很大的书都是由这一类的文章衍生出来的。

这一类的文章更像是干货型和技术细节型的结合,面向特定领域的技术,也属于干货。对于这种类型的文章来说,更依赖于代码——读者需要依据代码一步步往下深入。

所以在这一类型的文章中代码往往比较重要。

杂谈与鸡汤型

来几一些标题:

  1. 为什么整个互联网行业都缺前端工程师?
  2. 程序员职业生涯中应该思考的10个问题
  3. 怎么减少编程中的 bug?
  4. 为什么大公司看起来都那么糟糕?

BlaBla,简单地来说这一类文章基本上是没有技术的,都是一些以理论为主的概括。同时,写这一类文章的时候,也意料着可能在某一领域有一定的水平——写出来才会有人看。而由于偏向理论,这一类文章看的人往往会更多,因为它并不倾向于使用领域特定的技术。

所以这种类型是受众很广的文章,并且也像鸡汤一样容易传播。同时,这种类型的文章,更依赖于社区媒体及聚合网站的传播。因为大部分情况下,用户不会这么去搜索文章的。

如何写博客

对于博客的内容来说,下面几点很重要哦:

  1. 标题、小标题。一个好的标题会带来更多的流量的。
  2. 内容。以代码为例的文章,最好有代码。代码可以放在GitHub上,一举两得。
  3. 图 —— 一图胜千言,如本文第一节中的框架图。,一个框架图可以省去你的很多话语。
  4. 排版,又可称为UI设计。基本的语法高亮要有,容易阅读也要有。最简单就是白底黑字。

下面有我之前在《招聘笔杆子——成为笔杆子》一文中说到的一些要点:

标题——必须重要,类名

对于写博文的人来说,重点的是如何清楚的去表达他们的想法,标题算是其中之一,这个也就是为什么标题党成为了标题党,而《设计模式》成为了经典。刚开始学编程的时候,更吸引你注意力的可能是《72小时学会Javascript》,而不是《Javascript 权威指南》,兴许让你买前者的原因是因为你能看懂前者,而后者不仅看不懂,而且价格更贵。只是一年以后,《72 小时学会Javascript》被你扔到了垃圾箱,而《Javascript 权威指南》却放在了原来放那本书的位置上。你定义的类难道仅仅应该是class class1么?

小标题——地图,method

小标题有点类似于sitemap.xml,只是他就是站点地图,一点就到了相应的地方。他应该直接了解的说这是开始菜单,标题栏,菜单栏,而不应该是简简单单的第一章,如果你真是那样写的话,你写的函数想必是

def fun1 end

如果你写的是getdata那么,我想你的函数名应该和你的文章一样,告诉人们,你要的是getdata。所以不要吝啬你鼠标的一下,它可以承受上百万字的点击。如果因为那样坏了,你可以告诉我,我可以帮你免费换一个欧姆龙的微动,前提是你的鼠标可以换。如果是HTML那么应该是h2 h3,markdown也就是用得比较多的github上的README.md的##或者是###

内容——函数体

这里可不是让你用一个让人难以理解的Magic Number,你写得越复杂,别人看的时间就越久,通俗易懂,就是一个很好的开始。你可以把一个个复杂的方法分解出来,或者提炼函数,或者重命名。当你相信你看不懂你的文章,正如你看不懂你写的hello,world我想你是时候去重构你的函数了。

复杂的部分,就用段落来解决,一个函数如同一个段落只应该表达一个思想,太长了就如同这篇文章一样没有多少人会认真去看。你需要给你写的一个精美的代码加一个注释,所以你也需要给你复杂的地方加上个(PS)。

在编写内容的时候需要注意下面的几点:

  • 代码。必要的时候贴出代码,会是一种快速有效的方法,工作的时候是为了完成某个任务。
  • 列表。列表可以简明扼要的说明你想要表达的内容。
  • 图表。一张流程图可以说明程序的步骤,一个表格可以作好一个对比。
  • 标题。标题的好处,可以让用户快速定位,让用户找到想要的内容。
  • 链接。一个好的URL对于使用英文的人来说,可以利于SEO,对于中文,使用的人可以判断出文章的专业与否。

引言——README

我想都会去看的,无论是在破解软件的时候,还是github上面的项目。简单的说说,这篇文章是干什么的,这个程序是干什么的。大家都会,不是么?

没有什么好写的?说说你是怎么开始编程吧,然后写在你的博客上,你会发现你会爱不释手的。

如何收集写作的灵感

下面是我最近在做的,感觉很不错,推荐一下咯:

一般是先有个论点,然后再论据,最后才写。

第一步,在平时把想到的一些能写的文章用TODO的形式列出来,如我用的是“奇妙清单”。下面就是我最近想写的一些文章的一些标题:

程序员怎样才能写出一篇好的博客或者技术文章

但是有一些还没灵感,只是想到了个大概——所以有的是只是一个标题。这些文章大部分都属于杂谈型的,想到什么就说点什么,但是会有个核心。

第二步,在平时偶然会有点灵感的时候,就用Google Keep创建一个新的记事,稍微写几句,提醒一下自己咯。在这一步,相当于就是找一些论据来支撑自己的观点,等到这些观点差不多的时候就可以写了。

程序员怎样才能写出一篇好的博客或者技术文章

第三步,便是写。写的时候其实没有啥感觉,就如同我之前在《编程同写作,写代码只是在码字》一文中所说的。不得不再说说这个标题,一看就知道要写什么了~~。

真正的想法都在脑子里,而不在纸上,或者IDE里。

所以,其实写代码的时间很短,真实长的是想出怎么写,文章也是如此。

其他

转载保留来源微信公众号:Phodal

如果你也想着怎么写好文章,不烦多看看我的文章吧,哈哈~~

转自:http://blog.csdn.net/mapboo/article/details/49536297

CSDN博主Mapboo原创,感谢博主!

==============================

前言:

纵观国内的广告平台,比如多盟,万普,百度,腾讯,或者别的一些广告平台,真是应接不暇,但是具体接入那就自己判断了,经过一番折腾,最终还是选择了谷歌平台,理应是稳定,可靠,安全,收入颇高,但是登录网络有点问题,应该大家都懂吧,这里就不再赘述了,各自想办法吧;

准备工作:

1,首先你是Android开发者,或者至少会点Java编程基础;

2,熟悉使用Android Studio(以下简称:AS),即官方Android应用开发工具;

3,注册了http://www.google.cn/admob/ 应用,并且有个banner_ad_unit_id吧;

4,待加入横幅广告条的app;

5,可参考官方接入指南:https://developers.google.com/mobile-ads-sdk/docs/admob/android/quick-start

开发过程:

1,创建或打开AS 工程,本示例是新建工程;

2,打开Android SDK Manager安装Google Repository;

3,关联我们的广告SDK,这里有两种方式:

A  点击Project Structure 直接选取,如下图:

com.google.android.gms:play-services:7.8.0;

B 打开build-gradle 加入一行代码,如下图:

compile 'com.google.android.gms:play-services:6.+'

4,程序会开始自动编译,然后打开AndroidManifest.xml 文件,添加如下代码:

[java] view plaindata-mod="popu_168">data-mod="popu_168"> copy

data-mod="popu_169"> print?

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3.     package="com.mapboo.adviewdemo" >
  4.    <span style="color:#ff0000;"> <uses-permission android:name="android.permission.INTERNET" />
  5.     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/></span>
  6.     <application
  7.         android:allowBackup="true"
  8.         android:icon="@mipmap/ic_launcher"
  9.         android:label="@string/app_name"
  10.         android:theme="@style/AppTheme" >
  11.        <span style="color:#ff0000;"> <meta-data android:name="com.google.android.gms.version"
  12.             android:value="@integer/google_play_services_version" /></span>
  13.         <activity
  14.             android:name=".MainActivity"
  15.             android:label="@string/app_name" >
  16.             <intent-filter>
  17.                 <action android:name="android.intent.action.MAIN" />
  18.                 <category android:name="android.intent.category.LAUNCHER" />
  19.             </intent-filter>
  20.         </activity>
  21.        <span style="color:#ff0000;"> <activity
  22.             android:name="com.google.android.gms.ads.AdActivity"
  23.             android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
  24.             android:theme="@android:style/Theme.Translucent" /></span>
  25.     </application>
  26. </manifest>

 

5,打开activity_main.xml 文件,输入如下代码:

[java] view plaindata-mod="popu_168">data-mod="popu_168"> copy

data-mod="popu_169"> print?

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2.     xmlns:tools="http://schemas.android.com/tools"
  3.     xmlns:ads="http://schemas.android.com/apk/res-auto"
  4.     android:layout_width="match_parent"
  5.     android:layout_height="match_parent"
  6.     android:paddingBottom="@dimen/activity_vertical_margin"
  7.     android:paddingLeft="@dimen/activity_horizontal_margin"
  8.     android:paddingRight="@dimen/activity_horizontal_margin"
  9.     android:paddingTop="@dimen/activity_vertical_margin"
  10.     tools:context=".MainActivity"
  11.     android:gravity="center_vertical">
  12.     <TextView
  13.         android:layout_width="match_parent"
  14.         android:layout_height="wrap_content"
  15.         android:text="@string/demoName"
  16.         android:gravity="center"
  17.         android:textSize="30dp"
  18.         android:layout_marginTop="150dp"
  19.         />
  20.     <com.google.android.gms.ads.AdView
  21.         android:id="@+id/adView_bottom"
  22.         android:layout_width="match_parent"
  23.         android:layout_height="wrap_content"
  24.         android:layout_alignParentBottom="true"
  25.         android:layout_centerHorizontal="true"
  26.         android:layout_gravity="bottom"
  27.         ads:adSize="BANNER"
  28.         ads:adUnitId="@string/banner_ad_unit_id" />
  29. </RelativeLayout>

 

[java] view plaindata-mod="popu_168">data-mod="popu_168"> copy

data-mod="popu_169"> print?

  1. <resources>
  2.     <string name="app_name">AdViewDemo</string>
  3.     <string name="demoName">谷歌Admob广告条示例</string>
  4.     <string name="banner_ad_unit_id">ca-app-pub-8514769117499822/6386262194</string>
  5. </resources>

 

6,打开MainActivity文件,输入如下代码:

[java] view plaindata-mod="popu_168">data-mod="popu_168"> copy

data-mod="popu_169"> print?

  1. package com.mapboo.adviewdemo;
  2. import android.support.v7.app.ActionBarActivity;
  3. import android.os.Bundle;
  4. import android.util.Log;
  5. import android.view.Menu;
  6. import android.view.MenuItem;
  7. import com.google.android.gms.ads.AdListener;
  8. import com.google.android.gms.ads.AdRequest;
  9. import com.google.android.gms.ads.AdView;
  10. public class MainActivity extends ActionBarActivity {
  11.     @Override
  12.     protected void onCreate(Bundle savedInstanceState) {
  13.         super.onCreate(savedInstanceState);
  14.         setContentView(R.layout.activity_main);
  15.         /**
  16.          * 创建广告条对象
  17.          */
  18.         AdView mAdView = (AdView) findViewById(R.id.adView_bottom);
  19.         AdRequest adRequest = new AdRequest.Builder().build();
  20.         /**
  21.          * 创建一个监听,比如判断用户是不是已经点击了广告条,以此来给用户增加积分等操作;
  22.          */
  23.         AdListener listener = new AdListener() {
  24.             @Override
  25.             public void onAdClosed() {
  26.                 super.onAdClosed();
  27.                 Log.i("TAG""onAdClosed");
  28.             }
  29.             @Override
  30.             public void onAdFailedToLoad(int errorCode) {
  31.                 super.onAdFailedToLoad(errorCode);
  32.                 Log.i("TAG""onAdFailedToLoad");
  33.             }
  34.             @Override
  35.             public void onAdLeftApplication() {
  36.                 super.onAdLeftApplication();
  37.                 Log.i("TAG""onAdLeftApplication");
  38.             }
  39.             @Override
  40.             public void onAdLoaded() {
  41.                 super.onAdLoaded();
  42.                 Log.i("TAG""onAdLoaded");
  43.             }
  44.             @Override
  45.             public void onAdOpened() {
  46.                 super.onAdOpened();
  47.                 Log.i("TAG""onAdOpened");
  48.             }
  49.         };
  50.         /**
  51.          * 设置监听
  52.          */
  53.         mAdView.setAdListener(listener);
  54.         /**
  55.          * 开始载入广告条
  56.          */
  57.         mAdView.loadAd(adRequest);
  58.     }
  59.     /**
  60.      *
  61.      官方示例:https://developers.google.com/mobile-ads-sdk/docs/admob/android/quick-start
  62.      
  63.      分享:安卓发布平台 http://blog.csdn.net/mapboo/article/details/49531043
  64.      应用汇:http://www.appchina.com/
  65.      安智市场:http://www.anzhi.com/
  66.      华为市场:http://appstore.huawei.com/
  67.      百度市场:http://app.baidu.com/pass/center
  68.      蒲公英:http://www.pgyer.com
  69.      N多网 :http://www.nduoa.com/developer
  70.      豌豆荚:http://developer.wandoujia.com/
  71.      360:http://dev.360.cn
  72.      QQ:http://op.open.qq.com
  73.      FIR:http://fir.im
  74.      Android中国开发者 交流QQ群:361871827 欢迎加入一起讨论技术...
  75.      */
  76. }

 

编译运行:

运行代码,就会出现Admob广告条,只要替换自己的banner_ad_unit_id就能开始赚钱了;

效果图:

本实例源代码下载地址:http://pan.baidu.com/s/1pJ3UEcr

Android中国开发者 QQ群:361871827 欢迎一起讨论技术..

原文:http://ask.android-studio.org/?/article/21

 

本篇教程中使用到的Android Studio版本为1.0, Eclipse ADT版本23.0.4。请尝试更新到该版本。

Android Studio默认使用 Gradle 构建项目, Eclipse 默认使用Ant构建项目。建议Android Studio导入项目时,使用Gradle 构建项目。

导入 Eclipse 项目

本例中,使用到的 Eclipse 项目结构如图:

data-fancybox-group="thumb">

e-demo 为主项目, appcompat_v7 为 library 项目。

导入 Generate Gradle build files 项目

Google官方建议是通过本方法进行Android Studio导入 Eclipse 项目。

这种方式有一个好处就是兼容 Eclipse 的文件目录结构,通过版本控制中的文件过滤,可以在一个项目组中,同时使用 Eclipse 和Android Studio。

讲解1

File --> Export

data-fancybox-group="thumb">

讲解2

选择导出类型。选择 Android --> Generate Gradle build files 。

data-fancybox-group="thumb">

点击 Next 。

讲解3

很长一段英语(完全看不懂是什么意思)。

data-fancybox-group="thumb">

点击 Next 。

讲解4

选择要导出的项目。

data-fancybox-group="thumb">

因为我的 e-demo 项目依赖了 appcompat_v7 项目,所以我将 e-demo 和 appcompat_v7 都选择了导出。

点击 Next 。

讲解5

最终确认要导出的项目。

data-fancybox-group="thumb">

Force overriding of existing files 表示覆盖导出文件。使用 Generate Gradle build files 的方式导出项目,会在项目目录中生成一些文件。这里的覆盖文件指的就是覆盖这些可能已经生成过的文件。如果你之前有使用这种方式导出过项目,建议勾选。

点击 Finish 。

讲解6

这一步没有什么好说的,直接点击 Finish 。

data-fancybox-group="thumb">

讲解7