分类 技术 下的文章

如果你对一次又一次的克隆、构建、测试和部署代码感到厌倦了,可以考虑一下持续集成。持续集成简称 CI,是一种像我们一样的频繁提交的代码库,构建、测试和部署的软件工程实践。CI 可以帮助我们快速的集成新代码到已有的代码库。如果这个过程是自动化进行的,那么就会提高开发的速度,因为这可以减少开发人员手工构建和测试的时间。Drone 是一个自由开源项目,用来提供一个非常棒的持续集成服务的环境,采用 Apache 2.0 协议发布。它已经集成近很多代码库提供商,比如 Github、Bitbucket 以及 Google Code,它可以从代码库提取代码,使我们可以对包括 PHP, Node, Ruby, Go, Dart, Python, C/C++, JAVA 等等在内的各种语言编译构建。它是如此一个强大的平台,它使用了容器和 docker 技术,这让用户每次构建都可以在保证隔离的条件下完全控制他们自己的构建环境。

1. 安装 Docker

首先,我们要安装 docker,因为这是 Drone 的工作流的最关键的元素。Drone 合理的利用了 docker 来构建和测试应用。容器技术提高了应用部署的效率。要安装 docker ,我们需要在不同的 linux 发行版本运行下面对应的命令,我们这里会说明 Ubuntu 14.04 和 CentOS 7 两个版本。

Ubuntu

要在 Ubuntu 上安装 Docker ,我们只需要运行下面的命令。

# apt-get update
# apt-get install docker.io

安装之后我们需要使用service 命令重启 docker 引擎。

# service docker restart

然后我们让 docker 在系统启动时自动启动。

# update-rc.d docker defaults

Adding system startup for /etc/init.d/docker ...
/etc/rc0.d/K20docker -> ../init.d/docker
/etc/rc1.d/K20docker -> ../init.d/docker
/etc/rc6.d/K20docker -> ../init.d/docker
/etc/rc2.d/S20docker -> ../init.d/docker
/etc/rc3.d/S20docker -> ../init.d/docker
/etc/rc4.d/S20docker -> ../init.d/docker
/etc/rc5.d/S20docker -> ../init.d/docker

CentOS

第一,我们要更新机器上已经安装的软件包。我们可以使用下面的命令。

#  sudo yum update

要在 centos 上安装 docker,我们可以简单的运行下面的命令。

#  curl -sSL https://get.docker.com/ | sh

安装好 docker 引擎之后我么只需要简单使用下面的systemd 命令启动 docker,因为 centos 7 的默认初始化系统是 systemd。

# systemctl start docker

然后我们要让 docker 在系统启动时自动启动。

# systemctl enable docker

ln -s '/usr/lib/systemd/system/docker.service' '/etc/systemd/system/multi-user.target.wants/docker.service'

2. 安装 SQlite 驱动

Drone 默认使用 SQlite3 数据库服务器来保存数据和信息。它会在 /var/lib/drone/ 自动创建名为 drone.sqlite 的数据库来处理数据库模式的创建和迁移。要安装 SQlite3 我们要完成以下几步。

Ubuntu 14.04

因为 SQlite3 存在于 Ubuntu 14.04 的默认软件库,我们只需要简单的使用 apt 命令安装它。

# apt-get install libsqlite3-dev

CentOS 7

要在 Centos 7 上安装需要使用下面的 yum 命令。

# yum install sqlite-devel

3. 安装 Drone

最后,我们安装好依赖的软件,我们现在更进一步的接近安装 Drone。在这一步里我们只简单的从官方链接下载对应的二进制软件包,然后使用默认软件包管理器安装 Drone。

Ubuntu

我们将使用 wget 从官方的 Debian 文件下载链接下载 drone 的 debian 软件包。下面就是下载命令。

# wget downloads.drone.io/master/drone.deb

Resolving downloads.drone.io (downloads.drone.io)... 54.231.48.98
Connecting to downloads.drone.io (downloads.drone.io)|54.231.48.98|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 7722384 (7.4M) [application/x-debian-package]
Saving to: 'drone.deb'
100%[======================================>] 7,722,384 1.38MB/s in 17s
2015-11-06 14:09:28 (456 KB/s) - 'drone.deb' saved [7722384/7722384]

下载好之后,我们将使用 dpkg 软件包管理器安装它。

# dpkg -i drone.deb

Selecting previously unselected package drone.
(Reading database ... 28077 files and directories currently installed.)
Preparing to unpack drone.deb ...
Unpacking drone (0.3.0-alpha-1442513246) ...
Setting up drone (0.3.0-alpha-1442513246) ...
Your system ubuntu 14: using upstart to control Drone
drone start/running, process 9512

CentOS

在 CentOS 机器上我们要使用 wget 命令从下载链接下载 RPM 包。

# wget downloads.drone.io/master/drone.rpm

--2015-11-06 11:06:45-- http://downloads.drone.io/master/drone.rpm
Resolving downloads.drone.io (downloads.drone.io)... 54.231.114.18
Connecting to downloads.drone.io (downloads.drone.io)|54.231.114.18|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 7763311 (7.4M) [application/x-redhat-package-manager]
Saving to: ‘drone.rpm’
100%[======================================>] 7,763,311 1.18MB/s in 20s
2015-11-06 11:07:06 (374 KB/s) - ‘drone.rpm’ saved [7763311/7763311]

然后我们使用 yum 安装 rpm 包。

# yum localinstall drone.rpm

4. 配置端口

安装完成之后,我们要先进行配置才能工作起来。drone 的配置文件在/etc/drone/drone.toml 。默认情况下 drone 的 web 接口使用的是80,而这也是 http 默认的端口,如果我们修改它,请按下面所示的修改配置文件里 server 块对应的值。

[server]
port=":80"

5. 集成 Github

为了运行 Drone 我们必须设置最少一个和 GitHub、GitHub 企业版,Gitlab,Gogs,Bitbucket 关联的集成点。在本文里我们只集成了 github,但是如果我们要集成其他的服务,我们可以在配置文件做修改。为了集成 github 我们需要在github 的设置里创建一个新的应用:https://github.com/settings/developers

Registering App Github

要创建一个应用,我们需要在 New Application 页面点击 Register,然后如下所示填表。

Registering OAuth app github

我们应该保证在应用的配置项里设置了授权回调链接,链接看起来类似 http://drone.linoxide.com/api/auth/github.com。然后我们点击注册应用。所有都做好之后我们会看到我们需要在我们的 Drone 配置文件里配置的客户端 ID 和客户端密钥。

Client ID and Secret Token

在这些都完成之后我们需要使用文本编辑器编辑 drone 配置文件,比如使用下面的命令。

# nano /etc/drone/drone.toml

然后我们会在 drone 的配置文件里面找到[github] 部分,紧接着的是下面所示的配置内容

[github]
client="3dd44b969709c518603c"
secret="4ee261abdb431bdc5e96b19cc3c498403853632a"
# orgs=[]
# open=false

Configuring Github Drone

6. 配置 SMTP 服务器

如果我们想让 drone 使用 email 发送通知,那么我们需要在 SMTP 配置里面设置我们的 SMTP 服务器。如果我们已经有了一个 SMTP 服务,那就只需要简单的使用它的配置文件就行了,但是因为我们没有一个 SMTP 服务器,我们需要安装一个 MTA 比如 Postfix,然后在 drone 配置文件里配置好 SMTP。

Ubuntu

在 ubuntu 里使用下面的 apt 命令安装 postfix。

# apt-get install postfix

CentOS

在 CentOS 里使用下面的 yum 命令安装 postfix。

# yum install postfix

安装好之后,我们需要编辑我们的 postfix 配置文件。

# nano /etc/postfix/main.cf

然后我们要把 myhostname 的值替换为我们自己的 FQDN,比如 drone.linoxide.com。

myhostname = drone.linoxide.com

现在开始配置 drone 配置文件里的 SMTP 部分。

# nano /etc/drone/drone.toml

找到[smtp] 部分补充上下面的内容。

[smtp]
host = "drone.linoxide.com"
port = "587"
from = "[email protected]"
user = "root"
pass = "password"

Configuring SMTP Drone

注意:这里的 userpass 参数强烈推荐一定要改成某个具体用户的配置。

7. 配置 Worker

如我们所知的 drone 利用了 docker 完成构建、测试任务,我们需要把 docker 配置为 drone 的 worker。要完成这些需要修改 drone 配置文件里的[worker] 部分。

# nano /etc/drone/drone.toml

然后取消底下几行的注释并且补充上下面的内容。

[worker]
nodes=[
"unix:///var/run/docker.sock",
"unix:///var/run/docker.sock"
]

这里我们只设置了两个节点,这意味着上面的配置文件只能同时执行2 个构建操作。要提高并发性可以增大节点的值。

[worker]
nodes=[
"unix:///var/run/docker.sock",
"unix:///var/run/docker.sock",
"unix:///var/run/docker.sock",
"unix:///var/run/docker.sock"
]

使用上面的配置文件 drone 被配置为使用本地的 docker 守护程序可以同时构建4个任务。

8. 重启 Drone

最后,当所有的安装和配置都准备好之后,我们现在要在本地的 linux 机器上启动 drone 服务器。

Ubuntu

因为 ubuntu 14.04 使用了 sysvinit 作为默认的初始化系统,所以只需要简单执行下面的 service 命令就可以启动 drone 了。

# service drone restart

要让 drone 在系统启动时也自动运行,需要运行下面的命令。

# update-rc.d drone defaults

CentOS

因为 CentOS 7使用 systemd 作为初始化系统,所以只需要运行下面的 systemd 命令就可以重启 drone。

# systemctl restart drone

要让 drone 自动运行只需要运行下面的命令。

# systemctl enable drone

9. 添加防火墙例外规则

众所周知 drone 默认使用了80 端口而我们又没有修改它,所以我们需要配置防火墙程序允许80 端口(http)开放并允许其他机器可以通过网络连接。

Ubuntu 14.04

iptables 是最流行的防火墙程序,并且 ubuntu 默认安装了它。我们需要修改 iptable 以暴露端口80,这样我们才能让 drone 的 web 界面在网络上被大家访问。

# iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
# /etc/init.d/iptables save

CentOS 7

因为 CentOS 7 默认安装了 systemd,它使用 firewalld 作为防火墙程序。为了在 firewalld 上打开80端口(http 服务),我们需要执行下面的命令。

# firewall-cmd --permanent --add-service=http
success

# firewall-cmd --reload
success

10. 访问 web 界面

现在我们将在我们最喜欢的浏览器上通过 web 界面打开 drone。要完成这些我们要把浏览器指向运行 drone 的服务器。因为 drone 默认使用80 端口而我们有没有修改过,所以我们只需要在浏览器里根据我们的配置输入http://ip-address/http://drone.linoxide.com 就行了。在我们正确的完成了上述操作后,我们就可以看到登录界面了。

Login Github Drone

因为在上面的步骤里配置了 Github,我们现在只需要简单的选择 github 然后进入应用授权步骤,这些完成后我们就可以进入工作台了。

Drone Dashboard

这里它会同步我们在 github 上的代码库,然后询问我们要在 drone 上构建那个代码库。

Activate Repository

这一步完成后,它会询问我们在代码库里添加.drone.yml 文件的新名称,并且在这个文件里定义构建的过程和配置项,比如使用那个 docker 镜像,执行那些命令和脚本来编译,等等。

我们按照下面的内容来配置我们的.drone.yml

image: python
script:
 - python helloworld.py
 - echo "Build has been completed."

这一步完成后我们就可以使用 drone 应用里的 YAML 格式的配置文件来构建我们的应用了。所有对代码库的提交和改变此时都会同步到这个仓库。一旦提交完成了,drone 就会自动开始构建。

Building Application Drone

所有操作都完成后,我们就能在终端看到构建的结果了。

Build Success Drone

总结

在本文中我们学习了如何安装一个可以工作的使用 drone 的持续集成平台。如果我们愿意我们甚至可以从 drone.io 官方提供的服务开始工作。我们可以根据自己的需求从免费的服务或者收费服务开始。它通过漂亮的 web 界面和强大的功能改变了持续集成的世界。它可以集成很多第三方应用和部署平台。如果你有任何问题、建议可以直接反馈给我们,谢谢。


via: http://linoxide.com/linux-how-to/setup-drone-continuous-integration-linux/

作者:Arun Pyasi 译者:ezio 校对:wxy

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

你在 Linux 终端中会有很多的乐趣。我今天要讲的不是在终端中跑火车

我今天要讲的技巧可以放松你的心情。前面一篇文章中,你学习了如何在命令行中增加 sudo 命令的超时。今天的文章中,我会向你展示如何让 sudo 在输错密码的时候“嘲讽”你(或者其他人)。

对我讲的感到疑惑?这里,让我们看下这张 gif 来了解下 sudo 是如何在你输错密码之后“嘲讽”你的。

那么,为什么要这么做?毕竟,“嘲讽”不会让你的一天变得开心,不是么?

对我来说,一点小技巧都是有趣的,并且要比以前的“密码错误”的错误提示更有趣。另外,我可以向我的朋友展示来逗弄他们(这个例子中是通过自由开源软件)。我很肯定你有你自己的理由来使用这个技巧的。

在 sudo 中启用“嘲讽”

你可以在sudo配置中增加下面的行来启用“嘲讽”功能:

Defaults    insults

让我们看看该如何做。打开终端并使用下面的命令:

sudo visudo

这会在 nano中打开配置文件。

是的,我知道传统的 ‘visudo’ 应该在 vi 中打开 /etc/sudoers 文件,但是 Ubuntu 及基于它的发行版会使用 nano 打开。由于我们在讨论vi,这里有一份 vi 速查表可以在你决定使用 vi 的时候使用。

回到编辑 sudeors 文件界面,你需要找出 Defaults 所在的行。简单的很,只需要在文件的开头加上Defaults insults,就像这样:

如果你正在使用 nano,使用Ctrl+X来退出编辑器。在退出的时候,它会询问你是否保存更改。要保存更改,按下“Y”。

一旦你保存了 sudoers 文件之后,打开终端并使用 sudo 运行各种命令。故意输错密码并享受嘲讽吧:)

sudo 可能会生气的。看见没,他甚至在我再次输错之后威胁我。哈哈。

如果你喜欢这个终端技巧,你也可以查看其他终端技巧的文章。如果你有其他有趣的技巧,在评论中分享。


via: http://itsfoss.com/sudo-insult-linux/

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

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

Linux 基金会已经发起了一个全新的 LFCS( Linux 基金会认证系统管理员 Linux Foundation Certified Sysadmin )认证,旨在让来自世界各地的人有机会参加到 LFCS 测试,获得关于有能力在 Linux 系统中执行中间系统管理任务的认证。该认证包括:维护正在运行的系统和服务的能力、全面监控和分析的能力以及何时向上游团队请求支持的决策能力。

Linux Foundation Certified Sysadmin – Part 5

LFCS 系列第五讲

请看以下视频,这里边介绍了 Linux 基金会认证程序。

本讲是系列教程中的第五讲,在这一讲里边,我们会解释如何在 Linux 中挂载/卸载本地和网络文件系统。这些都是 LFCS 认证中的必备知识。

挂载文件系统

在个硬盘分好区之后,Linux 需要通过某些方式对硬盘分区上的数据进行访问。Linux 并不会像 DOS 或者 Windows 那样给每个硬盘分区分配一个字母来作为盘符,而是将硬盘分区挂载到统一的目录树上的挂载点。

挂载点是一个目录,挂载是一种访问分区上文件系统的方法,挂载文件系统实际上是将一个确切的文件系统(比如一个分区)和目录树中指定的目录联系起来的过程。

换句话说,管理存储设备的第一步就是把设备关联到文件系统树。要完成这一步,通常可以这样:用 mount 命令来进行临时挂载(用完的时候,使用 umount 命令来卸载),或者通过编辑 /etc/fstab 文件之后重启系统来永久性挂载,这样每次开机都会进行挂载。

不带任何选项的 mount 命令,可以显示当前已挂载的文件系统。

# mount

Check Mounted Filesystem in Linux

检查已挂载的文件系统

另外,mount 命令通常用来挂载文件系统。其基本语法如下:

# mount -t type device dir -o options

该命令会指引内核将在设备上找到的文件系统(如已格式化为指定类型的文件系统)挂载到指定目录。像这样的形式,mount 命令不会再到 /etc/fstab 文件中进行确认。

除非像下面,挂载指定的目录或者设备:

# mount /dir -o options
或
# mount device -o options

mount 命令会尝试寻找挂载点,如果找不到就会查找设备(上述两种情况下,mount 命令会在 /etc/fstab 查找相应的设备或挂载点),最后尝试完成挂载操作(这个通常可以成功执行,除非你的挂载点或者设备正在使用中,或者你调用 mount 命令的时候没有 root 权限)。

你可以看到,mount 命令的每行输出都是如下格式:

device on directory type (options)

例如:

/dev/mapper/debian-home on /home type ext4 (rw,relatime,user_xattr,barrier=1,data=ordered)

读作:

设备 dev/mapper/debian-home 挂载在 /home 下,它被格式化为 ext4,并且有以下挂载选项: rw,relatime,user\_xattr,barrier=1,data=ordered。

mount 命令选项

下面列出 mount 命令的常用选项

  • async:允许在将要挂载的文件系统上进行异步 I/O 操作
  • auto:标示该文件系统通过 mount -a 命令挂载,与 noauto 相反。
  • defaults:该选项相当于 async,auto,dev,exec,nouser,rw,suid 的组合。注意,多个选项必须由逗号隔开并且中间没有空格。倘若你不小心在两个选项中间输入了一个空格,mount 命令会把后边的字符解释为另一个参数。
  • loop:将镜像文件(如 .iso 文件)挂载为 loop 设备。该选项可以用来模拟显示光盘中的文件内容。
  • noexec:阻止该文件系统中可执行文件的执行。与 exec 选项相反。
  • nouser:阻止任何用户(除 root 用户外) 挂载或卸载文件系统。与 user 选项相反。
  • remount:重新挂载文件系统。
  • ro:只读模式挂载。
  • rw:读写模式挂载。
  • relatime:只要访问时间早于修改时间,就更新文件的的访问时间。
  • user\_xattr:允许用户设置和移除可扩展文件系统属性。

以 ro 和 noexec 模式挂载设备

# mount -t ext4 /dev/sdg1 /mnt -o ro,noexec

在本例中,我们可以看到,在挂载点 /mnt 中尝试写入文件或者运行可执行文件都会显示相应的错误信息。

# touch /mnt/myfile
# /mnt/bin/echo “Hi there”

Mount Device in Read Write Mode

可读写模式挂载设备

以默认模式挂载设备

以下场景,我们在重新挂载设备的挂载点中,像上例一样尝试你写入文件和运行可执行文件。

# mount -t ext4 /dev/sdg1 /mnt -o defaults

Mount Device in Linux

挂载设备

在这个例子中,我们发现写入文件和命令都完美执行了。

卸载设备

使用 umount 命令卸载设备,意味着将所有的“在使用”数据全部写入到文件系统,然后可以安全移除文件系统。请注意,倘若你移除一个没有事先正确卸载的设备,就会有造成设备损坏和数据丢失的风险。

也就是说,你必须“离开”设备的块设备描述符或者挂载点,才能卸载设备。换言之,你的当前工作目录不能是需要卸载设备的挂载点。否则,系统将返回设备繁忙的提示信息。

Unmount Device in Linux

卸载设备

离开需卸载设备的挂载点最简单的方法就是,运行不带任何选项的 cd 命令,这样会回到当前用户的家目录。

挂载常见的网络文件系统

最常用的两种网络文件系统是 SMB( 服务器消息块 Server Message Block )和 NFS( 网络文件系统 Network File System )。如果你只向类 Unix 客户端提供共享,用 NFS 就可以了,如果是向 Windows 和其他类 Unix 客户端提供共享服务,就需要用到 Samba 了。

扩展阅读

下面的例子中,假设 Samba 和 NFS 已经在地址为 192.168.0.10 的服务器上架设好了(请注意,架设 NFS 服务器也是 LFCS 考试中需要考核的能力,我们会在后边中提到)。

在 Linux 中挂载 Samba 共享

第一步:在 Red Hat 以 Debian 系发行版中安装 samba-client、samba-common 和 cifs-utils 软件包,如下:

# yum update && yum install samba-client samba-common cifs-utils
# aptitude update && aptitude install samba-client samba-common cifs-utils

然后运行下列命令,查看服务器上可用的 Samba 共享。

# smbclient -L 192.168.0.10

并输入远程机器上 root 账户的密码。

Mount Samba Share in Linux

挂载 Samba 共享

上图中,已经对可以挂载到我们本地系统上的共享进行高亮显示。你只需要与一个远程服务器上的合法用户名及密码就可以访问共享了。

第二步:当挂载有密码保护的网络文件系统时候,将你的访问凭证写入到 /etc/fstab 文件中并非明智的选择。你需要将这些信息写入到具有 600 权限的隐藏文件中,像这样:

# mkdir /media/samba
# echo “username=samba_username” > /media/samba/.smbcredentials
# echo “password=samba_password” >> /media/samba/.smbcredentials
# chmod 600 /media/samba/.smbcredentials

第三步:然后将下面的内容添加到 /etc/fstab 文件中。

# //192.168.0.10/gacanepa /media/samba cifs credentials=/media/samba/.smbcredentials,defaults 0 0

第四步:现在可以挂载你的 Samba 共享了。手动挂载(mount //192.168.0.10/gacanepa)或者重启系统并应用 /etc/fstab 中相应行来用就挂载都可以。

Mount Password Protect Samba Share

挂载有密码保护的 Samba 共享

在 Linux 系统中挂载 NFS 共享

第一步:在 Red Hat 以 Debian 系发行版中安装 nfs-common 和 portmap 软件包。如下:

# yum update && yum install nfs-utils nfs-utils-lib
# aptitude update && aptitude install nfs-common

第二步:为 NFS 共享创建挂载点。

# mkdir /media/nfs

第三步:将下面的内容添加到 /etc/fstab 文件中。

192.168.0.10:/NFS-SHARE /media/nfs nfs defaults 0 0

第四步:现在可以挂载你的 Samba 共享了。手动挂载(mount 192.168.0.10:/NFS-SHARE)或者重启系统并应用 /etc/fstab 中相应行来用就挂载都可以。

Mount NFS Share in Linux

挂载 NFS 共享

永久性挂载文件系统

像前面两个例子那样,/etc/fstab 控制着Linux如何访问硬盘分区及可移动设备。/etc/fstab 由六个字段的内容组成,各个字段之间通过一个空格符或者制表符来分开。井号(#)开始的行只是会被忽略的注释。

每一行都按照这个格式来写入:

<file system> <mount point> <type> <options> <dump> <pass>

其中:

  • : 第一个字段指定挂载的设备。大多数发行版本都通过分区的标卷(label)或者 UUID 来指定。这样做可以避免分区号改变时带来的错误。
  • : 第二个字段指定挂载点。
  • :文件系统的类型代码与 mount 命令挂载文件系统时使用的类型代码是一样的。通过 auto 类型代码可以让内核自动检测文件系统,这对于可移动设备来说非常方便。注意,该选项可能不是对所有文件系统可用。
  • : 一个(或多个)挂载选项。
  • : 你可能把这个字段设置为 0(否则设置为 1),使得系统启动时禁用 dump 工具(dump 程序曾经是一个常用的备份工具,但现在越来越少用了)对文件系统进行备份。
  • : 这个字段指定启动系统是是否通过 fsck 来检查文件系统的完整性。0 表示 fsck 不对文件系统进行检查。数字越大,优先级越低。因此,根分区(/)最可能使用数字 1,其他所有需要检查的分区则是以数字 2.

Mount 命令例示

1、在系统启动时,通过 TECMINT 标卷来挂载文件系统,并具备 rw 和 noexec 属性,你应该将以下语句添加到 /etc/fstab 文件中。

LABEL=TECMINT /mnt ext4 rw,noexec 0 0  

2、若你想在系统启动时挂载 DVD 光驱中的内容,添加以下语句。

/dev/sr0 /media/cdrom0 iso9660 ro,user,noauto 0 0

其中 /dev/sr0 为你的 DVD 光驱。

总结

不用怀疑,在命令行中挂载/卸载本地和网络文件系统将是你作为系统管理员的日常责任的一部分。同时,你需要掌握 /etc/fstab 文件的编写。希望本文对你有帮助。随时在下边发表评论(或者提问),并分享本文到你的朋友圈。

参考链接


via: http://www.tecmint.com/mount-filesystem-in-linux/

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

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

3月30日在美国旧金山的莫斯康展览中心,微软召开了 Build 2016开发者大会,大会上微软除了介绍自家生态系统的产品与技术外,还为开发者带来了 Ubuntu on Windows 功能

Bash 是 Linux/Unix 上非常流行的命令行 Shell,它是 Ubuntu、RHEL 等 Linux 发行版以及苹果 OS X 操作系统默认的命令行 Shell。

Bash on Ubuntu on Windows 是通过 Windows Subsystem for Linux(WSL)这一 Windows 10 的最新特性实现的,使用此功能,你可以在 Windows 中原生运行 Linux 的大多数命令行程序。

其实在 Windows 7 之前的操作系统中,都含有一个 POSIX 子系统,以便将 UNIX 的程序源代码编译为 Windows 程序。微软为 POSIX 子系统提供了众多的 UNIX 工具,而这些工具都是基于 POSIX 子系统直接使用GNU 的原生代码编译实现的,你也可以在这个 POSIX 子系统运行 C Shell、Korn Shell 等命令行 Shell。不过Windows 7 以后的操作系统中都默认移除了 POSIX 子系统。如果有兴趣的话可以在 Windows 7 操作系统中的“启用或关闭 Windows 功能”中启用“基于 UNIX 的应用程序子系统”,即可体验 POSIX 子系统。

启用 WSL 功能之后,如果使用 Bash,则 Windows 10 操作系统会下载一个由 Canonical 创建的 Ubuntu用户模式镜像 Ubuntu user-mode image ,然后 Bash 程序以及其他的 Linux 二进制程序就可以运行于该 Ubuntu 镜像上。此外,微软也承诺未来会提供更多 Linux 发行版以供选择。

Bash on Ubuntu on Windows 功能主要是面向于开发者,尤其是 Web 开发者或者参与某些开源项目的开发者,他们可以在 Windows 中使用一些 Linux 生态链的开发工具。

之前我们为大家披露过 Ubuntu on Windows 的一些技术细节,今天为大家带来更具体的技术细节和体验方式。

如何安装体验 Ubuntu on Windows

启用Bash on Ubuntu on Windows

启用 Bash on Ubuntu on Windows 功能,首先你得先满足以下2个条件。

  • 使用x86-64架构的 CPU。
  • 使用 Windows 10 Insider Preview (Build 14316)64位版本。

如何获取 Windows 10 Insider Preview (Build 14316)呢?

这里有两种办法:

  • 第一种是从网上下载由别人制作好的 Windows 10 Insider Preview (Build 14316)安装镜像进行安装,但是由于安装镜像来源的问题,所以不推荐此方法,当然如果你是要在虚拟机中体验一下的话,用这种方式最合适不过了。
  • 第二种是加入 Windows Insider 计划,然后将 Windows 10 正式版升级至最新的 Insider Preview 版本。

加入Windows Insider 计划方法如下:

1、在 Windows Insider 网站中使用你的微软账户登录,登录成功之后,会出现如下图所示画面:

Windows Insider

然后单击图中的“入门”,会出现注册界面,勾选接受 Insider 计划协议,最后单击“提交”,等待提示注册完成。

2、确保使用上述加入 Windows Insider 计划的微软账户登录你的 Windows 10 操作系统,然后依次转到开始菜单-“设置”-“更新和安全”- “Windows 更新” -“高级选项”>“获取 Insider Preview 版本”,然后单击“开始”按钮,并按照屏幕上的说明进行操作,提示成功之后表示此电脑将会获取 Windows 10 Insider Preview 版本 。

获取 Insider Preview 版本

3、Windows Insider 计划默认自动获取慢速通道的 Insider Preview 版本,而 Windows 10 Insider Preview (Build 14316)属于快速通道版本,所以需要在如下图中,将滑块移至右侧的快速通道模式。

快速通道模式

4、进入快速通道模式之后,需要等待24小时才能获取 Insider Preview 版本,所以请耐心的等待吧!24小时之后检查更新,就会开始下载安装 Windows 10 Insider Preview (Build 14316)。

启用 Bash on Ubuntu on Windows

如果上述条件满足,按照以下步骤即可启用 Bash on Ubuntu on Windows。

1、依次在“设置”-“更新与安全”-“针对开发人员”选项中,启用开发人员模式,如下图所示。

启用开发人员模式

2、在开始菜单中搜索并打开“启用或关闭 Windows功能”,然后勾选其中的“Windows Subsystem for Linux(Beta)”选项,如下图所示,最后按照操作系统提示完成 WSL 安装(需要重启计算机)。

勾选其中的“Windows Subsystem for Linux(Beta)”

此外,也可以在 PowerShell 中输入以下命令完成 WSL 安装。

Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux

3、在命令提示符或 PowerShell 中输入 bash,然后按照提示按下 y 确认继续,操作系统会自动开始安装 Ubuntu on Windows,此时会下载 Ubuntu 用户模式镜像,并创建一个 Bash on Ubuntu on Windows 访问路径。等待安装完成之后,会自动进入 bash,如下图所示:

自动安装 Ubuntu on Windows

使用 Bash on Ubuntu on Windows

在命令提示符或 PowerShell 中输入 bash,或者在开始菜单中查找打开“Bash on Ubuntu on Windows”,即可运行。

运行之后,可以发现使用的是 Ubuntu 14.04.4 LTS 版本,同时也可以使用 apt-get 更新或安装程序,如下图所示。此外。在 bash 当中,Windows 的分区被挂载于 /mnt 目录,可以使用其中存储的数据。

可以使用 apt-get 更新或安装程序

当你试用了 Bash on Ubuntu on Windows 之后,你可能会觉得这是一个虚拟机,但它真不是一个虚拟机。其功能有点类似于模拟器。通过使用 WSL,可以将 Linux 的系统调用实时地转换为 Windows 的系统调用。

此外,在 Windows 下运行这些 Linux 的原生的 ELF(Executable and Linkable Format)二进制程序和在 Linux 下运行所消耗的 CPU 、内存和 IO 性能相当,完全不用担心性能的问题。

Bash on Ubuntu on Windows限制

  • 不支持使用 GUI 的桌面程序或 Gnome、KDE 类应用。
  • 处于 Beta 阶段,支持的 Linux 程序与功能有限,未来会支持更多的 Linux 工具。
  • 目前只支持使用 Ubuntu,未来会提供更多 Linux 发行版。
  • WSL 只支持在 Windows 10 build 14316 以后版本中使用,不支持 Windows Server。

命令参考

有两个命令 bash.exelxrun.exe 用于和 Windows Subsystem for Linux (WSL) 进行交互。它们安装在 \Windows\System32 目录下,可以在命令行或 Powershell 中运行。

  • bash.exe 启动 bash 环境并运行 /bin/bash
  • lxrun.exe 用于管理 WSL,可以用来安装或卸载 Ubuntu 镜像
命令描述
bash在当前目录启动 bash shell,如果 Bash 没有安装,这自动运行 lxrun /install
bash ~启动 bash,并切换到用户的 Ubuntu 主目录,类似运行 cd ~
bash -c "<command>"运行命令、打印输出并返回 Windows 命令行例子: bash -c "ls"
命令描述
lxrun用于管理 WSL 实例
lxrun /install启动下载和安装过程/y 选项可以用于自动应答安装过程的确认提示
lxrun /uninstall卸载并删除 Ubuntu 镜像。默认不删除用户的 Ubuntu 主目录。

/y 选项可以用于自动应答安装过程的确认提示
/full 选项会卸载并删除用户的 Ubuntu 主目录 |

总结

Bash on Ubuntu on Windows 的发布, 让众多的 Linux 粉丝大跌眼镜,曾经被微软视为癌症的 Linux,如今却被部分的集成进了微软最重要的产品中,这背后的目的似乎不是那么很平常。

有人说 Bash on Ubuntu on Windows 是微软布局 Docker 的开始,其实在 Windows Server 2016 预览版中已经加入了对Docker 技术的支持。也有人说是微软看中了 Linux 生态中的海量程序,用以补充自家的生态系统,但是就程序的数量来说,Windows 生态说第二,没人会说第一,所以似乎这个原因也站不住脚。

其实依目前的情况来看,个人觉得 Bash on Ubuntu on Windows 最主要的用处,还是为开发者提供便利,协助完成一些跨平台开发的工作。但是,也说不准微软最终的目的是什么,只能期待7月份的 Windows 10 周年更新里面为 Bash on Ubuntu on Windows 带来更多的功能。

提高 web 应用的性能从来没有比现在更重要过。网络经济的比重一直在增长;全球经济超过 5% 的价值是在因特网上产生的(数据参见下面的资料)。这个时刻在线的超连接世界意味着用户对其的期望值也处于历史上的最高点。如果你的网站不能及时的响应,或者你的 app 不能无延时的工作,用户会很快的投奔到你的竞争对手那里。

举一个例子,一份亚马逊十年前做过的研究可以证明,甚至在那个时候,网页加载时间每减少100毫秒,收入就会增加1%。另一个最近的研究特别强调一个事实,即超过一半的网站拥有者在调查中承认它们会因为应用程序性能的问题流失用户。

网站到底需要多快呢?对于页面加载,每增加1秒钟就有4%的用户放弃使用。顶级的电子商务站点的页面在第一次交互时可以做到1秒到3秒加载时间,而这是提供最高舒适度的速度。很明显这种利害关系对于 web 应用来说很高,而且在不断的增加。

想要提高效率很简单,但是看到实际结果很难。为了在你的探索之旅上帮助到你,这篇文章会给你提供10条最高可以提升10倍网站性能的建议。这是一系列介绍提高应用程序性能的第一篇文章,包括充分测试的优化技术和一点 NGINX 的帮助。这个系列也给出了潜在的提高安全性的帮助。

Tip #1: 通过反向代理来提高性能和增加安全性

如果你的 web 应用运行在单个机器上,那么这个办法会明显的提升性能:只需要换一个更快的机器,更好的处理器,更多的内存,更快的磁盘阵列,等等。然后新机器就可以更快的运行你的 WordPress 服务器, Node.js 程序, Java 程序,以及其它程序。(如果你的程序要访问数据库服务器,那么解决方法依然很简单:添加两个更快的机器,以及在两台电脑之间使用一个更快的链路。)

问题是,机器速度可能并不是问题。web 程序运行慢经常是因为计算机一直在不同的任务之间切换:通过成千上万的连接和用户交互,从磁盘访问文件,运行代码,等等。应用服务器可能会 抖动 thrashing -比如说内存不足、将内存数据交换到磁盘,以及有多个请求要等待某个任务完成,如磁盘I/O。

你可以采取一个完全不同的方案来替代升级硬件:添加一个反向代理服务器来分担部分任务。反向代理服务器 位于运行应用的机器的前端,是用来处理网络流量的。只有反向代理服务器是直接连接到互联网的;和应用服务器的通讯都是通过一个快速的内部网络完成的。

使用反向代理服务器可以将应用服务器从等待用户与 web 程序交互解放出来,这样应用服务器就可以专注于为反向代理服务器构建网页,让其能够传输到互联网上。而应用服务器就不需要等待客户端的响应,其运行速度可以接近于优化后的性能水平。

添加反向代理服务器还可以给你的 web 服务器安装带来灵活性。比如,一个某种类型的服务器已经超载了,那么就可以轻松的添加另一个相同的服务器;如果某个机器宕机了,也可以很容易替代一个新的。

因为反向代理带来的灵活性,所以反向代理也是一些性能加速功能的必要前提,比如:

  • 负载均衡 (参见 Tip #2) – 负载均衡运行在反向代理服务器上,用来将流量均衡分配给一批应用。有了合适的负载均衡,你就可以添加应用服务器而根本不用修改应用。
  • 缓存静态文件 (参见 Tip #3) – 直接读取的文件,比如图片或者客户端代码,可以保存在反向代理服务器,然后直接发给客户端,这样就可以提高速度、分担应用服务器的负载,可以让应用运行的更快。
  • 网站安全 – 反向代理服务器可以提高网站安全性,以及快速的发现和响应攻击,保证应用服务器处于被保护状态。

NGINX 软件为用作反向代理服务器而专门设计,也包含了上述的多种功能。NGINX 使用事件驱动的方式处理请求,这会比传统的服务器更加有效率。NGINX plus 添加了更多高级的反向代理特性,比如应用的健康度检查,专门用来处理请求路由、高级缓冲和相关支持。

NGINX Worker Process helps increase application performance

Tip #2: 添加负载平衡

添加一个负载均衡服务器 是一个相当简单的用来提高性能和网站安全性的的方法。与其将核心 Web 服务器变得越来越大和越来越强,不如使用负载均衡将流量分配到多个服务器。即使程序写的不好,或者在扩容方面有困难,仅是使用负载均衡服务器就可以很好的提高用户体验。

负载均衡服务器首先是一个反向代理服务器(参见Tip #1)——它接受来自互联网的流量,然后转发请求给另一个服务器。特别是负载均衡服务器支持两个或多个应用服务器,使用分配算法将请求转发给不同服务器。最简单的负载均衡方法是 轮转法 round robin ,每个新的请求都会发给列表里的下一个服务器。其它的复制均衡方法包括将请求发给活动连接最少的服务器。NGINX plus 拥有将特定用户的会话分配给同一个服务器的能力

负载均衡可以很好的提高性能是因为它可以避免某个服务器过载而另一些服务器却没有需要处理的流量。它也可以简单的扩展服务器规模,因为你可以添加多个价格相对便宜的服务器并且保证它们被充分利用了。

可以进行负载均衡的协议包括 HTTP、HTTPS、SPDY、HTTP/2、WebSocket、FastCGI、SCGI、uwsgi、 memcached 等,以及几种其它的应用类型,包括基于 TCP 的应用和其它的第4层协议的程序。分析你的 web 应用来决定你要使用哪些以及哪些地方性能不足。

相同的服务器或服务器群可以被用来进行负载均衡,也可以用来处理其它的任务,如 SSL 末端服务器,支持客户端的 HTTP/1.x 和 HTTP/2 请求,以及缓存静态文件。

NGINX 经常被用于进行负载均衡;要想了解更多的情况,可以下载我们的电子书《选择软件负载均衡器的五个理由》。你也可以从 《使用 NGINX 和 NGINX Plus 配置负载均衡,第一部分》中了解基本的配置指导,在 NGINX Plus 管理员指南中有完整的 NGINX 负载均衡的文档。。我们的商业版本 NGINX Plus 支持更多优化了的负载均衡特性,如基于服务器响应时间的加载路由和 Microsoft’s NTLM 协议上的负载均衡。

Tip #3: 缓存静态和动态的内容

缓存可以通过加速内容的传输速度来提高 web 应用的性能。它可以采用以下几种策略:当需要的时候预处理要传输的内容,保存数据到速度更快的设备,把数据存储在距离客户端更近的位置,或者将这几种方法结合起来使用。

有两种不同类型数据的缓冲:

  • 静态内容缓存。不经常变化的文件,比如图像(JPEG、PNG) 和代码(CSS,JavaScript),可以保存在外围服务器上,这样就可以快速的从内存和磁盘上提取。
  • 动态内容缓存。很多 web 应用会针对每次网页请求生成一个新的 HTML 页面。在短时间内简单的缓存生成的 HTML 内容,就可以很好的减少要生成的内容的数量,而且这些页面足够新,可以满足你的需要。

举个例子,如果一个页面每秒会被浏览10次,你将它缓存 1 秒,90%请求的页面都会直接从缓存提取。如果你分开缓存静态内容,甚至新生成的页面可能都是由这些缓存构成的。

下面由是 web 应用发明的三种主要的缓存技术:

  • 缩短数据与用户的网络距离。把一份内容的拷贝放的离用户更近的节点来减少传输时间。
  • 提高内容服务器的速度。内容可以保存在一个更快的服务器上来减少提取文件的时间。
  • 从过载服务器上移走数据。机器经常因为要完成某些其它的任务而造成某个任务的执行速度比测试结果要差。将数据缓存在不同的机器上可以提高缓存资源和非缓存资源的性能,而这是因为主机没有被过度使用。

对 web 应用的缓存机制可以在 web 应用服务器内部实现。首先,缓存动态内容是用来减少应用服务器加载动态内容的时间。其次,缓存静态内容(包括动态内容的临时拷贝)是为了更进一步的分担应用服务器的负载。而且缓存之后会从应用服务器转移到对用户而言更快、更近的机器,从而减少应用服务器的压力,减少提取数据和传输数据的时间。

改进过的缓存方案可以极大的提高应用的速度。对于大多数网页来说,静态数据,比如大图像文件,构成了超过一半的内容。如果没有缓存,那么这可能会花费几秒的时间来提取和传输这类数据,但是采用了缓存之后不到1秒就可以完成。

举一个在实际中缓存是如何使用的例子, NGINX 和 NGINX Plus 使用了两条指令来设置缓存机制:proxy\_cache\_path 和 proxy\_cache。你可以指定缓存的位置和大小、文件在缓存中保存的最长时间和其它一些参数。使用第三条(而且是相当受欢迎的一条)指令 proxy\_cache\_use\_stale,如果提供新鲜内容的服务器忙碌或者挂掉了,你甚至可以让缓存提供较旧的内容,这样客户端就不会一无所得。从用户的角度来看这可以很好的提高你的网站或者应用的可用时间。

NGINX plus 有个高级缓存特性,包括对缓存清除的支持和在仪表盘上显示缓存状态信息。

要想获得更多关于 NGINX 的缓存机制的信息可以浏览 NGINX Plus 管理员指南中的《参考文档》和《NGINX 内容缓存》。

注意:缓存机制分布于应用开发者、投资决策者以及实际的系统运维人员之间。本文提到的一些复杂的缓存机制从 DevOps 的角度来看很具有价值,即对集应用开发者、架构师以及运维操作人员的功能为一体的工程师来说可以满足它们对站点功能性、响应时间、安全性和商业结果(如完成的交易数)等需要。

Tip #4: 压缩数据

压缩是一个具有很大潜力的提高性能的加速方法。现在已经有一些针对照片(JPEG 和PNG)、视频(MPEG-4)和音乐(MP3)等各类文件精心设计和高压缩率的标准。每一个标准都或多或少的减少了文件的大小。

文本数据 —— 包括HTML(包含了纯文本和 HTML 标签),CSS 和代码,比如 Javascript —— 经常是未经压缩就传输的。压缩这类数据会在对应用程序性能的感觉上,特别是处于慢速或受限的移动网络的客户端,产生更大的影响。

这是因为文本数据经常是用户与网页交互的有效数据,而多媒体数据可能更多的是起提供支持或者装饰的作用。智能的内容压缩可以减少 HTML,Javascript,CSS和其它文本内容对带宽的要求,通常可以减少 30% 甚至更多的带宽和相应的页面加载时间。

如果你使用 SSL,压缩可以减少需要进行 SSL 编码的的数据量,而这些编码操作会占用一些 CPU 时间而抵消了压缩数据减少的时间。

压缩文本数据的方法很多,举个例子,在 HTTP/2 中,小说文本的压缩模式就特别调整了头部数据。另一个例子是可以在 NGINX 里打开使用 GZIP 压缩。你在你的服务里预先压缩文本数据之后,你就可以直接使用 gzip\_static 指令来处理压缩过的 .gz 版本。

Tip #5: 优化 SSL/TLS

安全套接字(SSL) 协议和它的下一代版本传输层安全(TLS)协议正在被越来越多的网站采用。SSL/TLS 对从原始服务器发往用户的数据进行加密提高了网站的安全性。影响这个趋势的部分原因是 Google 正在使用 SSL/TLS,这在搜索引擎排名上是一个正面的影响因素。

尽管 SSL/TLS 越来越流行,但是使用加密对速度的影响也让很多网站望而却步。SSL/TLS 之所以让网站变的更慢,原因有二:

  1. 任何一个连接第一次连接时的握手过程都需要传递密钥。而采用 HTTP/1.x 协议的浏览器在建立多个连接时会对每个连接重复上述操作。
  2. 数据在传输过程中需要不断的在服务器端加密、在客户端解密。

为了鼓励使用 SSL/TLS,HTTP/2 和 SPDY(在下一章会描述)的作者设计了新的协议来让浏览器只需要对一个浏览器会话使用一个连接。这会大大的减少上述第一个原因所浪费的时间。然而现在可以用来提高应用程序使用 SSL/TLS 传输数据的性能的方法不止这些。

web 服务器有对应的机制优化 SSL/TLS 传输。举个例子,NGINX 使用 OpenSSL 运行在普通的硬件上提供了接近专用硬件的传输性能。NGINX 的 SSL 性能 有详细的文档,而且把对 SSL/TLS 数据进行加解密的时间和 CPU 占用率降低了很多。

更进一步,参考这篇文章了解如何提高 SSL/TLS 性能的更多细节,可以总结为一下几点:

  • 会话缓冲。使用指令 ssl\_session\_cache 可以缓存每个新的 SSL/TLS 连接使用的参数。
  • 会话票据或者 ID。把 SSL/TLS 的信息保存在一个票据或者 ID 里可以流畅的复用而不需要重新握手。
  • OCSP 分割。通过缓存 SSL/TLS 证书信息来减少握手时间。

NGINX 和 NGINX Plus 可以被用作 SSL/TLS 服务端,用于处理客户端流量的加密和解密,而同时以明文方式和其它服务器进行通信。要设置 NGINX 和 NGINX Plus 作为 SSL/TLS 服务端,参看 《HTTPS 连接》 和《加密的 TCP 连接》。

Tip #6: 使用 HTTP/2 或 SPDY

对于已经使用了 SSL/TLS 的站点,HTTP/2 和 SPDY 可以很好的提高性能,因为每个连接只需要一次握手。而对于没有使用 SSL/TLS 的站点来说,从响应速度的角度来说 HTTP/2 和 SPDY 将让迁移到 SSL/TLS 没有什么压力(原本会降低效率)。

Google 在2012年开始把 SPDY 作为一个比 HTTP/1.x 更快速的协议来推荐。HTTP/2 是目前 IETF 通过的标准,是基于 SPDY 的。SPDY 已经被广泛的支持了,但是很快就会被 HTTP/2 替代。

SPDY 和 HTTP/2 的关键是用单一连接来替代多路连接。单个连接是被复用的,所以它可以同时携带多个请求和响应的分片。

通过使用单一连接,这些协议可以避免像在实现了 HTTP/1.x 的浏览器中一样建立和管理多个连接。单一连接在对 SSL 特别有效,这是因为它可以最小化 SSL/TLS 建立安全链接时的握手时间。

SPDY 协议需要使用 SSL/TLS,而 HTTP/2 官方标准并不需要,但是目前所有支持 HTTP/2 的浏览器只有在启用了 SSL/TLS 的情况下才能使用它。这就意味着支持 HTTP/2 的浏览器只有在网站使用了 SSL 并且服务器接收 HTTP/2 流量的情况下才会启用 HTTP/2。否则的话浏览器就会使用 HTTP/1.x 协议。

当你实现 SPDY 或者 HTTP/2 时,你不再需要那些常规的 HTTP 性能优化方案,比如按域分割、资源聚合,以及图像拼合。这些改变可以让你的代码和部署变得更简单和更易于管理。要了解 HTTP/2 带来的这些变化可以浏览我们的《白皮书》。

NGINX Supports SPDY and HTTP/2 for increased web application performance

作为支持这些协议的一个样例,NGINX 已经从一开始就支持了 SPDY,而且大部分使用 SPDY 协议的网站都运行的是 NGINX。NGINX 同时也很早对 HTTP/2 的提供了支持,从2015 年9月开始,开源版 NGINX 和 NGINX Plus 就支持它了。

经过一段时间,我们 NGINX 希望更多的站点完全启用 SSL 并且向 HTTP/2 迁移。这将会提高安全性,同时也会找到并实现新的优化手段,简化的代码表现的会更加优异。

Tip #7: 升级软件版本

一个提高应用性能的简单办法是根据软件的稳定性和性能的评价来选在你的软件栈。进一步说,因为高性能组件的开发者更愿意追求更高的性能和解决 bug ,所以值得使用最新版本的软件。新版本往往更受开发者和用户社区的关注。更新的版本往往会利用到新的编译器优化,包括对新硬件的调优。

稳定的新版本通常比旧版本具有更好的兼容性和更高的性能。一直进行软件更新,可以非常简单的保持软件保持最佳的优化,解决掉 bug,以及提高安全性。

一直使用旧版软件也会阻止你利用新的特性。比如上面说到的 HTTP/2,目前要求 OpenSSL 1.0.1。在2016 年中期开始将会要求1.0.2 ,而它是在2015年1月才发布的。

NGINX 用户可以开始迁移到 NGINX 最新的开源软件 或者 NGINX Plus;它们都包含了最新的能力,如 socket 分割和线程池(见下文),这些都已经为性能优化过了。然后好好看看的你软件栈,把它们升级到你能升级到的最新版本吧。

Tip #8: Linux 系统性能调优

Linux 是大多数 web 服务器使用的操作系统,而且作为你的架构的基础,Linux 显然有不少提高性能的可能。默认情况下,很多 Linux 系统都被设置为使用很少的资源,以符合典型的桌面应用使用。这就意味着 web 应用需要一些微调才能达到最大效能。

这里的 Linux 优化是专门针对 web 服务器方面的。以 NGINX 为例,这里有一些在加速 Linux 时需要强调的变化:

  • 缓冲队列。如果你有挂起的连接,那么你应该考虑增加 net.core.somaxconn 的值,它代表了可以缓存的连接的最大数量。如果连接限制太小,那么你将会看到错误信息,而你可以逐渐的增加这个参数直到错误信息停止出现。
  • 文件描述符。NGINX 对一个连接使用最多2个文件描述符。如果你的系统有很多连接请求,你可能就需要提高sys.fs.file\_max ,以增加系统对文件描述符数量整体的限制,这样才能支持不断增加的负载需求。
  • 临时端口。当使用代理时,NGINX 会为每个上游服务器创建临时端口。你可以设置net.ipv4.ip\_local\_port\_range 来提高这些端口的范围,增加可用的端口号。你也可以减少非活动的端口的超时判断来重复使用端口,这可以通过 net.ipv4.tcp\_fin\_timeout 来设置,这可以快速的提高流量。

对于 NGINX 来说,可以查阅 《NGINX 性能调优指南》来学习如果优化你的 Linux 系统,这样它就可以很好的适应大规模网络流量而不会超过工作极限。

Tip #9: web 服务器性能调优

无论你是用哪种 web 服务器,你都需要对它进行优化来提高性能。下面的推荐手段可以用于任何 web 服务器,但是一些设置是针对 NGINX 的。关键的优化手段包括:

  • 访问日志。不要把每个请求的日志都直接写回磁盘,你可以在内存将日志缓存起来然后批量写回磁盘。对于NGINX 来说,给指令 access\_log 添加参数 buffer=size 可以让系统在缓存满了的情况下才把日志写到磁盘。如果你添加了参数 flush=time ,那么缓存内容会每隔一段时间再写回磁盘。
  • 缓存。缓存会在内存中存放部分响应,直到满了为止,这可以让与客户端的通信更加高效。内存放不下的响应会写回磁盘,而这就会降低效能。当 NGINX 启用了缓存机制后,你可以使用指令 proxy\_buffer\_sizeproxy\_buffers 来管理缓存。
  • 客户端保活。保活连接可以减少开销,特别是使用 SSL/TLS 时。对于 NGINX 来说,你可以从 keepalive\_requests 的默认值 100 开始增加最大连接数,这样一个客户端就可以在一个指定的连接上请求多次,而且你也可以通过增加 keepalive\_timeout 的值来允许保活连接存活更长时间,这样就可以让后来的请求处理的更快速。
  • 上游保活。上游的连接——即连接到应用服务器、数据库服务器等机器的连接——同样也会受益于连接保活。对于上游连接来说,你可以增加 keepalive,即每个工人进程的空闲保活连接个数。这就可以提高连接的复用次数,减少需要重新打开全新连接的次数。更多关于保活连接的信息可以参见这篇“ HTTP 保活连接和性能”
  • 限制。限制客户端使用的资源可以提高性能和安全性。对于 NGINX 来说,指令 limit\_connlimit\_conn\_zone 限制了给定来源的连接数量,而 limit\_rate 限制了带宽。这些限制都可以阻止合法用户扒取资源,同时也避免了攻击。指令 limit\_reqlimit\_req\_zone 限制了客户端请求。对于上游服务器来说,可以在 upstream 的配置块里的 server 指令使用 max\_conns 参数来限制连接到上游服务器的连接数。 这样可以避免服务器过载。关联的 queue 指令会创建一个队列来在连接数抵达 max\_connS 限制时在指定长度的时间内保存特定数量的请求。
  • 工人进程。工人进程负责处理请求。NGINX 采用事件驱动模型和操作系统特定的机制来有效的将请求分发给不同的工人进程。这条建议推荐设置 worker\_processes 为每个 CPU 一个 。worker\_connections 的最大数(默认512)可以在大部分系统上根据需要增加,实验性地找到最适合你的系统的值。
  • 套接字分割。通常一个套接字监听器会把新连接分配给所有工人进程。套接字分割会为每个工人进程创建一个套接字监听器,这样一来以当套接字监听器可用时,内核就会将连接分配给它。这可以减少锁竞争,并且提高多核系统的性能,要启用套接字分隔需要在 listen 指令里面加上 reuseport 参数。
  • 线程池。计算机进程可能被一个单一的缓慢的操作所占用。对于 web 服务器软件来说,磁盘访问会影响很多更快的操作,比如计算或者在内存中拷贝。使用了线程池之后慢操作可以分配到不同的任务集,而主进程可以一直运行快速操作。当磁盘操作完成后结果会返回给主进程的循环。在 NGINX 里有两个操作——read() 系统调用和 sendfile() ——被分配到了线程池

Thread pools help increase application performance by assigning a slow operation to a separate set of tasks

技巧。当改变任何操作系统或支持服务的设置时,一次只改变一个参数然后测试性能。如果修改引起问题了,或者不能让你的系统更快,那么就改回去。

在《调优 NGINX 性能》里可以看到更详细的 NGINX 调优方法。

Tip #10: 监视系统活动来解决问题和瓶颈

在应用开发中要使得系统变得非常高效的关键是监视你的系统在现实世界运行的性能。你必须能通过特定的设备和你的 web 基础设施上监控程序活动。

监视活动是最积极的——它会告诉你发生了什么,把问题留给你发现和最终解决掉。

监视可以发现几种不同的问题。它们包括:

  • 服务器宕机。
  • 服务器出问题一直在丢失连接。
  • 服务器出现大量的缓存未命中。
  • 服务器没有发送正确的内容。

应用的总体性能监控工具,比如 New Relic 和 Dynatrace,可以帮助你监控到从远程加载网页的时间,而 NGINX 可以帮助你监控到应用交付端。当你需要考虑为基础设施添加容量以满足流量需求时,应用性能数据可以告诉你你的优化措施的确起作用了。

为了帮助开发者快速的发现、解决问题,NGINX Plus 增加了应用感知健康度检查 ——对重复出现的常规事件进行综合分析并在问题出现时向你发出警告。NGINX Plus 同时提供会话过滤功能,这可以阻止当前任务完成之前接受新的连接,另一个功能是慢启动,允许一个从错误恢复过来的服务器追赶上负载均衡服务器群的进度。当使用得当时,健康度检查可以让你在问题变得严重到影响用户体验前就发现它,而会话过滤和慢启动可以让你替换服务器,并且这个过程不会对性能和正常运行时间产生负面影响。下图就展示了内建的 NGINX Plus 模块实时活动监视的仪表盘,包括了服务器群,TCP 连接和缓存信息等 Web 架构信息。

Use real-time application performance monitoring tools to identify and resolve issues quickly

总结: 看看10倍性能提升的效果

这些性能提升方案对任何一个 web 应用都可用并且效果都很好,而实际效果取决于你的预算、你能花费的时间、目前实现方案的差距。所以你该如何对你自己的应用实现10倍性能提升?

为了指导你了解每种优化手段的潜在影响,这里是上面详述的每个优化方法的关键点,虽然你的情况肯定大不相同:

  • 反向代理服务器和负载均衡。没有负载均衡或者负载均衡很差都会造成间歇的性能低谷。增加一个反向代理,比如 NGINX ,可以避免 web 应用程序在内存和磁盘之间波动。负载均衡可以将过载服务器的任务转移到空闲的服务器,还可以轻松的进行扩容。这些改变都可以产生巨大的性能提升,很容易就可以比你现在的实现方案的最差性能提高10倍,对于总体性能来说可能提高的不多,但是也是有实质性的提升。
  • 缓存动态和静态数据。如果你有一个负担过重的 web 服务器,那么毫无疑问肯定是你的应用服务器,只通过缓存动态数据就可以在峰值时间提高10倍的性能。缓存静态文件可以提高几倍的性能。
  • 压缩数据。使用媒体文件压缩格式,比如图像格式 JPEG,图形格式 PNG,视频格式 MPEG-4,音乐文件格式 MP3 可以极大的提高性能。一旦这些都用上了,然后压缩文件数据可以将初始页面加载速度提高两倍。
  • 优化 SSL/TLS。安全握手会对性能产生巨大的影响,对它们的优化可能会对初始响应产生2倍的提升,特别是对于大量文本的站点。优化 SSL/TLS 下媒体文件只会产生很小的性能提升。
  • 使用 HTTP/2 和 SPDY。当你使用了 SSL/TLS,这些协议就可以提高整个站点的性能。
  • 对 Linux 和 web 服务器软件进行调优。比如优化缓存机制,使用保活连接,分配时间敏感型任务到不同的线程池可以明显的提高性能;举个例子,线程池可以加速对磁盘敏感的任务近一个数量级

我们希望你亲自尝试这些技术。我们希望知道你说取得的各种性能提升案例。请在下面评论栏分享你的结果或者在标签 #NGINX 和 #webperf 下 tweet 你的故事。

网上资源


via: https://www.nginx.com/blog/10-tips-for-10x-application-performance/

作者:Floyd Smith 译者:Ezio 校对:wxy

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

Learn to live with Apache Hive in 12 easy steps

Hive 可以让你在 Hadoop 上使用 SQL,但是在分布式系统上优化 SQL 则有所不同。这里是让你可以轻松驾驭 Hive 的12个技巧。

Hive 并不是关系型数据库(RDBMS),但是它大多数时候都表现得像是一个关系型数据库一样,它有表、可以运行 SQL、也支持 JDBC 和 ODBC。

这种表现既有好的一面,也有不好的一面:Hive 并不像关系型数据库那样执行 SQL 查询。我在 Hive 上花费了大量时间,光是我自己在工作中就为了优化它花费了超过80个小时。不说你也知道,我就像呆在蜂巢(Hive)旁边一样脑袋嗡嗡作响。所以,为了让你免受这种痛苦,我决定将它们写出来,以便让你在你的下一个 Hive 项目中逃离这种折磨。

1、不要使用 MapReduce

不管你是不是觉得 Tez、Spark 或 Impala 能行,但是不要指望 MapReduce。它本身就很慢,比 Hive 还慢。如果你用的是 Hortonwork 的版本,你可以在脚本前面写上 set hive.execution.engine=tez ;用 Cloudera 的话,使用 Impala。如果 Impala 不适用的话,我希望到时候可以使用 hive.execution.engine=spark

2、不要在 SQL 中做字符串匹配

绝不要,特别是在 Hive 中!如果你坚持要在 WHERE 语句中使用 LIKE 匹配,就会产生一个跨产品的警告。本来你的查询可能只用几秒钟,但是使用字符串匹配的话就会变成几分钟。最好的办法是使用那些可以在 Hadoop 中进行搜索的工具,可以试试 Elasticsearch 的 Hive 集成版本Lucidwork 的 Solr,以及 Cloudera Search。关系型数据库这方面表现并不好,但是 Hive 则更糟糕。

3、不要用表连接子查询

你最好创建一个临时表,然后对这个临时表进行连接,而不是让 Hive 自己智能处理子查询。即不要这样做:

select a.* from something a inner join 
  (select ... from somethingelse union b select ... from anotherthing c) d 
  on a.key1 = d.key1 and a.key2 = b.key2 where a.condition=1

而是应该这样:

create var_temp as select ... from somethingelse b 
  union select ... from anotherthing c 
and then 
select a.* from something a inner join from var_temp b 
  where a.key1=b.key1 and a.key2=b.key2 where a.condition=1

一般来说,这会比 Hive 自己处理子查询要快许多。

4、使用 Parquet 或 ORC,但是不要转换使用

也就是说,使用 Parquet 或 ORC 而不要用 TEXTFILE。然而,如果你要把文本数据中导入到更具结构性的数据中,应该做一些转换再导入到目标表中。你不应该用 LOAD DATA 将文本文件加载到 ORC 中,而是应该将其加载到一个文本中。

如果你要创建另外一个表,并最终大多数分析都是对它进行的,那么你就该对该表进行 ORC 化,因为转换到 ORC 或 Parquet 要花费很多时间,并不值得将其放到你的 ETL 处理中。如果你有一个简单的普通文本要导入,也没做过任何优化,你应该将其加载到一个临时表并通过 select create 放到 ORC 或 Parquet 中。不过,这有点慢。

5、开关矢量化试试

在你的脚本前面加上 set hive.vectorized.execution.enabled = trueset hive.vectorized.execution.reduce.enabled = true ,然后试着打开或关闭它们看看。因为最近版本的 Hive 的矢量化有点问题。

6、不要在表连接中使用 structs

我必须承认我大脑里面的 SQL 格式还是 SQL-92 时代的,所以我无论如何都不会想到去用 structs。但是如果你做一些超级复杂的操作,比如在联合主键上使用 ON 语句,那么 structs 就很方便。不幸的是,Hive 对它们很不适应,特别是在 ON 语句上。当然,大多数情况下,在较小的数据集和 yields 下是没错误的。在 Tez 里面,你会得到一个有趣的矢量错误。这个限制并未见于我所知的任何文档,也许这是一个探索你的执行引擎内部的好办法。

7、检查你的容器大小

你也许需要为 ImpalaTez 增加你的容器大小。如果有你的节点大小比较大,“推荐的”容器大小可能就不适用于你的系统。你也许需要确保你的 YARN 队列和常规的 YARN 内存大小合适。你也许应该注意默认的队列并不适合所有的常规使用。

8、启用统计

Hive 在表连接时会做一些蠢事,除非启用了统计。你也可以在 Impala 中使用查询提示

9、考虑 MapJoin 优化

如果你分析你的查询,你可能发现最新的 Hive 已经可以足够智能地进行自动优化了。但是你也许需要再调整一下。

10、如果可以,将大表放到最后

如标题。

11、分区总会帮到你,不管多少

如果你有一个出现在许多地方的东西,比如语句中的日期(但不是日期范围)或重复的地点,你也许应该做分区。分区的基本意思是“拆分到它自己的目录里面”,而不是到一个大的文件中去查找。当你在你的 join/where 语句中仅检索 location=’NC’这样一个小数据集时,Hive 就可以在一个文件中查找。此外,和列值不同,你可以在你的 LOAD DATA 语句中加上分区。另外,要记住,HDFS 并不喜欢小文件

12、使用哈希进行列比较

如果你要在每个查询中比较同样的10个字段,可以考虑使用 hash() 来比较它们的校验值。在一个输出表中展示它们也许很有用。注意,在 Hive 0.12 中,哈希功能比较差,0.13中的哈希更好一些。

以上就是我的12点经验,我希望这些能够帮到你,让你从 Hive 的嗡嗡声中逃离出来。