Skip to content Skip to main navigation Skip to footer

Linux

Linux:Linux下如何过滤、分割以及合并 pcap 文件

如果你是一个测试入侵侦测系统或一些网络访问控制策略的网络管理员,那么你经常需要抓取数据包并在离线状态下分析这些文件。当需要保存捕获的数据包时,我们一般会存储为 libpcap 的数据包格式 pcap,这是一种被许多开源的嗅探工具以及捕包程序广泛使用的格式。如果 pcap 文件被用于入侵测试或离线分析的话,那么在将他们注入网络之前通常要先对 pcap 文件进行一些操作。

Linux:Linux下如何过滤、分割以及合并 pcap 文件
Linux:Linux下如何过滤、分割以及合并 pcap 文件

在这篇文章中,我将介绍一些操作 pcap 文件的工具,以及如何使用它们 。

Editcap 与 Mergecap

Wireshark,是最受欢迎的 GUI 嗅探工具,实际上它带了一套非常有用的命令行工具集。其中包括 editcap 与 mergecap。editcap 是一个万能的 pcap 编辑器,它可以过滤并且能以多种方式来分割 pcap 文件。mergecap 可以将多个 pcap 文件合并为一个。 这篇文章就是基于这些 Wireshark 命令行工具的。

如果你已经安装过 Wireshark 了,那么这些工具已经在你的系统中了。如果还没装的话,那么我们接下来就安装 Wireshark 命令行工具。 需要注意的是,在基于 Debian 的发行版上我们可以不用安装 Wireshark GUI 而仅安装命令行工具,但是在 Red Hat 及 基于它的发行版中则需要安装整个 Wireshark 包。

Debian, Ubuntu 或 Linux Mint

$ sudo apt-get install wireshark-common

Fedora, CentOS 或 RHEL

$ sudo yum install wireshark

当安装好工具后, 就可以开始使用 editca 与 mergecap 了。

pcap 文件过滤

通过 editcap, 我们能以很多不同的规则来过滤 pcap 文件中的内容,并且将过滤结果保存到新文件中。

首先,以“起止时间”来过滤 pcap 文件。 ” – A < start-time > 和 ” – B < end-time > 选项可以过滤出在这个时间段到达的数据包(如,从 2:30 ~ 2:35)。时间的格式为 “ YYYY-MM-DD HH:MM:SS”。

$ editcap -A '2014-12-10 10:11:01' -B '2014-12-10 10:21:01' input.pcap output.pcap

也可以从某个文件中提取指定的 N 个包。下面的命令行从 input.pcap 文件中提取100个包(从 401 到 500)并将它们保存到 output.pcap 中:

$ editcap input.pcap output.pcap 401-500

使用 “-D < dup-window >” (dup-window可以看成是对比的窗口大小,仅与此范围内的包进行对比)选项可以提取出重复包。每个包都依次与它之前的 < dup-window > -1 个包对比长度与MD5值,如果有匹配的则丢弃。

$ editcap -D 10 input.pcap output.pcap

遍历了 37568 个包, 在 10 窗口内重复的包仅有一个,并丢弃。

也可以将 < dup-window > 定义成时间间隔。使用”-w < dup-time-window >“选项,对比< dup-time-window > 时间内到达的包。

$ editcap -w 0.5 input.pcap output.pcap

检索了 50000 个包, 以0.5s作为重复窗口,未找到重复包。

分割 pcap 文件

当需要将一个大的 pcap 文件分割成多个小文件时,editcap 也能起很大的作用。

将一个 pcap 文件分割成数据包数目相同的多个文件

$ editcap -c   

输出的每个文件有相同的包数量,以 < output-prefix >-NNNN的形式命名。

以时间间隔分割 pcap 文件

$ editcap -i   

合并 pcap 文件

如果想要将多个文件合并成一个,用 mergecap 就很方便。

当合并多个文件时,mergecap 默认将内部的数据包以时间先后来排序。

$ mergecap -w output.pcap input.pcap input2.pcap [input3.pcap . . .]

如果要忽略时间戳,仅仅想以命令行中的顺序来合并文件,那么使用 -a 选项即可。

例如,下列命令会将 input.pcap 文件的内容写入到 output.pcap, 并且将 input2.pcap 的内容追加在后面。

$ mergecap -a -w output.pcap input.pcap input2.pcap

总结

在这篇指导中,我演示了多个 editcap、 mergecap 操作 pcap 文件的例子。除此之外,还有其它的相关工具,如 reordercap用于将数据包重新排序,text2pcap 用于将 pcap 文件转换为文本格式, pcap-diff用于比较 pcap 文件的异同,等等。当进行网络入侵测试及解决网络问题时,这些工具与包注入工具非常实用,所以最好了解他们。

你是否使用过 pcap 工具? 如果用过的话,你用它来做过什么呢?


via: http://xmodulo.com/filter-split-merge-pcap-linux.html

作者:Dan Nanni 译者:SPccman 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

来源:https://linux.cn/article-4762-1.html

Linux:如何使用Aptik来备份和恢复Ubuntu中的Apps和PPAs

00_lead_image_aptik

当你想重装Ubuntu或者仅仅是想安装它的一个新版本的时候,如果有个便捷的方法来重新安装之前的应用并且重置其设置会很方便的。此时 Aptik 粉墨登场,它可以帮助你轻松实现。

Aptik(自动包备份和恢复)是一个可以用在Ubuntu,Linux Mint 和其他基于Debian以及Ubuntu的Linux发行版上的应用,它允许你将已经安装过的包括软件库、下载包、安装的应用和主题、用户设置在内的PPAs(个人软件包存档)备份到外部的U盘、网络存储或者类似于Dropbox的云服务上。

注意:当我们在此文章中说到输入某些东西的时候,如果被输入的内容被引号包裹,请不要将引号一起输入进去,除非我们有特殊说明。

想要安装Aptik,需要先添加其PPA。使用Ctrl + Alt + T快捷键打开一个新的终端窗口。输入以下文字,并按回车执行。

sudo apt-add-repository –y ppa:teejee2008/ppa

当提示输入密码的时候,输入你的密码然后按回车。

01_command_to_add_repository

在命令行提示符输入下边的命令,来确保资源库已经是最新版本。

sudo apt-get update

02_update_command

更新完毕后,你就完成了安装Aptik的准备工作。接下来输入以下命令并按回车:

sudo apt-get install aptik

注意:你可能会看到一些有关于获取不到包更新的错误提示。不过别担心,如果这些提示看起来跟下边图片中类似的话,你的Aptik的安装就没有任何问题。

03_command_to_install_aptik

安装过程会被显示出来。其中一个被显示出来的消息会提到此次安装会使用掉多少磁盘空间,然后提示你是否要继续,按下“y”再按回车,继续安装。

04_do_you_want_to_continue

当安装完成后,输入“Exit”并按回车或者按下左上角的“X”按钮,关闭终端窗口。

05_closing_terminal_window

在正式运行Aptik前,你需要设置好备份目录到一个U盘、网络驱动器或者类似于Dropbox和Google Drive的云帐号上。这儿的例子中,我们使用的是Dropbox。

06_creating_backup_folder

一旦设置好备份目录,点击启动栏上方的“Search”按钮。

07_opening_search

在搜索框中键入 “aptik”。结果会随着你的输入显示出来。当Aptik图标显示出来的时候,点击它打开应用。

08_starting_aptik

此时一个对话框会显示出来要求你输入密码。输入你的密码并按“OK”按钮。

09_entering_password

Aptik的主窗口显示出来了。从“Backup Directory”下拉列表中选择“Other…”。这个操作允许你选择你已经建立好的备份目录。

注意:在下拉列表的右侧的 “Open” 按钮会在一个文件管理窗口中打开选择目录功能。

10_selecting_other_for_directory

在 “Backup Directory” 对话窗口中,定位到你的备份目录,然后按“Open”。

注意:如果此时你尚未建立备份目录或者想在备份目录中新建个子目录,你可以点“Create Folder”来新建目录。

11_choosing_directory

点击“Software Sources (PPAs).”右侧的 “Backup”来备份已安装的PPAs。

12_clicking_backup_software_sources

然后“Backup Software Sources”对话窗口显示出来。已安装的包和对应的源(PPA)同时也显示出来了。选择你需要备份的源(PPAs),或者点“Select All”按钮选择所有源。

13_selecting_all_software_sources

点击 “Backup” 开始备份。

14_clicking_backup_for_all_software_sources

备份完成后,一个提示你备份完成的对话窗口会蹦出来。点击 “OK” 关掉。

一个名为“ppa.list”的文件出现在了备份目录中。

15_closing_finished_dialog_software_sources

来源:https://linux.cn/article-4763-1.html

Linux:CentOS 7.x中正确设置时间与时钟服务器同步

Chrony是一个开源的自由软件,它能帮助你保持系统时钟与时钟服务器(NTP)同步,因此让你的时间保持精确。它由两个程序组成,分别是chronyd和chronyc。chronyd是一个后台运行的守护进程,用于调整内核中运行的系统时钟和时钟服务器同步。它确定计算机增减时间的比率,并对此进行补偿。chronyc提供了一个用户界面,用于监控性能并进行多样化的配置。它可以在chronyd实例控制的计算机上工作,也可以在一台不同的远程计算机上工作。

在像CentOS 7之类基于RHEL的操作系统上,已经默认安装有Chrony。

Linux:CentOS 7.x中正确设置时间与时钟服务器同步
Linux:CentOS 7.x中正确设置时间与时钟服务器同步

Chrony配置

当Chrony启动时,它会读取/etc/chrony.conf配置文件中的设置。CentOS 7操作系统上最重要的设置有:

server – 该参数可以多次用于添加时钟服务器,必须以”server “格式使用。一般而言,你想添加多少服务器,就可以添加多少服务器。

server 0.centos.pool.ntp.org
server 3.europe.pool.ntp.org

stratumweight – stratumweight指令设置当chronyd从可用源中选择同步源时,每个层应该添加多少距离到同步距离。默认情况下,CentOS中设置为0,让chronyd在选择源时忽略源的层级。

driftfile – chronyd程序的主要行为之一,就是根据实际时间计算出计算机增减时间的比率,将它记录到一个文件中是最合理的,它会在重启后为系统时钟作出补偿,甚至可能的话,会从时钟服务器获得较好的估值。

rtcsync – rtcsync指令将启用一个内核模式,在该模式中,系统时间每11分钟会拷贝到实时时钟(RTC)。

allow / deny – 这里你可以指定一台主机、子网,或者网络以允许或拒绝NTP连接到扮演时钟服务器的机器。

allow 192.168.4.5
deny 192.168/16

cmdallow / cmddeny – 跟上面相类似,只是你可以指定哪个IP地址或哪台主机可以通过chronyd使用控制命令

bindcmdaddress – 该指令允许你限制chronyd监听哪个网络接口的命令包(由chronyc执行)。该指令通过cmddeny机制提供了一个除上述限制以外可用的额外的访问控制等级。

bindcmdaddress 127.0.0.1
bindcmdaddress ::1

makestep – 通常,chronyd将根据需求通过减慢或加速时钟,使得系统逐步纠正所有时间偏差。在某些特定情况下,系统时钟可能会漂移过快,导致该调整过程消耗很长的时间来纠正系统时钟。该指令强制chronyd在调整期大于某个阀值时步进调整系统时钟,但只有在因为chronyd启动时间超过指定限制(可使用负值来禁用限制),没有更多时钟更新时才生效。

使用chronyc

你也可以通过运行chronyc命令来修改设置,命令如下:

accheck – 检查NTP访问是否对特定主机可用

activity – 该命令会显示有多少NTP源在线/离线

add server – 手动添加一台新的NTP服务器。

clients – 在客户端报告已访问到服务器

delete – 手动移除NTP服务器或对等服务器

settime – 手动设置守护进程时间

tracking – 显示系统时间信息

你可以通过使用帮助命令查看完整的命令列表:

Linux:CentOS 7.x中正确设置时间与时钟服务器同步
Linux:CentOS 7.x中正确设置时间与时钟服务器同步

via: http://linoxide.com/linux-command/chrony-time-sync/

作者:Adrian Dinu 译者:GOLinux 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

来源:https://linux.cn/article-4764-1.html

Linux:使用 HAProxy 配置 HTTP 负载均衡器

随着基于 Web 的应用和服务的增多,IT 系统管理员肩上的责任也越来越重。当遇到不可预期的事件如流量达到高峰,流量增大或者内部的挑战比如硬件的损坏或紧急维修,无论如何,你的 Web 应用都必须要保持可用性。甚至现在流行的 devops 和持续交付(CD)也可能威胁到你的 Web 服务的可靠性和性能的一致性。

不可预测,不一致的性能表现是你无法接受的。但是我们怎样消除这些缺点呢?大多数情况下一个合适的负载均衡解决方案可以解决这个问题。今天我会给你们介绍如何使用 HAProxy 配置 HTTP 负载均衡器。

Linux:使用 HAProxy 配置 HTTP 负载均衡器
Linux:使用 HAProxy 配置 HTTP 负载均衡器

什么是 HTTP 负载均衡?

HTTP 负载均衡是一个网络解决方案,它将进入的 HTTP 或 HTTPs 请求分配至一组提供相同的 Web 应用内容的服务器用于响应。通过将请求在这样的多个服务器间进行均衡,负载均衡器可以防止服务器出现单点故障,可以提升整体的可用性和响应速度。它还可以让你能够简单的通过添加或者移除服务器来进行横向扩展或收缩,对工作负载进行调整。

什么时候,什么情况下需要使用负载均衡?

负载均衡可以提升服务器的使用性能和最大可用性,当你的服务器开始出现高负载时就可以使用负载均衡。或者你在为一个大型项目设计架构时,在前端使用负载均衡是一个很好的习惯。当你的环境需要扩展的时候它会很有用。

什么是 HAProxy?

HAProxy 是一个流行的开源的 GNU/Linux 平台下的 TCP/HTTP 服务器的负载均衡和代理软件。HAProxy 是单线程,事件驱动架构,可以轻松的处理 10 Gbps 速率 的流量,在生产环境中被广泛的使用。它的功能包括自动健康状态检查,自定义负载均衡算法,HTTPS/SSL 支持,会话速率限制等等。

这个教程要实现怎样的负载均衡

在这个教程中,我们会为 HTTP Web 服务器配置一个基于 HAProxy 的负载均衡。

准备条件

你至少要有一台,或者最好是两台 Web 服务器来验证你的负载均衡的功能。我们假设后端的 HTTP Web 服务器已经配置好并可以运行

在 Linux 中安装 HAProxy

对于大多数的发行版,我们可以使用发行版的包管理器来安装 HAProxy。

在 Debian 中安装 HAProxy

在 Debian Wheezy 中我们需要添加源,在 /etc/apt/sources.list.d 下创建一个文件 “backports.list” ,写入下面的内容

deb http://cdn.debian.net/debian wheezy­backports main

刷新仓库的数据,并安装 HAProxy

# apt­ get update
# apt ­get install haproxy

在 Ubuntu 中安装 HAProxy

# apt ­get install haproxy

在 CentOS 和 RHEL 中安装 HAProxy

# yum install haproxy

配置 HAProxy

本教程假设有两台运行的 HTTP Web 服务器,它们的 IP 地址是 192.168.100.2 和 192.168.100.3。我们将负载均衡配置在 192.168.100.4 的这台服务器上。

为了让 HAProxy 工作正常,你需要修改 /etc/haproxy/haproxy.cfg 中的一些选项。我们会在这一节中解释这些修改。一些配置可能因 GNU/Linux 发行版的不同而变化,这些会被标注出来。

1. 配置日志功能

你要做的第一件事是为 HAProxy 配置日志功能,在排错时日志将很有用。日志配置可以在 /etc/haproxy/haproxy.cfg 的 global 段中找到他们。下面是针对不同的 Linux 发型版的 HAProxy 日志配置。

CentOS 或 RHEL:

在 CentOS/RHEL中启用日志,将下面的:

log         127.0.0.1 local2

替换为:

log         127.0.0.1 local0

然后配置 HAProxy 在 /var/log 中的日志分割,我们需要修改当前的 rsyslog 配置。为了简洁和明了,我们在 /etc/rsyslog.d 下创建一个叫 haproxy.conf 的文件,添加下面的内容:

$ModLoad imudp
$UDPServerRun 514
$template Haproxy,"%msg%n"
local0.=info ­/var/log/haproxy.log;Haproxy
local0.notice ­/var/log/haproxy­status.log;Haproxy
local0.* ~

这个配置会基于 $template 在 /var/log 中分割 HAProxy 日志。现在重启 rsyslog 应用这些更改。

# service rsyslog restart

Debian 或 Ubuntu:

在 Debian 或 Ubuntu 中启用日志,将下面的内容

log /dev/log        local0
log /dev/log        local1 notice

替换为:

log         127.0.0.1 local0

然后为 HAProxy 配置日志分割,编辑 /etc/rsyslog.d/ 下的 haproxy.conf (在 Debian 中可能叫 49-haproxy.conf),写入下面你的内容

$ModLoad imudp
$UDPServerRun 514
$template Haproxy,"%msg%n"
local0.=info ­/var/log/haproxy.log;Haproxy
local0.notice ­/var/log/haproxy­status.log;Haproxy
local0.* ~

这个配置会基于 $template 在 /var/log 中分割 HAProxy 日志。现在重启 rsyslog 应用这些更改。

 # service rsyslog restart

2. 设置默认选项

下一步是设置 HAProxy 的默认选项。在 /etc/haproxy/haproxy.cfg 的 default 段中,替换为下面的配置:

    defaults
    log     global
    mode    http
    option  httplog
    option  dontlognull
    retries 3
    option redispatch
    maxconn 20000
    contimeout      5000
    clitimeout      50000
    srvtimeout      50000

上面的配置是当 HAProxy 为 HTTP 负载均衡时建议使用的,但是并不一定是你的环境的最优方案。你可以自己研究 HAProxy 的手册并配置它。

3. Web 集群配置

Web 集群配置定义了一组可用的 HTTP 服务器。我们的负载均衡中的大多数设置都在这里。现在我们会创建一些基本配置,定义我们的节点。将配置文件中从 frontend 段开始的内容全部替换为下面的:

listen webfarm *:80
       mode http
       stats enable
       stats uri /haproxy?stats
       stats realm Haproxy Statistics
       stats auth haproxy:stats
       balance roundrobin
       cookie LBN insert indirect nocache
       option httpclose
       option forwardfor
       server web01 192.168.100.2:80 cookie node1 check
       server web02 192.168.100.3:80 cookie node2 check

“listen webfarm *:80” 定义了负载均衡器监听的地址和端口。为了教程的需要,我设置为 “*” 表示监听在所有接口上。在真实的场景汇总,这样设置可能不太合适,应该替换为可以从 internet 访问的那个网卡接口。

stats enable
stats uri /haproxy?stats
stats realm Haproxy Statistics
stats auth haproxy:stats

上面的设置定义了,负载均衡器的状态统计信息可以通过 http:///haproxy?stats 访问。访问需要简单的 HTTP 认证,用户名为 “haproxy” 密码为 “stats”。这些设置可以替换为你自己的认证方式。如果你不需要状态统计信息,可以完全禁用掉。

下面是一个 HAProxy 统计信息的例子

“balance roundrobin” 这一行表明我们使用的负载均衡类型。这个教程中,我们使用简单的轮询算法,可以完全满足 HTTP 负载均衡的需要。HAProxy 还提供其他的负载均衡类型:

  • leastconn:将请求调度至连接数最少的服务器­
  • source:对请求的客户端 IP 地址进行哈希计算,根据哈希值和服务器的权重将请求调度至后端服务器。
  • uri:对 URI 的左半部分(问号之前的部分)进行哈希,根据哈希结果和服务器的权重对请求进行调度
  • url_param:根据每个 HTTP GET 请求的 URL 查询参数进行调度,使用固定的请求参数将会被调度至指定的服务器上
  • hdr(name):根据 HTTP 首部中的 字段来进行调度

“cookie LBN insert indirect nocache” 这一行表示我们的负载均衡器会存储 cookie 信息,可以将后端服务器池中的节点与某个特定会话绑定。节点的 cookie 存储为一个自定义的名字。这里,我们使用的是 “LBN”,你可以指定其他的名称。后端节点会保存这个 cookie 的会话。

server web01 192.168.100.2:80 cookie node1 check
server web02 192.168.100.3:80 cookie node2 check

上面是我们的 Web 服务器节点的定义。服务器有由内部名称(如web01,web02),IP 地址和唯一的 cookie 字符串表示。cookie 字符串可以自定义,我这里使用的是简单的 node1,node2 … node(n)

来源:https://linux.cn/article-4765-1.html

Linux:使用Docker、CoreOS、Mesos部署可扩展的Web应用

【编者的话】本文作者重点介绍了如何使用Docker、CoreOS、Mesos、Vulcand、对象存储来部署一个可扩展的Web应用,他首先介绍了 为什么要选择这些工具以及与其它工具相比这些工具的优势。紧接着,他通过实际案例演示了整个部署过程,图文并茂,推荐阅读。

介绍

让我们先来讨论一下为什么我决定使用这些软件来展示如何创建一个可扩展的Web基础架构。

为什么选择Docker?

那问题来了,为啥要选择Linux容器?因为相比于虚拟机,Linux容器拥有更低的计算和存储开销。

Docker简化了人们使用Linux容器的方式,并且提供一些非常实用的特性,比如Dockerfiles、Docker Hub、分层文件系统。在本文中,我将使用使用Amazon S3 API的VIPR搭建私有的Docker Registry以存储镜像(如我以前的帖子中描述)。

为什么选择CoreOS?

所有的组件都会在Docker容器中运行,所以你可能会说,操作系统并没有那么重要。但是,CoreOS有很多的优势,具体如下:

  • 以一个单元的形式自动更新整个系统,而不是一个包接着一个包的更新(如果你的基础设施没有SPOF,甚至要重启系统)
  • 包含用于发现服务的etcd,也使用Vulcand(甚至设置中需要mesos)
  • 包含了systemd和fleet,一个可以以一个init系统呈现你整个集群的工具。在这个设置中我不使用fleet,但是在其它方面我有使用它,比如几秒内启动elastic search集群。 

为什么选择Vulcand?

我看到有关如何部署容器或虚拟机的很多教程,但我总是惊讶地看到,他们很少涉及基础设施的负载均衡部分。

在我看来,负载均衡是一个可扩展的Web应用架构的重要组成部分。如果用户不能正常访问你的应用,那还搞什么自动化?

Vulcand是一个为HTTP API管理和微服务而设计的反向代理工具。Vulcand会监控etcd,并自动检测到它需要实现新的规则,所以你不需要重新加载任何服务。只需在etcd添加正确的密钥,然后你的服务/应用程序就可以被使用了。

为什么选择Mesos?

有三种不同的方式来自动化部署Docker容器,具体如下:

  • Fleet:Fleet是一个通过Systemd对CoreOS集群进行控制和管理的工具。如果你想启动容器或者手动指定映射到主机的端口,那Fleet是一个不错的选择(译者注:Fleet的更多资料可以阅读本文)。
  • Kubernetes:这可能是最佳的选择之一,但现在Kuernetes还太年轻。
  • Mesos:Mesos目前已经支持Docker,它已经是一个相对稳定的平台,并且可以用来部署其它软件,例如Hadoop。 

为什么选择对象存储?

我们可以通过上面介绍的软件来部署可扩展和高可用的应用。但是,数据怎么处理?

结构化的内容可能会被存储到分布式数据库中,例如MongoDB。非结构化的内容一般会存储在一个本地文件系统、NAS或者对象存储。

本地文件系统并不适合现在的场景,因为容器可能会被部署到集群的任何一个节点上。

理论上NAS共享方案可行,但是特别复杂的。例如,NAS共享需要挂载到所有的主机上,所以你需要为每个容器指定Volume,并在特权模式下运行容器…当容器启动而NAS共享不可用时,容器内的应用程序需要能够处理相关问题。

然而,对象存储却可以在任何容器的任何应用中使用,并且是高可用的,因为我们使用了负载均衡器,它不需要任何配置,这也可以加快应用程序的开发周期。为什么了?因为开发者不需要考虑数据的存储方式、目录结构管理等。

我已经开发了一个Web应用程序,它展示了一个应用程序如何不通过数据路径处理上传和下载,我会在下面运行这个应用程序。

Linux:使用Docker、CoreOS、Mesos部署可扩展的Web应用
Linux:使用Docker、CoreOS、Mesos部署可扩展的Web应用
上图展示了几个不同的组件,以及我如何设置3个节点的CoreOS集群。

我使用Keepalived来确保公共 IP 10.64.231.84是可用的,不管对应在coreos1还是coreos3节点上。

Vulcand会运行再每个节点上,以均衡用户和Web应用程序之间的负载,同事也可以平衡应用程序和不同的VIPR节点。

私有的Docker Registry在coreos1节点上运行,并使用Amazon S3 API在VIPR上存储镜像。

Mesos主节点(Master)和Marathon运行在coreos2节点上。

Demo

视频可以点此链接浏览。

来源:http://dockerone.com/article/162

Linux:为什么不能用memcached存储Session?

Memcached创建者Dormando很早就写过两篇文章[1][2],告诫开发人员不要用memcached存储Session。他在第一篇文章中给出的理由大致是说,如果用memcached存储Session,那么当memcached集群发生故障(比如内存溢出)或者维护(比如升级、增加或减少服务器)时,用户会无法登录,或者被踢掉线。而在第二篇文章中,他则指出,memcached的回收机制可能会导致用户无缘无故地掉线。

Titas Norkūnas是DevOps咨询服务提供商Bear Mountain的联合创始人。由于看到Ruby/Rails社区忽略了Dormando那两篇文章所指出的问题,所以他近日撰文对此进行了进一步的阐述。他认为问题的根本在于,memcached是一个设计用于缓存数据而不是存储数据的系统,因此不应该用于存储Session

Linux:为什么不能用memcached存储Session?
Linux:为什么不能用memcached存储Session?

对于Dormando的那两篇文章,他认为第一篇文章给出的原因很容易理解,而人们经常会对第二篇文章给出的原因认识不足。因此他对这个原因进行了详细地阐述:

Memcached使用“最近最少使用(LRU)”算法回收缓存。但memcached的LRU算法针对每个slab类执行,而不是针对整体

这意味着,如果所有Session的大小大致相同,那么它们会分成两三个slab类。所有其它大小大致相同的数据也会放入同一些slab,与Session争用存储空间。一旦slab满了,即使更大的slab中还有空间,数据也会被回收,而不是放入更大的slab中……在特定的slab中,Session最老的用户将会掉线。用户将会开始随机掉线,而最糟糕的是,你很可能甚至都不会注意到它,直至用户开始抱怨……

另外,Norkūnas提到,如果Session中增加了新数据,那么Session变大也可能会导致掉线问题出现。

有人提出将Session和其它数据分别使用单独的memcached缓存。不过,由于memcached的LRU算法是局部的,那种方式不仅导致内存使用率不高,而且也无法消除用户因为Session回收而出现随机掉线的风险。

如果读者非常希望借助memcached提高Session读取速度,那么可以借鉴Norkūnas提出的memcached+RDBMS(在有些情况下,NoSQL也可以)的模式:

  • 当用户登录时,将Session “set”到memcached,并写入数据库;
  • 在Session中增加一个字段,标识Session最后写入数据库的时间;
  • 每个页面加载的时候,优先从memcached读取Session,其次从数据库读取;
  • 每加载N页或者Y分钟后,再次将Session写入数据库;
  • 从数据库中获取过期Session,优先从memcached中获取最新数据。

 

来源:http://www.infoq.com/cn/news/2015/01/memcached-store-session

Linux:Docker 中 latest 标签引发的困惑

【编者的话】本文介绍了Docker中的一个小知识:latest标签,由于它的字面意思是“最新的”,所以很多时候也容易被误解,其实latest就是个普通标签,不要期望它是最新或最稳定的版本。它只是个名字,没有其它附加作用,更不会自动更新。:)

在Docker中,最容易产生误解的部分应该是latest这个标签。困惑主要是由于这个名字造成的,因为字面意思并不能表达它的真正含义。在本文中,我们来学习下latest标签的真正作用和如何正确使用它。

Linux:Docker 中 latest 标签引发的困惑
Linux:Docker 中 latest 标签引发的困惑

通常有两种方式来对镜像打标签:使用docker tag命令或者是在执行docker build的时候用-t来传递参数。在这两种情况下,参数的形式通常是repository_name:tag_name,例如:docker tag myrepo:mytag。如果这个资源库被上传到了Docker Hub,资源库的名字会加上一个由Docker Hub用户名和斜线组成的前缀,例如:amouat/myrepo:mytag。如果没有添加tag部分的参数,例如:docker tag myrepo:1.0 myrepo,Docker会自动的给它latest标签。前面这些内容或许你已经熟知,其实它也就这点内容,并没有什么神奇的地方。

不能因为镜像的标签是latest就认为这是资源库中最新的镜像。只有这个资源库的拥有者约定这样,拥有latest标签的镜像才一定是最新的镜像。例如,我可以轻易地把一个过时的镜像变成带有latest标签的镜像,例如:

$ docker images myrepo
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
myrepo              1.0                 2e9f372f03a0        44 seconds ago      2.433 MB
myrepo              latest              2e9f372f03a0        44 seconds ago      2.433 MB
myrepo              0.9                 4986bf8c1536        2 weeks ago         2.433 MB
$ docker tag -f myrepo:0.9 myrepo:latest
$ docker images myrepo
REPOSITORY          TAG                 IMAGE ID            CREATED              VIRTUAL SIZE
myrepo              1.0                 2e9f372f03a0        About a minute ago   2.433 MB
myrepo              0.9                 4986bf8c1536        2 weeks ago          2.433 MB
myrepo              latest              4986bf8c1536        2 weeks ago          2.433 MB

这里带latest标签的镜像与0.9版本的镜像是一样的,都是两周前的版本,然而1.0的镜像是一分钟以前的。

为什么这个标签让很多人迷惑,其实比较容易理解。‘just pull the latest image’ 这句话的意思是获取带有latest标签的镜像还是获取最新的镜像?这两者是否是一样呢?它们是不是资源库中最新的镜像呢?是不是最新的稳定版镜像或者是最新的开发版镜像呢?

更糟糕的是,很多人似乎认为latest标签会自动更新,也就是说如果我获取一个带有latest标签的镜像,Docker会在每次运行之前去检查它是不是最新的版本。这是绝对不会出现的情况,就像其它的标签一样,你需要去手工决定Docker获取最新版本的镜像。

困惑并不仅仅是这些。如果我从资源库docker pull一个镜像却没指定标签,会发生什么呢?如果你认为会获取下所有的镜像,那么就错了,它只会获取下来带有latest标签的那个。如果你需要获取全部镜像,需要加上-a标志。 如果你在资源库执行了pull操作,却没带latest标签,会发生什么呢?如下所示:

$ docker pull amouat/myrepo
Pulling repository amouat/myrepo
2015/01/21 12:04:06 Tag latest not found in repository amouat/myrepo

意料之中的是Docker给出了错误信息。但是我认为你不知道这其中发生了什么。

一个更令人讨厌的是latest标签隐藏了其它的标签,假设你要下载带latest标签的debian镜像。哪个是它的版本呢?

$ docker images debian
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
debian              latest              4d6ce913b130        4 days ago          84.98 MB

额,不知道。事实上是7.8 wheezy版本。

$ docker pull debian:7.8
debian:7.8: The image you are pulling has been verified
511136ea3c5a: Already exists
d0a18d3b84de: Already exists
4d6ce913b130: Already exists
Status: Image is up to date for debian:7.8
$ docker pull debian:wheezy
debian:wheezy: The image you are pulling has been verified
511136ea3c5a: Already exists
d0a18d3b84de: Already exists
4d6ce913b130: Already exists
Status: Image is up to date for debian:wheezy
$ docker images debian
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
debian              7.8                 4d6ce913b130        4 days ago          84.98 MB
debian              latest              4d6ce913b130        4 days ago          84.98 MB
debian              wheezy              4d6ce913b130        4 days ago          84.98 MB

我认为Docker在下载镜像时应该把所有的标签都带上,但是我不知道为什么它没有这么做。现在的情况是用户可以拥有同一个镜像的不同版本因为服务器上用标签来标示。例如:如果wheezy和latest都在Hub上更新了,而我只获取了更新后的wheezy版本debian,那么尽管在Hub上他们可以被区分开,但是我的wheezy标签将会比本地的latest标签的版本新。

上述只是覆盖了latest的大部分语义以及它造成的常见误解。这种情况怎么能够改善呢?个人认为,可以取消latest标签并用一个更接近其字面意思的词来代替,例如default。我也希望可以看到一些改进标签原作方式的工作,例如同时更新一个镜像的全部标签。与此同时,我也强烈建议资源库管理员去警惕这个latest标签并彻底废弃它。

来源:http://dockerone.com/article/165

Linux:基础 RAID 介绍

简介

RAID是一个我们经常能见到的名词。但却因为很少能在实际环境中体验,所以很难对其原理 能有很清楚的认识和掌握。本文将对RAID技术进行介绍和总结,以期能尽量阐明其概念。

RAID全称为独立磁盘冗余阵列(Rdeundant Array of Independent Disks),基本思想就是把 多个相对便宜的硬盘组合起来,成为一个硬盘阵列组,使性能达到甚至超过一个价格昂贵、 容量巨大的硬盘。RAID通常被用在服务器电脑上,使用完全相同的硬盘组成一个逻辑扇区, 因此操作系统只会把它当做一个硬盘。

RAID分为不同的等级,各个不同的等级均在数据可靠性及读写性能上做了不同的权衡。 在实际应用中,可以依据自己的实际需求选择不同的RAID方案。

Linux:基础 RAID 介绍
Linux:基础 RAID 介绍

标准RAID

RAID 0

RAID0称为条带化(Striping)存储,将数据分段存储于 各个磁盘中,读写均可以并行处理。因此其读写速率为单个磁盘的N倍(N为组成RAID0的磁盘个数),但是却没有数 据冗余,单个磁盘的损坏会导致数据的不可修复。

大多数striping的实现允许管理者通过调节两个关键的参数来定义数据分段及写入磁盘的 方式,这两个参数对RAID0的性能有很重要的影响。

STRIPE WIDTH

stripe width是指可被并行写入的 stripe 的个数,即等于磁盘阵列中磁盘的个数。

STRIPE SIZE

也可称为 block size(chunk size,stripe length,granularity),指写入每个磁 盘的数据块大小。以块分段的RAID通常可允许选择的块大小从 2KB 到 512KB不等,也有更 高的,但一定要是2的指数倍。以字节分段的(比如RAID3)一般的stripe size为1字节或者 512字节,并且用户不能调整。

stripe size对性能的影响是很难简单估量的,最好在实际应用中依自己需求多多调整并 观察其影响。通常来说,减少stripe size,文件会被分成更小的块,传输数据会更快,但 是却需要更多的磁盘来保存,增加positioning performance,反之则相反。应该说,没有 一个理论上的最优的值。很多时候,也要考虑磁盘控制器的策略,比如有的磁盘控制器会等 等到一定数据量才开始往磁盘写入。

RAID 1

镜像存储(mirroring),没有数据校验。数据被同等地写入两个或多个磁盘中,可想而知,写入速度会比较 慢,但读取速度会比较快。读取速度可以接近所有磁盘吞吐量的总和,写入速度受限于最慢 的磁盘。

RAID1也是磁盘利用率最低的一个。如果用两个不同大小的磁盘建立RAID1,可以用空间较小 的那一个,较大的磁盘多出来的部分可以作他用,不会浪费。

RAID 2

RAID0的改良版,加入了汉明码(Hanmming Code)错误校验。

Linux:基础 RAID 介绍
Linux:基础 RAID 介绍

汉明码能够检测最多两个同时发生的比特错误,并且能够更正单一比特的错误。汉明码的位 数与数据的位数有一个不等式关系,即:

2^P ≥ P + D +1

P代表汉明码的个数,D代表数据位的个数,比如4位数据需要3位汉明码,7位数据需要4位汉 明码,64位数据时就需要7位汉明码。RAID2是按1bit来分割数据写入的,而P:D就代表了数据 盘与校验盘的个数。所以如果数据位宽越大,用于校验的盘的比例就越小。由于汉明码能够 纠正单一比特的错误,所以当单个磁盘损坏时,汉明码便能够纠正数据。

RAID 2 因为每次读写都需要全组磁盘联动,所以为了最大化其性能,最好保证每块磁盘主 轴同步,使同一时刻每块磁盘磁头所处的扇区逻辑编号都一致,并存并取,达到最佳性能。 如果不能同步,则会产生等待,影响速度。

与RAID0相比,RAID2的传输率更好。因为RAID0一般stripe size 相对于RAID2的1bit来说 实在太大,并不能保证每次都是多磁盘并行。而RAID2每次IO都能保证是多磁盘并行,为了 发挥这个优势,磁盘的寻道时间一定要减少(寻道时间比数据传输时间要大几个数量级),所 以RAID2适合于连续IO,大块IO(比如视频流服务)的情况。

RAID 3

类似于RAID2,数据条带化(stripe)存储于不同的硬盘,数据以字节为单位,只是RAID3使用单块磁盘存储简单的 奇偶校验信息,所以最终磁盘数量为 N+1 。当这N+1个硬盘中的其中一个硬盘出现故障时, 从其它N个硬盘中的数据也可以恢复原始数据,当更换一个新硬盘后,系统可以重新恢复完整 的校验容错信息。

由于在一个硬盘阵列中,多于一个硬盘同时出现故障率的几率很小,所以一般情况下,使用 RAID3,安全性是可以得到保障的。RAID 3会把数据的写入操作分散到多个磁盘上进行,不管是向哪一个数据盘写入数据, 都需要同时重写校验盘中的相关信息。因此,对于那些经常需要执行大量写入操作的应用来 说,校验盘的负载将会很大,无法满足程序的运行速度,从而导致整个RAID系统性能的下降。 鉴于这种原因,RAID 3更加适合应用于那些写入操作较少,读取操作较多的应用环境,例如 数据库和WEB服务器等。

RAID 4

与RAID3类似,但RAID4是按块(扇区)存取。无须像RAID3那样,哪怕每一次小I/O操作也要涉 及全组,只需涉及组中两块硬盘(一块数据盘,一块校验盘)即可,从而提高了小量数据 I/O速度。

RAID 5

奇偶校验(XOR),数据以块分段条带化存储。校验信息交叉地存储在所有的数据盘上。

RAID5把数据和相对应的奇偶校验信息存储到组成RAID5的各个磁盘上,并且奇偶校验信息和 相对应的数据分别存储于不同的磁盘上,其中任意N-1块磁盘上都存储完整的数据,也就是 说有相当于一块磁盘容量的空间用于存储奇偶校验信息。因此当RAID5的一个磁盘发生损坏 后,不会影响数据的完整性,从而保证了数据安全。当损坏的磁盘被替换后,RAID还会自动 利用剩下奇偶校验信息去重建此磁盘上的数据,来保持RAID5的高可靠性。

RAID 5可以理解为是RAID 0和RAID 1的折衷方案。RAID 5可以为系统提供数据安全保障,但 保障程度要比镜像低而磁盘空间利用率要比镜像高。RAID 5具有和RAID 0相近似的数据读取 速度,只是因为多了一个奇偶校验信息,写入数据的速度相对单独写入一块硬盘的速度略慢。

RAID 6

类似RAID5,但是增加了第二个独立的奇偶校验信息块,两个独立的奇偶系统使用不同的算法, 数据的可靠性非常高,即使两块磁盘同时失效也不会影响数据的使用。但RAID 6需要分配给 奇偶校验信息更大的磁盘空间,相对于RAID 5有更大的“写损失”,因此“写性能”非常差。

由图所知,每个硬盘上除了都有同级数据XOR校验区外,还有一个针对每个数据 块的XOR校验区。当然,当前盘数据块的校验数据不可能存在当前盘而是交错存储的。从数 学角度来说,RAID 5使用一个方程式解出一个未知变量,而RAID 6则能通过两个独立的线性 方程构成方程组,从而恢复两个未知数据。

伴随着硬盘容量的增长,RAID6已经变得越来越重要。TB级别的硬盘上更容易造成数据丢失, 数据重建过程(比如RAID5,只允许一块硬盘损坏)也越来越长,甚至到数周,这是完全不可接受的。而RAID6允许两 块硬盘同时发生故障,所以渐渐受到人们的青睐。

伴随CD,DVD和蓝光光盘的问世,存储介质出现了擦除码技术,即使媒介表面出现划痕,仍 然可以播放,大多数常见的擦除码算法已经演变为上世纪60年代麻省理工学院林肯实验室开 发的Reed-Solomon码。实际情况中,多数RAID6实现都采用了标准的RAID5教校验比特和Reed-Solomon码 。而纯擦除码算法的使用使得RAID 6阵列可以失效两块以上的硬盘,保护力度更强,有些实现 方法提供了多种级别的保护,甚至允许用户(或存储管理员)指定保护级别。

混合RAID

RAID 01

顾名思义,是RAID0和RAID1的结合。先做条带(0),再做镜像(1)。

Linux:基础 RAID 介绍
Linux:基础 RAID 介绍

RAID 10

同上,但是先做镜像(1),再做条带(0)

Linux:基础 RAID 介绍
Linux:基础 RAID 介绍

RAID01和RAID10非常相似,二者在读写性能上没有什么差别。但是在安全性上RAID10要好于 RAID01。如图中所示,假设DISK0损坏,在RAID10中,在剩下的3块盘中,只有当DISK1故障, 整个RAID才会失效。但在RAID01中,DISK0损坏后,左边的条带将无法读取,在剩下的3快盘 中,只要DISK2或DISK3两个盘中任何一个损坏,都会导致RAID失效。

RAID10和RAID5也是经常用来比较的两种方案,二者都在生产实践中得到了广泛的应用。 RAID10安全性更高,但是空间利用率低。至于读写性能,与cache有很大关联,最好根据实 际情况测试比较选择。

非标准RAID

DRFS

DRFS,即DistributedRaidFileSystem,是一种尝试将RAID与Hadoop的DFS结合起来的技术。 通常的HDFS在实践中需要将replication factor设为3以保证数据完整性,而如果利用 RAID的stripe和partity(奇偶校验)技术,将数据分为多个块,并且存储各个块的校验信 息(XOR或擦除码)。有了这些措施,块的副本数就可以降低并且保证同样的数据可靠性,就能节省相当一部 分的存储空间。

DRFS包含以下几个组件:

  • DRFS client : 提供应用程序访问DRFS的接口,在发现读取到的文件有损坏时修复,整 个操作对应用程序透明
  • RaidNode : 创建,维护检验文件的daemon
  • BlockFixer : 周期性地检查文件,重新计算校验和,修复文件.
  • RaidShell : 类似于hadoop shell.
  • ErasureCode : 即DRFS所使用的生成校验码的算法,可为XOR或者 Reed-Solomon算法。 XOR仅能创建一个校验字节,而Reed-Solomon则可以创建无数位(位数越多,能恢复的数 据也越多),如果使用Reed-Solomon,replication甚至可以降为1,缺点是降低了数据读 写的并行程度(只能从单机读写)。

实现

软件实现

现在很都操作系统都提供了RAID的软件实现,主要由以下几个方面:

  • 由软件在多个设备上创建RAID,比如linux上的mdadm工具.具体使用方法可查看参考链接中 的例子。
  • LVM或者 Veritas,虚拟卷管理工具.
  • 文件系统实现 : btrfs,ZFS,GPFS.这些文件都可以直接管理多个设备上的数据,实 现了类似各级RAID的功能。
  • 在已有文件系统之上提供数据校验功能的RAID系统(RAID-F)

固件/驱动实现

软件实现并总是与系统的启动进程兼容,硬件实现(RAID控制器)总是太贵并且都是厂商专有的技术,所以 有了一中混合的实现:系统启动时,由固件(firmware)来实现RAID,系统启动的差不多了,由驱动来管 理RAID。当然,这需要操作系统对这种驱动提供支持。

参考链接

  1. 维基百科 : RAID
  2. Stripe Width and Stripe Size
  3. RAID6
  4. DRFS
  5. HDFS and Erasure Codes
  6. Linux下的软磁盘矩阵Software RAID实现步骤简介
  7. Wiki: mdadm
  8. VxFS(Veritas File System)文件系统简介
  9. Linux LVM逻辑卷管理详细介绍
  10. GPFS介绍
  11. RAID-F
  12. 基本的RAID介绍

来源:http://yayua.github.io/storage/raid/

Linux:Spark 内核研究

1、Spark介绍

Spark是起源于美国加州大学伯克利分校AMPLab的大数据计算平台,在2010年开源,目前是Apache软件基金会的顶级项目。随着Spark在大数据计算领域的暂露头角,越来越多的企业开始关注和使用。2014年11月,Spark在Daytona Gray Sort 100TB Benchmark竞赛中打破了由Hadoop MapReduce保持的排序记录。Spark利用1/10的节点数,把100TB数据的排序时间从72分钟提高到了23分钟

Spark在架构上包括内核部分和4个官方子模块–Spark SQL、Spark Streaming、机器学习库MLlib和图计算库GraphX。图1所示为Spark在伯克利的数据分析软件栈BDAS(Berkeley Data Analytics Stack)中的位置。可见Spark专注于数据的计算,而数据的存储在生产环境中往往还是由Hadoop分布式文件系统HDFS承担。

Linux:Spark 内核研究
Linux:Spark 内核研究

图1 Spark在BDAS中的位置 

Spark被设计成支持多场景的通用大数据计算平台,它可以解决大数据计算中的批处理,交互查询及流式计算等核心问题。Spark可以从多数据源的读取数据,并且拥有不断发展的机器学习库和图计算库供开发者使用。数据和计算在Spark内核及Spark的子模块中是打通的,这就意味着Spark内核和子模块之间成为一个整体。Spark的各个子模块以Spark内核为基础,进一步支持更多的计算场景,例如使用Spark SQL读入的数据可以作为机器学习库MLlib的输入。表1列举了一些在Spark平台上的计算场景。

Linux:Spark 内核研究
Linux:Spark 内核研究

表1 Spark的应用场景举例

在本文写作是,Spark的最新版本为1.2.0,文中的示例代码也来自于这个版本。

2、Spark内核介绍 

相信大数据工程师都非常了解Hadoop MapReduce一个最大的问题是在很多应用场景中速度非常慢,只适合离线的计算任务。这是由于MapReduce需要将任务划分成map和reduce两个阶段,map阶段产生的中间结果要写回磁盘,而在这两个阶段之间需要进行shuffle操作。Shuffle操作需要从网络中的各个节点进行数据拷贝,使其往往成为最为耗时的步骤,这也是Hadoop MapReduce慢的根本原因之一,大量的时间耗费在网络磁盘IO中而不是用于计算。在一些特定的计算场景中,例如像逻辑回归这样的迭代式的计算,MapReduce的弊端会显得更加明显。

那Spark是如果设计分布式计算的呢?首先我们需要理解Spark中最重要的概念–弹性分布数据集(Resilient Distributed Dataset),也就是RDD。 

2.1 弹性分布数据集RDD

RDD是Spark中对数据和计算的抽象,是Spark中最核心的概念,它表示已被分片(partition),不可变的并能够被并行操作的数据集合。对RDD的操作分为两种transformation和action。Transformation操作是通过转换从一个或多个RDD生成新的RDD。Action操作是从RDD生成最后的计算结果。在Spark最新的版本中,提供丰富的transformation和action操作,比起MapReduce计算模型中仅有的两种操作,会大大简化程序开发的难度。

RDD的生成方式只有两种,一是从数据源读入,另一种就是从其它RDD通过transformation操作转换。一个典型的Spark程序就是通过Spark上下文环境(SparkContext)生成一个或多个RDD,在这些RDD上通过一系列的transformation操作生成最终的RDD,最后通过调用最终RDD的action方法输出结果。

每个RDD都可以用下面5个特性来表示,其中后两个为可选的:

  • 分片列表(数据块列表)
  • 计算每个分片的函数
  • 对父RDD的依赖列表
  • 对key-value类型的RDD的分片器(Partitioner)(可选)
  • 每个数据分片的预定义地址列表(如HDFS上的数据块的地址)(可选)

虽然Spark是基于内存的计算,但RDD不光可以存储在内存中,根据useDisk、useMemory、useOffHeap, deserialized、replication五个参数的组合Spark提供了12种存储级别,在后面介绍RDD的容错机制时,我们会进一步理解。值得注意的是当StorageLevel设置成OFF_HEAP时,RDD实际被保存到Tachyon中。Tachyon是一个基于内存的分布式文件系统,目前正在快速发展,本文不做详细介绍,可以通过其官方网站进一步了解。

class StorageLevel private(
    private var _useDisk: Boolean,
    private var _useMemory: Boolean,
    private var _useOffHeap: Boolean,
    private var _deserialized: Boolean
    private var _replication: Int = 1)
    extends Externalizable { //… }
    val NONE = new StorageLevel(false, false, false, false)
    val DISK_ONLY = new StorageLevel(true, false, false, false)
    val DISK_ONLY_2 = new StorageLevel(true, false, false, false, 2)
    val MEMORY_ONLY = new StorageLevel(false, true, false, true)
    val MEMORY_ONLY_2 = new StorageLevel(false, true, false, true, 2)
    val MEMORY_ONLY_SER = new StorageLevel(false, true, false, false)
    val MEMORY_ONLY_SER_2 = new StorageLevel(false, true, false, false, 2)
    val MEMORY_AND_DISK = new StorageLevel(true, true, false, true)
    val MEMORY_AND_DISK_2 = new StorageLevel(true, true, false, true, 2)
    val MEMORY_AND_DISK_SER = new StorageLevel(true, true, false, false)
    val MEMORY_AND_DISK_SER_2 = new StorageLevel(true, true, false, false, 2)
    val OFF_HEAP = new StorageLevel(false, false, true, false)

2.2 DAG、Stage与任务的生成

Spark的计算发生在RDD的action操作,而对action之前的所有transformation,Spark只是记录下RDD生成的轨迹,而不会触发真正的计算。

Spark内核会在需要计算发生的时刻绘制一张关于计算路径的有向无环图,也就是DAG。举个例子,在图2中,从输入中逻辑上生成A和C两个RDD,经过一系列transformation操作,逻辑上生成了F,注意,我们说的是逻辑上,因为这时候计算没有发生,Spark内核做的事情只是记录了RDD的生成和依赖关系。当F要进行输出时,也就是F进行了action操作,Spark会根据RDD的依赖生成DAG,并从起点开始真正的计算。

Linux:Spark 内核研究
Linux:Spark 内核研究

图2 逻辑上的计算过程:DAG 

有了计算的DAG图,Spark内核下一步的任务就是根据DAG图将计算划分成任务集,也就是Stage,这样可以将任务提交到计算节点进行真正的计算。Spark计算的中间结果默认是保存在内存中的,Spark在划分Stage的时候会充分考虑在分布式计算中可流水线计算(pipeline)的部分来提高计算的效率,而在这个过程中,主要的根据就是RDD的依赖类型。根据不同的transformation操作,RDD的依赖可以分为窄依赖(Narrow Dependency)和宽依赖(Wide Dependency,在代码中为ShuffleDependency)两种类型。窄依赖指的是生成的RDD中每个partition只依赖于父RDD(s) 固定的partition。宽依赖指的是生成的RDD的每一个partition都依赖于父 RDD(s) 所有partition。窄依赖典型的操作有map, filter, union等,宽依赖典型的操作有groupByKey, sortByKey等。可以看到,宽依赖往往意味着shuffle操作,这也是Spark划分stage的主要边界。对于窄依赖,Spark会将其尽量划分在同一个stage中,因为它们可以进行流水线计算。

Linux:Spark 内核研究
Linux:Spark 内核研究

图3 RDD的宽依赖和窄依赖

我们再通过图4详细解释一下Spark中的Stage划分。我们从HDFS中读入数据生成3个不同的RDD,通过一系列transformation操作后再将计算结果保存回HDFS。可以看到这幅DAG中只有join操作是一个宽依赖,Spark内核会以此为边界将其前后划分成不同的Stage. 同时我们可以注意到,在图中Stage2中,从map到union都是窄依赖,这两步操作可以形成一个流水线操作,通过map操作生成的partition可以不用等待整个RDD计算结束,而是继续进行union操作,这样大大提高了计算的效率。

Linux:Spark 内核研究
Linux:Spark 内核研究

图4 Spark中的Stage划分 

Spark在运行时会把Stage包装成任务提交,有父Stage的Spark会先提交父Stage。弄清楚了Spark划分计算的原理,我们再结合源码看一看这其中的过程。下面的代码是DAGScheduler中的得到一个RDD父Stage的函数,可以看到宽依赖为划分Stage的边界。

/**
   * Get or create the list of parent stages for a given RDD. The stages will be assigned the
   * provided jobId if they haven't already been created with a lower jobId.
   */
  private def getParentStages(rdd: RDD[_], jobId: Int): List[Stage] = {
    val parents = new HashSet[Stage]
    val visited = new HashSet[RDD[_]]
    // We are manually maintaining a stack here to prevent StackOverflowError
    // caused by recursively visiting
    val waitingForVisit = new Stack[RDD[_]]
    def visit(r: RDD[_]) {
      if (!visited(r)) {
        visited += r
        // Kind of ugly: need to register RDDs with the cache here since
        // we can't do it in its constructor because # of partitions is unknown
        for (dep <- r.dependencies) {
          dep match {
            case shufDep: ShuffleDependency[_, _, _] =>
              parents += getShuffleMapStage(shufDep, jobId)
            case _ =>
              waitingForVisit.push(dep.rdd)
          }
        }
      }
    }
    waitingForVisit.push(rdd)
    while (!waitingForVisit.isEmpty) {
      visit(waitingForVisit.pop())
    }
    parents.toList
  }

上面提到Spark的计算是从RDD调用action操作时候触发的,我们来看一个action的代码

RDD的collect方法是一个action操作,作用是将RDD中的数据返回到一个数组中。可以看到,在此action中,会触发Spark上下文环境SparkContext中的runJob方法,这是一系列计算的起点。

abstract class RDD[T: ClassTag](
    @transient private var sc: SparkContext,
    @transient private var deps: Seq[Dependency[_]]
  ) extends Serializable with Logging {
  //….
/**
   * Return an array that contains all of the elements in this RDD.
   */
  def collect(): Array[T] = {
    val results = sc.runJob(this, (iter: Iterator[T]) => iter.toArray)
    Array.concat(results: _*)
  }
}

SparkContext拥有DAGScheduler的实例,在runJob方法中会进一步调用DAGScheduler的runJob方法。在此时,DAGScheduler会生成DAG和Stage,将Stage提交给TaskScheduler。TaskSchduler将Stage包装成TaskSet,发送到Worker节点进行真正的计算,同时还要监测任务状态,重试失败和长时间无返回的任务。整个过程如图5所示。

Linux:Spark 内核研究
Linux:Spark 内核研究

图5 Spark中任务的生成 

2.3 RDD的缓存与容错

上文提到,Spark的计算是从action开始触发的,如果在action操作之前逻辑上很多transformation操作,一旦中间发生计算失败,Spark会重新提交任务,这在很多场景中代价过大。还有一些场景,如有些迭代算法,计算的中间结果会被重复使用,重复计算同样增加计算时间和造成资源浪费。因此,在提高计算效率和更好支持容错,Spark提供了基于RDDcache机制和checkpoint机制。

我们可以通过RDD的toDebugString来查看其递归的依赖信息,图6展示了在spark shell中通过调用这个函数来查看wordCount RDD的依赖关系,也就是它的Lineage.

Linux:Spark 内核研究
Linux:Spark 内核研究

图6 RDD wordCount的lineage 

如果发现Lineage过长或者里面有被多次重复使用的RDD,我们就可以考虑使用cache机制或checkpoint机制了。

我们可以通过在程序中直接调用RDD的cache方法将其保存在内存中,这样这个RDD就可以被多个任务共享,避免重复计算。另外,RDD还提供了更为灵活的persist方法,可以指定存储级别。从源码中可以看到RDD.cache就是简单的调用了RDD.persist(StorageLevel.MEMORY_ONLY)。

 /** Persist this RDD with the default storage level (`MEMORY_ONLY`). */
  def persist(): this.type = persist(StorageLevel.MEMORY_ONLY)
  def cache(): this.type = persist()

同样,我们可以调用RDD的checkpoint方法将其保存到磁盘。我们需要在SparkContext中设置checkpoint的目录,否则调用会抛出异常。值得注意的是,在调用checkpoint之前建议先调用cache方法将RDD放入内存,否则将RDD保存到文件的时候需要重新计算。 

  /**
   * Mark this RDD for checkpointing. It will be saved to a file inside the checkpoint
   * directory set with SparkContext.setCheckpointDir() and all references to its parent
   * RDDs will be removed. This function must be called before any job has been
   * executed on this RDD. It is strongly recommended that this RDD is persisted in
   * memory, otherwise saving it on a file will require recomputation.
   */
  def checkpoint() {
    if (context.checkpointDir.isEmpty) {
      throw new SparkException("Checkpoint directory has not been set in the SparkContext")
    } else if (checkpointData.isEmpty) {
      checkpointData = Some(new RDDCheckpointData(this))
      checkpointData.get.markForCheckpoint()
    }
  }

Cache机制和checkpoint机制的差别在于cache将RDD保存到内存,并保留Lineage,如果缓存失效RDD还可以通过Lineage重建。而checkpoint将RDD落地到磁盘并切断Lineage,由文件系统保证其重建。

2.4 Spark任务的部署

Spark的集群部署分为Standalone、Mesos和Yarn三种模式,我们以Standalone模式为例,简单介绍Spark程序的部署。如图7示,集群中的Spark程序运行时分为3种角色,driver, master和worker(slave)。在集群启动前,首先要配置master和worker节点。启动集群后,worker节点会向master节点注册自己,master节点会维护worker节点的心跳。Spark程序都需要先创建Spark上下文环境,也就是SparkContext。创建SparkContext的进程就成为了driver角色,上一节提到的DAGScheduler和TaskScheduler都在driver中运行。Spark程序在提交时要指定master的地址,这样可以在程序启动时向master申请worker的计算资源。Driver,master和worker之间的通信由Akka支持。Akka 也使用 Scala 编写,用于构建可容错的、高可伸缩性的Actor 模型应用。关于Akka,可以访问其官方网站进行进一步了解,本文不做详细介绍。

Linux:Spark 内核研究
Linux:Spark 内核研究

图7 Spark任务部署

3、更深一步了解Spark内核

了解了Spark内核的基本概念和实现后,更深一步理解其工作原理的最好方法就是阅读源码。最新的Spark源码可以从Spark官方网站下载。源码推荐使用IntelliJ IDEA阅读,会自动安装Scala插件。读者可以从core工程,也就是Spark内核工程开始阅读,更可以设置断点尝试跟踪一个任务的执行。另外,读者还可以通过分析Spark的日志来进一步理解Spark的运行机制,Spark使用log4j记录日志,可以在启动集群前修改log4j的配置文件来配置日志输出和格式。

来源:http://www.mininglamp.com

Linux:Docker 最佳实践

【编者的话】本文是Docker使用过程中的一些最佳实践。虽然很多都是老话重谈,但是很多人在使用过程中还是没有遵守,比如每个进程只使用一个容器这个最佳实践,有很多人都来问,如果不这样行不行,当然行,但是如果你想长久的用Docker,那还是请遵守最佳实践吧。

精益、简单,易于管理,这是Docker的精髓。最佳实践可以确保你利用到Docker的所有优势,使得这个强大工具能够发挥最大的效果。本文的Docker最佳实践可以帮助你学习使用已经在开发者中十分流行的Docker容器化技术。

Linux:Docker 最佳实践
Linux:Docker 最佳实践

使用可信任的Build

可信任Build让一切变得简单。可信任的Build这个特性有助于简化和共享repository。关键之处是在push任何build之前在本地完成所有开发和测试。如果你在本地构建和测试容器,当其被push到别的地方时也会用同样的方式工作。

最少化Layer

太多的层次使得事情无端复杂,避免不必要的层次。要点是在可读性和最少可能的层次间找到最优平衡。只在真正需要增加层次的时候增加额外的层次。

每个进程只使用一个容器

将应用解耦合到不同的容器中,每个进程一个容器。这使得系统更容易横向扩展,也使得容器可以再利用。处理相互依赖的服务时,使用容器的关联特性,而不是将它们直接放在同一个Docker容器里。

不要安装不需要的Package

避免安装不需要的package。这会帮助减少文件大小,减少依赖的复杂性,并且降低构造时间。比如,在数据库镜像里就没有必要安装文本编辑器,这完全是在浪费资源。任何时候尽可能地减少冗余。

使用DockerIgnore

DockerIngore可以很好得从构建上下文以及最终镜像里排除不必要的文件和目录。这个特性使得容器可以更快更有效地加载,节省很多浪费的启动时间。

构建容易被替换的容器

容器是临时的。也就是说,我们在设计容器就应该考虑到,仅用很少的步骤和配置就可以将其停止、删除和替换。构建Docker容器时就要考虑到之后这个容器如何能被轻易丢弃替换。

注意使用标签

Docker Build会生成一个易读的标签,帮助人们更轻松地管理镜像。使用-t选项就可以使用Docker Build特性。追本溯源,Docker容器化最佳实践是关于如何让容器更简单更纯净。避免任何会导致程序膨胀的不必要操作。时刻考虑到精简,那么Docker就会回报给你灵活性,更少的启动时间以及更好的易用性。

来源:http://dockerone.com/article/161

Linux:在 Linux 下你所不知道的 df 命令的那些功能

问题: 我知道在Linux上我可以用df命令来查看磁盘使用空间。你能告诉我df命令的实际例子使我可以最大限度得利用它吗?

Linux:在 Linux 下你所不知道的 df 命令的那些功能
Linux:在 Linux 下你所不知道的 df 命令的那些功能

对于磁盘存储方面,有很多命令行或基于GUI的工具,它可以告诉你关于当前磁盘空间的使用情况。这些工具用各种人们可读的格式展示磁盘利用率的详细信息,比如易于理解的总结,详细的统计信息或直观的可视化报告。如果你只想知道不同文件系统有多少空闲的磁盘空间,那么df命令可能是你所需要的。

Linux:在 Linux 下你所不知道的 df 命令的那些功能
Linux:在 Linux 下你所不知道的 df 命令的那些功能

df命令可以展示任何“mounted”文件系统的磁盘利用率。该命令可以用不同的方式调用。这里有一些有用的 df 命令例子.

用人们可读的方式展示

默认情况下,df命令用1K为块来展示磁盘空间,这看起来不是很直观。“-h”参数使df用更可读的方式打印磁盘空间(例如 100K,200M,3G)。

$ df -h

Filesystem               Size  Used Avail Use% Mounted on
/dev/mapper/ubuntu-root  909G  565G  299G  66% /
none                     4.0K     0  4.0K   0% /sys/fs/cgroup
udev                     3.9G  4.0K  3.9G   1% /dev
tmpfs                    785M  1.2M  784M   1% /run
none                     5.0M     0  5.0M   0% /run/lock
none                     3.9G   63M  3.8G   2% /run/shm
none                     100M   48K  100M   1% /run/user
/dev/sda1                228M   98M  118M  46% /boot

展示Inode使用情况

当你监视磁盘使用情况时,你必须注意的不仅仅是磁盘空间还有“inode”的使用情况。在Linux中,inode是用来存储特定文件的元数据的一种数据结构,在创建一个文件系统时,inode的预先定义数量将被分配。这意味着,一个文件系统可能耗尽空间不只是因为大文件用完了所有可用空间,也可能是因为很多小文件用完了所有可能的inode。用“-i”选项展示inode使用情况。

$ df -i

Filesystem                Inodes   IUsed    IFree IUse% Mounted on
/dev/mapper/ubuntu-root 60514304 1217535 59296769    3% /
none                     1004417      13  1004404    1% /sys/fs/cgroup
udev                     1000623     552  1000071    1% /dev
tmpfs                    1004417     608  1003809    1% /run
none                     1004417      11  1004406    1% /run/lock
none                     1004417     288  1004129    1% /run/shm
none                     1004417      28  1004389    1% /run/user
/dev/sda1                 124496     346   124150    1% /boot

展示磁盘总利用率

默认情况下, df命令显示磁盘的单个文件系统的利用率。如果你想知道的所有文件系统的总磁盘使用量,增加“ –total ”选项(见最下面的汇总行)。

$ df -h --total

Filesystem               Size  Used Avail Use% Mounted on
/dev/mapper/ubuntu-root  909G  565G  299G  66% /
none                     4.0K     0  4.0K   0% /sys/fs/cgroup
udev                     3.9G  4.0K  3.9G   1% /dev
tmpfs                    785M  1.2M  784M   1% /run
none                     5.0M     0  5.0M   0% /run/lock
none                     3.9G   62M  3.8G   2% /run/shm
none                     100M   48K  100M   1% /run/user
/dev/sda1                228M   98M  118M  46% /boot
total                    918G  565G  307G  65% -

展示文件系统类型

默认情况下,df命令不显示文件系统类型信息。用“-T”选项来添加文件系统信息到输出中。

$ df -T

Filesystem              Type     1K-blocks      Used Available Use% Mounted on
/dev/mapper/ubuntu-root ext4     952893348 591583292 312882844  66% /
none                    tmpfs            4         0         4   0% /sys/fs/cgroup
udev                    devtmpfs   4002492         4   4002488   1% /dev
tmpfs                   tmpfs       803536      1196    802340   1% /run
none                    tmpfs         5120         0      5120   0% /run/lock
none                    tmpfs      4017668     60176   3957492   2% /run/shm
none                    tmpfs       102400        48    102352   1% /run/user
/dev/sda1               ext2        233191    100025    120725  46% /boot

包含或排除特定的文件系统类型

如果你想知道特定文件系统类型的剩余空间,用“-t ”选项。你可以多次使用这个选项来包含更多的文件系统类型。

$ df -t ext2 -t ext4

Filesystem              1K-blocks      Used Available Use% Mounted on
/dev/mapper/ubuntu-root 952893348 591583380 312882756  66% /
/dev/sda1                  233191    100025    120725  46% /boot

排除特定的文件系统类型,用“-x ”选项。同样,你可以用这个选项多次来排除多种文件系统类型。

$ df -x tmpfs

显示一个具体的挂载点磁盘使用情况

如果你用df指定一个挂载点,它将报告挂载在那个地方的文件系统的磁盘使用情况。如果你指定一个普通文件(或一个目录)而不是一个挂载点,df将显示包含这个文件(或目录)的文件系统的磁盘利用率。

$ df /

Filesystem              1K-blocks      Used Available Use% Mounted on
/dev/mapper/ubuntu-root 952893348 591583528 312882608  66% /

$ df /home/dev

Filesystem              1K-blocks      Used Available Use% Mounted on
/dev/mapper/ubuntu-root 952893348 591583528 312882608  66% /

显示虚拟文件系统的信息

如果你想显示所有已经存在的文件系统(包括虚拟文件系统)的磁盘空间信息,用“-a”选项。这里,虚拟文件系统是指没有相对应的物理设备的假文件系统,例如,tmpfs,cgroup虚拟文件系统或FUSE文件安系统。这些虚拟文件系统大小为0,不用“-a”选项将不会被报告出来。

$ df -a

Filesystem              1K-blocks      Used Available Use% Mounted on
/dev/mapper/ubuntu-root 952893348 591578716 312887420  66% /
proc                            0         0         0    - /proc
sysfs                           0         0         0    - /sys
none                            4         0         4   0% /sys/fs/cgroup
none                            0         0         0    - /sys/fs/fuse/connections
none                            0         0         0    - /sys/kernel/debug
none                            0         0         0    - /sys/kernel/security
udev                      4002492         4   4002488   1% /dev
devpts                          0         0         0    - /dev/pts
tmpfs                      803536      1196    802340   1% /run
none                         5120         0      5120   0% /run/lock
none                      4017668     58144   3959524   2% /run/shm
none                       102400        48    102352   1% /run/user
none                            0         0         0    - /sys/fs/pstore
cgroup                          0         0         0    - /sys/fs/cgroup/cpuset
cgroup                          0         0         0    - /sys/fs/cgroup/hugetlb
/dev/sda1                  233191    100025    120725  46% /boot
vmware-vmblock                  0         0         0    - /run/vmblock-fuse

via: http://ask.xmodulo.com/check-disk-space-linux-df-command.html

译者:mtunique 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

来源:https://linux.cn/article-4788-1.html

Linux:Ubuntu中跟踪多个时区的简捷方法

Linux:Ubuntu中跟踪多个时区的简捷方法
Linux:Ubuntu中跟踪多个时区的简捷方法

无论我是要在醒来时发个关于澳大利亚的 Chromebook 销售已经售罄的推特,还是要记着和Ohso的半个开发商山姆陈进行Skype通话,我大脑都需要同时工作在多个时区下。

那里头有个问题,如果你认识我,你会知道我的脑容量也就那么丁点,跟金鱼差不多,里头却塞着像Windows Vista这样一个臃肿货(也就是,不是很好)。我几乎记不得昨天之前的事情,更记不得我的门和金门大桥脚之间的时间差!

作为臂助,我使用一些小部件和菜单项来让我保持同步。在我常规工作日的空间里,我在多个操作系统间游弋,涵盖移动系统和桌面系统,但只有一个可以让我最快速便捷地设置“世界时钟”。

它的名字就是我们标题上提到的那个。

添加世界时钟到Ubuntu日期/时间小应用

Unity中默认的日期-时间指示器提供了添加并查看多个时区的支持,不需要附加组件,不需要额外的包。

  1. 点击时钟小应用,然后选择‘时间和日期设置’条目
  2. 在‘时钟’标签中,选中‘其它位置的时间’选框
  3. 点击‘选择位置’按钮
  4. 点击‘+’,然后输入位置名称

其它桌面环境

KDE Plasma中默认的时钟小应用有类似的功能,其它功能如下:

  1. 在数字时钟小部件上右击,然后选择‘数字时钟设置
  2. 点击‘时区’项
  3. 在搜索区输入城市名
  4. 点击‘确定

GNOME Shell的可扩展特性可以看到有许多世界时钟选项可用,可以用它的默认时间表填补左边的空白,我个人喜欢‘多个时钟’。对于Cinnamon桌面而言也是一样的,它的‘面板小部件’仓库有丰富的可选部件,如超级顺滑的“世界时钟日历”。

Linux:Ubuntu中跟踪多个时区的简捷方法
Linux:Ubuntu中跟踪多个时区的简捷方法

Cinnamon 2.4中的世界时钟日历

XFCELXDE就不那么慷慨了,除了自带的“工作区”作为多个时钟添加到面板外,每个都需要手动配置以指定位置。两个都支持‘指示器小部件’,所以,如果你不用Unity的话,你可以安装/添加单独的日期/时间指示器。

Budgie还刚初出茅庐,不足以胜任这种角落里的需求,因为Pantheon我还没试过——希望你们通过评论来让我知道得更多。

桌面应用、部件和Conky主题

当然,面板小部件只是收纳其它国家多个时区的一种方式。如果你不满意通过面板去访问,那里还有各种各样的桌面应用可供使用,其中许多都可以跨版本,甚至跨平台使用。

GNOME时钟就是这样一个应用,在Ubuntu 14.04 LTS及其后续版本中,你可以通过Ubuntu软件中心直接安装。Conky是一个很有潜力的备选(尽管我还没发现有哪个预制主题为此目的设计),而其它像日历时钟这样轻量级的Chrome应用可以在任何安装有Chrome这个免费浏览器的地方工作。

你也关注时区吗?如果是,你使用什么应用、采用什么方法或者小部件让它显示在顶层呢?


via: http://www.omgubuntu.co.uk/2014/12/add-time-zones-world-clock-ubuntu

作者:Joey-Elijah Sneddon 译者:GOLinux 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

来源:https://linux.cn/article-4789-1.html

Linux:20条Linux命令面试问答

Linux:20条Linux命令面试问答
Linux:20条Linux命令面试问答

问:1 如何查看当前的Linux服务器的运行级别?

答: ‘who -r’ 和 ‘runlevel’ 命令可以用来查看当前的Linux服务器的运行级别。

问:2 如何查看Linux的默认网关?

答: 用 “route -n” 和 “netstat -nr” 命令,我们可以查看默认网关。除了默认的网关信息,这两个命令还可以显示当前的路由表。

问:3 如何在Linux上重建初始化内存盘镜像文件?

答: 在CentOS 5.X / RHEL 5.X中,可以用mkinitrd命令来创建初始化内存盘文件,举例如下:

# mkinitrd -f -v /boot/initrd-$(uname -r).img $(uname -r)

如果你想要给特定的内核版本创建初始化内存盘,你就用所需的内核名替换掉 ‘uname -r’ 。

在CentOS 6.X / RHEL 6.X中,则用dracut命令来创建初始化内存盘文件,举例如下:

# dracut -f

以上命令能给当前的系统版本创建初始化内存盘,给特定的内核版本重建初始化内存盘文件则使用以下命令:

# dracut -f initramfs-2.x.xx-xx.el6.x86_64.img 2.x.xx-xx.el6.x86_64

问:4 cpio命令是什么?

答: cpio就是复制入和复制出的意思。cpio可以向一个归档文件(或单个文件)复制文件、列表,还可以从中提取文件。

问:5 patch命令是什么?如何使用?

答: 顾名思义,patch命令就是用来将修改(或补丁)写进文本文件里。patch命令通常是接收diff的输出并把文件的旧版本转换为新版本。举个例子,Linux内核源代码由百万行代码文件构成,所以无论何时,任何代码贡献者贡献出代码,只需发送改动的部分而不是整个源代码,然后接收者用patch命令将改动写进原始的源代码里。

创建一个diff文件给patch使用,

# diff -Naur old_file new_file > diff_file

旧文件和新文件要么都是单个的文件要么都是包含文件的目录,-r参数支持目录树递归。

一旦diff文件创建好,我们就能在旧的文件上打上补丁,把它变成新文件:

# patch < diff_file

问:6 aspell有什么用 ?

答: 顾名思义,aspell就是Linux操作系统上的一款交互式拼写检查器。aspell命令继任了更早的一个名为ispell的程序,并且作为一款免费替代品 ,最重要的是它非常好用。当aspell程序主要被其它一些需要拼写检查能力的程序所使用的时候,在命令行中作为一个独立运行的工具的它也能十分有效。

问:7 如何从命令行查看域SPF记录?

答: 我们可以用dig命令来查看域SPF记录。举例如下:

linuxtechi@localhost:~$ dig -t TXT google.com

问:8 如何识别Linux系统中指定文件(/etc/fstab)的关联包?

答: 

# rpm -qf /etc/fstab

以上命令能列出提供“/etc/fstab”这个文件的包。

问:9 哪条命令用来查看bond0的状态?

答: 

cat /proc/net/bonding/bond0

问:10 Linux系统中的/proc文件系统有什么用?

答: /proc文件系统是一个基于内存的文件系统,其维护着关于当前正在运行的内核状态信息,其中包括CPU、内存、分区划分、I/O地址、直接内存访问通道和正在运行的进程。这个文件系统所代表的并不是各种实际存储信息的文件,它们指向的是内存里的信息。/proc文件系统是由系统自动维护的。

问:11 如何在/usr目录下找出大小超过10MB的文件?

答: 

# find /usr -size +10M

问:12 如何在/home目录下找出120天之前被修改过的文件?

答: 

# find /home -mtime +120

问:13 如何在/var目录下找出90天之内未被访问过的文件?

答: 

# find /var ! -atime -90

问:14 在整个目录树下查找文件“core”,如发现则无需提示直接删除它们。

答:

# find / -name core -exec rm {} ;

问:15 strings命令有什么作用?

答: strings命令用来提取和显示非文本文件中的文本字符串。(LCTT 译注:当用来分析你系统上莫名其妙出现的二进制程序时,可以从中找到可疑的文件访问,对于追查入侵有用处)

问:16 tee 过滤器有什么作用 ?

答: tee 过滤器用来向多个目标发送输出内容。如果用于管道的话,它可以将输出复制一份到一个文件,并复制另外一份到屏幕上(或一些其它程序)。

linuxtechi@localhost:~$ ll /etc | nl | tee /tmp/ll.out

在以上例子中,从ll输出可以捕获到 /tmp/ll.out 文件中,并且同样在屏幕上显示了出来。

问:17 export PS1 = ”$LOGNAME@hostname:$PWD: 这条命令是在做什么?

答: 这条export命令会更改登录提示符来显示用户名、本机名和当前工作目录。

问:18 ll | awk ‘{print $3,”owns”,$9}’ 这条命令是在做什么?

答: 这条ll命令会显示这些文件的文件名和它们的拥有者。

问:19 :Linux中的at命令有什么用?

答: at命令用来安排一个程序在未来的做一次一次性执行。所有提交的任务都被放在 /var/spool/at 目录下并且到了执行时间的时候通过atd守护进程来执行。

问:20 linux中lspci命令的作用是什么?

答: lspci命令用来显示你的系统上PCI总线和附加设备的信息。指定-v,-vv或-vvv来获取越来越详细的输出,加上-r参数的话,命令的输出则会更具有易读性。


via: http://www.linuxtechi.com/20-linux-commands-interview-questions-answers/

作者:Pradeep Kumar 译者:ZTinoZ 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

来源:https://linux.cn/article-4790-1.html

Linux:Linux有问必答 – 如何在linux上安装WPS

问题: 我听说一个好东西Kingsoft Office(译注:就是WPS),所以我想在我的Linux上试试。我怎样才能安装Kingsoft Office呢?

Linux:Linux有问必答 - 如何在linux上安装WPS
Linux:Linux有问必答 – 如何在linux上安装WPS

Kingsoft Office 是一套办公套件,支持多个平台,包括Windows, Linux, iOS 和 Android。它包含三个组件:Writer(WPS文字)用来文字处理,Presentation(WPS演示)支持幻灯片,Spereadsheets(WPS表格)是电子表格。其使用免费增值模式,其中基础版本是免费使用。比较其他的linux办公套件,如LibreOffice、 OpenOffice,其最大优势在于,Kingsoft Office能最好的兼容微软的Office(译注:版权问题?了解下wps和Office的历史问题,可以得到一些结论)。因此如果你需要在windows和linux平台间交互,Kingsoft office是一个很好的选择。

CentOS, Fedora 或 RHEL中安装Kingsoft Office

官方页面下载RPM文件.官方RPM包只支持32位版本linux,但是你可以在64位中安装。

需要使用yum命令并用”localinstall”选项来本地安装这个RPM包

$ sudo yum localinstall kingsoft-office-9.1.0.4244-0.1.a12p3.i686.rpm

注意不要使用rpm命令安装。否者,你会得到依赖错误,而且很难解决:

错误: 依赖失败:
        libICE.so.6 is needed by kingsoft-office-9.1.0.4244-0.1.a12p3.i686
        libSM.so.6 is needed by kingsoft-office-9.1.0.4244-0.1.a12p3.i686
        libX11.so.6 is needed by kingsoft-office-9.1.0.4244-0.1.a12p3.i686
        libXext.so.6 is needed by kingsoft-office-9.1.0.4244-0.1.a12p3.i686
        libXrender.so.1 is needed by kingsoft-office-9.1.0.4244-0.1.a12p3.i686
        libc.so.6 is needed by kingsoft-office-9.1.0.4244-0.1.a12p3.i686

基于Red Hat的发行版有多重库支持。如果你要想安装的RPM包是32位的并有32位库依赖(你的系统是64位的),一个很好的解决方法就是使用yum来安装。只要RPM在构建时候已经添加所有依赖关系,yum就可以自动使用yum库解决依赖关系。

Linux:Linux有问必答 - 如何在linux上安装WPS
Linux:Linux有问必答 – 如何在linux上安装WPS

Debian, Ubuntu 和 Linux Mint 中安装Kingsoft Office

官方页面下载DEB包。官方RPM包同样只支持32位版本linux,但是你可以在64位中安装。

DEB包同样遇到一堆依赖。因此使用gdebi命令来代替dpkg来自动解决依赖。

$ sudo apt-get install gdebi-core
$ sudo gdebi kingsoft-office_9.1.0.4244~a12p3_i386.deb

启动 Kingsoft Office

安装完成后,你就可以在桌面管理器轻松启动Witer(WPS文字), Presentation(WPS演示), and Spreadsheets(WPS表格),如下图。

Ubuntu Unity中:

Linux:Linux有问必答 - 如何在linux上安装WPS
Linux:Linux有问必答 – 如何在linux上安装WPS

GNOME桌面中:

Linux:Linux有问必答 - 如何在linux上安装WPS
Linux:Linux有问必答 – 如何在linux上安装WPS

不但如此,你也可以在命令行中启动Kingsoft Office。

启动Wirter(WPS文字),使用这个命令:

$ wps (译注:原文丢失此命令)
Linux:Linux有问必答 - 如何在linux上安装WPS
Linux:Linux有问必答 – 如何在linux上安装WPS

启动Presentation(WPS演示),使用这个命令:

$ wpp
Linux:Linux有问必答 - 如何在linux上安装WPS
Linux:Linux有问必答 – 如何在linux上安装WPS

启动Spreadsheets(WPS表格),使用这个命令:

$ et
Linux:Linux有问必答 - 如何在linux上安装WPS
Linux:Linux有问必答 – 如何在linux上安装WPS

via: http://ask.xmodulo.com/install-kingsoft-office-linux.html

译者:Vic020/VicYu 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

来源:https://linux.cn/article-4791-1.html

Linux:六百字读懂 Git

译注:来自 Hacker School 的 Mary Rose Cook 实现了一个纯 JavaScript (Node.js)写就的 Git:Gitlet,包含了最主要的一些命令。这个项目一是为了了解 Git 内部原理,二是希望写一篇深入浅出解释 Git 核心概念的短文。学习一件东西的原理最好的方法就是去亲自实现它,而设计精巧的 Git 核心功能代码也不过 300 行。这就是这篇精巧的小文:Git in 600 words,相应的代码在 Github 上。短文很有趣,思路清晰也足够深入,值得一看。

Linux:六百字读懂 Git
Linux:六百字读懂 Git

设想你现在位于 alpha/ 目录下,这里有一个文本文件 number.txt,里面的内容只有一个词:“first”。

现在执行 git init 将这个 alpha 文件夹初始化为 Git 仓库。

执行 git add number.txt 会将 number.txt 添加到 Git 的索引(index)中。这个索引记录了所有 Git 保持追踪的文件,现在它有了一个映射记录 number.txt -> first,同时 add 命令还会把一个包含了 first 字符串的二进制对象加入 Git 的对象数据库里。

现在执行 git commit -m first。这条命令会做三件事情。首先在对象数据库内创建一个树对象,用以记录 alpha 目录下的文件列表,这个对象有一个指针指向前面 git add 命令创建的 first 二进制对象;第二,这条命令还会创建一个 commit 对象用以代表刚刚提交的版本,它包含一个指针指向刚刚的树对象;第三,master 分支也会指向这个新创建的 commit 对象。

现在执行 git clone . ../beta。它会创建一个新目录 beta 并将其初始化为 Git 仓库,然后把 alpha 仓库的对象数据库中所有对象拷贝给 beta 的对象数据库,将 beta 的 master 分支像 alpha 的 master 一样指向相应的对象。它还根据 first 提交的内容配置索引,并根据索引更新目录下的文件——也就是 number.txt。

现在切换到 beta 目录,修改 number.txt 的内容为“second”,执行 git add number.txt 和 git commit -m second,新创建的提交对象 second(译注:姑且称之为 second)会有一个指向父提交(first)的指针,表示 second 继承自 first,而 master 分支则指向 second 提交。

回到 alpha 目录,执行 git remote add beta ../beta,将 beta 仓库设为远程仓库。然后执行 git pull beta master。

在这条命令背后,它其实会执行 git fetch beta master,从 beta 仓库中找到 second 提交的相关对象拷贝到 alpha 仓库;把 alpha 中关于 beta 的 master 分支记录指向这个 second 提交;更新 FETCH_HEAD 指向刚刚从 beta 仓库拉取的 master 分支,还是这个 second 提交。

此外,pull 命令还会执行 git merge FETCH_HEAD。从 FETCH_HEAD 得知最近拉取的分支是 beta 仓库的 master 分支,据此拿到相应的对象,也就是 second 提交对象。此时 alpha 的 master 分支指着 first 提交,正好是 second 的祖先提交,于是对于 merge 命令来说只需要将 master 分支指向 second 提交即可。接下来 merge 命令还会更新索引以匹配 second 提交的内容,并且相应更新工作目录中的文件。

现在执行 git branch red,创建一个名为“red”、指向 second 提交的新分支。

然后执行 git checkout red。在 checkout 之前,HEAD 指向 master 分支,执行命令之后它就指向了 red 分支,使得 red 成为当前分支。

接下来把 number.txt 的内容修改为 “third”,执行 git add numbers.txt 和 run git commit -m third。

之后再执行 git push beta red,这条命令会把 alpha 仓库内跟 third 提交相关的对象拷贝至 beta 仓库,并且将(alpha 仓库内记录的)beta 仓库 red 分支指向 third 提交。就酱。

来源:http://segmentfault.com/blog/amio/1190000002514702

Linux:在CentOS 7中安装Jetty服务器

Jetty 是一款纯Java的HTTP (Web) 服务器和Java Servlet容器。 通常在更大的网络框架中,Jetty经常用于设备间的通信,而其他Web服务器通常给“人类”传递文件 :D。Jetty是一个Eclipse基金会的免费开源项目。这个Web服务器用于如Apache ActiveMQ、 Alfresco、 Apache Geronimo、 Apache Maven、 Apache Spark、Google App Engine、 Eclipse、 FUSE、 Twitter的 Streaming API 和 Zimbra中。

Linux:在CentOS 7中安装Jetty服务器
Linux:在CentOS 7中安装Jetty服务器

这篇文章会介绍‘如何在CentOS服务器中安装Jetty服务器’。

首先我们要用下面的命令安装JDK:

yum -y install java-1.7.0-openjdk wget

JDK安装之后,我们就可以下载最新版本的Jetty了:

wget http://download.eclipse.org/jetty/stable-9/dist/jetty-distribution-9.2.5.v20141112.tar.gz

解压并移动下载的包到/opt:

tar zxvf jetty-distribution-9.2.5.v20141112.tar.gz -C /opt/

重命名文件夹名为jetty:

mv /opt/jetty-distribution-9.2.5.v20141112/ /opt/jetty

创建一个jetty用户:

useradd -m jetty

改变jetty文件夹的所属用户:

chown -R jetty:jetty /opt/jetty/

为jetty.sh创建一个软链接到 /etc/init.d directory 来创建一个启动脚本文件:

ln -s /opt/jetty/bin/jetty.sh /etc/init.d/jetty

添加脚本:

chkconfig --add jetty

是jetty在系统启动时启动:

chkconfig --level 345 jetty on

使用你最喜欢的文本编辑器打开 /etc/default/jetty 并修改端口和监听地址:

vi /etc/default/jetty

JETTY_HOME=/opt/jetty
JETTY_USER=jetty
JETTY_PORT=8080
JETTY_HOST=50.116.24.78
JETTY_LOGS=/opt/jetty/logs/

*我们完成了安装,现在可以启动jetty服务了 *

service jetty start

完成了!

现在你可以在 http://<你的 IP 地址>:8080 中访问了

就是这样。

干杯!!


via: http://www.unixmen.com/install-jetty-web-server-centos-7/

作者:Jijo 译者:geekpi 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

来源:https://linux.cn/article-4792-1.html

Linux:12 个最佳的免费网络监控工具

要让一个多级机构运行良好而且平稳的话,一个非常艰巨重大的任务就是做好网络管理。每个机构都配备专门的人员,即网络分析师,来进行网络管理。他们 使用了 许多工具来监视网络的运行状况,并查看网络流量的上升和下降状况。他们还必须确保整个网络能够平稳地运行,因为只要有一分钟的网络中断就会使得整个机构的 工作出现混乱。

使得机构工作平稳运行的最重要的方式之一就是使用各种网络监视工具。使用IDS检测来自外部网络的威胁和问题,使用网络监 视软件来监视由于内部服务器负载 过高或者某个网络部员工的小错误而引起的问题。网络监视软件可以跟踪数据包的流向,而且它还可以对数据包活动表现异常的地方进行检测,以确定出错的地方。 例如,为了检测web服务器的运行状况,网络监视软件将定期不间断地发送32位字节的ping请求,跟踪服务器是否收到了该请求并及时响应。

现有的网络监控工具可以说是数以百计,但是这些工具往往比较昂贵,因此花些时间去选购是很值得的,需要仔细研究其适用性、性能、专业性等方面的特 性,需要判断的因素很多,但短时间内理解这些指标并作出选择可不是一件容易的事。因此,我们利用专业经验,建立了包括一些最佳免费网络监控工具的清单,为实现网络的安全、稳定长期运行提供帮助,以下是具体的清单列表:

1) Fiddler

Fiddler(几乎)是适用于任何平台和任何操作系统的最好的免费网络工具,并提供了一些广受欢迎的关键特性。如:性能测试、捕捉记录HTTP/HTTPs请求响应、进行web调试等很多功能.

Linux:12 个最佳的免费网络监控工具
Linux:12 个最佳的免费网络监控工具

2) Nagios

Nagios是另外一款在互联网上的免费网络监控工具。 它是开源的监控解决方案,它表现非凡并且持续为全球成千上万的组织提供可靠的监测。

Linux:12 个最佳的免费网络监控工具
Linux:12 个最佳的免费网络监控工具

3) Nedi

Nedi也是一款对用户来说开源的网络监控工具。 NeDi可以在你的核心网络设备上,针对CDP, FDP和、或LLDP充分发挥潜力。它还可以包括其他网络组件, 当他们位于网络边界上,也可以工作地非常好。

4) EasyNetMonitor

一个监控你电脑本地和互联网主机之间网络的最小免费工具。开始我们的EasyNetMonitor,打开弹出菜单可以看到你电脑的网络状态信息。

免费网络监控 EasyNetMonitor 是一个小而简单易用的测试远程主机和其他网络主机之间网络到达率的工具。很简单的点击EasyNetMonitor图标就可以获得关于你本地网络和互联网主机的实时信息。

Linux:12 个最佳的免费网络监控工具
Linux:12 个最佳的免费网络监控工具

5) Microsoft Network Monitor

这 个是Microsoft. Network Monitor 3.4稳定版非开发版协议分析器提供的网络监控工具。微软消息分析器替代了网络监控3.4。微软消息分析器提供最新的协议分析,比如捕捉屏幕,显示,协议 消息流量分析、事件和在其他系统或应用程序消息故障排除和诊断方案方面。这是一个更强大的工具来捕获和分析协议消息。

Linux:12 个最佳的免费网络监控工具
Linux:12 个最佳的免费网络监控工具

6) Cacti

Cacti 是一个完整的网络绘图解决方案旨在利用RRDTool的数据存储和图形绘制功能。Cacti提供了一个快速的轮询器,先进的图形模板,多个数据采集方法和 用户管理的开箱即用的特性。所有的封装都是为局域网内的数百台设备复杂网络的安装提供很直观的,易用的界面。

Linux:12 个最佳的免费网络监控工具
Linux:12 个最佳的免费网络监控工具

7) Zenoss

Zenoss 的核心是为企业IT监控工具提供一些关键特性-

  • 跨平台设备性能和可用性监控

  • 高度可定制的基于web的控制台和仪表板

  • 设备探索、建模和分类

  • 三层网络拓扑图

  • 最好的数据收集

  • 错误和事件监控和管理

  • 事件分类、重复数据删除、自动清档、映射转换,和生命周期管理

  • 事件触发和通知

  • 可用性监控设备、网络、进程和服务等

8) Paessler

Paessler 是一个强大的易用的网络监控软件。PRTG网络监视器运行在Windows机器的网络上,可以收集你指定的机器,软件和设备的各种统计数 据。PRTG附带一个易于使用的web界面点击配置。你可以很容易地共享数据给非技术的同事和客户,包括通过现场图和自定义报告。

Linux:12 个最佳的免费网络监控工具
Linux:12 个最佳的免费网络监控工具

9) Bandwidthd

BandwidthD可以跟踪使用TCP / IP网络的子网和构建html文件图表显示的利用率。

Linux:12 个最佳的免费网络监控工具
Linux:12 个最佳的免费网络监控工具

10) Icinga

Icinga是一个处理多服务,多设备以及它们之间复杂依赖关系的网络监控工具。不需要进行复杂的安装或维护监测系统。

11) The Dude

The Dude 网络监控是由 MikroTik 提供的新的应用程序,可以大大提高你的管理您的网络环境。它会自动扫描指定的子网内的所有设备,绘制地图和布局你的网络,监控服务的设备和提醒你,以防一些服务问题。

Linux:12 个最佳的免费网络监控工具
Linux:12 个最佳的免费网络监控工具

12) Total Network Monitor

Total Network Monitor 是一个为持续监控本地网络,个人电脑以及需要细心观察和深入控制的服务提供的免费网络监控软件。

Linux:12 个最佳的免费网络监控工具
Linux:12 个最佳的免费网络监控工具

来源:http://www.oschina.net/translate/top-12-best-free-network-monitoring-tools

Linux:PHP 中「自增、自减」运算引发的奇怪问题

在 PHP 的官方手册中写道:

PHP 支持 C 风格的前/后递增与递减运算符。

Linux:PHP 中「自增、自减」运算引发的奇怪问题
Linux:PHP 中「自增、自减」运算引发的奇怪问题

第一个注意事:递增/递减运算符不影响布尔值。递减 NULL 值也没有效果,但是递增 NULL 的结果是 1

换句话说:递增/递减运算中,不会把操作数转换成整数后再运算。如果运算数是布尔值,则直接返回结果。

递增/递减布尔值:

$a = TRUE;
var_dump(++$a); // bool(true)
$a = TRUE;
var_dump(--$a); // bool(true)
$b = FALSE;
var_dump(++$b); // bool(false)
$b = FALSE;
var_dump(--$b); // bool(false)

递增/递减 NULL:

$a = NULL;
var_dump(++$a); // int(1)
$a = NULL;
var_dump(--$a); // NULL

在处理字符变量的算数运算时,PHP 沿袭了 Perl 的习惯,而非 C 的

例如,在 Perl 中

$a = 'Z';
$a++;

将把 $a 变成 ‘AA’,而在 C 中,

a = 'Z';
a++;

将把 a 变成 ‘[‘(’Z’ 的 ASCII 值是 90,'[‘ 的 ASCII 值是 91)。

注意字符变量只能递增,不能递减,并且只支持纯字母(a-z 和 A-Z)

例如:

$a="9D9";
var_dump(++$a);  // string(3) "9E0"

但是,这里又有一个陷阱了:

$a="9E0";
echo ++$a;  // 10

安装上面的规则,应该输出 9E1,但是这里却输出了 10。WTF?

如果我们这么写,大部人就知道是为什么了。

$a = "9E0";
var_dump(++$a);  // float(10)

$a 的类型是浮点型,也就是说,9E0 是浮点数的科学记数法,即 9 * 10^0 = 9,对 9 自增,结果当然是 10 了。(参考:字符串转换为数值

现在问题又来了:

$l = "Z99";
$l++;

这个结果是多少呢?结果按照 perl 语言的规则,是 “AA00″。

还有一个注意事项:

递增/递减其他字符变量则无效,原字符串没有变化

这个就不解释了。

最后一个注意事项:

$a = '012';
$a++;
var_dump($a);

这个结果是 ‘013’?13?11?

这段的结果是 int(13),字符串 ‘012’ 并没有被当作八进制。

$a = 012;   // 八进制,十进制为 10
$b = "012"; // 转换为整数为十进制 12

如果是 0x 开头的呢?

$a = '0x1A';
$a++;
var_dump($a);   // int(27)

WTF!居然不按套路出牌。0 开头的不被认为是八进制,但是 0x 开头的却被认为是十六进制。

在 PHP 官方文档中 Integer 整型 还有另一个八进制陷阱:

var_dump(01090); // 八进制 010 = 十进制 8

手册中对此的解释为:

Warning如果向八进制数传递了一个非法数字(即 8 或 9),则后面其余数字会被忽略。

综上,PHP 不愧是世界上「最好」的语言。

没有之一。

来源:http://www.jianshu.com/p/d736607b1f0c

Linux:etcd:从应用场景到实现原理的全方位解读

随着CoreOS和Kubernetes等项目在开源社区日益火热,它们项目中都用到的etcd组件作为一个高可用强一致性的服务发现存储仓库,渐渐为开发人员所关注。在云计算时代,如何让服务快速透明地接入到计算集群中,如何让共享配置信息快速被集群中的所有机器发现,更为重要的是,如何构建这样一套高可用、安全、易于部署以及响应快速的服务集群,已经成为了迫切需要解决的问题。etcd为解决这类问题带来了福音,本文将从etcd的应用场景开始,深入解读etcd的实现方式,以供开发者们更为充分地享用etcd所带来的便利。

经典应用场景

要问etcd是什么?很多人第一反应可能是一个键值存储仓库,却没有重视官方定义的后半句,用于配置共享和服务发现。

A highly-available key value store for shared configuration and service discovery.

实际上,etcd作为一个受到ZooKeeper与doozer启发而催生的项目,除了拥有与之类似的功能外,更专注于以下四点。

  • 简单:基于HTTP+JSON的API让你用curl就可以轻松使用。
  • 安全:可选SSL客户认证机制。
  • 快速:每个实例每秒支持一千次写操作。
  • 可信:使用Raft算法充分实现了分布式。

随着云计算的不断发展,分布式系统中涉及到的问题越来越受到人们重视。受阿里中间件团队对ZooKeeper典型应用场景一览一文的启发,笔者根据自己的理解也总结了一些etcd的经典使用场景。让我们来看看etcd这个基于Raft强一致性算法的分布式存储仓库能给我们带来哪些帮助。

值得注意的是,分布式系统中的数据分为控制数据和应用数据。使用etcd的场景默认处理的数据都是控制数据,对于应用数据,只推荐数据量很小,但是更新访问频繁的情况

场景一:服务发现(Service Discovery)

服务发现要解决的也是分布式系统中最常见的问题之一,即在同一个分布式集群中的进程或服务,要如何才能找到对方并建立连接。本质上来说,服务发现就 是想要了解集群中是否有进程在监听udp或tcp端口,并且通过名字就可以查找和连接。要解决服务发现的问题,需要有下面三大支柱,缺一不可。

  1. 一个强一致性、高可用的服务存储目录。基于Raft算法的etcd天生就是这样一个强一致性高可用的服务存储目录。
  2. 一种注册服务和监控服务健康状态的机制。用户可以在etcd中注册服务,并且对注册的服务设置key TTL,定时保持服务的心跳以达到监控健康状态的效果。
  3. 一种查找和连接服务的机制。通过在etcd指定的主题下注册的服务也能在对应的主题下查找到。为了确保连接,我们可以在每个服务机器上都部署一个Proxy模式的etcd,这样就可以确保能访问etcd集群的服务都能互相连接。

图1 服务发现示意图

下面我们来看服务发现对应的具体场景。

  • 微服务协同工作架构中,服务动态添加。随着Docker容器的流行,多种微服务共同协作,构成一个相对功能 强大的架构的案例越来越多。透明化的动态添加这些服务的需求也日益强烈。通过服务发现机制,在etcd中注册某个服务名字的目录,在该目录下存储可用的服 务节点的IP。在使用服务的过程中,只要从服务目录下查找可用的服务节点去使用即可。

图2 微服务协同工作

  • PaaS平台中应用多实例与实例故障重启透明化。PaaS平台中的应用一般都有多个实例,通过域名,不仅可以透明的对这多个实例进行访问,而且还可以做到负载均衡。但是应用的某个实例随时都有可能故障重启,这时就需要动态的配置域名解析(路由)中的信息。通过etcd的服务发现功能就可以轻松解决这个动态配置的问题。

图3 云平台多实例透明化

场景二:消息发布与订阅

在分布式系统中,最适用的一种组件间通信方式就是消息发布与订阅。即构建一个配置共享中心,数据提供者在这个配置中心发布消息,而消息使用者则订阅他们关心的主题,一旦主题有消息发布,就会实时通知订阅者。通过这种方式可以做到分布式系统配置的集中式管理与动态更新。

  • 应用中用到的一些配置信息放到etcd上进行集中管理。这类场景的使用方式通常是这样:应用在启动的时候主动从etcd获取一次配置信息,同时,在etcd节点上注册一个Watcher并等待,以后每次配置有更新的时候,etcd都会实时通知订阅者,以此达到获取最新配置信息的目的。
  • 分布式搜索服务中,索引的元信息和服务器集群机器的节点状态存放在etcd中,供各个客户端订阅使用。使用etcd的key TTL功能可以确保机器状态是实时更新的。
  • 分布式日志收集系统。这个系统的核心工作是收集分布在不同机器的日志。收集器通常是按照应用(或主题)来分 配收集任务单元,因此可以在etcd上创建一个以应用(主题)命名的目录P,并将这个应用(主题相关)的所有机器ip,以子目录的形式存储到目录P上,然 后设置一个etcd递归的Watcher,递归式的监控应用(主题)目录下所有信息的变动。这样就实现了机器IP(消息)变动的时候,能够实时通知到收集 器调整任务分配。
  • 系统中信息需要动态自动获取与人工干预修改信息请求内容的情况。通常是暴露出接口,例如JMX接口,来获取一些运行时的信息。引入etcd之后,就不用自己实现一套方案了,只要将这些信息存放到指定的etcd目录中即可,etcd的这些目录就可以通过HTTP的接口在外部访问。

图4 消息发布与订阅

场景三:负载均衡

在场景一中也提到了负载均衡,本文所指的负载均衡均为软负载均衡。分布式系统中,为了保证服务的高可用以及数据的一致 性,通常都会把数据和服务部署多份,以此达到对等服务,即使其中的某一个服务失效了,也不影响使用。由此带来的坏处是数据写入性能下降,而好处则是数据访 问时的负载均衡。因为每个对等服务节点上都存有完整的数据,所以用户的访问流量就可以分流到不同的机器上。

  • etcd本身分布式架构存储的信息访问支持负载均衡。etcd集群化以后,每个etcd的核心节点都可以处 理用户的请求。所以,把数据量小但是访问频繁的消息数据直接存储到etcd中也是个不错的选择,如业务系统中常用的二级代码表(在表中存储代码,在 etcd中存储代码所代表的具体含义,业务系统调用查表的过程,就需要查找表中代码的含义)。
  • 利用etcd维护一个负载均衡节点表。etcd可以监控一个集群中多个节点的状态,当有一个请求发过来后,可以轮询式的把请求转发给存活着的多个状态。类似KafkaMQ,通过ZooKeeper来维护生产者和消费者的负载均衡。同样也可以用etcd来做ZooKeeper的工作。

图5 负载均衡

场景四:分布式通知与协调

这里说到的分布式通知与协调,与消息发布和订阅有些相似。都用到了etcd中的Watcher机制,通过注册与异步通知机制,实现分布式环境下不同 系统之间的通知与协调,从而对数据变更做到实时处理。实现方式通常是这样:不同系统都在etcd上对同一个目录进行注册,同时设置Watcher观测该目 录的变化(如果对子目录的变化也有需要,可以设置递归模式),当某个系统更新了etcd的目录,那么设置了Watcher的系统就会收到通知,并作出相应 处理。

  • 通过etcd进行低耦合的心跳检测。检测系统和被检测系统通过etcd上某个目录关联而非直接关联起来,这样可以大大减少系统的耦合性。
  • 通过etcd完成系统调度。某系统有控制台和推送系统两部分组成,控制台的职责是控制推送系统进行相应的推送工作。管理人员在控制台作的一些操作,实际上是修改了etcd上某些目录节点的状态,而etcd就把这些变化通知给注册了Watcher的推送系统客户端,推送系统再作出相应的推送任务。
  • 通过etcd完成工作汇报。大部分类似的任务分发系统,子任务启动后,到etcd来注册一个临时工作目录,并且定时将自己的进度进行汇报(将进度写入到这个临时目录),这样任务管理者就能够实时知道任务进度。

图6 分布式协同工作

场景五:分布式锁

因为etcd使用Raft算法保持了数据的强一致性,某次操作存储到集群中的值必然是全局一致的,所以很容易实现分布式锁。锁服务有两种使用方式,一是保持独占,二是控制时序。

  • 保持独占即所有获取锁的用户最终只有一个可以得到。etcd为此提供了一套实现分布式锁原子操作CAS(CompareAndSwap)的API。通过设置prevExist值,可以保证在多个节点同时去创建某个目录时,只有一个成功。而创建成功的用户就可以认为是获得了锁。
  • 控制时序,即所有想要获得锁的用户都会被安排执行,但是获得锁的顺序也是全局唯一的,同时决定了执行顺序。etcd为此也提供了一套API(自动创建有序键),对一个目录建值时指定为POST动作,这样etcd会自动在目录下生成一个当前最大的值为键,存储这个新的值(客户端编号)。同时还可以使用API按顺序列出所有当前目录下的键值。此时这些键的值就是客户端的时序,而这些键中存储的值可以是代表客户端的编号。

图7 分布式锁

场景六:分布式队列

分布式队列的常规用法与场景五中所描述的分布式锁的控制时序用法类似,即创建一个先进先出的队列,保证顺序。

另一种比较有意思的实现是在保证队列达到某个条件时再统一按顺序执行。这种方法的实现可以在/queue这个目录中另外建立一个/queue/condition节点。

  • condition可以表示队列大小。比如一个大的任务需要很多小任务就绪的情况下才能执行,每次有一个小任务就绪,就给这个condition数字加1,直到达到大任务规定的数字,再开始执行队列里的一系列小任务,最终执行大任务。
  • condition可以表示某个任务在不在队列。这个任务可以是所有排序任务的首个执行程序,也可以是拓扑结构中没有依赖的点。通常,必须执行这些任务后才能执行队列中的其他任务。
  • condition还可以表示其它的一类开始执行任务的通知。可以由控制程序指定,当condition出现变化时,开始执行队列任务。

图8 分布式队列

场景七:集群监控与Leader竞选

通过etcd来进行监控实现起来非常简单并且实时性强。

  1. 前面几个场景已经提到Watcher机制,当某个节点消失或有变动时,Watcher会第一时间发现并告知用户。
  2. 节点可以设置TTL key,比如每隔30s发送一次心跳使代表该机器存活的节点继续存在,否则节点消失。

这样就可以第一时间检测到各节点的健康状态,以完成集群的监控要求。

另外,使用分布式锁,可以完成Leader竞选。这种场景通常是一些长时间CPU计算或者使用IO操作的机器,只需要竞选出的Leader计算或处理一次,就可以把结果复制给其他的Follower。从而避免重复劳动,节省计算资源。

这个的经典场景是搜索系统中建立全量索引。如果每个机器都进行一遍索引的建立,不但耗时而且建立索引的一致性不能保证。通过在etcd的CAS机制同时创建一个节点,创建成功的机器作为Leader,进行索引计算,然后把计算结果分发到其它节点。

图9 Leader竞选

场景八:为什么用etcd而不用ZooKeeper

阅读了“ZooKeeper典型应用场景一览”一文的读者可能会发现,etcd实现的这些功能,ZooKeeper都能实现。那么为什么要用etcd而非直接使用ZooKeeper呢?

相较之下,ZooKeeper有如下缺点:

  1. 复杂。ZooKeeper部署维护复杂,管理员需要掌握一系列的知识和技能;而Paxos强一致性算法也是素来以复杂难懂而闻名于世;另外,ZooKeeper的使用也比较复杂,需要安装客户端,官方只提供了Java和C两种语言的接口。
  2. Java编写。这里不是对Java有偏见,而是Java本身就偏向于重型应用,它会引入大量的依赖。而运维人员则普遍希望保持强一致、高可用的机器集群尽可能简单,维护起来也不易出错。
  3. 发展缓慢。Apache基金会项目特有的“Apache Way”在开源界饱受争议,其中一大原因就是由于基金会庞大的结构以及松散的管理导致项目发展缓慢。

而etcd作为一个后起之秀,其优点也很明显。

  1. 简单。使用Go语言编写部署简单;使用HTTP作为接口使用简单;使用Raft算法保证强一致性让用户易于理解。
  2. 数据持久化。etcd默认数据一更新就进行持久化。
  3. 安全。etcd支持SSL客户端安全认证。

最后,etcd作为一个年轻的项目,真正告诉迭代和开发中,这既是一个优点,也是一个缺点。优点是它的未来具有无限的可能性,缺点是无法得到大项目 长时间使用的检验。然而,目前CoreOS、Kubernetes和CloudFoundry等知名项目均在生产环境中使用了etcd,所以总的来 说,etcd值得你去尝试。

来源:http://www.infoq.com/cn/articles/etcd-interpretation-application-scenario-implement-principle

Linux:如何解压 tar 文件到不同的目录中

我想要解压一个tar文件到一个叫/tmp/data的指定目录。我该如何在Linux或者类Unix的系统中使用tar命令解压一个tar文件到不同的目录中?

Linux:如何解压 tar 文件到不同的目录中
Linux:如何解压 tar 文件到不同的目录中

你不必使用cd命令切换到其他的目录并解压。可以使用下面的语法解压一个文件:

语法

典型Unix tar语法:

tar -xf file.name.tar -C /path/to/directory

GNU/tar 语法:

tar xf file.tar -C /path/to/directory
tar xf file.tar --directory /path/to/directory

示例:解压文件到另一个目录中

在本例中。我解压$HOME/etc.backup.tar到/tmp/data目录中。首先,需要手动创建这个目录,输入:

mkdir /tmp/data

要解压$HOME/etc.backup.tar 到/tmp/data中,输入:

tar -xf $HOME/etc.backup.tar -C /tmp/data

要看到进度,使用-v选项:

tar -xvf $HOME/etc.backup.tar -C /tmp/data

示例输出:

Linux:如何解压 tar 文件到不同的目录中
Linux:如何解压 tar 文件到不同的目录中

Gif 01: tar命令解压文件到不同的目录

你也可以指定解压的文件:

tar -xvf $HOME/etc.backup.tar file1 file2 file3 dir1 -C /tmp/data

要解压foo.tar.gz(.tgz扩展文件)包到/tmp/bar中,输入:

mkdir /tmp/bar
tar -zxvf foo.tar.gz -C /tmp/bar

要解压foo.tar.bz2(.tbz, .tbz2 和 .tb2 扩展文件)包到/tmp/bar中,输入:

mkdir /tmp/bar
tar -jxvf foo.tar.bz2  -C /tmp/bar

via: http://www.cyberciti.biz/faq/howto-extract-tar-file-to-specific-directory-on-unixlinux/

作者:nixCraft 译者:geekpi 校对:Caroline

本文由 LCTT 原创翻译,Linux中国 荣誉推出

来源:https://linux.cn/article-4814-1.html

Linux:为什么 Cloudera 要创建 Hadoop 安全组件 Sentry ?

1.  大数据的安全体系

要说清楚这个问题,还得从大数据平台安全体系的四个层次说起:外围安全、数据安全、访问安全以及访问行为监控;如下图所示;

Linux:为什么 Cloudera 要创建 Hadoop 安全组件 Sentry ?
Linux:为什么 Cloudera 要创建 Hadoop 安全组件 Sentry ?

外围安全技术多指传统意义上提到的网络安全技术,如防火墙,登陆认证等;

数据安全从狭义上说包括对用户数据的加解密,又可细分为存储加密和传输加密;还包括用户数据的脱敏,脱敏可以看做“轻量级”的数据加密。如某人的生日为“2014-12-12”,脱敏后的数据为“2014-x-x”。数据的轮廓依然存在,但已无法精确定位数值。脱敏的程度越高数据可辨认度越低。上述的例子还可脱敏为“x-x-x”,相当于完全对外屏蔽该信息。

访问安全主要是对用户的授权进行管理。Linux/Unix系统中用户-组的读、写、执行权限管理堪称其中的经典模型。HDFS对这一概念进行了扩充,形成了更加完备的ACL体系;另外随着大数据的应用的普及和深入,文件内部数据访问权限差异化的需求也变得越来越重要;

访问行为监控多指记录用户对系统的访问行为:如查看哪个文件;运行了哪些SQL查询;访问行为监控一方面为了进行实时报警,迅速处置非法或者危险的访问行为;另一方面为了事后调查取证,从长期的数据访问行为中分析定位特定的目的。

在这四个安全的层次中,第三层同上层业务的关系最为直接:应用程序的多租户,分权限访问控制都直接依赖这一层的技术实现。

2.  HDFS的授权体系

在上述的第三层中,Hadoop生态圈长久以来一直沿用Linux/Unix系统的授权管理模型,将文件的访问权限分为读-写两种权限(HDFS上没有可执行文件的概念),将权限的所有者划分为三个大类:拥有者(owner),所在组(group),以及其他人(other)。这种模型限制权限的所有者只能有三类。如果试图增加一个新的“组”,并设定该组的用户拥有不同于owner,group或other的权限,现有的Linux/Unix授权模型是无法优雅地解决这个问题的。

举例来说明上述状况:假设有一个销售部门,部门经理manager具有修改销售数据sales_data的权利;销售部门的成员具有查看sales_data的权利,销售部门以外的人无法看到销售数据sales_data。那么对于销售数据sales_data的授权如下所示:

-rw-r-----   3  manager sales      0   2015-01-25  18:51  sales_data 

后来该销售部门扩充了人员,又来两个销售经理,一个叫manager1,另一个叫manager2。这两个销售经理也被允许修改销售数据。这种情况下,manager1和manager2只能使用一个新账号manager_account,然后使该账号能够使用setuid对sales_data进行修改。这使得对同一份数据的权限管理变得复杂而不容易维护。

由于上述问题的存在,Hadoop2.4.0中添加了对HDFS ACL(Access Control Lists)的支持。这一新特性很好地解决了上述的问题。然而随着Hadoop在企业中广泛地应用,越来越多的业务场景要求大数据访问控制的粒度也不再局限在文件级别,而是更加细致地约束文件内部的数据哪些能被读写,哪些只能被读,哪些完全不允许被访问。对于基于SQL的大数据引擎来说,数据访问不止要到表粒度,更要精确到行列级别。

3.  Hiveserver2的授权

Hive是早期将高级查询语言SQL引入Hadoop平台的引擎之一,早期的Hive服务器进程被称作Hiveserver1;Hiveserver1既不支持处理并行的多个连接,又不支持访问授权控制;后来这两个问题在Hiveserver2上被解决,Hiveserver2能够使用grant/revoke语句来限制用户对数据库、表、视图的访问权限,行列权限的控制是通过生成视图来实现的;但Hiveserver2的授权管理体系被认为存在问题,那就是任何通过认证登陆的用户都能够为自己增加对任何资源的访问权限。也就是说Hiveserver2提供的不是一种安全的授权体系,Hiveserver2的授权体系是为防止正常用户误操作而提供保障机制;不是为保护敏感数据的安全性而设计的。然而这些更多的是某些公司的说辞,事实上Hiveserver2自身的安全体系也在逐步完善,上述问题也在快速修复中。

但授权管理其实不止是Hive需要,其他的查询引擎也迫切需要这些技术来完善和规范应用程序对数据的访问。对于细粒度授权管理的实现,很大一部分功能在各引擎之间是可以公用的,因此独立实现的授权管理工具是非常必要的。

4.  Sentry提供的安全授权管理

在这样的背景下,Cloudera公司的一些开发者利用Hiveserver2中现有的授权管理模型,扩展并细化了很多细节,完成了一个相对具有使用价值的授权管理工具Sentry,下图是Sentry与Hiveserver2中的授权管理模型的对比:

Linux:为什么 Cloudera 要创建 Hadoop 安全组件 Sentry ?
Linux:为什么 Cloudera 要创建 Hadoop 安全组件 Sentry ?

Sentry的很多基本模型和设计思路都来源于Hiveserver2,但在其基础之上加强了RBAC的概念。在Sentry中,所有的权限都只能授予角色,当角色被挂载到用户组的时候,该组内的用户才具有相应的权限。权限à角色à用户组à用户,这一条线的映射关系在Sentry中显得尤为清晰,这条线的映射显示了一条权限如何能最后被一个用户所拥有;从权限到角色,再到用户组都是通过grant/revoke的SQL语句来授予的。从“用户组”到能够影响“用户”是通过Hadoop自身的用户-组映射来实现的。Hadoop提供两种映射:一种是本地服务器上的Linux/Unix用户到所在组的映射;另一种是通过LDAP实现的用户到所属组的映射;后者对于大型系统而言更加适用,因为具有集中配置,易于修改的好处。

Sentry将Hiveserver2中支持的数据对象从数据库/表/视图扩展到了服务器,URI以及列粒度。虽然列的权限控制可以用视图来实现,但是对于多用户,表数量巨大的情况,视图的方法会使得给视图命名变得异常复杂;而且用户原先写的针对原表的查询语句,这时就无法直接使用,因为视图的名字可能与原表完全不同。

目前Sentry1.4能够支持的授权级别还局限于SELECT,INSERT,ALL这三个级别,但后续版本中已经能够支持到与Hiveserver2现有的水平。Sentry来源于Hiveserver2中的授权管理模型,但却不局限于只管理Hive,而希望能管理Impala, Solr等其他需要授权管理的查询引擎,Sentry的架构图如下所示:

Linux:为什么 Cloudera 要创建 Hadoop 安全组件 Sentry ?
Linux:为什么 Cloudera 要创建 Hadoop 安全组件 Sentry ?

Sentry的体系结构中有三个重要的组件:一是Binding;二是Policy Engine;三是Policy Provider。

Binding实现了对不同的查询引擎授权,Sentry将自己的Hook函数插入到各SQL引擎的编译、执行的不同阶段。这些Hook函数起两大作用:一是起过滤器的作用,只放行具有相应数据对象访问权限的SQL查询;二是起授权接管的作用,使用了Sentry之后,grant/revoke管理的权限完全被Sentry接管,grant/revoke的执行也完全在Sentry中实现;对于所有引擎的授权信息也存储在由Sentry设定的统一的数据库中。这样所有引擎的权限就实现了集中管理。

Policy Engine判定输入的权限要求与已保存的权限描述是否匹配,Policy Provider负责从文件或者数据库中读取出原先设定的访问权限。Policy Engine以及Policy Provider其实对于任何授权体系来说都是必须的,因此是公共模块,后续还可服务于别的查询引擎。

5.  小结

大数据平台上细粒度的访问权限控制各家都在做,当然平台厂商方面主导的还是Cloudera和Hortonworks两家,Cloudera主推Sentry为核心的授权体系;Hortonwork一方面靠对开源社区走向得把控,另一方面靠收购的XA Secure。无论今后两家公司对大数据平台市场的影响力如何变化,大数据平台上的细粒度授权访问都值得我们去学习。

6.  引用

来源:http://www.mininglamp.com

Linux:HTML5应用程序缓存Application Cache

什么是Application Cache

HTML5引入了应用程序缓存技术,意味着web应用可进行缓存,并在没有网络的情况下使用,通过创建cache manifest文件,可以轻松的创建离线应用。

Application Cache带来的三个优势是:

① 离线浏览

② 提升页面载入速度

③ 降低服务器压力

而且主要浏览器皆以支持Application Cache,就算不支持也不会对程序造成什么影响

离线存储技术

HTML5提出了两大离线存储技术:localstorage与Application Cache,两者各有应用场景;传统还有离线存储技术为Cookie。

经过实践我们认为localstorage应该存储一些非关键性ajax数据,做锦上添花的事情;

Application Cache用于存储静态资源,仍然是干锦上添花的事情;

而cookie只能保存一小段文本(4096字节);所以不能存储大数据,这是cookie与上述缓存技术的差异之一,而因为HTTP是无状态的, 服务器为了区分请求是否来源于同一个服务器,需要一个标识字符串,而这个任务就是cookie完成的,这一段文本每次都会在服务器与浏览器之间传递,以验 证用户的权限。

所以Application Cache的应用场景不一样,所以使用也不一致。

Application Cache简介

Application Cache的使用要做两方面的工作:

① 服务器端需要维护一个manifest清单

② 浏览器上只需要一个简单的设置即可


以例子做说明:

CACHE MANIFEST
CACHE:
# 需要缓存的列表
style1.css
1.jpg
01.js
http://localhost/applicationcache/02.js
http://localhost/applicationcache/zepto.js
NETWORK:
# 不需要缓存的
4.jpg
FALLBACK:
# 访问缓存失败后,备用访问的资源,第一个是访问源,第二个是替换文件*.html /offline.html
2.jpg/3.jpg

首先我这里报了一个错:

 Application Cache Error event: Manifest fetch failed (404)

这个错误的原因是:manifest 文件需要配置正确的 MIME-type,即 “text/cache-manifest”。必须在 web 服务器上进行配置,不同的服务器不一样

Linux:HTML5应用程序缓存Application Cache
Linux:HTML5应用程序缓存Application Cache
APPLICATIONCACHE
    01.js
    02.js
    1.jpg
    2.jpg
    3.jpg
    4.jpg
    demo.appcache
    index.html
    style1.css
    style2.css
    web.config
    zepto.js

这样一来便可以离线应用了,这个时候就算断网了,那些文件依旧能访问

Linux:HTML5应用程序缓存Application Cache
Linux:HTML5应用程序缓存Application Cache

这里有一点值得注意,比如这里不带/index.html他会将“applicationcache/”缓存,其实这个就是index.html

manifest 文件可分为三个部分:
CACHE MANIFEST - 在此标题下列出的文件将在首次下载后进行缓存
NETWORK - 在此标题下列出的文件需要与服务器的连接,且不会被缓存
FALLBACK - 在此标题下列出的文件规定当页面无法访问时的回退页面(比如 404 页面)
Linux:HTML5应用程序缓存Application Cache
Linux:HTML5应用程序缓存Application Cache

如图所示,HTML5定义了几个事件点,但是我们一般不会主动使用js去操作什么,大多数情况下,我们完全依赖浏览器的处理即可。

来源:http://www.cnblogs.com/yexiaochai/p/4271834.html

Linux:CentOS上配置rsyslog客户端用以远程记录日志

rsyslog是一个开源工具,被广泛用于Linux系统以通过TCP/UDP协议转发或接收日志消息。rsyslog守护进程可以被配置成两种环境,一种是配置成日志收集服务器,rsyslog进程可以从网络中收集其它主机上的日志数据,这些主机会将日志配置为发送到另外的远程服务器。rsyslog的另外一个用法,就是可以配置为客户端,用来过滤和发送内部日志消息到本地文件夹(如/var/log)或一台可以路由到的远程rsyslog服务器上。

假定你的网络中已经有一台已经配置好并启动的rsyslog服务器,本指南将为你展示如何来设置CentOS系统将其内部日志消息路由到一台远程rsyslog服务器上。这将大大改善你的系统磁盘空间的使用,尤其是当你还没有一个用于/var目录的独立的大分区。

Linux:CentOS上配置rsyslog客户端用以远程记录日志
Linux:CentOS上配置rsyslog客户端用以远程记录日志

步骤一: 安装Rsyslog守护进程

在CentOS 6和7上,rsyslog守护进程已经预先安装了。要验证rsyslog是否已经安装到你的CentOS系统上,请执行如下命令:

# rpm -qa | grep rsyslog
# rsyslogd -v
Linux:CentOS上配置rsyslog客户端用以远程记录日志
Linux:CentOS上配置rsyslog客户端用以远程记录日志

如果处于某种原因,rsyslog守护进程没有出现在你的系统中,请使用以下命令来安装:

 # yum install rsyslog

步骤二: 配置Rsyslog守护进程为客户端

接下来的步骤,是要将你的CentOS机器转变成rsyslog客户端,将其所有内部日志消息发送到远程中央日志服务器上。

要实现该功能,请使用你喜爱的文本编辑器打开位于/etc路径下的rsyslog主配置文件:

# nano /etc/rsyslog.conf

开启文件用于编辑后,你需要添加以下声明到文件底部。将IP地址替换为你的远程rsyslog服务器的IP地址。

*.*  @192.168.1.25:514

上面的声明告诉rsyslog守护进程,将系统上各个设备的各种日志消息路由到远程rsyslog服务器(192.168.1.25)的UDP端口514。

如果出于某种原因,你需要更为可靠的协议,如TCP,而rsyslog服务器也被配置为监听TCP连接,你必须在远程主机的IP地址前添加一个额外的@字符,像下面这样:

*.*  @@192.168.1.25:514

注意,你也可以将rsyslog服务器的IP地址替换成它的主机名(FQDN)。

如果你只想要转发服务器上的指定设备的日志消息,比如说内核设备,那么你可以在rsyslog配置文件中使用以下声明。

kern.* @192.168.1.25:514

修改配置文件后,你需要重启进程以激活修改:

CentOS 7:

# systemctl restart rsyslog.service

CentOS 6:

# service rsyslog restart

非 syslog 日志的转发

在另外一种环境中,让我们假定你已经在机器上安装了一个名为“foobar”的应用程序,它会在/var/log下生成foobar.log日志文件。现在,你想要将它的日志定向到rsyslog服务器,这可以通过像下面这样在rsyslog配置文件中加载imfile模块来实现。

首先,加载imfile模块,这只需做一次。

module(load="imfile" PollingInterval="5")

然后,指定日志文件的路径以便imfile模块可以检测到:

input(type="imfile"
      File="/var/log/foobar.log"
      Tag="foobar"
      Severity="error"
      Facility="local7")

最后,定向local7设备到远程rsyslog服务器:

local7.* @192.168.1.25:514

别忘了重启rsyslog进程哦!

步骤三: 让Rsyslog进程自动启动

要让rsyslog客户端在每次系统重启后自动启动,请运行以下命令:

CentOS 7:

# systemctl enable rsyslog.service

CentOS 6:

# chkconfig rsyslog on

小结

在本教程中,我演示了如何将CentOS系统转变成rsyslog客户端以强制它发送日志消息到远程rsyslog服务器。这里我假定rsyslog客户端和服务器之间的连接是安全的(如,在有防火墙保护的公司网络中)。不管在任何情况下,都不要配置rsyslog客户端将日志消息通过不安全的网络转发,或者,特别是通过互联网转发,因为syslog协议是一个明文协议。要进行安全传输,可以考虑使用TLS/SSL来加密日志消息的传输。


via: http://xmodulo.com/configure-rsyslog-client-centos.html

作者:Caezsar M 译者:GOLinux 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

来源:https://linux.cn/article-4835-1.html

Linux:Linux有问必答:如何检查Linux的内存使用状况

问题:我想要监测Linux系统的内存使用状况。有哪些可用的图形界面或者命令行工具来检查当前内存使用情况?

当涉及到Linux系统性能优化的时候,物理内存是一个最重要的因素。自然的,Linux提供了丰富的选择来监测珍贵的内存资源的使用情况。不同的工具,在监测粒度(例如:全系统范围,每个进程,每个用户),接口方式(例如:图形用户界面,命令行,ncurses)或者运行模式(交互模式,批量处理模式)上都不尽相同。

Linux:Linux有问必答:如何检查Linux的内存使用状况
Linux:Linux有问必答:如何检查Linux的内存使用状况

下面是一个可供选择的,但并不全面的图形或命令行工具列表,这些工具用来检查Linux平台中已用和可用的内存。

1. /proc/meminfo

一种最简单的方法是通过“/proc/meminfo”来检查内存使用状况。这个动态更新的虚拟文件事实上是诸如free,top和ps这些与内存相关的工具的信息来源。从可用/闲置物理内存数量到等待被写入缓存的数量或者已写回磁盘的数量,只要是你想要的关于内存使用的信息,“/proc/meminfo”应有尽有。特定进程的内存信息也可以通过“/proc//statm”和“/proc//status”来获取。

$ cat /proc/meminfo
Linux:Linux有问必答:如何检查Linux的内存使用状况
Linux:Linux有问必答:如何检查Linux的内存使用状况

2. atop

atop命令是用于终端环境的基于ncurses的交互式的系统和进程监测工具。它展示了动态更新的系统资源摘要(CPU, 内存, 网络, 输入/输出, 内核),并且用醒目的颜色把系统高负载的部分以警告信息标注出来。它同样提供了类似于top的线程(或用户)资源使用视图,因此系统管理员可以找到哪个进程或者用户导致的系统负载。内存统计报告包括了总计/闲置内存,缓存的/缓冲的内存和已提交的虚拟内存。

$ sudo atop
Linux:Linux有问必答:如何检查Linux的内存使用状况
Linux:Linux有问必答:如何检查Linux的内存使用状况

3. free

free命令是一个用来获得内存使用概况的快速简单的方法,这些信息从“/proc/meminfo”获取。它提供了一个快照,用于展示总计/闲置的物理内存和系统交换区,以及已使用/闲置的内核缓冲区。

$ free -h

4. GNOME System Monitor

GNOME System Monitor 是一个图形界面应用,它展示了包括CPU,内存,交换区和网络在内的系统资源使用率的较近历史信息。它同时也可以提供一个带有CPU和内存使用情况的进程视图。

$ gnome-system-monitor
Linux:Linux有问必答:如何检查Linux的内存使用状况
Linux:Linux有问必答:如何检查Linux的内存使用状况

5. htop

htop命令是一个基于ncurses的交互式的进程视图,它实时展示了每个进程的内存使用情况。它可以报告所有运行中进程的常驻内存大小(RSS)、内存中程序的总大小、库大小、共享页面大小和脏页面大小。你可以横向或者纵向滚动进程列表进行查看。

$ htop
Linux:Linux有问必答:如何检查Linux的内存使用状况
Linux:Linux有问必答:如何检查Linux的内存使用状况

6. KDE System Monitor

就像GNOME桌面拥有GNOME System Monitor一样,KDE桌面也有它自己的对口应用:KDE System Monitor。这个工具的功能与GNOME版本极其相似,也就是说,它同样展示了一个关于系统资源使用情况,以及带有每个进程的CPU/内存消耗情况的实时历史记录。

$ ksysguard
Linux:Linux有问必答:如何检查Linux的内存使用状况
Linux:Linux有问必答:如何检查Linux的内存使用状况

来源:https://linux.cn/article-4836-1.html

Linux:golang 环境配置建议

开发环境的必要特征

  1. 项目管理
  2. 快速文件跳转
  3. 自动语法检查
  4. 自动补全
  5. 查找定义
  6. 启动速度快
  7. 如果自己有需求的话插件可以随便写

(project,lint,hint,autocomplete)

要实现上面几点我们来一步一步的配置。

Linux:golang 环境配置建议
Linux:golang 环境配置建议

我的大环境

  1. OSX
  2. GO 1.4
  3. HomeBrew

go 环境安装

这一部分是最重要的,如果没有它,每次build的时候出现 too many errors 心里真的是非常难过的。

  1. 环境配置:(golint,gooracle,mercurial)
    • 安装mercurial: brew install mercurial

      这个东西是用来做版本管理的,也是下载代码的工具类似git,貌似google的项目用的挺多的。

    • 安装golint:
      $ go get github.com/golang/lint
      $ go install github.com/golang/lint
  2. 安装gooracle
    go get code.google.com/p/go.tools/cmd/oracle
  3. 安装goimport
    go get golang.org/x/tools/cmd/goimports
  4. 安装gocode
    go get -u github.com/nsf/gocode
  5. 安装 godef
    go get -v code.google.com/p/rog-go/exp/cmd/godef
    go install -v code.google.com/p/rog-go/exp/cmd/godef
  6. 安装环境的时候经常会出现下载不下来的问题,大概是我网络不好吧。连接google经常出现问题。

    解决方案:

    golang中国的下载频道中有一个第三方包的下载工具,只要输入地址之后人家会给你提供下载tar包的。放到gopath中就ok了。

    此步骤只能替代go get的步骤,最后还是需要go install

  7. go install 之后会在 $GOPATH/bin/ 中出现各种工具文件

    • gocode 提供代码补全
    • godef 代码跳转
    • gofmt 自动代码整理
    • golint 代码语法检查
    • goimports 自动整理imports
    • oracle 代码callgraph查询(plugin中还在todolist中,但是不配置一直报错。实在烦。)

    最后不要忘记复制上面的命令到 $GOROOT/bin/下面

  8. 最后的配置结果(安装完之后 Package->Go Plus->Display Go Information)

    Cover Tool: /usr/local/go/pkg/tool/darwin_amd64/cover
    Vet Tool: /usr/local/go/pkg/tool/darwin_amd64/vet
    Format Tool: /Users/Li-jianying/git/bin/goimports
    Lint Tool: /usr/local/go/bin/golint
    Gocode Tool: /Users/Li-jianying/git/bin/gocode
    Gocode Status: Enabled
    Oracle Tool: /Users/Li-jianying/git/bin/oracle
    Git: /usr/bin/git
    Mercurial: /usr/local/Cellar/mercurial/3.2.1/bin/hg
    PATH: /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/go/bin
    

     没有红色的行就没有问题了。

项目管理,自动文件跳转

  1. 插件:project-manager

    这个插件是非常hot的,在atom.io的首页上排名还是非常靠前的。

  2. 使用细节:
    • 配合tree view ( cmd – ) 打开关闭project file
    • 搜索项目文件 ( cmd -t )

      输入的时候按照顺序输入关键字,比如说 user模块的controll中的go源代码。搜索的时候可以使用多个快捷键 =》 user controll go,就可以准确的找到源代码了

    • 打开项目列表 ( ctrl-cmd-p )

      然后就会显示出来一个项目列表回车就可以打开项目。

  3. 总结:

    感觉这个插件的treeview用途的确不是很大,因为正常项目的项目文件会很多。不过是快速打开项目(文件夹)是非常方便的,配合快速打开文件还是相当爽的。

  4. 按快捷键之后的效果展示:

    Linux:golang 环境配置建议
    Linux:golang 环境配置建议

自动语法检查,自动补全

  1. 插件go-plus,autocomplete-plus(dependance),gocode使用 apm install 安装就可以了。速度还可以。

  2. 使用细节 在保存的时候

    • 会自动补上imports
    • 会自动整理代码

      比如说 a:=5 会变成 a := 5

      两个空行自动变成一个空格

    • lint自动检查语法错误(go build 的错误都会显示出来)
    • vet会自动检查语法拼写建议

      函数,结构体 会提示补上注释。

      比如说会提示你函数前面需要加入godoc类型的注释: // functionname

      注释的第一行需要使用双斜杠注释+空格+函数名+空格+简短的函数功能说明。

  3. 使用细节: 在编辑的时候

    • go-plus会配合autocomplete-plus会自动补全包名字(tab补全,回车不行,这个真心舒服)
    • 包名.之后输入方法名开头几个字母会给出补全建议。
  4. 安装之后的演示(类似go-plus官方演示)

    Linux:golang 环境配置建议
    Linux:golang 环境配置建议
  5. gocode 插件自动补全演示

    • 这个插件继承自autocomplete,因为年久失修。api用的是老版本,所以一直都会出现api警告。(我是实用主义,视而不见)
    • gocode如果找不到就进入代码找到文件autocomplete-view.coffee 中105行写成绝对路径就肯定没有问题了。
    • 绑定快捷键,因为这个插件没有绑定快捷键的文件(keymap)所以需要在keymap.cson下自己手动绑定配置如下:
      '.active.pane':
        'ctrl-;': 'gocode:toggle'
    • 效果演示
      Linux:golang 环境配置建议
      Linux:golang 环境配置建议

查找定义

  1. 插件 godef
  2. 使用细节:光标在目标代码上的时候,使用快捷键ctrl-k跳转到目标代码的定义代码上。

总结

  1. 我这里只是总结了我用的所有的golang相关的atom插件。
  2. 要相信golang使用编辑器就够用的事实了。因为 go tool 实在是太好用了。

我的key map

  1. cmd-d duplicate line
  2. cmd-w 关闭标签
  3. cmd-r 文件内的标签列表
  4. cmd-e 使用选中的内容做搜索的pattern
  5. shift-cmd-f project内部搜索,这个非常实用。command 配置(keymap.cson)
    '.platform-darwin atom-text-editor':
      'shift-cmd-D': 'find-and-replace:select-next'

感谢golang

  1. golang能有如此的开发体验,以及在如此低的版本中表现的这么好。实在是大牛赐予我们最好的礼物了。
  2. golang的有如此好的开发工具加上各种扩展性比较强的编辑器(vim,emacs,sublime,atom等)开发体验的确是非常好的。

来源:http://www.philo.top/2015/02/06/golang-%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE%E5%BB%BA%E8%AE%AE/

Linux:手把手教你用Docker部署一个MongoDB集群

【编者的话】MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中最像关系数据库的。支持类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。本文介绍了如何使用Docker搭建MongoDB集群。

Linux:手把手教你用Docker部署一个MongoDB集群
Linux:手把手教你用Docker部署一个MongoDB集群

本文我会向大家介绍如何使用Docker部署一个MongoDB集群,具体如下:

  • 2.6.5版本的MongoDB
  • 有3个节点的副本集(Replica set)
  • 身份验证
  • 持久化数据到本地文件系统

首先要准备三个运行的Docker服务器,这意味着你要准备一个安装了Docker的本地Vagrant Box虚拟机(系统可以使用CoreOS)或者使用AWS或者其它的你喜欢的方式。

步骤

Step1

你要拿到3台Docker服务器的IP地址,并且将下面给出的IP地址配置到所有的服务器上面,每一台服务器都要执行如下命令(记得要替换掉IP地址哦):

root@node *:/# export node1=10.11.32.174
root@node *:/# export node2=10.11.33.37
root@node *:/# export node3=10.11.31.176

理想情况下你并不需要这么做,这些IP都是可以通过DNS自动配置好的。但是这样会更加简单,毕竟这只是一次安装测试。

Step2

为每个节点创建密钥文件。在其中某一台服务器上面执行如下的命令,然后把密钥文件复制到其余两个服务器的同样的位置。

在这个教程中,我将把所有的东西都放在“/home/core”文件夹中。

root@node *:/# mkdir -p /home/core
root@node *:/# cd /home/core
root@node *:/# openssl rand -base64 741 > mongodb-keyfile
root@node *:/# chmod 600 mongodb-keyfile
root@node *:/# sudo chown 999 mongodb-keyfile

这个密钥文件的所有者被设置成id为“999”的用户了,因为在MongoDB的Docker容器中,这个用户需要有操作密钥文件的权限。

Step3

启动node1(即第一台Docker服务器)的MongoDB容器。它会启动一个没有身份验证机制的容器,所以我们要设置一个用户。

root@node1:/# docker run --name mongo 
-v /home/core/mongo-files/data:/data/db 
-v /home/core/mongo-files:/opt/keyfile 
--hostname="node1.example.com" 
-p 27017:27017 
-d mongo:2.6.5 --smallfiles 

现在创建一个admin用户。我们可以连接到刚刚启动的mongoDB容器,并进入一个交互式的shell环境.

root@node1:/# docker exec -it mongo /bin/bash

这时候,我们就进到MongoDB的Docker容器里面了,然后我们要打开一个mongo shell环境:

root@node1:/# mongo

上面的命令可以打开mongo shell环境。执行后你会看到这样的输出:

MongoDB shell version: 2.6.5
connecting to: test
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
http://docs.mongodb.org/
Questions? Try the support group
http://groups.google.com/group/mongodb-user
> 

切换到admin用户:

> use admin
switched to db admin

创建一个新的site admin 用户

> db.createUser( {
 user: "siteUserAdmin",
 pwd: "password",
 roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
});

创建成功的话你会看到如下的成功信息:

Successfully added user: {
"user" : "siteUserAdmin",
"roles" : [
     {
          "role" : "userAdminAnyDatabase",
          "db" : "admin"
     }
  ]}

创建一个root用户:

> db.createUser( {
 user: "siteRootAdmin",
 pwd: "password",
 roles: [ { role: "root", db: "admin" } ]
});

你会看到如下的成功信息:

Successfully added user: {
        "user" : "siteRootAdmin",
              "roles" : [
        {
        "role" : "root",
              "db" : "admin"
        }
    ]}

我们已经创建好了我们以后要使用的几个用户,现在我们不会退出交互式shell环境(mongo和Docker容器的环境)。

> exit
bye
root@node1:/# exit

Step4

停止第一个MongoDB实例:

root@node1:/# docker stop mongo

Step5

这次使用密钥文件启动第一台MongoDB实例(还是在node1上面操作的)。

root@node1:/# docker rm mongo
root@node1:/# docker run 
--name mongo 
-v /home/core/mongo-files/data:/data/db 
-v /home/core/mongo-files:/opt/keyfile 
--hostname="node1.example.com" 
--add-host node1.example.com:${node1} 
--add-host node2.example.com:${node2} 
--add-host node3.example.com:${node3} 
-p 27017:27017 -d mongo:2.6.5 
--smallfiles 
--keyFile /opt/keyfile/mongodb-keyfile 
--replSet "rs0"

注意:

  1. –keyFile的路径是/opt/keyfile/mongodb-keyfile,这是正确的。这是密钥文件在Docker内部的地址,我们用-v选项将密钥文件映射到容器内部的那个路径上(即:/opt/keyfile/mongodb-keyfile)。
  2. –add-host把这些信息添加到Docker容器的/etc/hosts文件中,所以我们可以使用域名而不是IP地址了。在实际的生产环境中这些信息都是DNS,这些参数都可以忽略。

Step6

连接到副本集上并且安装配置好它。这还是在node1上面进行的。我们要开启另外一个新的交互式shell环境进入mongo容器,同时开启一个mongo shell环境:

root@node1:/# docker exec -it mongo /bin/bash
root@node1:/# mongo
MongoDB shell version: 2.6.5
> 

切换到admin用户下:

> use admin
switched to db admin

因为我们已经设置了一个密码,所以这次我们不得不做身份验证。我们把密码设置为:password。

> db.auth("siteRootAdmin", "password");
1

现在我们可以开启副本集:

> rs.initiate()
{
     "info2" : "no configuration explicitly specified -- making one",
     "me" : "node1.example.com:27017",
     "info" : "Config now saved locally.  Should come online in about a minute.",
     "ok" : 1
}
>

Step7

验证已经初始化的副本集的配置:

>
rs0:PRIMARY> rs.conf()
{
    "_id" : "rs0",
    "version" : 1,r
    "members" : [
          {
              "_id" : 0,
              "host" : "node1.example.com:27017"
          }
    ]}

Step8

在其余的两个节点启动MongoDB。

在node2上面执行命令:

root@node2:/# docker run 
--name mongo 
-v /home/core/mongo-files/data:/data/db 
-v /home/core/mongo-files:/opt/keyfile 
--hostname="node2.example.com" 
--add-host node1.example.com:${node1} 
--add-host node2.example.com:${node2} 
--add-host node3.example.com:${node3} 
-p 27017:27017 -d mongo:2.6.5 
--smallfiles 
--keyFile /opt/keyfile/mongodb-keyfile 
--replSet "rs0"

在node3上面执行命令:

root@node3:/# docker run 
--name mongo 
-v /home/core/mongo-files/data:/data/db 
-v /home/core/mongo-files:/opt/keyfile 
--hostname="node3.example.com" 
--add-host node1.example.com:${node1} 
--add-host node2.example.com:${node2} 
--add-host node3.example.com:${node3} 
-p 27017:27017 -d mongo:2.6.5 
--smallfiles 
--keyFile /opt/keyfile/mongodb-keyfile 
--replSet "rs0"

Step 9

将那两个节点加到副本集上。

回到node1节点,如果你在这里按了几次回车键(enter)的话,你会看到下面的提示:“rs0:PRIMARY”。这是因为这个节点是副本集“rso”的主节点。

rs0:PRIMARY> rs.add("node2.example.com")
rs0:PRIMARY> rs.add("node3.example.com")

我们可以通过执行下面的命令来验证其它两个节点是否正确的加到这个副本集当中:

rs0:PRIMARY> rs.status()

可能会花几分钟的时间来将node1上面的数据同步到其余的两个节点上面。你可以通过查看日志来观察每一个MongoDB的Docker容器里面发生了什么。在任意一个服务器上面执行下面的命令就可以了:

root@node*:/# docker logs -ft mongo

结论

现在你拥有了一个MongoDB集群。你可以自由的在任何时刻添加节点到这个集群上。你甚至可以关闭其中的一个节点,包括主节点,然后观察一个另外一个节点重新变成了主节点。由于这些数据都被写在了你的本机文件系统当中了,所以重启任何一个节点都不是什么大问题。

来源:http://dockerone.com/article/181

Linux:推荐一款不错的 VPS 控制面板:Ajenti

任何有经验的Linux人员都认为没有任何一款控制面板可以打败纯命令行界面来管理虚拟主机(VPS)。也有人争辩说好的控制面板还是应该有一席之地,因为顺滑的操作界面让常规管理操作通过点几下鼠标就可以完成。

至于控制面板,有那种充满浮华装饰的商业控制面板,也有各种免费的但也强大多功能的免费开源面板替代品。这之中的杰出代表是Ajenti控制面板。

Ajenti可以让你很简单地配置不同的常规服务程序,如Apache/nginx、Samba、BIND、Squid、MySQL、cron、防火墙等等,对管理常规的 VPS 实例可以节省大量的时间。对于生产环境,Ajenti同样提供了插件和平台来支持虚拟 web 主机管理和自定义 web UI开发。

Ajenti有双重授权;一个是针对个人、企业内部或者教育用途免费使用的AGPLv3。然而,如果你是一家托管企业或者硬件提供商,那么你需要购买商业授权来使用Ajenti作为商业服务。

在Linux上安装Ajenti

为了简化安装,Ajenti为主流Linux发行版提供了自己的仓库。安装Ajenti要做的就是配置目标仓库,并用默认包管理器来安装。

安装前会生成用于SSL的一个RSA密钥和证书,Ajenti会在8000端口监听HTTPS的web请求。如果你正在使用防火墙,你需要在防火墙中允许8000端口访问。为了安全,最好默认禁止8000端口的公开访问,并添加你的少数IP地址到白名单中。

在Debian上安装Ajenti

$ wget http://repo.ajenti.org/debian/key -O- | sudo apt-key add -
$ sudo sh -c 'echo "deb http://repo.ajenti.org/debian main main debian" >> /etc/apt/sources.list'
$ sudo apt-get update
$ sudo apt-get install ajenti

在Ubuntu上安装Ajenti

$ wget http://repo.ajenti.org/debian/key -O- | sudo apt-key add -
$ sudo sh -c 'echo "deb http://repo.ajenti.org/ng/debian main main ubuntu" >> /etc/apt/sources.list'
$ sudo apt-get update
$ sudo apt-get install ajenti

在 CentOS/RHEL或者Fedora上安装Ajenti

在CentOS/RHEL上,首先配置EPEL仓库,接着运行下面的命令。在Fedora上,直接使用下面的命令。

$ wget http://repo.ajenti.org/ajenti-repo-1.0-1.noarch.rpm
$ sudo rpm -ivh ajenti-repo-1.0-1.noarch.rpm
$ sudo yum install ajenti

接着配置防火墙。

在Fedora或者CentOS/RHEL 7上:

$ sudo firewall-cmd --zone=public --add-port=8000/tcp --permanent
$ sudo firewall-cmd --reload

在CentOS/RHEL 6上:

$ sudo iptables -I INPUT -p tcp -m tcp --dport 8000 -j ACCEPT
$ sudo service iptables save

访问Ajenti web界面

在访问Ajenti的web界面前,先确保启动了ajenti服务。

$ sudo service ajenti restart

直接在浏览器中输入https://:8000,你就会看到下面的Ajenti的登录界面。

Linux:推荐一款不错的 VPS 控制面板:Ajenti
Linux:推荐一款不错的 VPS 控制面板:Ajenti

默认的登录凭证是用户名“root”,密码“admin”。当你登录后,你会看到初始化的Ajenti菜单。

Linux:推荐一款不错的 VPS 控制面板:Ajenti
Linux:推荐一款不错的 VPS 控制面板:Ajenti

在左边面板的”SOFTWARE”选项下,你会看带一些已安装的服务。当你安装了任何Ajenti支持的服务端程序时,软件会在重启ajenti服务后被自动加入列表。

 $ sudo service ajenti restart

来源:https://linux.cn/article-4851-1.html

Linux:在 Linux 终端下使用 calcurse 安排约会和待办事项

如果你是一个享受linux终端的系统管理员,但同样需要一种方法来安排每天最重要的任务、约会和会议,你会发现calcurse是一个很有用的工具。calcurse包含了日历、一个待办事项管理、一个调度程序和一个可配置的通知系统,这些都集成进了一个软件中,基于的都是ncurse的接口。同时,它不会限制你在终端中,你可以将你的日历和笔记导出成可以打印的格式。

本篇文章我们会探索如何在Linux上安装calcurse,并且教你如何利用它的特性。

在Linux上安装Culcurse

calcurse在大多数Linux发行版的标准仓库都有。万一在你的发行版上没有(比如CentOS/RHEL),只要你安装了gcc和ncurse开发文件后就可以很简单地从源码安装。

Debian、Ubuntu或者Linux Mint

# aptitude install calcurse

Fedora

# yum install calcurse

CentOS/RHEL

# yum install gcc ncurses-devel
# wget http://calcurse.org/files/calcurse-3.2.1.tar.gz
# tar xvfvz calcurse-3.2.1.tar.gz
# cd calcurse-3.2.1
# ./configure
# make
# make install

启动 Calcurse

安装完成后,你就可以用下面的命令启动calcurse了:

$ calcurse

你将会看到下面的空白界面。如果这配色不吸引你,你可以以后换一个。

Linux:在 Linux 终端下使用 calcurse 安排约会和待办事项
Linux:在 Linux 终端下使用 calcurse 安排约会和待办事项

我们现在可以按下回车-‘q’- 再次按下回车- ‘y’来退出主界面。这个按键序列激活界面底部的主菜单,并告诉它保存当前的笔记并确认退出。

我们第一次运行 calcurse 时,会在主目录创建如下子目录:

这里是每一个子目录的简要描述:

  • apts文件包含了用户所有的约会和事项,todo文件包含了所有的待办事项 列表。
  • conf文件,如你所想的那样,包含当前用户的独立设置。
  • keys文件包含了用户定义的按键绑定(比如:q或者Q退出,x或者X导出内容等等)。
  • notes子目录你会看到包含了笔记描述的文件,这些笔记你可以附到任何一个安排事项中。

改变配色

要改变配色,按照下面的步骤:

Linux:在 Linux 终端下使用 calcurse 安排约会和待办事项
Linux:在 Linux 终端下使用 calcurse 安排约会和待办事项

使用最后一幅图的按键绑定来选择前景色和背景色配置,以更好地适应你的需求:

Linux:在 Linux 终端下使用 calcurse 安排约会和待办事项
Linux:在 Linux 终端下使用 calcurse 安排约会和待办事项

添加约会和待办任务

在前面的选项卡中浏览命令菜单时,我们看到按下‘o’可以从一个菜单跳到下一个菜单。我们可以把第二个菜单作为安排编辑菜单

那么我们用Ctrl + A 和 Ctrl + T组合键为今天添加一个新的约会和一个新的待办任务。如果我们希望为约会指定一个具体的日期而不是今天,我们可以在添加约会和待办事项前使用Ctrl + L (+1 天)、Ctrl + H (-1 天)、Ctrl + J (+1 周)和Ctrl + K (-1 周)组合键。

Linux:在 Linux 终端下使用 calcurse 安排约会和待办事项
Linux:在 Linux 终端下使用 calcurse 安排约会和待办事项

添加待办任务的步骤是相似的,只是用Ctrl + T,之前已经解释了:

你还会被要求输入一个优先级,这样待办任务就会显示在主页上了:

你现在可以验证待办任务和约会已经相应地添加到了.culcurse文件夹下的todo和apts文件中了:

注意你可以使用你最喜欢的编辑器或者菜单底部的calcurse屏幕来编辑这些文件。你可以按下TAB来在不同的面板间切换,并选择你想要编辑的项目:

Linux:在 Linux 终端下使用 calcurse 安排约会和待办事项
Linux:在 Linux 终端下使用 calcurse 安排约会和待办事项

为事项设置通知

你可以在通知菜单下配置通知。按照相同的步骤来改变配色方案,但是选择Notify而不是Colour

Linux:在 Linux 终端下使用 calcurse 安排约会和待办事项
Linux:在 Linux 终端下使用 calcurse 安排约会和待办事项

假设你想要设置email通知。按下数字5来编辑notify-bar_command的值:

按照上面的设置之后,如果这个任务被标为重要,那么root@localhost会在300秒(或者5分钟)后收到邮件通知,这会发生在下一个安排的任务之前。如果你想要即使calcurse不在运行也启用这个功能,那么将notify-daemon_enable设成yes。在本例中,dev2是本机的主机名。

请注意出于演示目的,我已经在这篇教程中改变了原始约会的开始和/或者结束时间。

总结

本篇教程中我们展示了如何设置一个多样化的调度器和提醒器来帮助你组织每日的活动和提前安排重要的事项。你或许还要看看calcurse的PDF 手册,请随意在下面的评论中提出你的疑问。欢迎你的评论,我也很高兴看到这些。


via: http://xmodulo.com/schedule-appointments-todo-tasks-linux-terminal.html

作者:Gabriel Cánepa 译者:geekpi 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

来源:https://linux.cn/article-4853-1.html

Linux:Linux有问必答-如何在Linux中安装Go语言

Go (也叫 “golang”)是一款由Google最初开发的编程语言。它自诞生就有几个设计原则:简单性、安全性和速度。Go语言发行版拥有各种调试、测试、调优和代码审查工具。如今Go语言和它的工具链在大多数Linux发行版的基础仓库都可用,用默认的包管理器就可以安装。

在Ubuntu、Debian 或者 Linux Mint上安装Go语言

下面是在基于Debian的发行版上使用apt-get来安装Go语言和它的开发工具。

$ sudo apt-get install golang

检查Go语言的版本来验证安装。

$ go version

go version go1.2.1 linux/amd64

根据你的需要,你或许想要使用apt-get安装额外的Go工具。

$ sudo apt-cache search golang

在Fedora、CentOS/RHEL中安装Go语言

下面的命令会在基于Red Hat的发行版中安装Go语言和它的工具。

$ sudo yum install golang

检查Go语言的版本来验证安装。

$ go version

go version go1.3.3 linux/amd64

根据你的需要,你或许想要使用yum安装额外的Go工具。

$ yum search golang

从官网安装Go语言

有时发行版中的go语言版本并不是最新的。为了避免这种情况,你可以从官网安装最新的Go语言。下面是步骤。

进入Go语言的官方源码,并下载预编译二进制代码。

对于64位Linux:

$ wget https://storage.googleapis.com/golang/go1.4.1.linux-amd64.tar.gz

对于32位Linux:

$ wget https://storage.googleapis.com/golang/go1.4.1.linux-386.tar.gz

在/usr/local下安装程序

$ sudo tar -xzf go1.4.1.linux-xxx.tar.gz -C /usr/local

在/etc/profile中添加系统范围的PATH环境变量。

$ sudo vi /etc/profile

export PATH=$PATH:/usr/local/go/bin

如果你在/usr/local之外的自定义位置中安装了Go,你同样需要设置GOROOT环境变量来指向自定义的安装位置。

$ sudo vi /etc/profile

export GOROOT=/path/to/custom/location

检查Go语言的版本

$ go version

go version go1.4.1 linux/amd64

via: http://ask.xmodulo.com/install-go-language-linux.html

译者:geekpi 校对:Caroline

本文由 LCTT 原创翻译,Linux中国 荣誉推出

来源:https://linux.cn/article-4854-1.html

Linux:20分钟 Awk 入门

什么是Awk

Awk是一种小巧的编程语言及命令行工具。(其名称得自于它的创始人Alfred Aho、Peter Weinberger 和 Brian Kernighan姓氏的首个字母)。它非常适合服务器上的日志处理,主要是因为Awk可以对文件进行操作,通常以可读文本构建行。

Linux:20分钟 Awk 入门
Linux:20分钟 Awk 入门

我说它适用于服务器是因为日志文件,转储文件(dump files),或者任意文本格式的服务器终止转储到磁盘都会变得很大,并且在每个服务器你都会拥有大量的这类文件。如果你经历过这样的情境——在没有像Splunk或者其他等价的工具情况下不得不在50个不同的服务器里分析几G的文件,你会觉得去获取和下载所有的这些文件并分析他们是一件很糟糕的事。

我亲身经历过这种情境。当一些Erlang节点将要死掉并留下一个700MB到4GB的崩溃转储文件(crash dump)时,或者当我需要在一个小的个人服务器(叫做VPS)上快速浏览日志,查找一个常规模式时。

在任何情况下,Awk都不仅仅只是用来查找数据的(否则,grep或者ack已经足够使用了)——它同样使你能够处理数据并转换数据。

代码结构

Awk脚本的代码结构很简单,就是一系列的模式(pattern)和行为(action):

# comment
Pattern1 { ACTIONS; }
# comment
Pattern2 { ACTIONS; }
# comment
Pattern3 { ACTIONS; }
# comment
Pattern4 { ACTIONS; }

扫描文档的每一行时都必须与每一个模式进行匹配比较,而且一次只匹配一个模式。那么,如果我给出一个包含以下内容的文件:

this is line 1
this is line 2

this is line 1 这行就会与Pattern1进行匹配。如果匹配成功,就会执行ACTIONS。然后this is line 1 会和Pattern2进行匹配。如果匹配失败,它就会跳到Pattern3进行匹配,以此类推。

一旦所有的模式都匹配过了,this is line 2 就会以同样的步骤进行匹配。其他的行也一样,直到读取完整个文件。

简而言之,这就是Awk的运行模式

数据类型

Awk仅有两个主要的数据类型:字符串和数字。即便如此,Awk的字符串和数字还可以相互转换。字符串能够被解释为数字并把它的值转换为数字值。如果字符串不包含数字,它就被转换为0.

它们都可以在你代码里的ACTIONS部分使用 = 操作符给变量赋值。我们可以在任意时刻、任意地方声明和使用变量,也可以使用未初始化的变量,此时他们的默认值是空字符串:“”。

最后,Awk有数组类型,并且它们是动态的一维关联数组。它们的语法是这样的:var[key] = value 。Awk可以模拟多维数组,但无论怎样,这是一个大的技巧(big hack)。

模式

可以使用的模式分为三大类:正则表达式、布尔表达式和特殊模式。

正则表达式和布尔表达式

你使用的Awk正则表达式比较轻量。它们不是Awk下的PCRE(但是gawk可以支持该库——这依赖于具体的实现!请使用 awk

–version查看),然而,对于大部分的使用需求已经足够了:

/admin/ { ... } # any line that contains 'admin'
/^admin/ { ... } # lines that begin with 'admin'
/admin$/ { ... } # lines that end with 'admin'
/^[0-9.]+ / { ... } # lines beginning with series of numbers and periods
/(POST|PUT|DELETE)/ # lines that contain specific HTTP verbs

注意,模式不能捕获特定的组(groups)使它们在代码的ACTIONS部分执行。模式是专门匹配内容的。

布尔表达式与PHP或者Javascript中的布尔表达式类似。特别的是,在awk中可以使用&&(“与”)、||(“或”)、!(“非”)操作符。你几乎可以在所有类C语言中找到它们的踪迹。它们可以对常规数据进行操作。

与PHP和Javascript更相似的特性是比较操作符,==,它会进行模糊匹配(fuzzy matching)。因此“23”字符串等于23,”23″ == 23 表达式返回true。!= 操作符同样在awk里使用,并且别忘了其他常见的操作符:>,<,>=,和<=。

你同样可以混合使用它们:布尔表达式可以和常规表达式一起使用。 /admin/ || debug == true 这种用法是合法的,并且在遇到包含“admin”单词的行或者debug变量等于true时该表达式就会匹配成功。

注意,如果你有一个特定的字符串或者变量要与正则表达式进行匹配,~ 和!~ 就是你想要的操作符。 这样使用它们:string ~ /regex/ 和 string !~ /regex/。

同样要注意的是,所有的模式都只是可选的。一个包含以下内容的Awk脚本:

{ ACTIONS }

对输入的每一行都将会简单地执行ACTIONS。

特殊的模式

在Awk里有一些特殊的模式,但不是很多。

第一个是BEGIN,它仅在所有的行都输入到文件之前进行匹配。这是你可以初始化你的脚本变量和所有种类的状态的主要地方。

另外一个就是END。就像你可能已经猜到的,它会在所有的输入都被处理完后进行匹配。这使你可以在退出前进行清除工作和一些最后的输出。

最后一类模式,要把它进行归类有点困难。它处于变量和特殊值之间,我们通常称它们为域(Field)。而且名副其实。

使用直观的例子能更好地解释域:

# According to the following line
#
# $1 $2 $3
# 00:34:23 GET /foo/bar.html
# _____________ _____________/
# $0
# Hack attempt?
/admin.html$/ && $2 == "DELETE" {
print "Hacker Alert!";
}

域(默认地)由空格分隔。$0 域代表了一整行的字符串。 $1 域是第一块字符串(在任何空格之前), $2 域是后一块,以此类推。

一个有趣的事实(并且是在大多是情况下我们要避免的事情),你可以通过给相应的域赋值来修改相应的行。例如,如果你在一个块里执行 $0 = “HAHA THE LINE IS GONE”,那么现在下一个模式将会对修改后的行进行操作而不是操作原始的行。其他的域变量都类似。

行为

这里有一堆可用的行为(possible actions),但是最常用和最有用的行为(以我的经验来说)是:

{ print $0; } # prints $0. In this case, equivalent to 'print' alone
{ exit; } # ends the program
{ next; } # skips to the next line of input
{ a=$1; b=$0 } # variable assignment
{ c[$1] = $2 } # variable assignment (array)
{ if (BOOLEAN) { ACTION }
else if (BOOLEAN) { ACTION }
else { ACTION }
}
{ for (i=1; i

这些内容将会成为你的Awk工具箱的主要工具,在你处理日志之类的文件时你可以随意地使用它们。

Awk里的变量都是全局变量。无论你在给定的块里定义什么变量,它对其他的块都是可见的,甚至是对每一行都是可见的。这严重限制了你的Awk脚本大小,不然他们会造成不可维护的可怕结果。请编写尽可能小的脚本。

函数

可以使用下面的语法来调用函数:

{ somecall($2) }

这里有一些有限的内置函数可以使用,所以我可以给出这些函数的通用文档(regular documentation)

用户定义的函数同样很简单:

# function arguments are call-by-value
function name(parameter-list) {
ACTIONS; # same actions as usual
}
# return is a valid keyword
function add1(val) {
return val+1;
}

特殊变量

除了常规变量(全局的,可以在任意地方使用),这里还有一系列特殊的变量,它们的的作用有点像配置条目(configuration entries):

BEGIN { # Can be modified by the user
FS = ","; # Field Separator
RS = "n"; # Record Separator (lines)
OFS = " "; # Output Field Separator
ORS = "n"; # Output Record Separator (lines)
}
{ # Can't be modified by the user
NF # Number of Fields in the current Record (line)
NR # Number of Records seen so far
ARGV / ARGC # Script Arguments
}

我把可修改的变量放在BEGIN里,因为我更喜欢在那重写它们。但是这些变量的重写可以放在脚本的任意地方然后在后面的行里生效。

来源:http://blog.jobbole.com/83844/