From 9d40d51ec16084d89dff974d9e8ef9dad87b2ddd Mon Sep 17 00:00:00 2001 From: bazz2 Date: Fri, 30 Sep 2016 14:49:32 +0800 Subject: [PATCH 001/316] [bazz2] finished Monitoring Docker Containers with Elasticsearch and cAdvisor --- ...tainers with Elasticsearch and cAdvisor.md | 208 ------------------ ...tainers with Elasticsearch and cAdvisor.md | 207 +++++++++++++++++ 2 files changed, 207 insertions(+), 208 deletions(-) delete mode 100644 sources/tech/20160913 Monitoring Docker Containers with Elasticsearch and cAdvisor.md create mode 100644 translated/tech/20160913 Monitoring Docker Containers with Elasticsearch and cAdvisor.md diff --git a/sources/tech/20160913 Monitoring Docker Containers with Elasticsearch and cAdvisor.md b/sources/tech/20160913 Monitoring Docker Containers with Elasticsearch and cAdvisor.md deleted file mode 100644 index ca4852afac..0000000000 --- a/sources/tech/20160913 Monitoring Docker Containers with Elasticsearch and cAdvisor.md +++ /dev/null @@ -1,208 +0,0 @@ -jiajia9linuxer -Monitoring Docker Containers with Elasticsearch and cAdvisor -======= - -If you’re running a Swarm Mode cluster or even a single Docker engine, you’ll end up asking this question: - ->How do I keep track of all that’s happening? - -The answer is “not easily.” - -You need a few things to have a complete overview of stuff like: - - -1. Number and status of containers -2. If, where, and when a container has been moved to another node -3. Number of containers on a given node -4. Traffic peaks at a given time -5. Orphan volumes and networks -6. Free disk space, free inodes -7. Number of containers against number of veths attached to the docker0 and docker_gwbridge bridges -8. Up and down Swarm nodes -9. Centralize logs - -The goal of this post is to demonstrate the use of [Elasticsearch][1] + [Kibana][2] + [cAdvisor][3] as tools to analyze and gather metrics and visualize dashboards for Docker containers. - -Later on in this post, you can find a dashboard trying to address a few points from the previous list. There are also points that can’t be addressed by simply using cAdvisor, like the status of Swarm Mode nodes. - -Also, if you have specific needs that aren’t covered by cAdvisor or another tool, I encourage you to write your own data collector and data shipper (e.g., [Beats][4]). Note that I won’t be showing you how to centralize Docker containers log on Elasticsearch. - ->[“How do you keep track of all that’s happening in a Swarm Mode cluster? Not easily.” via @fntlnz][5] - -### Why Do We Need to Monitor Containers? - -Imagine yourself in the classic situation of managing a virtual machine, either just one or several. You are a tmux hero, so you have your sessions preconfigured to do basically everything, monitoring included. There’s a problem in production? You just do a top, htop, iotop, jnettop, whatevertop on all your machines, and you’re ready for troubleshooting! - -Now imagine that you have the same three nodes but split into 50 containers. You need some history displayed nicely in a single place where you can perform queries to know what happened instead of just risking your life in front of those ncurses tools. - -### What Is the Elastic Stack? - -The Elastic Stack is a set of tools composed of: - -- Elasticsearch -- Kibana -- Logstash -- Beats - -We’re going to use a few open-source tools from the Elastic Stack, such as Elasticsearch for the JSON-based analytics engine and Kibana to visualize data and create dashboards. - -Another important piece of the Elastic Stack is Beats, but in this post, we’re focused on containers. There’s no official Beat for Docker, so we’ll just use cAdvisor that can natively talk with Elasticsearch. - -cAdvisor is a tool that collects, aggregates, and exports metrics about running containers. In our case, those metrics are being exported to an Elasticsearch storage. - -Two cool facts about cAdvisor are: - -- It’s not limited to Docker containers. -- It has its own webserver with a simple dashboard to visualize gathered metrics for the current node. - -### Set Up a Test Cluster or BYOI - -As I did in my previous posts, my habit is to provide a small script to allow the reader to set up a test environment on which to try out my project’s steps in no time. So you can use the following not-for-production-use script to set up a little Swarm Mode cluster with Elasticsearch running as a container. - ->If you have enough time/experience, you can BYOI (Bring Your Own Infrastructure). - - -To follow this post, you’ll just need: - -- One or more nodes running the Docker daemon >= 1.12 -- At least a stand-alone Elasticsearch node 2.4.X - -Again, note that this post is not about setting up a production-ready Elasticsearch cluster. A single node cluster is not recommended for production. So if you’re planning a production installation, please refer to [Elastic guidelines][6]. - -### A friendly note for early adopters - -I’m usually an early adopter (and I’m already using the latest alpha version in production, of course). But for this post, I chose not to use the latest Elasticsearch 5.0.0 alpha. Their roadmap is not perfectly clear to me, and I don’t want be the root cause of your problems! - -So the Elasticsearch reference version for this post is the latest stable version, 2.4.0 at the moment of writing. - -### Test cluster setup script - -As said, I wanted to provide this script for everyone who would like to follow the blog without having to figure out how to create a Swarm cluster and install an Elasticsearch. Of course, you can skip this if you choose to use your own Swarm Mode engines and your own Elasticsearch nodes. - -To execute the setup script, you’ll need: - -- [Docker Machine][7] – latest version: to provision Docker engines on DigitalOcean -- [DigitalOcean API Token][8]: to allow docker-machine to start nodes on your behalf - -![](https://resources.codeship.com/hubfs/CTAs/EVAL/Codeship_Request_Trial_Access.png?t=1473869513342) - -### Create Cluster Script - -Now that you have everything we need, you can copy the following script in a file named create-cluster.sh: - -``` -#!/usr/bin/env bash -# -# Create a Swarm Mode cluster with a single master and a configurable number of workers - -workers=${WORKERS:-"worker1 worker2"} - -####################################### -# Creates a machine on Digital Ocean -# Globals: -# DO_ACCESS_TOKEN The token needed to access DigitalOcean's API -# Arguments: -# $1 the actual name to give to the machine -####################################### -create_machine() { - docker-machine create \ - -d digitalocean \ - --digitalocean-access-token=$DO_ACCESS_TOKEN \ - --digitalocean-size 2gb \ - $1 -} - -####################################### -# Executes a command on the specified machine -# Arguments: -# $1 The machine on which to run the command -# $2..$n The command to execute on that machine -####################################### -machine_do() { - docker-machine ssh $@ -} - -main() { - - if [ -z "$DO_ACCESS_TOKEN" ]; then - echo "Please export a DigitalOcean Access token: https://cloud.digitalocean.com/settings/api/tokens/new" - echo "export DO_ACCESS_TOKEN=" - exit 1 - fi - - if [ -z "$WORKERS" ]; then - echo "You haven't provided your workers by setting the \$WORKERS environment variable, using the default ones: $workers" - fi - - # Create the first and only master - echo "Creating the master" - - create_machine master1 - - master_ip=$(docker-machine ip master1) - - # Initialize the swarm mode on it - echo "Initializing the swarm mode" - machine_do master1 docker swarm init --advertise-addr $master_ip - - # Obtain the token to allow workers to join - worker_tkn=$(machine_do master1 docker swarm join-token -q worker) - echo "Worker token: ${worker_tkn}" - - # Create and join the workers - for worker in $workers; do - echo "Creating worker ${worker}" - create_machine $worker - machine_do $worker docker swarm join --token $worker_tkn $master_ip:2377 - done -} - -main $@ -``` - -And make it executable: - -``` -chmod +x create-cluster.sh -``` - -### Create the cluster - -As the name suggests, we’ll use the script to create the cluster. By default, the script will create a cluster with a single master and two workers. If you want to configure the number of workers, you can do that by setting the WORKERS environment variable. - -Now, let’s create that cluster! - -``` -./create-cluster.sh -``` - -Ok, now you can go out for a coffee. This will take a while. - -Finally the cluster is ready! - --------------------------------------------------------------------------------- - -via: https://blog.codeship.com/monitoring-docker-containers-with-elasticsearch-and-cadvisor/ - -作者:[Lorenzo Fontana][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]: https://blog.codeship.com/author/lorenzofontana/ - - - - - - - -[1]: https://github.com/elastic/elasticsearch -[2]: https://github.com/elastic/kibana -[3]: https://github.com/google/cadvisor -[4]: https://github.com/elastic/beats -[5]: https://twitter.com/share?text=%22How+do+you+keep+track+of+all+that%27s+happening+in+a+Swarm+Mode+cluster%3F+Not+easily.%22+via+%40fntlnz&url=https://blog.codeship.com/monitoring-docker-containers-with-elasticsearch-and-cadvisor/ -[6]: https://www.elastic.co/guide/en/elasticsearch/guide/2.x/deploy.html -[7]: https://docs.docker.com/machine/install-machine/ -[8]: https://cloud.digitalocean.com/settings/api/tokens/new diff --git a/translated/tech/20160913 Monitoring Docker Containers with Elasticsearch and cAdvisor.md b/translated/tech/20160913 Monitoring Docker Containers with Elasticsearch and cAdvisor.md new file mode 100644 index 0000000000..08c8410764 --- /dev/null +++ b/translated/tech/20160913 Monitoring Docker Containers with Elasticsearch and cAdvisor.md @@ -0,0 +1,207 @@ +使用 Elasticsearch 和 cAdvisor 监控 Docker 容器 +======= + +如果你正在运行 Swarm 模式的集群,或者只运行单台 Docker,你都会有下面的疑问: + +>我如何才能监控到它们都在干些什么? + +这个问题的答案是“很不容易”。 + +你需要监控下面的参数: + +1. 容器的数量和状态。 +2. 一台容器是否已经移到另一个结点了,如果是,那是在什么时候,移动到哪个节点? +3. 一个结点上运行着的容器数量。 +4. 一段时间内的通信峰值。 +5. 孤儿卷和网络(LCTT 译注:孤儿卷就是当你删除容器时忘记删除它的卷,这个卷就不会再被使用,但会一直占用资源)。 +6. 回收磁盘空间,回收结点。 +7. 容器数量与连接在 docker0 和 docker_gwbridge 上的虚拟网卡数量不一致(LCTT 译注:当docker启动时,它会在宿主机器上创建一个名为docker0的虚拟网络接口)。 +8. 开启和关闭 Swarm 节点。 +9. 收集并集中处理日志。 + +本文的目标是介绍 [Elasticsearch][1] + [Kibana][2] + [cAdvisor][3] 的用法,使用它们来收集 Docker 容器的参数,分析数据并产生可视化报表。 + +阅读本文后你会发现有一个报表会显示上述9个参数的部分内容,如果简单使用 cAdvisor,有些参数就无法显示出来,比如 Swarm 模式的节点。 + +如果你的一些 cAdvisor 或其他工具无法提供的特殊需求,我建议你开发自己的数据收集器和数据处理器(比如 [Beats][4]),请注意我不会演示如何使用 Elasticsearch 来收集 Docker 容器的日志。 + +>[“你要如何才能监控到 Swarm 模式集群里面发生了什么事情?要做到这点很不容易。” 作者 @fntlnz][5] + +### 我们为什么要监控容器? + +想象一下这个经典场景:你在管理一台或多台虚拟机,你把 tmux 工具用得很溜,用各种 session 事先设定好了所有基础的东西,包括监控。然后生产环境出问题了,你使用 top htop iotop jnettop 各种 top 来排查,然后你准备好修复故障。 + +现在重新想象一下你有3个节点,包含50台容器,你需要在一个地方查看整洁的历史数据知道问题出在哪个地方,而不是把你的生命浪费在那些字符界面来赌你可以找到问题点。 + +### 什么是 Elastic Stack ? + +Elastic Stack 就一个工具集,包括以下工具: + +- Elasticsearch +- Kibana +- Logstash +- Beats + +我们会使用其中一部分工具,比如使用 Elasticsearch 来分析基于 JSON 格式的文本,以及使用 Kibana 来可视化数据并产生报表。 + +另一个重要的工具是 Beats,但在本文中我们还是把精力放在容器上,官方的 Beats 工具不支持 Docker,所以我们选择原生兼容 Elasticsearch 的 cAdvisor。 + +cAdvisor 工具负责收集、整合容器数据,并导出报表。在本文中,这些报表被到入到 Elasticsearch 中。 + +cAdvisor 有两个比较酷的特性: + +- 它不只局限于 Docker 容器。 +- 它有自己的 web 服务器,可以简单地显示当前节点的可视化报表。 + +### 设置测试集群,或搭建自己的基础架构 + +和我以前的文章一样,我习惯提供一个简单的脚本,让读者不用花很多时间就能部署好和我一样的测试环境。你可以使用以下(非生产环境使用的)脚本来搭建一个 Swarm 模式的集群,其中一个容器运行着 Elasticsearch。 + +> 如果你有充足的时间和经验,你可以搭建自己的基础架构。 + + +如果要继续阅读本文,你需要: + +- 一个或多个节点,运行 Docker 进程(docker 版本号大于等于 1.12)。 +- 至少有一个独立运行的 Elasticsearch 节点(版本号 2.4.X)。 + +重申一下,此 Elasticsearch 集群环境不能放在生产环境中使用。生产环境也不推荐使用单节点集群,所以如果你计划安装一个生产环境,请参考 [Elastic guidelines][6]。 + +### 对喜欢尝鲜的用户的友情提示 + +我就是一个喜欢尝鲜的人(当然我也已经在生产环境中使用了 alpha 版本),但是在本文中,我不会使用最新的 Elasticsearch 5.0.0 alpha 版本,我还不是很清楚这个版本的功能,所以我不想成为那个引导你们出错的关键。 + +所以本文中涉及的 Elasticsearch 版本为最新稳定版 2.4.0。 + +### 测试集群部署脚本 + +前面已经说过,我提供这个脚本给你们,让你们不必费神去部署 Swarm 集群和 Elasticsearch,当然你也可以跳过这一步,用你自己的 Swarm 模式引擎和你自己的 Elasticserch 节点。 + +执行这段脚本之前,你需要: + +- [Docker Machine][7] – 最终版:在 DigitalOcean 中提供 Docker 引擎。 +- [DigitalOcean API Token][8]: 让 docker 机器按照你的意思来启动节点。 + +![](https://resources.codeship.com/hubfs/CTAs/EVAL/Codeship_Request_Trial_Access.png?t=1473869513342) + +### 创建集群的脚本 + +现在万事俱备,你可以把下面的代码拷到 create-cluster.sh 文件中: + +``` +#!/usr/bin/env bash +# +# Create a Swarm Mode cluster with a single master and a configurable number of workers + +workers=${WORKERS:-"worker1 worker2"} + +####################################### +# Creates a machine on Digital Ocean +# Globals: +# DO_ACCESS_TOKEN The token needed to access DigitalOcean's API +# Arguments: +# $1 the actual name to give to the machine +####################################### +create_machine() { + docker-machine create \ + -d digitalocean \ + --digitalocean-access-token=$DO_ACCESS_TOKEN \ + --digitalocean-size 2gb \ + $1 +} + +####################################### +# Executes a command on the specified machine +# Arguments: +# $1 The machine on which to run the command +# $2..$n The command to execute on that machine +####################################### +machine_do() { + docker-machine ssh $@ +} + +main() { + + if [ -z "$DO_ACCESS_TOKEN" ]; then + echo "Please export a DigitalOcean Access token: https://cloud.digitalocean.com/settings/api/tokens/new" + echo "export DO_ACCESS_TOKEN=" + exit 1 + fi + + if [ -z "$WORKERS" ]; then + echo "You haven't provided your workers by setting the \$WORKERS environment variable, using the default ones: $workers" + fi + + # Create the first and only master + echo "Creating the master" + + create_machine master1 + + master_ip=$(docker-machine ip master1) + + # Initialize the swarm mode on it + echo "Initializing the swarm mode" + machine_do master1 docker swarm init --advertise-addr $master_ip + + # Obtain the token to allow workers to join + worker_tkn=$(machine_do master1 docker swarm join-token -q worker) + echo "Worker token: ${worker_tkn}" + + # Create and join the workers + for worker in $workers; do + echo "Creating worker ${worker}" + create_machine $worker + machine_do $worker docker swarm join --token $worker_tkn $master_ip:2377 + done +} + +main $@ +``` + +赋予它可执行权限: + +``` +chmod +x create-cluster.sh +``` + +### 创建集群 + +As the name suggests, we’ll use the script to create the cluster. By default, the script will create a cluster with a single master and two workers. If you want to configure the number of workers, you can do that by setting the WORKERS environment variable. +如文件名所示,我们可以用它来创建集群。默认情况下这个脚本会创建一个 master 和两个 worker,如果你想修改 worker 个数,可以设置环境变量 WORKERS。 + +现在就来创建集群吧。 + +``` +./create-cluster.sh +``` + +你可以出去喝杯咖啡,因为这需要花点时间。 + +最后集群部署好了。 + +-------------------------------------------------------------------------------- + +via: https://blog.codeship.com/monitoring-docker-containers-with-elasticsearch-and-cadvisor/ + +作者:[Lorenzo Fontana][a] +译者:[bazz2](https://github.com/bazz2) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://blog.codeship.com/author/lorenzofontana/ + + + + + + + +[1]: https://github.com/elastic/elasticsearch +[2]: https://github.com/elastic/kibana +[3]: https://github.com/google/cadvisor +[4]: https://github.com/elastic/beats +[5]: https://twitter.com/share?text=%22How+do+you+keep+track+of+all+that%27s+happening+in+a+Swarm+Mode+cluster%3F+Not+easily.%22+via+%40fntlnz&url=https://blog.codeship.com/monitoring-docker-containers-with-elasticsearch-and-cadvisor/ +[6]: https://www.elastic.co/guide/en/elasticsearch/guide/2.x/deploy.html +[7]: https://docs.docker.com/machine/install-machine/ +[8]: https://cloud.digitalocean.com/settings/api/tokens/new From 238e35ffd64a31d3b897baf4c34177918d32770f Mon Sep 17 00:00:00 2001 From: bazz2 Date: Fri, 30 Sep 2016 14:51:48 +0800 Subject: [PATCH 002/316] [bazz2] finished Monitoring Docker Containers with Elasticsearch and cAdvisor --- ...nitoring Docker Containers with Elasticsearch and cAdvisor.md | 1 - 1 file changed, 1 deletion(-) diff --git a/translated/tech/20160913 Monitoring Docker Containers with Elasticsearch and cAdvisor.md b/translated/tech/20160913 Monitoring Docker Containers with Elasticsearch and cAdvisor.md index 08c8410764..b5dcade1cf 100644 --- a/translated/tech/20160913 Monitoring Docker Containers with Elasticsearch and cAdvisor.md +++ b/translated/tech/20160913 Monitoring Docker Containers with Elasticsearch and cAdvisor.md @@ -166,7 +166,6 @@ chmod +x create-cluster.sh ### 创建集群 -As the name suggests, we’ll use the script to create the cluster. By default, the script will create a cluster with a single master and two workers. If you want to configure the number of workers, you can do that by setting the WORKERS environment variable. 如文件名所示,我们可以用它来创建集群。默认情况下这个脚本会创建一个 master 和两个 worker,如果你想修改 worker 个数,可以设置环境变量 WORKERS。 现在就来创建集群吧。 From 611563c4db39f8c5cd771f2ff89b41c221630c72 Mon Sep 17 00:00:00 2001 From: Bestony Date: Mon, 3 Oct 2016 15:43:13 +0800 Subject: [PATCH 003/316] =?UTF-8?q?=E7=BF=BB=E8=AF=91=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...s a Slick Desktop REST Client for Linux.md | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/sources/tech/20160915 Insomnia 3.0 Is a Slick Desktop REST Client for Linux.md b/sources/tech/20160915 Insomnia 3.0 Is a Slick Desktop REST Client for Linux.md index 5460c57e8d..2a08edfaa4 100644 --- a/sources/tech/20160915 Insomnia 3.0 Is a Slick Desktop REST Client for Linux.md +++ b/sources/tech/20160915 Insomnia 3.0 Is a Slick Desktop REST Client for Linux.md @@ -1,45 +1,43 @@ -translating by Bestony - -Insomnia 3.0 Is a Slick Desktop REST Client for Linux +一个漂亮的 Linux 桌面 REST 客户端: Insomnia 3.0 ===== ![](http://www.omgubuntu.co.uk/wp-content/uploads/2016/09/insomnia-app-screenshot.png) -Looking for a free REST client for the Linux desktop? Don’t lose sleep: get [Insomnia][1]. +正在为Linux桌面端找一个免费的 REST 客户端? 别睡不着觉了!试试 [Insomnia][1]. -The app is cross-platform and works on Linux, macOS and Windows. Its developer, Gregory Schier, told us that he created the app “to help developers communicate with [REST APIs][2].” +这个应用是跨平台的,可以工作在Linux、macOS、Windows。开发者 Gregory Schier 告诉我们他创造这个应用是为了“帮助开发者处理和[REST APIs][2]的通信” -He also told that Insomnia already has around 10,000 active users — 9% of which are on Linux. +他还说,Insomnia 已经有大约10000 个活跃用户,9% 使用着 Linux. -“So far, the feedback from Linux users has been very positive because similar applications (not nice ones anyway) aren’t usually available for Linux.” +“目前来说,Linux用户的反馈是非常积极的,因为类似的应用(反正不怎么样)通常不支持Linux。” -Insomnia aims to ‘speed up your API testing workflow’, by letting you organise, run and debug HTTP requests through a cleanly designed interface. +Insomnia 的目标是“加速你的API测试工作流”,通过一个简洁的接口让你组织、运行、调试 HTTP 请求。 -The app also includes advanced features like cookie management, global environments, SSL validation, and code snippet generation. +这款应用还包含一些其他的高级功能比如Cookie管理、全局环境、SSL验证和代码段生成。 -As I am not a developer I can’t evaluate this app first-hand, nor tell you why it rocks or highlight any major feature deficiencies. +由于我不是一个开发者,没有办法第一时间的评价这款应用,也没办法告诉你的他的特性或任何比较突出的大的不足之处。 -But I thought I’d bring the app to your attention and let you decide for yourself. If you’ve been hunting for a slickly designed GUI alternative to command-line tools like HTTPie, it might be well worth giving it a whirl. +但是,我将这款应用告诉你,让你自己决定它,如果你正在寻找一个有着流程的用户界面的替代命令行工具,比如HTTPie,它可能是值得一试的。 -### Download Insomnia 3.0 for Linux +### 下载 Linux 版 Insomnia 3.0 -Insomnia 3.0 (not to be confused with Insomnia v2.0 which is only available on Chrome) is available to download for Windows, macOS and Linux. +Insomnia 3.0 现在可以用在Windows、macOS、Linux 上(不要和只能在Chrome上使用的Insomnia v2.0 混淆)。 -[Download Insomnia 3.0][4] +[下载 Insomnia 3.0][4] -An installer is available for Ubuntu 14.04 LTS and up, as is a cross-distro AppImage: +对于 Ubuntu 14.04 LTS 或更高版本,有一个安装包,是一个跨发行版的安装包: -[Download Insomnia 3.0 (.AppImage)][5] +[下载 Insomnia 3.0 (.AppImage)][5] -If you want to keep pace with development of the app you can follow [Insomnia on Twitter][6]. +如果你想跟进这个应用的步伐,你可以在 [Twitter][6] 上关注他 -------------------------------------------------------------------------------- via: http://www.omgubuntu.co.uk/2016/09/insomnia-3-is-free-rest-client-for-linux?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+d0od+%28OMG%21+Ubuntu%21%29 作者:[JOEY-ELIJAH SNEDDON ][a] -译者:[译者ID](https://github.com/译者ID) +译者:[Bestony](https://github.com/Bestony) 校对:[校对者ID](https://github.com/校对者ID) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From 10937bf961733d6cd57a4bad1e072280f373bbb6 Mon Sep 17 00:00:00 2001 From: Bestony Date: Mon, 3 Oct 2016 15:43:47 +0800 Subject: [PATCH 004/316] =?UTF-8?q?=E7=A7=BB=E5=8A=A8=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...60915 Insomnia 3.0 Is a Slick Desktop REST Client for Linux.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {sources => translated}/tech/20160915 Insomnia 3.0 Is a Slick Desktop REST Client for Linux.md (100%) diff --git a/sources/tech/20160915 Insomnia 3.0 Is a Slick Desktop REST Client for Linux.md b/translated/tech/20160915 Insomnia 3.0 Is a Slick Desktop REST Client for Linux.md similarity index 100% rename from sources/tech/20160915 Insomnia 3.0 Is a Slick Desktop REST Client for Linux.md rename to translated/tech/20160915 Insomnia 3.0 Is a Slick Desktop REST Client for Linux.md From 3db1b8c3083688e475a5672695cd5eb46e5160f5 Mon Sep 17 00:00:00 2001 From: Lv Feng Date: Mon, 3 Oct 2016 22:06:51 +0800 Subject: [PATCH 005/316] =?UTF-8?q?=E7=BF=BB=E8=AF=91=E7=94=B3=E9=A2=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ebpack with the Amazon Cognito Identity SDK for JavaScript.md | 1 + 1 file changed, 1 insertion(+) diff --git a/sources/tech/20160908 Using webpack with the Amazon Cognito Identity SDK for JavaScript.md b/sources/tech/20160908 Using webpack with the Amazon Cognito Identity SDK for JavaScript.md index 62b30cb95d..1bd05eca6f 100644 --- a/sources/tech/20160908 Using webpack with the Amazon Cognito Identity SDK for JavaScript.md +++ b/sources/tech/20160908 Using webpack with the Amazon Cognito Identity SDK for JavaScript.md @@ -1,3 +1,4 @@ +ucasFL 翻译中 Using webpack with the Amazon Cognito Identity SDK for JavaScript ===== From db7d9f50c71aa31abe75ec39fc6f02eec5499d65 Mon Sep 17 00:00:00 2001 From: wxy Date: Mon, 3 Oct 2016 23:01:48 +0800 Subject: [PATCH 006/316] PUB:20160915 Insomnia 3.0 Is a Slick Desktop REST Client for Linux @bestony --- ...s a Slick Desktop REST Client for Linux.md | 50 ++++++++++++++++++ ...s a Slick Desktop REST Client for Linux.md | 51 ------------------- 2 files changed, 50 insertions(+), 51 deletions(-) create mode 100644 published/20160915 Insomnia 3.0 Is a Slick Desktop REST Client for Linux.md delete mode 100644 translated/tech/20160915 Insomnia 3.0 Is a Slick Desktop REST Client for Linux.md diff --git a/published/20160915 Insomnia 3.0 Is a Slick Desktop REST Client for Linux.md b/published/20160915 Insomnia 3.0 Is a Slick Desktop REST Client for Linux.md new file mode 100644 index 0000000000..74aa925fa6 --- /dev/null +++ b/published/20160915 Insomnia 3.0 Is a Slick Desktop REST Client for Linux.md @@ -0,0 +1,50 @@ +一个漂亮的 Linux 桌面 REST 客户端:Insomnia 3.0 +===== + +![](http://www.omgubuntu.co.uk/wp-content/uploads/2016/09/insomnia-app-screenshot.png) + +正在为 Linux 桌面端找一个免费的 REST 客户端? 别睡不着觉了!试试 [Insomnia][1]。 + +这个应用是跨平台的,可以工作在 Linux、macOS、Windows。开发者 Gregory Schier 告诉我们他创造这个应用是为了“帮助开发者处理和 [REST API][2] 的通信” + +他还说,Insomnia 已经有大约10000 个活跃用户,9% 使用着 Linux. + +“目前来说,Linux用户的反馈是非常积极的,因为类似的应用(反正不怎么样)通常不支持 Linux。” + +Insomnia 的目标是“加速你的 API 测试工作流”,通过一个简洁的接口让你组织、运行、调试 HTTP 请求。 + +这款应用还包含一些其他的高级功能比如 Cookie 管理、全局环境、SSL 验证和代码段生成。 + +由于我不是一个开发者,没有办法第一时间的评价这款应用,也没办法告诉你的它的特性或指出任何比较重大的不足之处。 + +但是,我将这款应用告诉你,让你自己决定它,如果你正在寻找一个有着顺滑的用户界面的替代命令行工具,比如HTTPie,它可能是值得一试的。 + +### 下载 Linux 版 Insomnia 3.0 + +Insomnia 3.0 现在可以用在 Windows、macOS、Linux 上(不要和只能在 Chrome 上使用的 Insomnia v2.0 混淆)。 + +- [下载 Insomnia 3.0][4] + +对于 Ubuntu 14.04 LTS 或更高版本,有一个安装包,它是一个跨发行版的安装包: + +- [下载 Insomnia 3.0 (.AppImage)][5] + +如果你想跟进这个应用的步伐,你可以在 [Twitter][6] 上关注它。 + +-------------------------------------------------------------------------------- + +via: http://www.omgubuntu.co.uk/2016/09/insomnia-3-is-free-rest-client-for-linux + +作者:[JOEY-ELIJAH SNEDDON][a] +译者:[Bestony](https://github.com/Bestony) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://plus.google.com/117485690627814051450/?rel=author +[1]: http://insomnia.rest/ +[2]: https://en.wikipedia.org/wiki/Representational_state_transfer +[3]: https://github.com/jkbrzt/httpie +[4]: https://insomnia.rest/download/ +[5]: https://builds.insomnia.rest/downloads/linux/latest +[6]: https://twitter.com/GetInsomnia diff --git a/translated/tech/20160915 Insomnia 3.0 Is a Slick Desktop REST Client for Linux.md b/translated/tech/20160915 Insomnia 3.0 Is a Slick Desktop REST Client for Linux.md deleted file mode 100644 index 2a08edfaa4..0000000000 --- a/translated/tech/20160915 Insomnia 3.0 Is a Slick Desktop REST Client for Linux.md +++ /dev/null @@ -1,51 +0,0 @@ -一个漂亮的 Linux 桌面 REST 客户端: Insomnia 3.0 -===== - -![](http://www.omgubuntu.co.uk/wp-content/uploads/2016/09/insomnia-app-screenshot.png) - -正在为Linux桌面端找一个免费的 REST 客户端? 别睡不着觉了!试试 [Insomnia][1]. - -这个应用是跨平台的,可以工作在Linux、macOS、Windows。开发者 Gregory Schier 告诉我们他创造这个应用是为了“帮助开发者处理和[REST APIs][2]的通信” - -他还说,Insomnia 已经有大约10000 个活跃用户,9% 使用着 Linux. - -“目前来说,Linux用户的反馈是非常积极的,因为类似的应用(反正不怎么样)通常不支持Linux。” - -Insomnia 的目标是“加速你的API测试工作流”,通过一个简洁的接口让你组织、运行、调试 HTTP 请求。 - -这款应用还包含一些其他的高级功能比如Cookie管理、全局环境、SSL验证和代码段生成。 - -由于我不是一个开发者,没有办法第一时间的评价这款应用,也没办法告诉你的他的特性或任何比较突出的大的不足之处。 - -但是,我将这款应用告诉你,让你自己决定它,如果你正在寻找一个有着流程的用户界面的替代命令行工具,比如HTTPie,它可能是值得一试的。 - -### 下载 Linux 版 Insomnia 3.0 - -Insomnia 3.0 现在可以用在Windows、macOS、Linux 上(不要和只能在Chrome上使用的Insomnia v2.0 混淆)。 - -[下载 Insomnia 3.0][4] - -对于 Ubuntu 14.04 LTS 或更高版本,有一个安装包,是一个跨发行版的安装包: - -[下载 Insomnia 3.0 (.AppImage)][5] - - -如果你想跟进这个应用的步伐,你可以在 [Twitter][6] 上关注他 - --------------------------------------------------------------------------------- - -via: http://www.omgubuntu.co.uk/2016/09/insomnia-3-is-free-rest-client-for-linux?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+d0od+%28OMG%21+Ubuntu%21%29 - -作者:[JOEY-ELIJAH SNEDDON ][a] -译者:[Bestony](https://github.com/Bestony) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]: https://plus.google.com/117485690627814051450/?rel=author -[1]: http://insomnia.rest/ -[2]: https://en.wikipedia.org/wiki/Representational_state_transfer -[3]: https://github.com/jkbrzt/httpie -[4]: https://insomnia.rest/download/ -[5]: https://builds.insomnia.rest/downloads/linux/latest -[6]: https://twitter.com/GetInsomnia From e3f33e88e5f4be25a0684fcdff7152ac19922a38 Mon Sep 17 00:00:00 2001 From: wxy Date: Tue, 4 Oct 2016 08:04:01 +0800 Subject: [PATCH 007/316] PUB:20160604 How to Build Your First Slack Bot with Python @jiajia9linuxer --- ... Build Your First Slack Bot with Python.md | 317 ++++++++++++++++++ ... Build Your First Slack Bot with Python.md | 315 ----------------- 2 files changed, 317 insertions(+), 315 deletions(-) create mode 100755 published/20160604 How to Build Your First Slack Bot with Python.md delete mode 100755 translated/tech/20160604 How to Build Your First Slack Bot with Python.md diff --git a/published/20160604 How to Build Your First Slack Bot with Python.md b/published/20160604 How to Build Your First Slack Bot with Python.md new file mode 100755 index 0000000000..8ac40095ad --- /dev/null +++ b/published/20160604 How to Build Your First Slack Bot with Python.md @@ -0,0 +1,317 @@ +如何运用 Python 建立你的第一个 Slack 聊天机器人? +============ + +[聊天机器人(Bot)](https://www.fullstackpython.com/bots.html) 是一种像 [Slack](https://slack.com/) 一样的实用的互动聊天服务方式。如果你之前从来没有建立过聊天机器人,那么这篇文章提供了一个简单的入门指南,告诉你如何用 Python 结合 [Slack API](https://api.slack.com/) 建立你第一个聊天机器人。 + +我们通过搭建你的开发环境, 获得一个 Slack API 的聊天机器人令牌,并用 Pyhon 开发一个简单聊天机器人。 + +### 我们所需的工具 + +我们的聊天机器人我们将它称作为“StarterBot”,它需要 Python 和 Slack API。要运行我们的 Python 代码,我们需要: + +* [Python 2 或者 Python 3](https://www.fullstackpython.com/python-2-or-3.html) +* [pip](https://pip.pypa.io/en/stable/) 和 [virtualenv](https://virtualenv.pypa.io/en/stable/) 来处理 Python [应用程序依赖关系](https://www.fullstackpython.com/application-dependencies.html) +* 一个可以访问 API 的[免费 Slack 账号](https://slack.com/),或者你可以注册一个 [Slack Developer Hangout team](http://dev4slack.xoxco.com/)。 +* 通过 Slack 团队建立的官方 Python [Slack 客户端](https://github.com/slackhq/python-slackclient)代码库 +* [Slack API 测试令牌](https://api.slack.com/tokens) + +当你在本教程中进行构建时,[Slack API 文档](https://api.slack.com/) 是很有用的。 + +本教程中所有的代码都放在 [slack-starterbot](https://github.com/mattmakai/slack-starterbot) 公共库里,并以 MIT 许可证开源。 + +### 搭建我们的环境 + +我们现在已经知道我们的项目需要什么样的工具,因此让我们来搭建我们所的开发环境吧。首先到终端上(或者 Windows 上的命令提示符)并且切换到你想要存储这个项目的目录。在那个目录里,创建一个新的 virtualenv 以便和其他的 Python 项目相隔离我们的应用程序依赖关系。 + +``` +virtualenv starterbot + +``` + +激活 virtualenv: + +``` +source starterbot/bin/activate + +``` + +你的提示符现在应该看起来如截图: + +![已经激活的 starterbot 的 virtualenv的命令提示符](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/virtualenv-activate.png) + +这个官方的 slack 客户端 API 帮助库是由 Slack 建立的,它可以通过 Slack 通道发送和接收消息。通过这个 `pip` 命令安装 slackclient 库: + +``` +pip install slackclient + +``` + +当 `pip` 命令完成时,你应该看到类似这样的输出,并返回提示符。 + +![在已经激活的 virtualenv 用 pip 安装 slackclient 的输出](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/pip-install-slackclient.png) + +我们也需要为我们的 Slack 项目获得一个访问令牌,以便我们的聊天机器人可以用它来连接到 Slack API。 + +### Slack 实时消息传递(RTM)API + +Slack 允许程序通过一个 [Web API](https://www.fullstackpython.com/application-programming-interfaces.html) 来访问他们的消息传递通道。去这个 [Slack Web API 页面](https://api.slack.com/) 注册建立你自己的 Slack 项目。你也可以登录一个你拥有管理权限的已有账号。 + +![使用 Web API页面的右上角登录按钮](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/sign-in-slack.png) + +登录后你会到达 [聊天机器人用户页面](https://api.slack.com/bot-users)。 + +![定制聊天机器人用户页面](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/custom-bot-users.png) + +给你的聊天机器人起名为“starterbot”然后点击 “Add bot integration” 按钮。 + +![添加一个bot integration 并起名为“starterbot”](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/starterbot.jpg) + +这个页面将重新加载,你将看到一个新生成的访问令牌。你还可以将标志改成你自己设计的。例如我给的这个“Full Stack Python”标志。 + +![为你的新 Slack 聊天机器人复制和粘贴访问令牌](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/slack-token.png) + +在页面底部点击“Save Integration”按钮。你的聊天机器人现在已经准备好连接 Slack API。 + +Python 开发人员的一个常见的做法是以环境变量输出秘密令牌。输出的 Slack 令牌名字为`SLACK_BOT_TOKEN`: + +``` +export SLACK_BOT_TOKEN='你的 slack 令牌粘帖在这里' + +``` + +好了,我们现在得到了将这个 Slack API 用作聊天机器人的授权。 + +我们建立聊天机器人还需要更多信息:我们的聊天机器人的 ID。接下来我们将会写一个简短的脚本,从 Slack API 获得该 ID。 + +### 获得我们聊天机器人的 ID + +这是最后写一些 Python 代码的时候了! 我们编写一个简短的 Python 脚本获得 StarterBot 的 ID 来热身一下。这个 ID 基于 Slack 项目而不同。 + +我们需要该 ID,当解析从 Slack RTM 上发给 StarterBot 的消息时,它用于对我们的应用验明正身。我们的脚本也会测试我们 `SLACK_BOT_TOKEN` 环境变量是否设置正确。 + +建立一个命名为 print_bot_id.py 的新文件,并且填入下面的代码: + +``` +import os +from slackclient import SlackClient + + +BOT_NAME = 'starterbot' + +slack_client = SlackClient(os.environ.get('SLACK_BOT_TOKEN')) + + +if __name__ == "__main__": + api_call = slack_client.api_call("users.list") + if api_call.get('ok'): + # retrieve all users so we can find our bot + users = api_call.get('members') + for user in users: + if 'name' in user and user.get('name') == BOT_NAME: + print("Bot ID for '" + user['name'] + "' is " + user.get('id')) + else: + print("could not find bot user with the name " + BOT_NAME) + +``` + +我们的代码导入 SlackClient,并用我们设置的环境变量 `SLACK_BOT_TOKEN` 实例化它。 当该脚本通过 python 命令执行时,我们通过会访问 Slack API 列出所有的 Slack 用户并且获得匹配一个名字为“satrterbot”的 ID。 + +这个获得聊天机器人的 ID 的脚本我们仅需要运行一次。 + +``` +python print_bot_id.py + +``` + +当它运行为我们提供了聊天机器人的 ID 时,脚本会打印出简单的一行输出。 + +![在你的 Slack 项目中用 Python 脚本打印 Slack 聊天机器人的 ID](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/printed-bot-id.png) + +复制这个脚本打印出的唯一 ID。并将该 ID 作为一个环境变量 `BOT_ID` 输出。 + +``` +(starterbot)$ export BOT_ID='bot id returned by script' + +``` + +这个脚本仅仅需要运行一次来获得聊天机器人的 ID。 我们现在可以在我们的运行 StarterBot 的 Python应用程序中使用这个 ID 。 + +### 编码我们的 StarterBot + +现在我们拥有了写我们的 StarterBot 代码所需的一切。 创建一个新文件命名为 starterbot.py ,它包括以下代码。 + +``` +import os +import time +from slackclient import SlackClient + +``` + +对 `os` 和 `SlackClient` 的导入我们看起来很熟悉,因为我们已经在 theprint_bot_id.py 中用过它们了。 + +通过我们导入的依赖包,我们可以使用它们获得环境变量值,并实例化 Slack 客户端。 + +``` +# starterbot 的 ID 作为一个环境变量 +BOT_ID = os.environ.get("BOT_ID") + +# 常量 +AT_BOT = "<@" + BOT_ID + ">:" +EXAMPLE_COMMAND = "do" + +# 实例化 Slack 和 Twilio 客户端 +slack_client = SlackClient(os.environ.get('SLACK_BOT_TOKEN')) + +``` + +该代码通过我们以输出的环境变量 `SLACK_BOT_TOKEN 实例化 `SlackClient` 客户端。 + +``` +if __name__ == "__main__": + READ_WEBSOCKET_DELAY = 1 # 1 从 firehose 读取延迟 1 秒 + if slack_client.rtm_connect(): + print("StarterBot connected and running!") + while True: + command, channel = parse_slack_output(slack_client.rtm_read()) + if command and channel: + handle_command(command, channel) + time.sleep(READ_WEBSOCKET_DELAY) + else: + print("Connection failed. Invalid Slack token or bot ID?") + +``` + +Slack 客户端会连接到 Slack RTM API WebSocket,然后当解析来自 firehose 的消息时会不断循环。如果有任何发给 StarterBot 的消息,那么一个被称作 `handle_command` 的函数会决定做什么。 + +接下来添加两个函数来解析 Slack 的输出并处理命令。 + +``` +def handle_command(command, channel): + """ + Receives commands directed at the bot and determines if they + are valid commands. If so, then acts on the commands. If not, + returns back what it needs for clarification. + """ + response = "Not sure what you mean. Use the *" + EXAMPLE_COMMAND + \ + "* command with numbers, delimited by spaces." + if command.startswith(EXAMPLE_COMMAND): + response = "Sure...write some more code then I can do that!" + slack_client.api_call("chat.postMessage", channel=channel, + text=response, as_user=True) + +def parse_slack_output(slack_rtm_output): + """ + The Slack Real Time Messaging API is an events firehose. + this parsing function returns None unless a message is + directed at the Bot, based on its ID. + """ + output_list = slack_rtm_output + if output_list and len(output_list) > 0: + for output in output_list: + if output and 'text' in output and AT_BOT in output['text']: + # 返回 @ 之后的文本,删除空格 + return output['text'].split(AT_BOT)[1].strip().lower(), \ + output['channel'] + return None, None + +``` + +`parse_slack_output` 函数从 Slack 接受信息,并且如果它们是发给我们的 StarterBot 时会作出判断。消息以一个给我们的聊天机器人 ID 的直接命令开始,然后交由我们的代码处理。目前只是通过 Slack 管道发布一个消息回去告诉用户去多写一些 Python 代码! + +这是整个程序组合在一起的样子 (你也可以 [在 GitHub 中查看该文件](https://github.com/mattmakai/slack-starterbot/blob/master/starterbot.py)): + +``` +import os +import time +from slackclient import SlackClient + +# starterbot 的 ID 作为一个环境变量 +BOT_ID = os.environ.get("BOT_ID") + +# 常量 +AT_BOT = "<@" + BOT_ID + ">:" +EXAMPLE_COMMAND = "do" + +# 实例化 Slack 和 Twilio 客户端 +slack_client = SlackClient(os.environ.get('SLACK_BOT_TOKEN')) + +def handle_command(command, channel): + """ + Receives commands directed at the bot and determines if they + are valid commands. If so, then acts on the commands. If not, + returns back what it needs for clarification. + """ + response = "Not sure what you mean. Use the *" + EXAMPLE_COMMAND + \ + "* command with numbers, delimited by spaces." + if command.startswith(EXAMPLE_COMMAND): + response = "Sure...write some more code then I can do that!" + slack_client.api_call("chat.postMessage", channel=channel, + text=response, as_user=True) + +def parse_slack_output(slack_rtm_output): + """ + The Slack Real Time Messaging API is an events firehose. + this parsing function returns None unless a message is + directed at the Bot, based on its ID. + """ + output_list = slack_rtm_output + if output_list and len(output_list) > 0: + for output in output_list: + if output and 'text' in output and AT_BOT in output['text']: + # 返回 @ 之后的文本,删除空格 + return output['text'].split(AT_BOT)[1].strip().lower(), \ + output['channel'] + return None, None + +if __name__ == "__main__": + READ_WEBSOCKET_DELAY = 1 # 1 second delay between reading from firehose + if slack_client.rtm_connect(): + print("StarterBot connected and running!") + while True: + command, channel = parse_slack_output(slack_client.rtm_read()) + if command and channel: + handle_command(command, channel) + time.sleep(READ_WEBSOCKET_DELAY) + else: + print("Connection failed. Invalid Slack token or bot ID?") + +``` + +现在我们的代码已经有了,我们可以通过 `python starterbot.py` 来运行我们 StarterBot 的代码了。 + +![当 StarterBot 开始运行而且连接到 API 的输出通道](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/starterbot-running.png) + +在 Slack 中创建新通道,并且把 StarterBot 邀请进来,或者把 StarterBot 邀请进一个已经存在的通道中。 + +![在 Slack 界面创建一个新通道并且邀请 StarterBot](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/create-channel.png) + +现在在你的通道中给 StarterBot 发命令。 + +![在你的 Slack 通道里给你的 StarterBot 发命令](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/working-starterbot.png) + +如果你从聊天机器人得到的响应中遇见问题,你可能需要做一个修改。正如上面所写的这个教程,其中一行 `AT_BOT = "<@" + BOT_ID + ">:"`,在“@starter”(你给你自己的聊天机器人起的名字)后需要一个冒号。从`AT_BOT` 字符串后面移除`:`。Slack 似乎需要在 `@` 一个人名后加一个冒号,但这好像是有些不协调的。 + +### 结束 + +好吧,你现在已经获得一个简易的聊天机器人,你可以在代码中很多地方加入你想要创建的任何特性。 + +我们能够使用 Slack RTM API 和 Python 完成很多功能。看看通过这些文章你还可以学习到什么: + +* 附加一个持久的[关系数据库](https://www.fullstackpython.com/databases.html) 或者 [NoSQL 后端](https://www.fullstackpython.com/no-sql-datastore.html) 比如 [PostgreSQL](https://www.fullstackpython.com/postgresql.html)、[MySQL](https://www.fullstackpython.com/mysql.html) 或者 [SQLite](https://www.fullstackpython.com/sqlite.html) ,来保存和检索用户数据 +* 添加另外一个与聊天机器人互动的通道,比如 [短信](https://www.twilio.com/blog/2016/05/build-sms-slack-bot-python.html) 或者[电话呼叫](https://www.twilio.com/blog/2016/05/add-phone-calling-slack-python.html) +* [集成其它的 web API](https://www.fullstackpython.com/api-integration.html),比如 [GitHub](https://developer.github.com/v3/)、[Twilio](https://www.twilio.com/docs) 或者 [api.ai](https://docs.api.ai/) + +有问题? 通过 Twitter 联系我 [@fullstackpython](https://twitter.com/fullstackpython) 或 [@mattmakai](https://twitter.com/mattmakai)。 我在 GitHub 上的用户名是 [mattmakai](https://github.com/mattmakai)。 + +这篇文章感兴趣? Fork 这个 [GitHub 上的页面](https://github.com/mattmakai/fullstackpython.com/blob/gh-pages/source/content/posts/160604-build-first-slack-bot-python.markdown)吧。 + +-------------------------------------------------------------------------------- +via: https://www.fullstackpython.com/blog/build-first-slack-bot-python.html + +作者:[Matt Makai][a] +译者:[jiajia9llinuxer](https://github.com/jiajia9linuxer) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出aa + +[a]: https://www.fullstackpython.com/about-author.html diff --git a/translated/tech/20160604 How to Build Your First Slack Bot with Python.md b/translated/tech/20160604 How to Build Your First Slack Bot with Python.md deleted file mode 100755 index 7f0c1f6a77..0000000000 --- a/translated/tech/20160604 How to Build Your First Slack Bot with Python.md +++ /dev/null @@ -1,315 +0,0 @@ -# 如何运用Python建立你的第一个Slack Bot? - -[Bots](https://www.fullstackpython.com/bots.html) 是一种像 [Slack](https://slack.com/) 一样实用的互动聊天服务方式. 如果你之前从来没有建立过bot, 这篇文章提供了一个简单的用Python建立你第一个bot的关于 [Slack API](https://api.slack.com/) 集合的入门教程. - -我们通过设置你的开发环境, 获得一个Slack API bot标记和我们用Pyhon编码的简单bot. - -### 我们所需的工具 - -我们的bot, 我们将它称作为 "StarterBot", 它需要 Python 和 the Slack API. 然后运行我们需要的Python代码: - -* [Python 2 或者 Python 3](https://www.fullstackpython.com/python-2-or-3.html) -* [pip](https://pip.pypa.io/en/stable/) 和 [virtualenv](https://virtualenv.pypa.io/en/stable/) 处理 Python [应用程序依赖关系](https://www.fullstackpython.com/application-dependencies.html) -* 一个你可以拥有API访问和注册Slack Developer Hangout team](http://dev4slack.xoxco.com/)的[免费Slack账号](https://slack.com/) -* 通过Slack团队建立的官方Python [Slack客户端](https://github.com/slackhq/python-slackclient)代码库 -* [Slack API 测试标志](https://api.slack.com/tokens) - -这也是一个方便你建立本教程的有用[Slack API 文档](https://api.slack.com/) - -对于本教程,所有的代码都是在[slack-starterbot](https://github.com/mattmakai/slack-starterbot)公共库里通过MIT许可证的可获得的开放源码. - -### 搭建我们的环境 - -我们现在已经知道我们的项目需要什么样的工具,因此我们要获得我们所建立的开发环境。首先到终端上(或者用Windows上的命令提示符)并且改变你想要存储这个项目的目录。在那个目录里,创建一个新的virtualenv以便从其他的Python项目来隔离我们的应用程序依赖关系。 - -``` -virtualenv starterbot - -``` - -Activate the virtualenv 激活virtualenv: - -``` -source starterbot/bin/activate - -``` - -你的提示现在应该看起来像在一个这样的截图里。 - -![Command prompt with starterbot's virtualenv activated 已经激活的starterbot's virtualenv的命令提示:](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/virtualenv-activate.png) - - -这个官方的slackclient API帮助库是通过Slack可以发送和接收消息的Slack通道所建立的。安装slackclient库是通过这个pip命令: - -``` -pip install slackclient - -``` - -当pip命令完成时,你应该看到这样的输出和你将返回的提示. - -![Output from using the pip install slackclient command with a virtualenv activated 在已经激活的virtualenv输出用pip安装slackclient的命令.](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/pip-install-slackclient.png) - -我们也需要从Slack项目获得一个访问提示,因此我们的bot可以用它来连接这个Slack API. - -### Slack实时消息传递(RTM)API - -Slack同意程序通过一个 [网络应用程序API](https://www.fullstackpython.com/application-programming-interfaces.html)访问他们的消息传递通道. 去这个[Slack网络应用程序API页面](https://api.slack.com/) 并且注册建立你自己的Slack项目.你也可以通过一个你拥有管理权限的有效账号登陆. - -![Use the sign in button on the top right corner of the Slack API page 在网络应用程序API页面的右上角使用登陆按钮.](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/sign-in-slack.png) - -然后你可以到[Bot用户页面](https://api.slack.com/bot-users)登陆. - -![Custom bot users webpage 定制bot用户网页.](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/custom-bot-users.png) - -给你的bot起名为 "starterbot" 然后点击 “Add bot integration” 按钮. - -![Add a bot integration named starterbot 添加一个bot integration并起名为“starterbot”.](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/starterbot.jpg) - -这个页面将重新加载,你将看到一个新生成的访问令牌。你还可以将标志改成自定义设计。例如我给的这个“Full Stack Python”标志. - -![Copy and paste the access token for your new Slack bot为你的新Slack bot复制和粘贴访问提示.](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/slack-token.png) - -在页面底部点击 "Save Integration"按钮. 你的 bot 现在已经准备好连接Slack's API. - -Python开发人员的一个常见的做法是输出秘密令牌提示作为环境变量。输出的Slack令牌名字为“SLACK_BOT_TOKEN”.: - -``` -export SLACK_BOT_TOKEN='your slack token pasted here' - -``` - -好了,我们现在将被作为bot授权使用这个Slack API . - -这个是一个更多的我们需要建立我们的bot的信息: 我们的bot的ID. 接下来我们将会写一个简短的脚本来从这个Slack API获得ID. - -### 获得我们Bot的ID - -这是最后一次写的一些Python代码! 我们将会在编译一个简短的Python脚本来获得StarterBot的ID时获得热身. 这个ID基于Slack项目而改变. - -我们需要ID,因为当消息被解析为从Slcak RTM在StarterBot上指导的,他会允许我们的应用程序作出终止.我们的脚本也会测试我们SLACK_BOT_TOKEN环境变量是否设置正确. - -建立一个新文件并命名为print_bot_id.py 并且填写下面的代码. - -``` -import os调用外部程序 -from slackclient import SlackClient从slackclient调用SlackClient - -BOT_NAME = 'starterbot' - -slack_client = SlackClient(os.environ.get('SLACK_BOT_TOKEN')) - -if __name__ == "__main__": - api_call = slack_client.api_call("users.list") - if api_call.get('ok'): - # retrieve all users so we can find our bot检索所有的用户以便我们可以找到我们的bot - users = api_call.get('members') - for user in users: - if 'name' in user and user.get('name') == BOT_NAME: - print("Bot ID for '" + user['name'] + "' is " + user.get('id')) - else: - print("could not find bot user with the name " + BOT_NAME) - -``` - -当我们设置为一个环境变量时,我们的代码调用于SlackClient并且为我们的SLACK_BOT_TOKEN而将它实例化. 当脚本通过pyhon命令执行时,我们通过会访问Slack API列出所有的Slack用户并且获得匹配一个名字为"satrterbot"的ID. - -我们仅仅需要运行一次脚本来获得我们bot的ID. - -``` -python print_bot_id.py - -``` - -当它运行为我们提供我们bot的ID时,脚本会打印出简单的一行输出. - -![在你的Slack项目中用Python脚本打印Slack bot的ID.](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/printed-bot-id.png) - -复制脚本打印出的唯一ID.并将ID作为一个环境变量命名为BOT_ID输出. - -``` -(starterbot)$ export BOT_ID='bot id returned by script' - -``` - -这个脚本仅仅需要运行一次来获得bot的ID. 我们现在可以使用这个ID在我们的Python应用程序中来运行StarterBot. - -### 编码我们的StarterBot - -我们通过我们拥有的一切来写我们需要书写的StarterBot代码. 创建一个新文件命名为starterbot.py ,它包括以下代码. - -``` -import os -import time -from slackclient import SlackClient - -``` - -操作系统和SlackClient调用将会看起来很熟悉,因为我们会使用它们在theprint_bot_id.py中. - -在我们的依赖关系调用中,我们可以使用它们获得环境变量值并且在Slack client中将它们实例化. - -``` -# starterbot's ID as an environment variable starterbot的ID作为一个环境变量 -BOT_ID = os.environ.get("BOT_ID") - -# constants 常量 -AT_BOT = "<@" + BOT_ID + ">:" -EXAMPLE_COMMAND = "do" - -# instantiate Slack & Twilio clients 实例化Slack和Twilio clients -slack_client = SlackClient(os.environ.get('SLACK_BOT_TOKEN')) - -``` - -代码在我们的SLACK_BOT_TOKEN中将SlackClient client实例化并且作为一个环境变量输出. - -``` -if __name__ == "__main__": - READ_WEBSOCKET_DELAY = 1 # 1 second delay between reading from firehose 从firehose阅读间延迟1秒 - if slack_client.rtm_connect(): - print("StarterBot connected and running!") - while True: - command, channel = parse_slack_output(slack_client.rtm_read()) - if command and channel: - handle_command(command, channel) - time.sleep(READ_WEBSOCKET_DELAY) - else: - print("Connection failed. Invalid Slack token or bot ID?") - -``` - -Slack client连接到Slack RTM API WebSocket(Slack RTM API 双向通信),然后当解析信息来自firehose时会不断循环.如果任何这些消息都指向StarterBot,那么一个被称作handle_command的函数会决定做什么. - -接下来添加两个函数来解析Slack输出和handle commands. - -``` -def handle_command(command, channel): - """ - Receives commands directed at the bot and determines if they - are valid commands. If so, then acts on the commands. If not, - returns back what it needs for clarification. - """ - response = "Not sure what you mean. Use the *" + EXAMPLE_COMMAND + \ - "* command with numbers, delimited by spaces." - if command.startswith(EXAMPLE_COMMAND): - response = "Sure...write some more code then I can do that!" - slack_client.api_call("chat.postMessage", channel=channel, - text=response, as_user=True) - -def parse_slack_output(slack_rtm_output): - """ - The Slack Real Time Messaging API is an events firehose. - this parsing function returns None unless a message is - directed at the Bot, based on its ID. - """ - output_list = slack_rtm_output - if output_list and len(output_list) > 0: - for output in output_list: - if output and 'text' in output and AT_BOT in output['text']: - # return text after the @ mention, whitespace removed 在@之后提到返回文本,空格删除 - return output['text'].split(AT_BOT)[1].strip().lower(), \ - output['channel'] - return None, None - -``` - -parse_slack_output函数从Slack接受信息并且如果他们指向我们的StarterBot时会作出判断.消息通过给我们bot的ID一个直接命令启动,然后交由我们的代码处理.-目前只是通过SLack管道发布一个消息回去告诉用户去多写一些Python代码! - -这是整个程序看上去应该如何组合在一起 (你也可以 [在GitHub中查看文件](https://github.com/mattmakai/slack-starterbot/blob/master/starterbot.py)): - -``` -import os -import time -from slackclient import SlackClient - -# 把 starterbot 的 ID作为一个环境变量 -BOT_ID = os.environ.get("BOT_ID") - -# constants 常量 -AT_BOT = "<@" + BOT_ID + ">:" -EXAMPLE_COMMAND = "do" - -# 实例化Slack和Twilio clients -slack_client = SlackClient(os.environ.get('SLACK_BOT_TOKEN')) - -def handle_command(command, channel): - """ - Receives commands directed at the bot and determines if they - are valid commands. If so, then acts on the commands. If not, - returns back what it needs for clarification. - """ - response = "Not sure what you mean. Use the *" + EXAMPLE_COMMAND + \ - "* command with numbers, delimited by spaces." - if command.startswith(EXAMPLE_COMMAND): - response = "Sure...write some more code then I can do that!" - slack_client.api_call("chat.postMessage", channel=channel, - text=response, as_user=True) - -def parse_slack_output(slack_rtm_output): - """ - The Slack Real Time Messaging API is an events firehose. - this parsing function returns None unless a message is - directed at the Bot, based on its ID. - """ - output_list = slack_rtm_output - if output_list and len(output_list) > 0: - for output in output_list: - if output and 'text' in output and AT_BOT in output['text']: - # 在@之后提到返回文本,空格删除 - return output['text'].split(AT_BOT)[1].strip().lower(), \ - output['channel'] - return None, None - -if __name__ == "__main__": - READ_WEBSOCKET_DELAY = 1 # 1 second delay between reading from firehose - if slack_client.rtm_connect(): - print("StarterBot connected and running!") - while True: - command, channel = parse_slack_output(slack_client.rtm_read()) - if command and channel: - handle_command(command, channel) - time.sleep(READ_WEBSOCKET_DELAY) - else: - print("Connection failed. Invalid Slack token or bot ID?") - -``` - -现在这是我们在这里所有的在命令行上通过python starterbot.py可以启动我们StarterBot的代码. - -![当StarterBot开始运行而且连接到API的输出通道.](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/starterbot-running.png) - -在 Slack 中创建新管道并且把 StarterBot 添加进来,或者直接把 StarterBot 添加进一个已经存在的管道。 - -![在Slack界面创建一个新通道并且请求StarterBot.](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/create-channel.png) - -现在在管道中启动 StarterBot。 - -![在你的Slack通道里给的StarterBot命令.](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/working-starterbot.png) - -当你从bot得到的响应中遇见问题时,这是你一种可能你想去做的修改.正如上面所写的这个教程,其中一行AT_BOT = "<@" + BOT_ID + ">:",在"@starter"后需要一个冒号(或者任何你自己所命名的特定bot).移除这些:从AT_BOT结束后的字符串.Slack clients似乎需要在@一个人名后加一个冒号,但这好像是有些不协调的. - -### 结束 - -好吧,你现在已经获得一个简易的你可以在代码中很多地方加入你想创建任何特性的StarterBot. - -这里有很多你可以使用的Slack RTM API 和 Python.看看通过这些文章你还可以学习到什么: - -* 附加一个持久的[relational database 关系数据库](https://www.fullstackpython.com/databases.html) 或者 [NoSQL back-end](https://www.fullstackpython.com/no-sql-datastore.html) 比如 [PostgreSQL](https://www.fullstackpython.com/postgresql.html),[MySQL](https://www.fullstackpython.com/mysql.html) 或者 [SQLite](https://www.fullstackpython.com/sqlite.html) 用来保存和检索用户数据 -* 添加另外一个与bot互动的通道 [via SMS](https://www.twilio.com/blog/2016/05/build-sms-slack-bot-python.html) 或者 [phone calls](https://www.twilio.com/blog/2016/05/add-phone-calling-slack-python.html) -* [Integrate other web APIs](https://www.fullstackpython.com/api-integration.html) 比如 [GitHub](https://developer.github.com/v3/), [Twilio](https://www.twilio.com/docs) 或者 [api.ai](https://docs.api.ai/) - -有问题? 通过Twitter联系我 [@fullstackpython](https://twitter.com/fullstackpython) or [@mattmakai](https://twitter.com/mattmakai). 这是我在GitHub上的用户名 [mattmakai](https://github.com/mattmakai). - -这篇文章还有问题? Fork [this page's source on GitHub 这是在GitHub上的页面源](https://github.com/mattmakai/fullstackpython.com/blob/gh-pages/source/content/posts/160604-build-first-slack-bot-python.markdown). - --------------------------------------------------------------------------------- -via: https://www.fullstackpython.com/blog/build-first-slack-bot-python.html - -作者: [Matt Makai][a] -译者:[jiajia9llinuxer](https://github.com/jiajia9linuxer) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出aa - -[a]: https://www.fullstackpython.com/about-author.html From baf675a5bcc85490651296c39c272ad6fb781fd8 Mon Sep 17 00:00:00 2001 From: Lv Feng Date: Tue, 4 Oct 2016 14:58:53 +0800 Subject: [PATCH 008/316] Update 20160908 Using webpack with the Amazon Cognito Identity SDK for JavaScript.md --- ...k with the Amazon Cognito Identity SDK for JavaScript.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sources/tech/20160908 Using webpack with the Amazon Cognito Identity SDK for JavaScript.md b/sources/tech/20160908 Using webpack with the Amazon Cognito Identity SDK for JavaScript.md index 1bd05eca6f..88b1a4d47f 100644 --- a/sources/tech/20160908 Using webpack with the Amazon Cognito Identity SDK for JavaScript.md +++ b/sources/tech/20160908 Using webpack with the Amazon Cognito Identity SDK for JavaScript.md @@ -1,12 +1,16 @@ -ucasFL 翻译中 Using webpack with the Amazon Cognito Identity SDK for JavaScript +把具有与亚马逊 Cognito 标志软件开发工具包(SDK)的 webpack 用于 Javascript ===== This blog post is aimed at developers of all experience levels who develop and deploy JavaScript based applications (whether server-side with Node.js or client side) that incorporate the AWS SDK, the Amazon Cognito Identity SDK for JavaScript and who also use the popular [webpack][1] module bundler. +这篇文章是针对开发和部署基于 Javascriot 应用(Node.js 服务器端或者客户端服务器端)的所有经验水平的开发者。通过本文,你将看到如何把 AWS SDK, 亚马逊标志软件开发工具包(SDK)嵌入到 Javsscript 中,以及如何使用流行的【webpack】【1】模块打包机。 In July 2016, Amazon Web Services [launched Amazon Cognito User Pools][2], a feature that makes it easy for developers to add sign-up and sign-in functionality to mobile and web applications. To help developers easily realize the power of user pools within their own applications, we also released the [Amazon Cognito Identity SDK for JavaScript][3]. +2016年7月,亚马逊网站服务【推出亚马逊 Cognito 用户库】【2】,这个新特性极大的方便了开发者在移动和 Web 应用程序上添加注册和登录功能。为了帮助开发者更容易在自己的应用程序中实现用户库权利,我们也发布了【针对 Javascript 的亚马逊 Cognito 特性 SDK】【3】。 + Amazon Cognito User Pools allows you to easily add user sign-up and sign-in to your mobile and web applications. The fully managed user pool can scale to hundreds of millions of users and you can have multiple directories per AWS account. Creating a user pool takes just a few minutes and allows you to decide exactly which attributes (including address, email, phone number as well as custom attributes) are mandatory and even optional when a new user signs up for your application or service. Your application can also specify the desired password strength, whether the use of Multi-Factor Authentication (MFA) is required, and verify new users via phone number or email address to further enhance the security of your application. +亚马逊 Cognito 用户库使得你在移动和 Web 应用程序上添加用户注册和登录功能更加容易。全托管用户库可以扩展到数以百万计的用户,你可以在一个 AWS 账户下有多重目录。创建一个用户库只需要几分钟的时间,并且你可以决定当一个新用户在你的应用程序或服务上注册时哪些属性(包括地址,邮箱,电话号码以及自定义属性)是强制的,哪些是可选择的。你的应用程序也可以指定所需的密码强度,指定用户需要进行多因素认证,通过电话号码或者邮件地址来验证新用户,从而进一步加强应用程序的安全性。 If you are new to the Amazon Cognito Identity SDK for JavaScript [this AWS blog post][4] is a great place to start. From 4160edcc38a816247f1d9d11b00c9359911944a6 Mon Sep 17 00:00:00 2001 From: Lv Feng Date: Tue, 4 Oct 2016 15:52:22 +0800 Subject: [PATCH 009/316] Update 20160908 Using webpack with the Amazon Cognito Identity SDK for JavaScript.md --- ...the Amazon Cognito Identity SDK for JavaScript.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/sources/tech/20160908 Using webpack with the Amazon Cognito Identity SDK for JavaScript.md b/sources/tech/20160908 Using webpack with the Amazon Cognito Identity SDK for JavaScript.md index 88b1a4d47f..235671098b 100644 --- a/sources/tech/20160908 Using webpack with the Amazon Cognito Identity SDK for JavaScript.md +++ b/sources/tech/20160908 Using webpack with the Amazon Cognito Identity SDK for JavaScript.md @@ -1,28 +1,34 @@ Using webpack with the Amazon Cognito Identity SDK for JavaScript -把具有与亚马逊 Cognito 标志软件开发工具包(SDK)的 webpack 用于 Javascript +把具有与亚马逊 Cognito 标志软件开发工具包(SDK)的 webpack 用于 JavaScript ===== This blog post is aimed at developers of all experience levels who develop and deploy JavaScript based applications (whether server-side with Node.js or client side) that incorporate the AWS SDK, the Amazon Cognito Identity SDK for JavaScript and who also use the popular [webpack][1] module bundler. -这篇文章是针对开发和部署基于 Javascriot 应用(Node.js 服务器端或者客户端服务器端)的所有经验水平的开发者。通过本文,你将看到如何把 AWS SDK, 亚马逊标志软件开发工具包(SDK)嵌入到 Javsscript 中,以及如何使用流行的【webpack】【1】模块打包机。 +这篇文章是针对开发和部署基于 JavaScriot 应用(Node.js 服务器端或者客户端服务器端)的所有经验水平的开发者。通过本文,你将看到如何把 AWS SDK, 亚马逊标志软件开发工具包(SDK)嵌入到 JavaScript 中,以及如何使用流行的【webpack】【1】模块打包机。 In July 2016, Amazon Web Services [launched Amazon Cognito User Pools][2], a feature that makes it easy for developers to add sign-up and sign-in functionality to mobile and web applications. To help developers easily realize the power of user pools within their own applications, we also released the [Amazon Cognito Identity SDK for JavaScript][3]. -2016年7月,亚马逊网站服务【推出亚马逊 Cognito 用户库】【2】,这个新特性极大的方便了开发者在移动和 Web 应用程序上添加注册和登录功能。为了帮助开发者更容易在自己的应用程序中实现用户库权利,我们也发布了【针对 Javascript 的亚马逊 Cognito 特性 SDK】【3】。 +2016年7月,亚马逊网站服务【推出亚马逊 Cognito 用户库】【2】,这个新特性极大的方便了开发者在移动和 Web 应用程序上添加注册和登录功能。为了帮助开发者更容易在自己的应用程序中实现用户库权利,我们也发布了【针对 JavaScript 的亚马逊 Cognito 特性 SDK】【3】。 Amazon Cognito User Pools allows you to easily add user sign-up and sign-in to your mobile and web applications. The fully managed user pool can scale to hundreds of millions of users and you can have multiple directories per AWS account. Creating a user pool takes just a few minutes and allows you to decide exactly which attributes (including address, email, phone number as well as custom attributes) are mandatory and even optional when a new user signs up for your application or service. Your application can also specify the desired password strength, whether the use of Multi-Factor Authentication (MFA) is required, and verify new users via phone number or email address to further enhance the security of your application. 亚马逊 Cognito 用户库使得你在移动和 Web 应用程序上添加用户注册和登录功能更加容易。全托管用户库可以扩展到数以百万计的用户,你可以在一个 AWS 账户下有多重目录。创建一个用户库只需要几分钟的时间,并且你可以决定当一个新用户在你的应用程序或服务上注册时哪些属性(包括地址,邮箱,电话号码以及自定义属性)是强制的,哪些是可选择的。你的应用程序也可以指定所需的密码强度,指定用户需要进行多因素认证,通过电话号码或者邮件地址来验证新用户,从而进一步加强应用程序的安全性。 If you are new to the Amazon Cognito Identity SDK for JavaScript [this AWS blog post][4] is a great place to start. +如果你是首次接触用于 JavaScript 的亚马逊 Cognito 标志 SDk,那么请先阅读【这篇 AWS 文章】【4】作为开始。 ### Why Use Asset & Module Bundling with the Amazon Cognito Identity SDK for JavaScript +### 为什么在 JavaScript 上使用具有资产模块的亚马逊 Cogtito 标志 SDK Today, modern web applications for both mobile and desktop have to provide the user with a secure, fast, responsive, and native-app-like experience. There is no doubt that modern browsers are extremely powerful and cater to a vast array of possible implementation approaches. Many of the more popular implementations rely heavily on the deployment of a JavaScript application through some form of asset packaging and/or module bundling. This allows a developer to take their JavaScript application and create one or more files that can be loaded by the client browser by using script tags. +今天,针对移动和桌面的现代 Web 应用程序都能为用户提供安全、快捷、灵敏以及类本地应用的体验。毫无疑问,现代的浏览器功能强大,能够满足大量可能的实现方法。许多流行的实现很大程度上依赖于 JavaScript 应用程序通过某种形式的资产包装和/或模块捆绑进行部署。这使得许多开发人员能够很好的维护自己的 JavaScript 应用程序,并且可以通过使用脚本标签创建一个或多个可以加载到客户端浏览器上的文件。 There are many schools of thought on how you can achieve this packaging , including task runners such as [Grunt][5] and [Gulp][6], and bundlers such as [Browserify][7]. However, there is a general consensus that asset packaging is not only about improving load times—it enables the modularization of your application while ensuring testability and robustness. +关于如何实现打包有许多学校的思想,包括任务运行者比如【Grunt】【5】和【Gulp】,还有打包机比如【Browserity】【7】.然而,一个普遍的共识是,资产打包不仅仅是关于缩短加载时间 - 它可以在确保可测试性和稳定性的前提下使你的应用程序模块化。 ### Using webpack with the Amazon Cognito Identity SDK for JavaScript +### 把具有亚麻逊 Cognito 标志 SDK 的 webpack 用于 JavaScript In the many requests we get to provide more detail on how to integrate the Amazon Cognito Identity SDK for JavaScript within a webpack environment, we’re specifically asked how to ensure that webpack correctly manages the following third-party dependencies: +有许多请求需要我们提供如何在 webpack 环境中整合用于 JavaScript 的亚马逊 Cognito 标志 SDK 的更多细节。我们特地询问了如何确保 webpack 正确管理下面三方的关系: - [JavaScript BN library for BigInteger computation][8] (jsbn) - [an extension to jsbn][9] the with the rest of the jsbn methods including most public BigInteger methods (jsbn2) From 563fedc564890fcb389aade4d0ce183ca121ad17 Mon Sep 17 00:00:00 2001 From: Lv Feng Date: Tue, 4 Oct 2016 17:26:09 +0800 Subject: [PATCH 010/316] Update 20160908 Using webpack with the Amazon Cognito Identity SDK for JavaScript.md --- ...zon Cognito Identity SDK for JavaScript.md | 42 ++++++++++++++++--- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/sources/tech/20160908 Using webpack with the Amazon Cognito Identity SDK for JavaScript.md b/sources/tech/20160908 Using webpack with the Amazon Cognito Identity SDK for JavaScript.md index 235671098b..6be4890f97 100644 --- a/sources/tech/20160908 Using webpack with the Amazon Cognito Identity SDK for JavaScript.md +++ b/sources/tech/20160908 Using webpack with the Amazon Cognito Identity SDK for JavaScript.md @@ -33,8 +33,12 @@ In the many requests we get to provide more detail on how to integrate the Amazo - [JavaScript BN library for BigInteger computation][8] (jsbn) - [an extension to jsbn][9] the with the rest of the jsbn methods including most public BigInteger methods (jsbn2) - the [Stanford JavaScript Crypto Library][10] (sjcl) +- 【用于 BigInteger 计算的 JavaScript 库】【8】(jsbn) +- 【jsbn 扩展】【9】其余的 jsbn 方法包含大多数公共 BigInteger 方法(jsbn2) +- 【标准 JavaScript Crypto 库】【10】(jscl) Throughout these examples, the following bower libraries are used by bower.json +通过这些例子,可以看到,下面这些 bower 库都被 bower.json 使用 ``` "aws-cognito-sdk": "https://raw.githubusercontent.com/aws/amazon-cognito-identity-js/master/dist/aws-cognito-sdk.js", @@ -44,6 +48,7 @@ Throughout these examples, the following bower libraries are used by bower.json ``` For all the reasons we gave earlier for the importance of asset packaging to development processes, and unless your application is extremely small, the use of an asset packaging tool such as webpack is almost always recommended. Of course, one could simply pull in all of these dependencies using tags. However, this would pollute global namespace, and not provide the most optimal resource management and loading approach. Many developers start with a standard webpack.config.js file that has a standard babel loader, as shown here. +出于我们前面给出的所有关于通过资产打包来改善进程的重要性的原因,除非你的应用程序非常小,使用像 webpack 这样的资产打包工具几乎总是必须的。当然,还有一个方法是可以通过使用标签简单的处理所有依赖关系。然而,这会污染全局命名空间,不能够提供最理想的资源管理和加载方法。许多开发者首次使用的是具有标准 babel 加载机的标准 webpack.config.js 文件,像下面展示的这样。 ``` { @@ -62,26 +67,35 @@ For all the reasons we gave earlier for the importance of asset packaging to dev ``` It’s important to remember that this configuration doesn’t take into account that some of third-party dependencies used by the Amazon Cognito Identity SDK for JavaScript currently do not use the [Universal Module Definition (UMD) pattern for JavaScript][11]. +需要重点记住的是,这个配置没有考虑一些第三方关系,这些被针对 JavaScript 的亚马逊 Cognito 标志 SDK 使用的第三方关系目前没有使用【JavaScript 通用模块定义(UMD)】【11】. The UMD pattern attempts to offer Asynchronous Module Definition (AMD) based compatibility with the most popular script loaders of the day such as [RequireJS][12] and [CommonJS][13]. +UMD 模式试图提供基于当前最流行的脚本加载器比如【RequireJS】【12】和【CommonJS】【13】兼容性的异步模块定义【AMD】. This is a pattern that webpack relies on, and so we must make some changes to how webpack loads these modules. Without these changes, you may encounter errors such as the following. +这是 webpack 所依靠的模式,为了让 webpack 能够工作我们必须做一些改变。不进行这些改变,你可能会遇到下面这些错误。 ``` amazon-cognito-identity.min.js:19 Uncaught ReferenceError: BigInteger is not defined ``` Such an error may be encountered when making a call to AWSCognito.CognitoIdentityServiceProvider.CognitoUser property authenticateUser This is an example of where we can make use of the webpack imports and exports loader capability to overcome this error. +这样一个错误可能会在调用 AWSCognito.CognitoIdentityServiceProvider.CognitoUser property authenticateUser 的时候出现。这是一个出现错误的例子,我们可以利用 webpack 的进出口加载能力来解决这个错误。 ### Using webpack Loaders +### 使用 webpack 加载器 According to the [webpack documentation][14] "loaders allow you to preprocess files as you require() or “load” them. Loaders are kind of like “tasks” are in other build tools, and provide a powerful way to handle front-end build steps. Loaders can transform files from a different language like, CoffeeScript to JavaScript, or inline images as data URLs" +根据【webpack 文件】,”加载器允许你按你的需求来预处理或“加载”文件。加载器是一种在其他搭建工具中类似 “tasks” 的工具,他可以提供一个处理前端搭建步骤的强大方法。加载器可以把一个文件从一种语言转化成另一种语言,比如把 CoffeeScript 转化成 JavaScript 或者作为数据 URLs 的内联图像。 In order to resolve the lack of UMD compatibility, you will rely to two specific loaders, import and export. +为了解决 UMD 的兼容性缺乏问题,你必须依赖两个具体的加载器,导入和导出加载器。 #### Using the Export Loader +#### 使用导出加载器 In the case of the Amazon Cognito Identity SDK for JavaScript, we need to ensure we export theAWSCognito variables into the scope of the module that requires/imports (for ES6) them. +在使用针对 JavaScript 的亚马逊 Cognito 标志 SDK 的情况下,我们需要确保把 theAWSCognito 变量导出到需要它们的模块/导出范围(针对 ES6). ``` { @@ -91,6 +105,7 @@ In the case of the Amazon Cognito Identity SDK for JavaScript, we need to ensure ``` Using the exports loader has the effect of exporting a module method within bundle created by webpack. As a result, both AWSCognito and AWS are now accessible when required or import(ed) (for ES6). +使用导出加载器可以在 webpack 创建的束【bundle】内导出模块。结果,现在 AWSCognito 和 AWS 都可以在需要它们的时候导出【针对 ES6】. ``` var AWSCognito = require('aws-cognito-sdk') @@ -100,12 +115,16 @@ module.exports = AWSCongito ``` More information about the exports loader can be found here +这儿可以找到更多关于导出加载器的信息。 #### Using the Import Loader +#### 使用导入加载器 The import loader is mostly used to inject (import) variables into the scope of another module. This is especially useful if third-party modules are relying on global variables like BitInteger or sjcl as is the case with Amazon Cognito Identity SDK for JavaScript. +导入加载器主要用于把(import)变量导入到另一个模块中。当第三方模块需要依赖全局变量的时候,导出加载器非常有用的,比如在针对 JavaScript 的亚马逊 Cognito 标志 SDK 需要依赖 BigInteger 或者sjcl 的时候。 If you don’t use the webpack loader, the following is generated within the bundle. +如果你不使用 webpack 加载器,下面这些会在一个束【bundle】中生成。 ``` __webpack_require__(431); // refers to jsbin @@ -113,8 +132,10 @@ __webpack_require__(432); // refers to sjcl ``` Beacuse neither jsbin or sjcl export anything, any calls that rely on these modules will result in an error. +因为 jsbin 和 sjcl 都不能导出任何东西,因此任何依赖于这些模块的调用都会导致一个错误。 To resolve this, we can use the following webpack loader configuration: +为了解决这个问题,我们需要使用下面的 webpack 加载器配置: ``` { @@ -128,6 +149,7 @@ To resolve this, we can use the following webpack loader configuration: ``` This injects the following into the bundle (in this case bundle.js) created by webpack. +这个配置把下面的这些插入到了由 webpack 创建的束【bundle】中(此时是 bundle.js)。 ```` /*** IMPORTS FROM imports-loader ***/ @@ -137,26 +159,34 @@ var sjcl = __webpack_require__(432); ``` As a result, jsbn, BigInteger and sjcl are all imported from their respective modules into Amazon Cognito Identity SDK for JavaScript. +结果,jsbn, BigInteger 和 sjcl 都被从它们各自的模块中导入到了用于 JavaScript 的亚马逊 Cognito 标志 SDK 中。 More information about the import loader can be found [here][15] +有关导出加载器的更多信息可以在这儿找到【15】。 ### Next Steps +### 下一步 We encourage you to download the [Amazon Cognito Identity SDK for JavaScript][16] and start building your application. Coupled with webpack, and by following the guidance in this blog, you we hope you have a smooth development experience. +如果你具有快速学习经验,我们鼓励你下载【用于 JavaScript 的亚马逊 Cognito 标志 SDk】【16】,并在这篇文章的指导下通过 webpack 开始构建你的应用程序。 + If you have any comments or questions, please free to comment below, reach out via email (teichtah@amazon.com) or raise an issue [here][17]. +如果你有任何意见或问题,请在下面自由评论,也可以发邮件到 teichtah@amazon.com 或者在这儿提出问题【17】. ### References +### 引用 This blog post makes reference to the following third party resources +这篇文章引用了下面这些第三方资源 - webpack - https://webpack.github.io/ -- webpack documentation - http://webpack.github.io/docs/what-is-webpack.html -- webpack exports loader - https://github.com/webpack/exports-loader -- webpack imports loader - https://github.com/webpack/imports-loader -- JavaScript BN library for BigInteger computation - http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn.js +- webpack 文件 - http://webpack.github.io/docs/what-is-webpack.html +- webpack 导出加载器 - https://github.com/webpack/exports-loader +- webpack 导入加载器 - https://github.com/webpack/imports-loader +- 用于 BigInteger 计算的 JavaScript BN 库- http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn.js - jsbns - http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn2.js -- Stanford JavaScript Crypto Library - https://github.com/bitwiseshiftleft/sjcl +- 标准 JavaScript Crypto 库 - https://github.com/bitwiseshiftleft/sjcl - RequireJS - http://requirejs.org/ - CommonJS - http://www.commonjs.org/ @@ -165,7 +195,7 @@ This blog post makes reference to the following third party resources via: https://mobile.awsblog.com/post/Tx1A84CLMDJ744T/Using-webpack-with-the-Amazon-Cognito-Identity-SDK-for-JavaScript?utm_source=webopsweekly&utm_medium=email 作者:[Marc Teichtahl ][a] -译者:[译者ID](https://github.com/译者ID) +译者:[ucasFL](https://github.com/ucasFL) 校对:[校对者ID](https://github.com/校对者ID) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From eae1c11b6c247c485ee5e76a3f86688ad1cfec27 Mon Sep 17 00:00:00 2001 From: Lv Feng Date: Tue, 4 Oct 2016 17:42:38 +0800 Subject: [PATCH 011/316] Update 20160908 Using webpack with the Amazon Cognito Identity SDK for JavaScript.md --- ...zon Cognito Identity SDK for JavaScript.md | 70 +++++-------------- 1 file changed, 16 insertions(+), 54 deletions(-) diff --git a/sources/tech/20160908 Using webpack with the Amazon Cognito Identity SDK for JavaScript.md b/sources/tech/20160908 Using webpack with the Amazon Cognito Identity SDK for JavaScript.md index 6be4890f97..f22739e71b 100644 --- a/sources/tech/20160908 Using webpack with the Amazon Cognito Identity SDK for JavaScript.md +++ b/sources/tech/20160908 Using webpack with the Amazon Cognito Identity SDK for JavaScript.md @@ -1,34 +1,23 @@ -Using webpack with the Amazon Cognito Identity SDK for JavaScript 把具有与亚马逊 Cognito 标志软件开发工具包(SDK)的 webpack 用于 JavaScript ===== -This blog post is aimed at developers of all experience levels who develop and deploy JavaScript based applications (whether server-side with Node.js or client side) that incorporate the AWS SDK, the Amazon Cognito Identity SDK for JavaScript and who also use the popular [webpack][1] module bundler. -这篇文章是针对开发和部署基于 JavaScriot 应用(Node.js 服务器端或者客户端服务器端)的所有经验水平的开发者。通过本文,你将看到如何把 AWS SDK, 亚马逊标志软件开发工具包(SDK)嵌入到 JavaScript 中,以及如何使用流行的【webpack】【1】模块打包机。 +这篇文章针对开发和部署基于 JavaScriot 应用(Node.js 服务器端或者客户端服务器端)的所有经验水平的开发者。通过本文,你将看到如何把 AWS SDK, 亚马逊标志软件开发工具包(SDK)嵌入到 JavaScript 中,以及如何使用流行的【webpack】【1】模块打包机。 -In July 2016, Amazon Web Services [launched Amazon Cognito User Pools][2], a feature that makes it easy for developers to add sign-up and sign-in functionality to mobile and web applications. To help developers easily realize the power of user pools within their own applications, we also released the [Amazon Cognito Identity SDK for JavaScript][3]. -2016年7月,亚马逊网站服务【推出亚马逊 Cognito 用户库】【2】,这个新特性极大的方便了开发者在移动和 Web 应用程序上添加注册和登录功能。为了帮助开发者更容易在自己的应用程序中实现用户库权利,我们也发布了【针对 JavaScript 的亚马逊 Cognito 特性 SDK】【3】。 +2016年7月,亚马逊网站服务【推出亚马逊 Cognito 用户库】【2】,这个新特性极大的方便了开发者在移动和 Web 应用程序上添加注册和登录功能。为了让开发者更容易在自己的应用程序中实现用户库功能,我们也发布了【针对 JavaScript 的亚马逊 Cognito 特性 SDK】【3】。 +亚马逊 Cognito 用户库可以让你在移动和 Web 应用程序上添加用户注册和登录功能更加容易。全托管用户库可以扩展到数以百万计的用户,你可以在一个 AWS 账户下有多重目录。创建一个用户库只需要几分钟的时间,并且你可以决定当一个新用户在你的应用程序或服务上注册时哪些属性(包括地址,邮箱,电话号码以及自定义属性)是强制的,哪些是可选择的。你的应用程序也可以指定所需的密码强度,指定用户需要进行多因素认证,通过电话号码或者邮件地址来验证新用户,从而进一步加强应用程序的安全性。 -Amazon Cognito User Pools allows you to easily add user sign-up and sign-in to your mobile and web applications. The fully managed user pool can scale to hundreds of millions of users and you can have multiple directories per AWS account. Creating a user pool takes just a few minutes and allows you to decide exactly which attributes (including address, email, phone number as well as custom attributes) are mandatory and even optional when a new user signs up for your application or service. Your application can also specify the desired password strength, whether the use of Multi-Factor Authentication (MFA) is required, and verify new users via phone number or email address to further enhance the security of your application. -亚马逊 Cognito 用户库使得你在移动和 Web 应用程序上添加用户注册和登录功能更加容易。全托管用户库可以扩展到数以百万计的用户,你可以在一个 AWS 账户下有多重目录。创建一个用户库只需要几分钟的时间,并且你可以决定当一个新用户在你的应用程序或服务上注册时哪些属性(包括地址,邮箱,电话号码以及自定义属性)是强制的,哪些是可选择的。你的应用程序也可以指定所需的密码强度,指定用户需要进行多因素认证,通过电话号码或者邮件地址来验证新用户,从而进一步加强应用程序的安全性。 - -If you are new to the Amazon Cognito Identity SDK for JavaScript [this AWS blog post][4] is a great place to start. 如果你是首次接触用于 JavaScript 的亚马逊 Cognito 标志 SDk,那么请先阅读【这篇 AWS 文章】【4】作为开始。 -### Why Use Asset & Module Bundling with the Amazon Cognito Identity SDK for JavaScript ### 为什么在 JavaScript 上使用具有资产模块的亚马逊 Cogtito 标志 SDK -Today, modern web applications for both mobile and desktop have to provide the user with a secure, fast, responsive, and native-app-like experience. There is no doubt that modern browsers are extremely powerful and cater to a vast array of possible implementation approaches. Many of the more popular implementations rely heavily on the deployment of a JavaScript application through some form of asset packaging and/or module bundling. This allows a developer to take their JavaScript application and create one or more files that can be loaded by the client browser by using script tags. 今天,针对移动和桌面的现代 Web 应用程序都能为用户提供安全、快捷、灵敏以及类本地应用的体验。毫无疑问,现代的浏览器功能强大,能够满足大量可能的实现方法。许多流行的实现很大程度上依赖于 JavaScript 应用程序通过某种形式的资产包装和/或模块捆绑进行部署。这使得许多开发人员能够很好的维护自己的 JavaScript 应用程序,并且可以通过使用脚本标签创建一个或多个可以加载到客户端浏览器上的文件。 -There are many schools of thought on how you can achieve this packaging , including task runners such as [Grunt][5] and [Gulp][6], and bundlers such as [Browserify][7]. However, there is a general consensus that asset packaging is not only about improving load times—it enables the modularization of your application while ensuring testability and robustness. -关于如何实现打包有许多学校的思想,包括任务运行者比如【Grunt】【5】和【Gulp】,还有打包机比如【Browserity】【7】.然而,一个普遍的共识是,资产打包不仅仅是关于缩短加载时间 - 它可以在确保可测试性和稳定性的前提下使你的应用程序模块化。 +关于如何实现打包有许多教育思想,包括任务运行者比如【Grunt】【5】和【Gulp】,还有打包机比如【Browserity】【7】。然而,一个普遍的共识是,资产打包不仅仅是关于缩短加载时间 - 它可以在确保可测试性和稳定性的前提下使你的应用程序模块化。 -### Using webpack with the Amazon Cognito Identity SDK for JavaScript -### 把具有亚麻逊 Cognito 标志 SDK 的 webpack 用于 JavaScript +### 把具有亚马逊 Cognito 标志 SDK 的 webpack 用于 JavaScript -In the many requests we get to provide more detail on how to integrate the Amazon Cognito Identity SDK for JavaScript within a webpack environment, we’re specifically asked how to ensure that webpack correctly manages the following third-party dependencies: -有许多请求需要我们提供如何在 webpack 环境中整合用于 JavaScript 的亚马逊 Cognito 标志 SDK 的更多细节。我们特地询问了如何确保 webpack 正确管理下面三方的关系: +有许多请求需要我们提供如何在 webpack 环境下整合用于 JavaScript 的亚马逊 Cognito 标志 SDK 的更多细节。我们特地询问了如何确保 webpack 正确管理下面三方的关系: - [JavaScript BN library for BigInteger computation][8] (jsbn) - [an extension to jsbn][9] the with the rest of the jsbn methods including most public BigInteger methods (jsbn2) @@ -37,7 +26,6 @@ In the many requests we get to provide more detail on how to integrate the Amazo - 【jsbn 扩展】【9】其余的 jsbn 方法包含大多数公共 BigInteger 方法(jsbn2) - 【标准 JavaScript Crypto 库】【10】(jscl) -Throughout these examples, the following bower libraries are used by bower.json 通过这些例子,可以看到,下面这些 bower 库都被 bower.json 使用 ``` @@ -47,8 +35,7 @@ Throughout these examples, the following bower libraries are used by bower.json "jsbn": "https://raw.githubusercontent.com/andyperlitch/jsbn/master/index.js", ``` -For all the reasons we gave earlier for the importance of asset packaging to development processes, and unless your application is extremely small, the use of an asset packaging tool such as webpack is almost always recommended. Of course, one could simply pull in all of these dependencies using tags. However, this would pollute global namespace, and not provide the most optimal resource management and loading approach. Many developers start with a standard webpack.config.js file that has a standard babel loader, as shown here. -出于我们前面给出的所有关于通过资产打包来改善进程的重要性的原因,除非你的应用程序非常小,使用像 webpack 这样的资产打包工具几乎总是必须的。当然,还有一个方法是可以通过使用标签简单的处理所有依赖关系。然而,这会污染全局命名空间,不能够提供最理想的资源管理和加载方法。许多开发者首次使用的是具有标准 babel 加载机的标准 webpack.config.js 文件,像下面展示的这样。 +出于我们前面给出的所有关于通过资产打包来改善进程重要性的原因,除非你的应用程序非常小,否则使用像 webpack 这样的资产打包工具几乎总是必须的。当然,还有一个方法是可以通过使用标签简单的处理所有依赖关系。然而,这会污染全局命名空间,而且不能够提供最理想的资源管理和加载方法。许多开发者首次使用的是具有标准 babel 加载机的标准 webpack.config.js 文件,像下面展示的这样。 ``` { @@ -66,35 +53,25 @@ For all the reasons we gave earlier for the importance of asset packaging to dev } ``` -It’s important to remember that this configuration doesn’t take into account that some of third-party dependencies used by the Amazon Cognito Identity SDK for JavaScript currently do not use the [Universal Module Definition (UMD) pattern for JavaScript][11]. -需要重点记住的是,这个配置没有考虑一些第三方关系,这些被针对 JavaScript 的亚马逊 Cognito 标志 SDK 使用的第三方关系目前没有使用【JavaScript 通用模块定义(UMD)】【11】. +需要重点记住的是,这个配置没有考虑一些第三方关系,这些被针对 JavaScript 的亚马逊 Cognito 标志 SDK 使用的第三方关系目前没有使用【JavaScript 通用模块定义(UMD)】【11】。 -The UMD pattern attempts to offer Asynchronous Module Definition (AMD) based compatibility with the most popular script loaders of the day such as [RequireJS][12] and [CommonJS][13]. -UMD 模式试图提供基于当前最流行的脚本加载器比如【RequireJS】【12】和【CommonJS】【13】兼容性的异步模块定义【AMD】. +UMD 模式试图提供基于当前最流行的脚本加载器比如【RequireJS】【12】和【CommonJS】【13】兼容性的异步模块定义【AMD】。 -This is a pattern that webpack relies on, and so we must make some changes to how webpack loads these modules. Without these changes, you may encounter errors such as the following. -这是 webpack 所依靠的模式,为了让 webpack 能够工作我们必须做一些改变。不进行这些改变,你可能会遇到下面这些错误。 +这是 webpack 所依赖的模式,为了让 webpack 能够工作,我们必须进行一些改变。不做这些改变,你可能会遇到下面这些错误。 ``` amazon-cognito-identity.min.js:19 Uncaught ReferenceError: BigInteger is not defined ``` +这样一个错误可能会在调用 AWSCognito.CognitoIdentityServiceProvider.CognitoUser property authenticateUser 的时候出现。这是一个错误出现的例子,我们可以利用 webpack 的导入导出加载能力来解决这个错误。 -Such an error may be encountered when making a call to AWSCognito.CognitoIdentityServiceProvider.CognitoUser property authenticateUser This is an example of where we can make use of the webpack imports and exports loader capability to overcome this error. -这样一个错误可能会在调用 AWSCognito.CognitoIdentityServiceProvider.CognitoUser property authenticateUser 的时候出现。这是一个出现错误的例子,我们可以利用 webpack 的进出口加载能力来解决这个错误。 - -### Using webpack Loaders ### 使用 webpack 加载器 -According to the [webpack documentation][14] "loaders allow you to preprocess files as you require() or “load” them. Loaders are kind of like “tasks” are in other build tools, and provide a powerful way to handle front-end build steps. Loaders can transform files from a different language like, CoffeeScript to JavaScript, or inline images as data URLs" -根据【webpack 文件】,”加载器允许你按你的需求来预处理或“加载”文件。加载器是一种在其他搭建工具中类似 “tasks” 的工具,他可以提供一个处理前端搭建步骤的强大方法。加载器可以把一个文件从一种语言转化成另一种语言,比如把 CoffeeScript 转化成 JavaScript 或者作为数据 URLs 的内联图像。 +根据【webpack 文件】,”加载器允许你按你的需求来预处理或“加载”文件。加载器是一种在其他搭建工具中类似 “tasks” 的工具,他可以提供一个处理前端搭建步骤的强大方法。加载器可以把一个文件从一种语言转化成另一种语言,比如把 CoffeeScript 转化成 JavaScript 或者作为数据 URLs 的内联图像。“ -In order to resolve the lack of UMD compatibility, you will rely to two specific loaders, import and export. 为了解决 UMD 的兼容性缺乏问题,你必须依赖两个具体的加载器,导入和导出加载器。 -#### Using the Export Loader #### 使用导出加载器 -In the case of the Amazon Cognito Identity SDK for JavaScript, we need to ensure we export theAWSCognito variables into the scope of the module that requires/imports (for ES6) them. 在使用针对 JavaScript 的亚马逊 Cognito 标志 SDK 的情况下,我们需要确保把 theAWSCognito 变量导出到需要它们的模块/导出范围(针对 ES6). ``` @@ -104,8 +81,7 @@ In the case of the Amazon Cognito Identity SDK for JavaScript, we need to ensure } ``` -Using the exports loader has the effect of exporting a module method within bundle created by webpack. As a result, both AWSCognito and AWS are now accessible when required or import(ed) (for ES6). -使用导出加载器可以在 webpack 创建的束【bundle】内导出模块。结果,现在 AWSCognito 和 AWS 都可以在需要它们的时候导出【针对 ES6】. +使用导出加载器可以在 webpack 创建的束【bundle】内导出模块。到目前, AWSCognito 和 AWS 都可以在需要它们的时候导出【针对 ES6】. ``` var AWSCognito = require('aws-cognito-sdk') @@ -114,27 +90,21 @@ var AWSCognito = require('aws-cognito-sdk') module.exports = AWSCongito ``` -More information about the exports loader can be found here 这儿可以找到更多关于导出加载器的信息。 -#### Using the Import Loader #### 使用导入加载器 -The import loader is mostly used to inject (import) variables into the scope of another module. This is especially useful if third-party modules are relying on global variables like BitInteger or sjcl as is the case with Amazon Cognito Identity SDK for JavaScript. -导入加载器主要用于把(import)变量导入到另一个模块中。当第三方模块需要依赖全局变量的时候,导出加载器非常有用的,比如在针对 JavaScript 的亚马逊 Cognito 标志 SDK 需要依赖 BigInteger 或者sjcl 的时候。 +导入加载器主要用于把(import)变量导入到另一个模块中。当第三方模块需要依赖全局变量的时候,导出加载器非常有用,比如针对 JavaScript 的亚马逊 Cognito 标志 SDK 需要依赖 BigInteger 或者sjcl 的时候。 -If you don’t use the webpack loader, the following is generated within the bundle. -如果你不使用 webpack 加载器,下面这些会在一个束【bundle】中生成。 +如果你不使用 webpack 加载器,下面这些内容会在一个束【bundle】中生成。 ``` __webpack_require__(431); // refers to jsbin __webpack_require__(432); // refers to sjcl ``` -Beacuse neither jsbin or sjcl export anything, any calls that rely on these modules will result in an error. 因为 jsbin 和 sjcl 都不能导出任何东西,因此任何依赖于这些模块的调用都会导致一个错误。 -To resolve this, we can use the following webpack loader configuration: 为了解决这个问题,我们需要使用下面的 webpack 加载器配置: ``` @@ -148,8 +118,7 @@ To resolve this, we can use the following webpack loader configuration: } ``` -This injects the following into the bundle (in this case bundle.js) created by webpack. -这个配置把下面的这些插入到了由 webpack 创建的束【bundle】中(此时是 bundle.js)。 +这个配置把下面的这些内容嵌入到了由 webpack 创建的束【bundle】中(此时是 bundle.js)。 ```` /*** IMPORTS FROM imports-loader ***/ @@ -158,26 +127,19 @@ var BigInteger = jsbn.BigInteger; var sjcl = __webpack_require__(432); ``` -As a result, jsbn, BigInteger and sjcl are all imported from their respective modules into Amazon Cognito Identity SDK for JavaScript. 结果,jsbn, BigInteger 和 sjcl 都被从它们各自的模块中导入到了用于 JavaScript 的亚马逊 Cognito 标志 SDK 中。 -More information about the import loader can be found [here][15] 有关导出加载器的更多信息可以在这儿找到【15】。 -### Next Steps ### 下一步 -We encourage you to download the [Amazon Cognito Identity SDK for JavaScript][16] and start building your application. Coupled with webpack, and by following the guidance in this blog, you we hope you have a smooth development experience. 如果你具有快速学习经验,我们鼓励你下载【用于 JavaScript 的亚马逊 Cognito 标志 SDk】【16】,并在这篇文章的指导下通过 webpack 开始构建你的应用程序。 -If you have any comments or questions, please free to comment below, reach out via email (teichtah@amazon.com) or raise an issue [here][17]. 如果你有任何意见或问题,请在下面自由评论,也可以发邮件到 teichtah@amazon.com 或者在这儿提出问题【17】. -### References ### 引用 -This blog post makes reference to the following third party resources 这篇文章引用了下面这些第三方资源 - webpack - https://webpack.github.io/ From 42dfbfdd2f40bb4a022c60f2ac1f64c5ff28b57f Mon Sep 17 00:00:00 2001 From: Lv Feng Date: Tue, 4 Oct 2016 17:44:57 +0800 Subject: [PATCH 012/316] =?UTF-8?q?=E7=BF=BB=E8=AF=91=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...zon Cognito Identity SDK for JavaScript.md | 183 ++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 translated/tech/20160908 Using webpack with the Amazon Cognito Identity SDK for JavaScript.md diff --git a/translated/tech/20160908 Using webpack with the Amazon Cognito Identity SDK for JavaScript.md b/translated/tech/20160908 Using webpack with the Amazon Cognito Identity SDK for JavaScript.md new file mode 100644 index 0000000000..5aa466ae7d --- /dev/null +++ b/translated/tech/20160908 Using webpack with the Amazon Cognito Identity SDK for JavaScript.md @@ -0,0 +1,183 @@ +把具有亚马逊 Cognito 标志软件开发工具包(SDK)的 webpack 用于 JavaScript +===== + +这篇文章针对开发和部署基于 JavaScriot 应用(Node.js 服务器端或者客户端服务器端)的所有经验水平的开发者。通过本文,你将看到如何把 AWS SDK, 亚马逊标志软件开发工具包(SDK)嵌入到 JavaScript 中,以及如何使用流行的【webpack】【1】模块打包机。 + +2016年7月,亚马逊网站服务【推出亚马逊 Cognito 用户库】【2】,这个新特性极大的方便了开发者在移动和 Web 应用程序上添加注册和登录功能。为了让开发者更容易在自己的应用程序中实现用户库功能,我们也发布了【针对 JavaScript 的亚马逊 Cognito 特性 SDK】【3】。 + +亚马逊 Cognito 用户库可以让你在移动和 Web 应用程序上添加用户注册和登录功能更加容易。全托管用户库可以扩展到数以百万计的用户,你可以在一个 AWS 账户下有多重目录。创建一个用户库只需要几分钟的时间,并且你可以决定当一个新用户在你的应用程序或服务上注册时哪些属性(包括地址,邮箱,电话号码以及自定义属性)是强制的,哪些是可选择的。你的应用程序也可以指定所需的密码强度,指定用户需要进行多因素认证,通过电话号码或者邮件地址来验证新用户,从而进一步加强应用程序的安全性。 + +如果你是首次接触用于 JavaScript 的亚马逊 Cognito 标志 SDk,那么请先阅读【这篇 AWS 文章】【4】作为开始。 + +### 为什么在 JavaScript 上使用具有资产模块的亚马逊 Cogtito 标志 SDK + +今天,针对移动和桌面的现代 Web 应用程序都能为用户提供安全、快捷、灵敏以及类本地应用的体验。毫无疑问,现代的浏览器功能强大,能够满足大量可能的实现方法。许多流行的实现很大程度上依赖于 JavaScript 应用程序通过某种形式的资产包装和/或模块捆绑进行部署。这使得许多开发人员能够很好的维护自己的 JavaScript 应用程序,并且可以通过使用脚本标签创建一个或多个可以加载到客户端浏览器上的文件。 + +关于如何实现打包有许多教育思想,包括任务运行者比如【Grunt】【5】和【Gulp】,还有打包机比如【Browserity】【7】。然而,一个普遍的共识是,资产打包不仅仅是关于缩短加载时间 - 它可以在确保可测试性和稳定性的前提下使你的应用程序模块化。 + +### 把具有亚马逊 Cognito 标志 SDK 的 webpack 用于 JavaScript + +有许多请求需要我们提供如何在 webpack 环境下整合用于 JavaScript 的亚马逊 Cognito 标志 SDK 的更多细节。我们特地询问了如何确保 webpack 正确管理下面三方的关系: + +- [JavaScript BN library for BigInteger computation][8] (jsbn) +- [an extension to jsbn][9] the with the rest of the jsbn methods including most public BigInteger methods (jsbn2) +- the [Stanford JavaScript Crypto Library][10] (sjcl) +- 【用于 BigInteger 计算的 JavaScript 库】【8】(jsbn) +- 【jsbn 扩展】【9】其余的 jsbn 方法包含大多数公共 BigInteger 方法(jsbn2) +- 【标准 JavaScript Crypto 库】【10】(jscl) + +通过这些例子,可以看到,下面这些 bower 库都被 bower.json 使用 + +``` +"aws-cognito-sdk": "https://raw.githubusercontent.com/aws/amazon-cognito-identity-js/master/dist/aws-cognito-sdk.js", +"amazon-cognito-identity": "https://raw.githubusercontent.com/aws/amazon-cognito-identity-js/master/dist/amazon-cognito-identity.min.js", +"sjcl": "https://raw.githubusercontent.com/bitwiseshiftleft/sjcl/master/sjcl.js", +"jsbn": "https://raw.githubusercontent.com/andyperlitch/jsbn/master/index.js", +``` + +出于我们前面给出的所有关于通过资产打包来改善进程重要性的原因,除非你的应用程序非常小,否则使用像 webpack 这样的资产打包工具几乎总是必须的。当然,还有一个方法是可以通过使用标签简单的处理所有依赖关系。然而,这会污染全局命名空间,而且不能够提供最理想的资源管理和加载方法。许多开发者首次使用的是具有标准 babel 加载机的标准 webpack.config.js 文件,像下面展示的这样。 + +``` +{ + /** test for file ending in js or jsx + * exclude node_module and bower_components - we dont want to babel these + * use the babel loader + * apply the react and es2015 (es6) transformations **/ + + test: /\.jsx?$/, + exclude: /(node_modules|bower_components)/, + loader: 'babel', + query: { + presets: ['react', 'es2015'] + } +} +``` + +需要重点记住的是,这个配置没有考虑一些第三方关系,这些被针对 JavaScript 的亚马逊 Cognito 标志 SDK 使用的第三方关系目前没有使用【JavaScript 通用模块定义(UMD)】【11】。 + +UMD 模式试图提供基于当前最流行的脚本加载器比如【RequireJS】【12】和【CommonJS】【13】兼容性的异步模块定义【AMD】。 + +这是 webpack 所依赖的模式,为了让 webpack 能够工作,我们必须进行一些改变。不做这些改变,你可能会遇到下面这些错误。 + +``` +amazon-cognito-identity.min.js:19 Uncaught ReferenceError: BigInteger is not defined +``` +这样一个错误可能会在调用 AWSCognito.CognitoIdentityServiceProvider.CognitoUser property authenticateUser 的时候出现。这是一个错误出现的例子,我们可以利用 webpack 的导入导出加载能力来解决这个错误。 + +### 使用 webpack 加载器 + +根据【webpack 文件】,”加载器允许你按你的需求来预处理或“加载”文件。加载器是一种在其他搭建工具中类似 “tasks” 的工具,他可以提供一个处理前端搭建步骤的强大方法。加载器可以把一个文件从一种语言转化成另一种语言,比如把 CoffeeScript 转化成 JavaScript 或者作为数据 URLs 的内联图像。“ + +为了解决 UMD 的兼容性缺乏问题,你必须依赖两个具体的加载器,导入和导出加载器。 + +#### 使用导出加载器 + +在使用针对 JavaScript 的亚马逊 Cognito 标志 SDK 的情况下,我们需要确保把 theAWSCognito 变量导出到需要它们的模块/导出范围(针对 ES6). + +``` +{ + test: /aws-cognito-sdk\/index\.js/, + loader: 'exports?AWSCognito' +} +``` + +使用导出加载器可以在 webpack 创建的束【bundle】内导出模块。到目前, AWSCognito 和 AWS 都可以在需要它们的时候导出【针对 ES6】. + +``` +var AWSCognito = require('aws-cognito-sdk') + +/*** EXPORTS from export-loader ***/ +module.exports = AWSCongito +``` + +这儿可以找到更多关于导出加载器的信息。 + +#### 使用导入加载器 + +导入加载器主要用于把(import)变量导入到另一个模块中。当第三方模块需要依赖全局变量的时候,导出加载器非常有用,比如针对 JavaScript 的亚马逊 Cognito 标志 SDK 需要依赖 BigInteger 或者sjcl 的时候。 + +如果你不使用 webpack 加载器,下面这些内容会在一个束【bundle】中生成。 + +``` +__webpack_require__(431); // refers to jsbin +__webpack_require__(432); // refers to sjcl +``` + +因为 jsbin 和 sjcl 都不能导出任何东西,因此任何依赖于这些模块的调用都会导致一个错误。 + +为了解决这个问题,我们需要使用下面的 webpack 加载器配置: + +``` +{ + test: /amazon-cognito-identity\/index\.js/, + loader: 'imports?jsbn,BigInteger=>jsbn.BigInteger,sjcl' +}, +{ + test: /sjcl\/index\.js/, + loader: 'imports?sjcl' +} +``` + +这个配置把下面的这些内容嵌入到了由 webpack 创建的束【bundle】中(此时是 bundle.js)。 + +```` +/*** IMPORTS FROM imports-loader ***/ +var jsbn = __webpack_require__(431); +var BigInteger = jsbn.BigInteger; +var sjcl = __webpack_require__(432); +``` + +结果,jsbn, BigInteger 和 sjcl 都被从它们各自的模块中导入到了用于 JavaScript 的亚马逊 Cognito 标志 SDK 中。 + +有关导出加载器的更多信息可以在这儿找到【15】。 + +### 下一步 + +如果你具有快速学习经验,我们鼓励你下载【用于 JavaScript 的亚马逊 Cognito 标志 SDk】【16】,并在这篇文章的指导下通过 webpack 开始构建你的应用程序。 + + +如果你有任何意见或问题,请在下面自由评论,也可以发邮件到 teichtah@amazon.com 或者在这儿提出问题【17】. + +### 引用 + +这篇文章引用了下面这些第三方资源 + +- webpack - https://webpack.github.io/ +- webpack 文件 - http://webpack.github.io/docs/what-is-webpack.html +- webpack 导出加载器 - https://github.com/webpack/exports-loader +- webpack 导入加载器 - https://github.com/webpack/imports-loader +- 用于 BigInteger 计算的 JavaScript BN 库- http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn.js +- jsbns - http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn2.js +- 标准 JavaScript Crypto 库 - https://github.com/bitwiseshiftleft/sjcl +- RequireJS - http://requirejs.org/ +- CommonJS - http://www.commonjs.org/ + +-------------------------------------------------------------------------------- + +via: https://mobile.awsblog.com/post/Tx1A84CLMDJ744T/Using-webpack-with-the-Amazon-Cognito-Identity-SDK-for-JavaScript?utm_source=webopsweekly&utm_medium=email + +作者:[Marc Teichtahl ][a] +译者:[ucasFL](https://github.com/ucasFL) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://mobile.awsblog.com/blog/author/Marc+Teichtahl +[1]: https://webpack.github.io/ +[2]: https://blogs.aws.amazon.com/security/post/Tx13NVD4AWG9QK9/Amazon-Cognito-Your-User-Pools-is-Now-Generally-Available +[3]: https://github.com/aws/amazon-cognito-identity-js +[4]: http://mobile.awsblog.com/post/Tx2O14ZY8A5LFHT/Accessing-Your-User-Pools-using-the-Amazon-Cognito-Identity-SDK-for-JavaScript +[5]: http://gruntjs.com/ +[6]: http://gulpjs.com/ +[7]: http://browserify.org/ +[8]: http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn.js +[9]: http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn2.js +[10]: https://github.com/bitwiseshiftleft/sjcl +[11]: https://github.com/umdjs/umd +[12]: http://requirejs.org/ +[13]: http://www.commonjs.org/ +[14]: http://webpack.github.io/docs/what-is-webpack.html +[15]: https://github.com/webpack/imports-loader +[16]: https://github.com/aws/amazon-cognito-identity-js +[17]: https://github.com/aws/amazon-cognito-identity-js/issues + From 8f48a8c3530ecf51cfeba52c34bf4305d4a671c3 Mon Sep 17 00:00:00 2001 From: Lv Feng Date: Tue, 4 Oct 2016 17:45:42 +0800 Subject: [PATCH 013/316] Delete 20160908 Using webpack with the Amazon Cognito Identity SDK for JavaScript.md --- ...zon Cognito Identity SDK for JavaScript.md | 183 ------------------ 1 file changed, 183 deletions(-) delete mode 100644 sources/tech/20160908 Using webpack with the Amazon Cognito Identity SDK for JavaScript.md diff --git a/sources/tech/20160908 Using webpack with the Amazon Cognito Identity SDK for JavaScript.md b/sources/tech/20160908 Using webpack with the Amazon Cognito Identity SDK for JavaScript.md deleted file mode 100644 index f22739e71b..0000000000 --- a/sources/tech/20160908 Using webpack with the Amazon Cognito Identity SDK for JavaScript.md +++ /dev/null @@ -1,183 +0,0 @@ -把具有与亚马逊 Cognito 标志软件开发工具包(SDK)的 webpack 用于 JavaScript -===== - -这篇文章针对开发和部署基于 JavaScriot 应用(Node.js 服务器端或者客户端服务器端)的所有经验水平的开发者。通过本文,你将看到如何把 AWS SDK, 亚马逊标志软件开发工具包(SDK)嵌入到 JavaScript 中,以及如何使用流行的【webpack】【1】模块打包机。 - -2016年7月,亚马逊网站服务【推出亚马逊 Cognito 用户库】【2】,这个新特性极大的方便了开发者在移动和 Web 应用程序上添加注册和登录功能。为了让开发者更容易在自己的应用程序中实现用户库功能,我们也发布了【针对 JavaScript 的亚马逊 Cognito 特性 SDK】【3】。 - -亚马逊 Cognito 用户库可以让你在移动和 Web 应用程序上添加用户注册和登录功能更加容易。全托管用户库可以扩展到数以百万计的用户,你可以在一个 AWS 账户下有多重目录。创建一个用户库只需要几分钟的时间,并且你可以决定当一个新用户在你的应用程序或服务上注册时哪些属性(包括地址,邮箱,电话号码以及自定义属性)是强制的,哪些是可选择的。你的应用程序也可以指定所需的密码强度,指定用户需要进行多因素认证,通过电话号码或者邮件地址来验证新用户,从而进一步加强应用程序的安全性。 - -如果你是首次接触用于 JavaScript 的亚马逊 Cognito 标志 SDk,那么请先阅读【这篇 AWS 文章】【4】作为开始。 - -### 为什么在 JavaScript 上使用具有资产模块的亚马逊 Cogtito 标志 SDK - -今天,针对移动和桌面的现代 Web 应用程序都能为用户提供安全、快捷、灵敏以及类本地应用的体验。毫无疑问,现代的浏览器功能强大,能够满足大量可能的实现方法。许多流行的实现很大程度上依赖于 JavaScript 应用程序通过某种形式的资产包装和/或模块捆绑进行部署。这使得许多开发人员能够很好的维护自己的 JavaScript 应用程序,并且可以通过使用脚本标签创建一个或多个可以加载到客户端浏览器上的文件。 - -关于如何实现打包有许多教育思想,包括任务运行者比如【Grunt】【5】和【Gulp】,还有打包机比如【Browserity】【7】。然而,一个普遍的共识是,资产打包不仅仅是关于缩短加载时间 - 它可以在确保可测试性和稳定性的前提下使你的应用程序模块化。 - -### 把具有亚马逊 Cognito 标志 SDK 的 webpack 用于 JavaScript - -有许多请求需要我们提供如何在 webpack 环境下整合用于 JavaScript 的亚马逊 Cognito 标志 SDK 的更多细节。我们特地询问了如何确保 webpack 正确管理下面三方的关系: - -- [JavaScript BN library for BigInteger computation][8] (jsbn) -- [an extension to jsbn][9] the with the rest of the jsbn methods including most public BigInteger methods (jsbn2) -- the [Stanford JavaScript Crypto Library][10] (sjcl) -- 【用于 BigInteger 计算的 JavaScript 库】【8】(jsbn) -- 【jsbn 扩展】【9】其余的 jsbn 方法包含大多数公共 BigInteger 方法(jsbn2) -- 【标准 JavaScript Crypto 库】【10】(jscl) - -通过这些例子,可以看到,下面这些 bower 库都被 bower.json 使用 - -``` -"aws-cognito-sdk": "https://raw.githubusercontent.com/aws/amazon-cognito-identity-js/master/dist/aws-cognito-sdk.js", -"amazon-cognito-identity": "https://raw.githubusercontent.com/aws/amazon-cognito-identity-js/master/dist/amazon-cognito-identity.min.js", -"sjcl": "https://raw.githubusercontent.com/bitwiseshiftleft/sjcl/master/sjcl.js", -"jsbn": "https://raw.githubusercontent.com/andyperlitch/jsbn/master/index.js", -``` - -出于我们前面给出的所有关于通过资产打包来改善进程重要性的原因,除非你的应用程序非常小,否则使用像 webpack 这样的资产打包工具几乎总是必须的。当然,还有一个方法是可以通过使用标签简单的处理所有依赖关系。然而,这会污染全局命名空间,而且不能够提供最理想的资源管理和加载方法。许多开发者首次使用的是具有标准 babel 加载机的标准 webpack.config.js 文件,像下面展示的这样。 - -``` -{ - /** test for file ending in js or jsx - * exclude node_module and bower_components - we dont want to babel these - * use the babel loader - * apply the react and es2015 (es6) transformations **/ - - test: /\.jsx?$/, - exclude: /(node_modules|bower_components)/, - loader: 'babel', - query: { - presets: ['react', 'es2015'] - } -} -``` - -需要重点记住的是,这个配置没有考虑一些第三方关系,这些被针对 JavaScript 的亚马逊 Cognito 标志 SDK 使用的第三方关系目前没有使用【JavaScript 通用模块定义(UMD)】【11】。 - -UMD 模式试图提供基于当前最流行的脚本加载器比如【RequireJS】【12】和【CommonJS】【13】兼容性的异步模块定义【AMD】。 - -这是 webpack 所依赖的模式,为了让 webpack 能够工作,我们必须进行一些改变。不做这些改变,你可能会遇到下面这些错误。 - -``` -amazon-cognito-identity.min.js:19 Uncaught ReferenceError: BigInteger is not defined -``` -这样一个错误可能会在调用 AWSCognito.CognitoIdentityServiceProvider.CognitoUser property authenticateUser 的时候出现。这是一个错误出现的例子,我们可以利用 webpack 的导入导出加载能力来解决这个错误。 - -### 使用 webpack 加载器 - -根据【webpack 文件】,”加载器允许你按你的需求来预处理或“加载”文件。加载器是一种在其他搭建工具中类似 “tasks” 的工具,他可以提供一个处理前端搭建步骤的强大方法。加载器可以把一个文件从一种语言转化成另一种语言,比如把 CoffeeScript 转化成 JavaScript 或者作为数据 URLs 的内联图像。“ - -为了解决 UMD 的兼容性缺乏问题,你必须依赖两个具体的加载器,导入和导出加载器。 - -#### 使用导出加载器 - -在使用针对 JavaScript 的亚马逊 Cognito 标志 SDK 的情况下,我们需要确保把 theAWSCognito 变量导出到需要它们的模块/导出范围(针对 ES6). - -``` -{ - test: /aws-cognito-sdk\/index\.js/, - loader: 'exports?AWSCognito' -} -``` - -使用导出加载器可以在 webpack 创建的束【bundle】内导出模块。到目前, AWSCognito 和 AWS 都可以在需要它们的时候导出【针对 ES6】. - -``` -var AWSCognito = require('aws-cognito-sdk') - -/*** EXPORTS from export-loader ***/ -module.exports = AWSCongito -``` - -这儿可以找到更多关于导出加载器的信息。 - -#### 使用导入加载器 - -导入加载器主要用于把(import)变量导入到另一个模块中。当第三方模块需要依赖全局变量的时候,导出加载器非常有用,比如针对 JavaScript 的亚马逊 Cognito 标志 SDK 需要依赖 BigInteger 或者sjcl 的时候。 - -如果你不使用 webpack 加载器,下面这些内容会在一个束【bundle】中生成。 - -``` -__webpack_require__(431); // refers to jsbin -__webpack_require__(432); // refers to sjcl -``` - -因为 jsbin 和 sjcl 都不能导出任何东西,因此任何依赖于这些模块的调用都会导致一个错误。 - -为了解决这个问题,我们需要使用下面的 webpack 加载器配置: - -``` -{ - test: /amazon-cognito-identity\/index\.js/, - loader: 'imports?jsbn,BigInteger=>jsbn.BigInteger,sjcl' -}, -{ - test: /sjcl\/index\.js/, - loader: 'imports?sjcl' -} -``` - -这个配置把下面的这些内容嵌入到了由 webpack 创建的束【bundle】中(此时是 bundle.js)。 - -```` -/*** IMPORTS FROM imports-loader ***/ -var jsbn = __webpack_require__(431); -var BigInteger = jsbn.BigInteger; -var sjcl = __webpack_require__(432); -``` - -结果,jsbn, BigInteger 和 sjcl 都被从它们各自的模块中导入到了用于 JavaScript 的亚马逊 Cognito 标志 SDK 中。 - -有关导出加载器的更多信息可以在这儿找到【15】。 - -### 下一步 - -如果你具有快速学习经验,我们鼓励你下载【用于 JavaScript 的亚马逊 Cognito 标志 SDk】【16】,并在这篇文章的指导下通过 webpack 开始构建你的应用程序。 - - -如果你有任何意见或问题,请在下面自由评论,也可以发邮件到 teichtah@amazon.com 或者在这儿提出问题【17】. - -### 引用 - -这篇文章引用了下面这些第三方资源 - -- webpack - https://webpack.github.io/ -- webpack 文件 - http://webpack.github.io/docs/what-is-webpack.html -- webpack 导出加载器 - https://github.com/webpack/exports-loader -- webpack 导入加载器 - https://github.com/webpack/imports-loader -- 用于 BigInteger 计算的 JavaScript BN 库- http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn.js -- jsbns - http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn2.js -- 标准 JavaScript Crypto 库 - https://github.com/bitwiseshiftleft/sjcl -- RequireJS - http://requirejs.org/ -- CommonJS - http://www.commonjs.org/ - --------------------------------------------------------------------------------- - -via: https://mobile.awsblog.com/post/Tx1A84CLMDJ744T/Using-webpack-with-the-Amazon-Cognito-Identity-SDK-for-JavaScript?utm_source=webopsweekly&utm_medium=email - -作者:[Marc Teichtahl ][a] -译者:[ucasFL](https://github.com/ucasFL) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]: https://mobile.awsblog.com/blog/author/Marc+Teichtahl -[1]: https://webpack.github.io/ -[2]: https://blogs.aws.amazon.com/security/post/Tx13NVD4AWG9QK9/Amazon-Cognito-Your-User-Pools-is-Now-Generally-Available -[3]: https://github.com/aws/amazon-cognito-identity-js -[4]: http://mobile.awsblog.com/post/Tx2O14ZY8A5LFHT/Accessing-Your-User-Pools-using-the-Amazon-Cognito-Identity-SDK-for-JavaScript -[5]: http://gruntjs.com/ -[6]: http://gulpjs.com/ -[7]: http://browserify.org/ -[8]: http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn.js -[9]: http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn2.js -[10]: https://github.com/bitwiseshiftleft/sjcl -[11]: https://github.com/umdjs/umd -[12]: http://requirejs.org/ -[13]: http://www.commonjs.org/ -[14]: http://webpack.github.io/docs/what-is-webpack.html -[15]: https://github.com/webpack/imports-loader -[16]: https://github.com/aws/amazon-cognito-identity-js -[17]: https://github.com/aws/amazon-cognito-identity-js/issues - From 66d2947c83dd90745081cebcc2fb63f7cdab3963 Mon Sep 17 00:00:00 2001 From: theArcticOcean <2722488604@qq.com> Date: Tue, 4 Oct 2016 22:41:08 +0800 Subject: [PATCH 014/316] Delete 20160622 Part III - How to apply Advanced Mathematical Processing Effects on Audio files with Octave 4.0 on Ubuntu.md --- ...n Audio files with Octave 4.0 on Ubuntu.md | 139 ------------------ 1 file changed, 139 deletions(-) delete mode 100644 sources/tech/20160622 Part III - How to apply Advanced Mathematical Processing Effects on Audio files with Octave 4.0 on Ubuntu.md diff --git a/sources/tech/20160622 Part III - How to apply Advanced Mathematical Processing Effects on Audio files with Octave 4.0 on Ubuntu.md b/sources/tech/20160622 Part III - How to apply Advanced Mathematical Processing Effects on Audio files with Octave 4.0 on Ubuntu.md deleted file mode 100644 index ce5bce5d9c..0000000000 --- a/sources/tech/20160622 Part III - How to apply Advanced Mathematical Processing Effects on Audio files with Octave 4.0 on Ubuntu.md +++ /dev/null @@ -1,139 +0,0 @@ -translating by theArcticOcean. - -Part III - How to apply Advanced Mathematical Processing Effects on Audio files with Octave 4.0 on Ubuntu -===== - -The third part of our Digital Audio processing tutorial series covers the signal Modulation, we explain how to apply Amplitude Modulation, Tremolo Effect, and Frequency Variation. - -### Modulation - -#### Amplitude Modulation - -As its name implies, this effect varies the amplitude of a sinusoid according to the message to be transmitted. A sine wave is called a carrier because it carries the information. This type of modulation is used in some commercial broadcasting and transmission citizen bands (AM). - -#### Why use the Amplitude Modulation? - -**Modulation Radiation.** - -If the communication channel is a free space, then antennas are required to radiate and receive the signal. It requires an efficient electromagnetic radiation antenna whose dimensions are of the same order of magnitude as the wavelength of the signal being radiated. Many signals, including audio components, have often 100 Hz or less. For these signals, it would be necessary to build antennas about 300 km in length if the signal were to be radiated directly. If signal modulation is used to print the message on a high-frequency carrier, let's say 100 MHz, then the antenna needs to have a length of over a meter (transverse length) only. - -**Concentration modulation or multi-channeling.** - -If more than one signal uses a single channel, modulation can be used for transferring different signals to different spectral positions allowing the receiver to select the desired signal. Applications that use concentration ("multiplexing") include telemetry data, stereo FM radio and long-distance telephony. - -**Modulation to Overcome Limitations on equipment.** - -The performance of signal processing devices such as filters and amplifiers, and the ease with which these devices can be constructed, depends on the situation of the signal in the frequency domain and the relationship between the higher frequency and low signal. Modulation can be used to transfer the signal to a position in the frequency domain where design requirements are met easier. The modulation can also be used to convert a "broadband signal" (a signal for which the ratio between the highest and lowest frequency is large) into a sign of "narrow band". - -**Audio Effects** - -Many audio effects use amplitude modulation due to the striking and ease with which it can handle such signals. We can name a few such as tremolo, chorus, flanger, etc. This utility is where we focus in this tutorial series. - -### Tremolo effect - -The tremolo effect is one of the simplest applications of amplitude modulation, to achieve this effect, we have to vary (multiply) the audio signal by a periodic signal, either sinusoidal or otherwise. - -``` ->> tremolo='tremolo.ogg'; ->> fs=44100; ->> t=0:1/fs:10; ->> wo=2*pi*440*t; ->> wa=2*pi*1.2*t; ->> audiowrite(tremolo, cos(wa).*cos(wo),fs); -``` - -[![Tremolo](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/tremolo.png)](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/big/tremolo.png) - -This will generate a sinusoid-shaped signal which effect is like a 'tremolo'. - -[![Tremolo Shape](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/tremoloshape.png)](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/big/tremoloshape.png) - -### Tremolo on real Audio Files - -Now we will show the tremolo effect in the real world, First, we use a file previously recorded by a male voice saying 'A'. The plot for this signal is the following: - -``` ->> [y,fs]=audioread('A.ogg'); ->> plot(y); -``` - -[![Vocal](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/avocalmale.png)](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/big/avocalmale.png) - -Now we have to create an enveloping sinusoidal signal with the following parameters: - -``` -Amplitude = 1 -Frequency= 1.5Hz -Phase = 0 -``` - -``` ->> t=0:1/fs:4.99999999; ->> t=t(:); ->> w=2*pi*1.5*t; ->> q=cos(w); ->> plot(q); -``` - -Note: when we create an array of values of the time, by default, this is created in the form of columns, ie, 1x220500 values. To multiply this set of values must transpose it in rows (220500x1). This is the t=t(:) command - -[![Sinusodial](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/sinusoidal.png)](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/big/sinusoidal.png) - -We will create a second ogg file which contains the resulting modulated signal: - -``` ->> tremolo='tremolo.ogg'; ->> audiowrite(tremolo, q.*y,fs); -``` - -[![](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/tremsignal1.png)](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/big/tremsignal1.png)[![Tremolo Signal](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/tremolsignal1.png)](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/big/tremolsignal1.png) - -### Frequency Variation - -We can vary the frequency to obtain quite interesting musical effects such as distortion, sound effects for movies and games among others. - -#### Effect of sinusoidal frequency modulation - -This is the code where the sinusoidal modulation frequency is shown, according to equation: - -``` -Y=Ac*Cos(wo*Cos(wo/k)) -``` - -Where: - -``` -Ac = Amplitude - -wo = fundamental frequency - -k = scalar divisor -``` - -``` ->> fm='fm.ogg'; ->> fs=44100; ->> t=0:1/fs:10; ->> w=2*pi*442*t; ->> audiowrite(fm, cos(cos(w/1500).*w), fs); ->> [y,fs]=audioread('fm.ogg'); ->> figure (); plot (y); -``` - -The plot of the signal is: - -[![](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/fmod.png)](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/big/fmod.png) - -You can use almost any type of periodic function as the frequency modulator. For this example, we only used a sine function here. Please feel free to experiment with changing the frequencies of the functions, mixing with other functions or change, even, the type of function. - --------------------------------------------------------------------------------- - -via: https://www.howtoforge.com/tutorial/ubuntu-octave-audio-processing-part-3/ - -作者:[David Duarte][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]: https://www.howtoforge.com/tutorial/ubuntu-octave-audio-processing-part-3/ From ca4aad1e2716630ce35ef0ab63499a9310fa4155 Mon Sep 17 00:00:00 2001 From: theArcticOcean <2722488604@qq.com> Date: Tue, 4 Oct 2016 22:43:52 +0800 Subject: [PATCH 015/316] 20160622 Part III - How to apply Advanced Mathematical Processing Effects on Audio files with Octave 4.0 on Ubuntu.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 翻译完成 --- ...n Audio files with Octave 4.0 on Ubuntu.md | 136 ++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 translated/tech/20160622 Part III - How to apply Advanced Mathematical Processing Effects on Audio files with Octave 4.0 on Ubuntu.md diff --git a/translated/tech/20160622 Part III - How to apply Advanced Mathematical Processing Effects on Audio files with Octave 4.0 on Ubuntu.md b/translated/tech/20160622 Part III - How to apply Advanced Mathematical Processing Effects on Audio files with Octave 4.0 on Ubuntu.md new file mode 100644 index 0000000000..f046a0b25f --- /dev/null +++ b/translated/tech/20160622 Part III - How to apply Advanced Mathematical Processing Effects on Audio files with Octave 4.0 on Ubuntu.md @@ -0,0 +1,136 @@ +第3部分 - 如何使用Ubuntu系统上Octave 4.0的先进数学技术处理音频文件 +===== + +我们的数字音频处理技术第三部分涵盖了信号调制内容,将解释如何进行调幅,颤音效果,和频率变化。 +### 调制 + +#### 调幅 + +正如它的名字暗示的那样, 影响正弦信号的振幅变化依据传递的信息不断改变。正弦波因为承载者大量的信息被称作载波。这种调制技术被用于许多的商业广播和市民信息传输波段(AM). + +#### 为何要使用调幅技术? + +**调制发射.** + +假设信道是免费资源,我们需要天线发射和接收信号。这要求有效的电磁信号发射天线,它的大小和要被发射的信号的波长应该是同一数量级。很多信号,包括音频成分,通常100赫兹或更少。对于这些信号,如果直接发射,我们就需要建立300公里的天线。如果信号调制用于在100MZ的高频载波中打印信息,那么天线仅仅需要1米(横向长度)。 + +**集中调制与多通道.** + +假设多个信号占用一个通道,可以调制不同的信号到接收特定信号的不同位置。使用集中调制(“复用”)的应用有遥感探测数据,立体声调频收音机和长途电话。 + +**克服设备限制的调制.** + +信号处理设备,比如过滤器,放大器,以及可以被重新创建的设备它们的性能依赖于信号在频域中的境况以及高频率和低频信号的关系。调制可以用于传递信号在频域中的位置,更容易满足设计的要求。调制也可以将“宽带信号“(高频和低频的比例很大的信号)转换成”窄带“信号 + +**音频特效** + +许多音频特效由于引人注目和处理信号的便捷性使用了调幅技术。我们可以说出很多,比如颤音、合唱、镶边等等。这种实用性就是我们关注它的原因。 + +### 颤音效果 + +颤音效果是调幅最简单的应用,为实现这样的效果,我们会用周期信号改变(乘)音频信号,使用正弦或其他。 + +``` +>> tremolo='tremolo.ogg'; +>> fs=44100; +>> t=0:1/fs:10; +>> wo=2*pi*440*t; +>> wa=2*pi*1.2*t; +>> audiowrite(tremolo, cos(wa).*cos(wo),fs); +``` + +[![Tremolo](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/tremolo.png)](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/big/tremolo.png) + +这将创造一个正弦形状的信号,它的效果就像‘颤音’。 + +[![Tremolo Shape](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/tremoloshape.png)](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/big/tremoloshape.png) + +### 在真实音频文件中的颤音 + +现在我们将展示真实世界中的颤音效果。首先,我们使用之前记录过男性发声‘A’的音频文件。这个信号图就像下面这样: + +``` +>> [y,fs]=audioread('A.ogg'); +>> plot(y); +``` + +[![Vocal](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/avocalmale.png)](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/big/avocalmale.png) + +现在我们将创建一个完整的正弦信号,使用如下的参数: + +``` +Amplitude = 1 +Frequency= 1.5Hz +Phase = 0 +``` + +``` +>> t=0:1/fs:4.99999999; +>> t=t(:); +>> w=2*pi*1.5*t; +>> q=cos(w); +>> plot(q); +``` + +注意: 当我们创建一组时间值时,默认情况下,它是以列的格式呈现,如, 1x220500的值。为了乘以这样的值,必须将其变成行的形式(220500x1). 这就是t=t(:)命令的作用。 + +[![Sinusodial](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/sinusoidal.png)](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/big/sinusoidal.png) + +我们将创建第二份ogg音频格式的文件,它包含了如下的调制信号: + +``` +>> tremolo='tremolo.ogg'; +>> audiowrite(tremolo, q.*y,fs); +``` + +[![](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/tremsignal1.png)](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/big/tremsignal1.png)[![Tremolo Signal](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/tremolsignal1.png)](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/big/tremolsignal1.png) + +### 频率变化 + +我们可以改变频率保持一些有趣的音效,比如原音变形,电影音效,多人比赛。 + +#### 正弦频率调制的影响 + +这是正弦调制频率变化的演示代码,根据方程: + +``` +Y=Ac*Cos(wo*Cos(wo/k)) +``` + +Where: + +``` +Ac = Amplitude + +wo = fundamental frequency + +k = scalar divisor +``` + +``` +>> fm='fm.ogg'; +>> fs=44100; +>> t=0:1/fs:10; +>> w=2*pi*442*t; +>> audiowrite(fm, cos(cos(w/1500).*w), fs); +>> [y,fs]=audioread('fm.ogg'); +>> figure (); plot (y); +``` + +信号图: + +[![](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/fmod.png)](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/big/fmod.png) + +你可以使用几乎任何类型的周期函数频率调制。本例中,我们仅仅用了一个正弦函数。请大胆的改变函数频率,用复合函数,甚至改变函数的类型。 + +-------------------------------------------------------------------------------- + +经由: https://www.howtoforge.com/tutorial/ubuntu-octave-audio-processing-part-3/ + +作者:[David Duarte][a] +译者:[theArcticOcean](https://github.com/theArcticOcean) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://www.howtoforge.com/tutorial/ubuntu-octave-audio-processing-part-3/ From 42671da94180293b73cc42d44f3c7c495cae0b19 Mon Sep 17 00:00:00 2001 From: bazz2 Date: Wed, 5 Oct 2016 15:49:00 +0800 Subject: [PATCH 016/316] [bazz2 append] Monitoring Docker Containers with Elasticsearch and cAdvisor.md --- ...tainers with Elasticsearch and cAdvisor.md | 276 ++++++++++++++++++ 1 file changed, 276 insertions(+) diff --git a/translated/tech/20160913 Monitoring Docker Containers with Elasticsearch and cAdvisor.md b/translated/tech/20160913 Monitoring Docker Containers with Elasticsearch and cAdvisor.md index 71781fa9a6..d79bdbef4e 100644 --- a/translated/tech/20160913 Monitoring Docker Containers with Elasticsearch and cAdvisor.md +++ b/translated/tech/20160913 Monitoring Docker Containers with Elasticsearch and cAdvisor.md @@ -177,6 +177,278 @@ chmod +x create-cluster.sh 最后集群部署好了。 +![](https://blog.codeship.com/wp-content/uploads/2016/09/cluster.png) + +现在为了验证 Swarm 模式集群已经正常运行,我们可以通过 ssh 登录进 master: + +``` +docker-machine ssh master1 +``` + +然后列出集群的节点: + +``` +docker node ls +``` + +``` +ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS +26fi3wiqr8lsidkjy69k031w2 * master1 Ready Active Leader +dyluxpq8sztj7kmwlzs51u4id worker2 Ready Active +epglndegvixag0jztarn2lte8 worker1 Ready Active +``` + +### 安装 Elasticsearch 和 Kibana + +> 注意,从现在开始所有的命令都运行在 master1 上。 + +在生产环境中,你可能会把 Elasticsearch 和 Kibana 安装在一个单独的、大小合适的实例集合中。但是在我们的实验中,我们还是把它们和 Swarm 模式集群安装在一起。 + +为了将 Elasticsearch 和 cAdvisor 连通,我们需要创建一个自定义的网络,因为我们使用了集群,并且容器可能会分布在不同的节点上,我们需要使用 [overlay][10] 网络(LCTT 译注:overlay 网络是指在不改变现有网络基础设施的前提下,通过某种约定通信协议,把二层报文封装在IP报文之上的新的数据格式,是目前最主流的容器跨节点数据传输和路由方案)。 + + +也许你会问,“为什么还要网络?我们不是可以用 LINK 吗?” 请考虑一下,自从引入用户定义网络后,LINK 机制就已经过时了。 + +以下内容摘自[此文档][11]: + +> 在 Docker network 特性出来以前,你可以使用 Docker link 特性实现容器互相发现、安全通信。而在 NETWORK 特性出来以后,你还可以使用 LINK,但是当容器处于默认桥接网络或用户自定义网络时,它们的表现是不一样的。 + +现在创建 overlay 网络,名称为 monitoring: + +``` +docker network create monitoring -d overlay +``` + +### Elasticsearch 容器 + +``` +docker service create --network=monitoring \ + --mount type=volume,target=/usr/share/elasticsearch/data \ + --constraint node.hostname==worker1 \ + --name elasticsearch elasticsearch:2.4.0 +``` + +注意 Elasticsearch 容器处于 worker1 节点,这是因为它运行时需要依赖 worker1 节点上挂载的卷。 + +### Kibana 容器 + +``` +docker service create --network=monitoring --name kibana -e ELASTICSEARCH_URL="http://elasticsearch:9200" -p 5601:5601 kibana:4.6.0 +``` + +如你所见,我们启动这两个容器时,都让它们加入 monitoring 网络,这样一来它们可以通过名称(如 elasticsearch 和 kibana)被(其他容器)访问。 + +现在,通过 [routing mesh][12] 机制,我们可以使用浏览器访问服务器的 IP 地址来查看 Kibana 报表界面。 + +获取 master1 实例的公共 IP 地址: + +``` +docker-machine ip master1 +``` + +打开浏览器输入地址:http://[master1 的 ip 地址]:5601/status + +所有项目都应该是绿色: + +![](https://blog.codeship.com/wp-content/uploads/2016/09/kibana-screenshot.png) + +让我们接下来开始收集数据! + +### 收集容器的运行数据 + +收集数据之前,我们需要创建一个服务,以全局模式运行 cAdvisor,为每个有效节点设置一个定时任务。 + +这个服务与 Elasticsearch 处于相同的网络,以便于 cAdvisor 可以推送数据给 Elasticsearch。 + +``` +docker service create --network=monitoring --mode global --name cadvisor \ + --mount type=bind,source=/,target=/rootfs,readonly=true \ + --mount type=bind,source=/var/run,target=/var/run,readonly=false \ + --mount type=bind,source=/sys,target=/sys,readonly=true \ + --mount type=bind,source=/var/lib/docker/,target=/var/lib/docker,readonly=true \ + google/cadvisor:latest \ + -storage_driver=elasticsearch \ + -storage_driver_es_host="http://elasticsearch:9200" +``` + +> 注意:如果你想配置 cAdvisor 选项,参考[这里][13]。 + +现在 cAdvisor 在发送数据给 Elasticsearch,我们通过定义一个索引模型来检索 Kibana 中的数据。两个方式做到这一点:通过 Kibana 或者通过 API,在这里我们使用 API 方式实现。 + +我们需要在一个运行中的容器中运行索引创建命令,你可以在 cAdvisor 容器中拿到 shell,不幸的是 Swarm 模式在开启服务时会在容器名称后面附加一个唯一的 ID 号,所以你需要手动指定 cAdvisor 容器的名称。 + +拿到 shell: + +``` +docker exec -ti sh +``` + +创建索引: + +``` +curl -XPUT http://elasticsearch:9200/.kibana/index-pattern/cadvisor -d '{"title" : "cadvisor*", "timeFieldName": "container_stats.timestamp"}' +``` + +如果你够懒,可以只执行下面这一句: + +``` +docker exec $(docker ps | grep cadvisor | awk '{print $1}' | head -1) curl -XPUT http://elasticsearch:9200/.kibana/index-pattern/cadvisor -d '{"title" : "cadvisor*", "timeFieldName": "container_stats.timestamp"}' +``` + +### 把数据汇总成报表 + +你现在可以使用 Kibana 来创建一份美观的报表了。但是不要着急,我为你们建了一份报表和一些图形界面来方便你们入门。 + +![](https://blog.codeship.com/wp-content/uploads/2016/09/dashboard.png) + +访问 Kibana 界面 => Setting => Objects => Import,然后选择包含以下内容的 JSON 文件,就可以导入我的配置信息了: + +``` +[ + { + "_id": "cAdvisor", + "_type": "dashboard", + "_source": { + "title": "cAdvisor", + "hits": 0, + "description": "", + "panelsJSON": "[{\"id\":\"Filesystem-usage\",\"type\":\"visualization\",\"panelIndex\":1,\"size_x\":6,\"size_y\":3,\"col\":1,\"row\":1},{\"id\":\"Memory-[Node-equal->Container]\",\"type\":\"visualization\",\"panelIndex\":2,\"size_x\":6,\"size_y\":4,\"col\":7,\"row\":4},{\"id\":\"memory-usage-by-machine\",\"type\":\"visualization\",\"panelIndex\":3,\"size_x\":6,\"size_y\":6,\"col\":1,\"row\":4},{\"id\":\"CPU-Total-Usage\",\"type\":\"visualization\",\"panelIndex\":4,\"size_x\":6,\"size_y\":5,\"col\":7,\"row\":8},{\"id\":\"Network-RX-TX\",\"type\":\"visualization\",\"panelIndex\":5,\"size_x\":6,\"size_y\":3,\"col\":7,\"row\":1}]", + "optionsJSON": "{\"darkTheme\":false}", + "uiStateJSON": "{}", + "version": 1, + "timeRestore": false, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[{\"query\":{\"query_string\":{\"query\":\"*\",\"analyze_wildcard\":true}}}]}" + } + } + }, + { + "_id": "Network", + "_type": "search", + "_source": { + "title": "Network", + "description": "", + "hits": 0, + "columns": [ + "machine_name", + "container_Name", + "container_stats.network.name", + "container_stats.network.interfaces", + "container_stats.network.rx_bytes", + "container_stats.network.rx_packets", + "container_stats.network.rx_dropped", + "container_stats.network.rx_errors", + "container_stats.network.tx_packets", + "container_stats.network.tx_bytes", + "container_stats.network.tx_dropped", + "container_stats.network.tx_errors" + ], + "sort": [ + "container_stats.timestamp", + "desc" + ], + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"cadvisor*\",\"query\":{\"query_string\":{\"analyze_wildcard\":true,\"query\":\"*\"}},\"highlight\":{\"pre_tags\":[\"@kibana-highlighted-field@\"],\"post_tags\":[\"@/kibana-highlighted-field@\"],\"fields\":{\"*\":{}},\"fragment_size\":2147483647},\"filter\":[]}" + } + } + }, + { + "_id": "Filesystem-usage", + "_type": "visualization", + "_source": { + "title": "Filesystem usage", + "visState": "{\"title\":\"Filesystem usage\",\"type\":\"histogram\",\"params\":{\"addLegend\":true,\"addTimeMarker\":false,\"addTooltip\":true,\"defaultYExtents\":false,\"mode\":\"stacked\",\"scale\":\"linear\",\"setYExtents\":false,\"shareYAxis\":true,\"times\":[],\"yAxis\":{}},\"aggs\":[{\"id\":\"1\",\"type\":\"avg\",\"schema\":\"metric\",\"params\":{\"field\":\"container_stats.filesystem.usage\",\"customLabel\":\"USED\"}},{\"id\":\"2\",\"type\":\"terms\",\"schema\":\"split\",\"params\":{\"field\":\"machine_name\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\",\"row\":false}},{\"id\":\"3\",\"type\":\"avg\",\"schema\":\"metric\",\"params\":{\"field\":\"container_stats.filesystem.capacity\",\"customLabel\":\"AVAIL\"}},{\"id\":\"4\",\"type\":\"terms\",\"schema\":\"segment\",\"params\":{\"field\":\"container_stats.filesystem.device\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}}],\"listeners\":{}}", + "uiStateJSON": "{\"vis\":{\"colors\":{\"Average container_stats.filesystem.available\":\"#E24D42\",\"Average container_stats.filesystem.base_usage\":\"#890F02\",\"Average container_stats.filesystem.capacity\":\"#3F6833\",\"Average container_stats.filesystem.usage\":\"#E24D42\",\"USED\":\"#BF1B00\",\"AVAIL\":\"#508642\"}}}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"cadvisor*\",\"query\":{\"query_string\":{\"analyze_wildcard\":true,\"query\":\"*\"}},\"filter\":[]}" + } + } + }, + { + "_id": "CPU-Total-Usage", + "_type": "visualization", + "_source": { + "title": "CPU Total Usage", + "visState": "{\"title\":\"CPU Total Usage\",\"type\":\"area\",\"params\":{\"shareYAxis\":true,\"addTooltip\":true,\"addLegend\":true,\"smoothLines\":false,\"scale\":\"linear\",\"interpolate\":\"linear\",\"mode\":\"stacked\",\"times\":[],\"addTimeMarker\":false,\"defaultYExtents\":false,\"setYExtents\":false,\"yAxis\":{}},\"aggs\":[{\"id\":\"1\",\"type\":\"avg\",\"schema\":\"metric\",\"params\":{\"field\":\"container_stats.cpu.usage.total\"}},{\"id\":\"2\",\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"container_stats.timestamp\",\"interval\":\"auto\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}},{\"id\":\"3\",\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"container_Name\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}},{\"id\":\"4\",\"type\":\"terms\",\"schema\":\"split\",\"params\":{\"field\":\"machine_name\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\",\"row\":true}}],\"listeners\":{}}", + "uiStateJSON": "{}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"cadvisor*\",\"query\":{\"query_string\":{\"query\":\"*\",\"analyze_wildcard\":true}},\"filter\":[]}" + } + } + }, + { + "_id": "memory-usage-by-machine", + "_type": "visualization", + "_source": { + "title": "Memory [Node]", + "visState": "{\"title\":\"Memory [Node]\",\"type\":\"area\",\"params\":{\"shareYAxis\":true,\"addTooltip\":true,\"addLegend\":true,\"smoothLines\":false,\"scale\":\"linear\",\"interpolate\":\"linear\",\"mode\":\"stacked\",\"times\":[],\"addTimeMarker\":false,\"defaultYExtents\":false,\"setYExtents\":false,\"yAxis\":{}},\"aggs\":[{\"id\":\"1\",\"type\":\"avg\",\"schema\":\"metric\",\"params\":{\"field\":\"container_stats.memory.usage\"}},{\"id\":\"2\",\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"container_stats.timestamp\",\"interval\":\"auto\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}},{\"id\":\"3\",\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"machine_name\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}}],\"listeners\":{}}", + "uiStateJSON": "{}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"cadvisor*\",\"query\":{\"query_string\":{\"query\":\"*\",\"analyze_wildcard\":true}},\"filter\":[]}" + } + } + }, + { + "_id": "Network-RX-TX", + "_type": "visualization", + "_source": { + "title": "Network RX TX", + "visState": "{\"title\":\"Network RX TX\",\"type\":\"histogram\",\"params\":{\"addLegend\":true,\"addTimeMarker\":true,\"addTooltip\":true,\"defaultYExtents\":false,\"mode\":\"stacked\",\"scale\":\"linear\",\"setYExtents\":false,\"shareYAxis\":true,\"times\":[],\"yAxis\":{}},\"aggs\":[{\"id\":\"1\",\"type\":\"avg\",\"schema\":\"metric\",\"params\":{\"field\":\"container_stats.network.rx_bytes\",\"customLabel\":\"RX\"}},{\"id\":\"2\",\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"container_stats.timestamp\",\"interval\":\"s\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}},{\"id\":\"3\",\"type\":\"avg\",\"schema\":\"metric\",\"params\":{\"field\":\"container_stats.network.tx_bytes\",\"customLabel\":\"TX\"}}],\"listeners\":{}}", + "uiStateJSON": "{\"vis\":{\"colors\":{\"RX\":\"#EAB839\",\"TX\":\"#BF1B00\"}}}", + "description": "", + "savedSearchId": "Network", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[]}" + } + } + }, + { + "_id": "Memory-[Node-equal->Container]", + "_type": "visualization", + "_source": { + "title": "Memory [Node=>Container]", + "visState": "{\"title\":\"Memory [Node=>Container]\",\"type\":\"area\",\"params\":{\"shareYAxis\":true,\"addTooltip\":true,\"addLegend\":true,\"smoothLines\":false,\"scale\":\"linear\",\"interpolate\":\"linear\",\"mode\":\"stacked\",\"times\":[],\"addTimeMarker\":false,\"defaultYExtents\":false,\"setYExtents\":false,\"yAxis\":{}},\"aggs\":[{\"id\":\"1\",\"type\":\"avg\",\"schema\":\"metric\",\"params\":{\"field\":\"container_stats.memory.usage\"}},{\"id\":\"2\",\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"container_stats.timestamp\",\"interval\":\"auto\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}},{\"id\":\"3\",\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"container_Name\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}},{\"id\":\"4\",\"type\":\"terms\",\"schema\":\"split\",\"params\":{\"field\":\"machine_name\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\",\"row\":true}}],\"listeners\":{}}", + "uiStateJSON": "{}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"cadvisor*\",\"query\":{\"query_string\":{\"query\":\"* NOT container_Name.raw: \\\\\\\"/\\\\\\\" AND NOT container_Name.raw: \\\\\\\"/docker\\\\\\\"\",\"analyze_wildcard\":true}},\"filter\":[]}" + } + } + } +] +``` + +这里还有很多东西可以玩,你也许想自定义报表界面,比如添加内存页错误状态,或者收发包的丢包数。如果你能实现开头列表处我没能实现的项目,那也是很好的。 + +### 总结 + +正确监控需要大量时间和精力,容器的 CPU、内存、IO、网络和磁盘,监控的这些参数还只是整个监控项目中的沧海一粟而已。 + +我不知道你执行到本文的哪一步,但接下来的任务也许是: + +- 收集容器的日志 +- 收集应用的日志 +- 监控应用的性能 +- 报警 +- 监控健康状态 + +如果你有意见或建议,请留言。祝你玩得开心。 + +现在你可以关掉基础架构了: + +``` +docker-machine rm master1 worker{1,2} +``` + -------------------------------------------------------------------------------- via: https://blog.codeship.com/monitoring-docker-containers-with-elasticsearch-and-cadvisor/ @@ -198,3 +470,7 @@ via: https://blog.codeship.com/monitoring-docker-containers-with-elasticsearch-a [7]: https://docs.docker.com/machine/install-machine/ [8]: https://cloud.digitalocean.com/settings/api/tokens/new [9]: https://blog.codeship.com/nginx-reverse-proxy-docker-swarm-clusters/ +[10]: https://docs.docker.com/engine/userguide/networking/get-started-overlay/ +[11]: https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/ +[12]: https://docs.docker.com/engine/swarm/ingress/ +[13]: https://github.com/google/cadvisor/blob/master/docs/runtime_options.md From 7be1a3c3c907b9636cb711c2e4c35b62edc9e37d Mon Sep 17 00:00:00 2001 From: wxy Date: Wed, 5 Oct 2016 21:13:57 +0800 Subject: [PATCH 017/316] PUB:20160913 Monitoring Docker Containers with Elasticsearch and cAdvisor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @bazz2 @jiajia9linuxer 干的漂亮! --- ...tainers with Elasticsearch and cAdvisor.md | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) rename {translated/tech => published}/20160913 Monitoring Docker Containers with Elasticsearch and cAdvisor.md (92%) diff --git a/translated/tech/20160913 Monitoring Docker Containers with Elasticsearch and cAdvisor.md b/published/20160913 Monitoring Docker Containers with Elasticsearch and cAdvisor.md similarity index 92% rename from translated/tech/20160913 Monitoring Docker Containers with Elasticsearch and cAdvisor.md rename to published/20160913 Monitoring Docker Containers with Elasticsearch and cAdvisor.md index d79bdbef4e..8f0cd9bdd2 100644 --- a/translated/tech/20160913 Monitoring Docker Containers with Elasticsearch and cAdvisor.md +++ b/published/20160913 Monitoring Docker Containers with Elasticsearch and cAdvisor.md @@ -15,7 +15,7 @@ 4. 一段时间内的通信峰值。 5. 孤儿卷和网络(LCTT 译注:孤儿卷就是当你删除容器时忘记删除它的卷,这个卷就不会再被使用,但会一直占用资源)。 6. 可用磁盘空间、可用 inode 数。 -7. 容器数量与连接在 docker0 和 docker_gwbridge 上的虚拟网卡数量不一致(LCTT 译注:当 docker 启动时,它会在宿主机器上创建一个名为 docker0 的虚拟网络接口)。 +7. 容器数量与连接在 `docker0` 和 `docker_gwbridge` 上的虚拟网卡数量不一致(LCTT 译注:当 docker 启动时,它会在宿主机器上创建一个名为 docker0 的虚拟网络接口)。 8. 开启和关闭 Swarm 节点。 9. 收集并集中处理日志。 @@ -200,18 +200,17 @@ epglndegvixag0jztarn2lte8 worker1 Ready Active ### 安装 Elasticsearch 和 Kibana -> 注意,从现在开始所有的命令都运行在 master1 上。 +> 注意,从现在开始所有的命令都运行在主节点 master1 上。 -在生产环境中,你可能会把 Elasticsearch 和 Kibana 安装在一个单独的、大小合适的实例集合中。但是在我们的实验中,我们还是把它们和 Swarm 模式集群安装在一起。 +在生产环境中,你可能会把 Elasticsearch 和 Kibana 安装在一个单独的、[大小合适][14]的实例集合中。但是在我们的实验中,我们还是把它们和 Swarm 模式集群安装在一起。 -为了将 Elasticsearch 和 cAdvisor 连通,我们需要创建一个自定义的网络,因为我们使用了集群,并且容器可能会分布在不同的节点上,我们需要使用 [overlay][10] 网络(LCTT 译注:overlay 网络是指在不改变现有网络基础设施的前提下,通过某种约定通信协议,把二层报文封装在IP报文之上的新的数据格式,是目前最主流的容器跨节点数据传输和路由方案)。 +为了将 Elasticsearch 和 cAdvisor 连通,我们需要创建一个自定义的网络,因为我们使用了集群,并且容器可能会分布在不同的节点上,我们需要使用 [overlay][10] 网络(LCTT 译注:overlay 网络是指在不改变现有网络基础设施的前提下,通过某种约定通信协议,把二层报文封装在 IP 报文之上的新的数据格式,是目前最主流的容器跨节点数据传输和路由方案)。 +也许你会问,“为什么还要网络?我们不是可以用 link 吗?” 请考虑一下,自从引入*用户定义网络*后,link 机制就已经过时了。 -也许你会问,“为什么还要网络?我们不是可以用 LINK 吗?” 请考虑一下,自从引入用户定义网络后,LINK 机制就已经过时了。 +以下内容摘自[ Docker 文档][11]: -以下内容摘自[此文档][11]: - -> 在 Docker network 特性出来以前,你可以使用 Docker link 特性实现容器互相发现、安全通信。而在 NETWORK 特性出来以后,你还可以使用 LINK,但是当容器处于默认桥接网络或用户自定义网络时,它们的表现是不一样的。 +> 在 Docker network 特性出来以前,你可以使用 Docker link 特性实现容器互相发现、安全通信。而在 network 特性出来以后,你还可以使用 link,但是当容器处于默认桥接网络或用户自定义网络时,它们的表现是不一样的。 现在创建 overlay 网络,名称为 monitoring: @@ -228,7 +227,7 @@ docker service create --network=monitoring \ --name elasticsearch elasticsearch:2.4.0 ``` -注意 Elasticsearch 容器处于 worker1 节点,这是因为它运行时需要依赖 worker1 节点上挂载的卷。 +注意 Elasticsearch 容器被限定在 worker1 节点,这是因为它运行时需要依赖 worker1 节点上挂载的卷。 ### Kibana 容器 @@ -236,7 +235,7 @@ docker service create --network=monitoring \ docker service create --network=monitoring --name kibana -e ELASTICSEARCH_URL="http://elasticsearch:9200" -p 5601:5601 kibana:4.6.0 ``` -如你所见,我们启动这两个容器时,都让它们加入 monitoring 网络,这样一来它们可以通过名称(如 elasticsearch 和 kibana)被(其他容器)访问。 +如你所见,我们启动这两个容器时,都让它们加入 monitoring 网络,这样一来它们可以通过名称(如 Kibana)被相同网络的其他服务访问。 现在,通过 [routing mesh][12] 机制,我们可以使用浏览器访问服务器的 IP 地址来查看 Kibana 报表界面。 @@ -246,7 +245,7 @@ docker service create --network=monitoring --name kibana -e ELASTICSEARCH_URL="h docker-machine ip master1 ``` -打开浏览器输入地址:http://[master1 的 ip 地址]:5601/status +打开浏览器输入地址:`http://[master1 的 ip 地址]:5601/status` 所有项目都应该是绿色: @@ -273,9 +272,9 @@ docker service create --network=monitoring --mode global --name cadvisor \ > 注意:如果你想配置 cAdvisor 选项,参考[这里][13]。 -现在 cAdvisor 在发送数据给 Elasticsearch,我们通过定义一个索引模型来检索 Kibana 中的数据。两个方式做到这一点:通过 Kibana 或者通过 API,在这里我们使用 API 方式实现。 +现在 cAdvisor 在发送数据给 Elasticsearch,我们通过定义一个索引模型来检索 Kibana 中的数据。有两种方式可以做到这一点:通过 Kibana 或者通过 API。在这里我们使用 API 方式实现。 -我们需要在一个运行中的容器中运行索引创建命令,你可以在 cAdvisor 容器中拿到 shell,不幸的是 Swarm 模式在开启服务时会在容器名称后面附加一个唯一的 ID 号,所以你需要手动指定 cAdvisor 容器的名称。 +我们需要在一个连接到 monitoring 网络的正在运行的容器中运行索引创建命令,你可以在 cAdvisor 容器中拿到 shell,不幸的是 Swarm 模式在开启服务时会在容器名称后面附加一个唯一的 ID 号,所以你需要手动指定 cAdvisor 容器的名称。 拿到 shell: @@ -433,9 +432,9 @@ docker exec $(docker ps | grep cadvisor | awk '{print $1}' | head -1) curl -XPUT 正确监控需要大量时间和精力,容器的 CPU、内存、IO、网络和磁盘,监控的这些参数还只是整个监控项目中的沧海一粟而已。 -我不知道你执行到本文的哪一步,但接下来的任务也许是: +我不知道你做到了哪一阶段,但接下来的任务也许是: -- 收集容器的日志 +- 收集运行中的容器的日志 - 收集应用的日志 - 监控应用的性能 - 报警 @@ -443,7 +442,7 @@ docker exec $(docker ps | grep cadvisor | awk '{print $1}' | head -1) curl -XPUT 如果你有意见或建议,请留言。祝你玩得开心。 -现在你可以关掉基础架构了: +现在你可以关掉这些测试系统了: ``` docker-machine rm master1 worker{1,2} @@ -474,3 +473,4 @@ via: https://blog.codeship.com/monitoring-docker-containers-with-elasticsearch-a [11]: https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/ [12]: https://docs.docker.com/engine/swarm/ingress/ [13]: https://github.com/google/cadvisor/blob/master/docs/runtime_options.md +[14]: https://www.elastic.co/blog/found-sizing-elasticsearch \ No newline at end of file From a3915e23e249736c67fa8fc81ec35460ecc5e40c Mon Sep 17 00:00:00 2001 From: GHLandy Date: Wed, 5 Oct 2016 13:58:51 +0000 Subject: [PATCH 018/316] =?UTF-8?q?=E5=8F=96=E6=B6=88=E7=BF=BB=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../talk/20160531 Linux vs. Windows device driver model.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sources/talk/20160531 Linux vs. Windows device driver model.md b/sources/talk/20160531 Linux vs. Windows device driver model.md index 9def01085b..2eda1e6927 100644 --- a/sources/talk/20160531 Linux vs. Windows device driver model.md +++ b/sources/talk/20160531 Linux vs. Windows device driver model.md @@ -1,5 +1,3 @@ -GHLandy Translating - Linux vs. Windows device driver model : architecture, APIs and build environment comparison ============================================================================================ @@ -179,7 +177,7 @@ Download this article as ad-free PDF (made possible by [your kind donation][2]): via: http://xmodulo.com/linux-vs-windows-device-driver-model.html 作者:[Dennis Turpitka][a] -译者:[GHLandy](https://github.com/GHLandy) +译者:[译者ID](https://github.com/译者ID) 校对:[校对者ID](https://github.com/校对者ID) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From 4efaaa47d6a6919bfbc3bfc32e6202ed377171a6 Mon Sep 17 00:00:00 2001 From: firstadream Date: Wed, 5 Oct 2016 22:15:04 +0800 Subject: [PATCH 019/316] Update 20160913 Ryver - Why You Should Be Using It instead of Slack.md --- ...0913 Ryver - Why You Should Be Using It instead of Slack.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20160913 Ryver - Why You Should Be Using It instead of Slack.md b/sources/tech/20160913 Ryver - Why You Should Be Using It instead of Slack.md index f4f4c54fcb..a576f65b1b 100644 --- a/sources/tech/20160913 Ryver - Why You Should Be Using It instead of Slack.md +++ b/sources/tech/20160913 Ryver - Why You Should Be Using It instead of Slack.md @@ -1,3 +1,5 @@ +firstadream is translating + Ryver: Why You Should Be Using It instead of Slack ===== From 19dd0ac48dd395832b3546841443cdc9fb93361a Mon Sep 17 00:00:00 2001 From: Bestony Date: Thu, 6 Oct 2016 15:12:16 +0800 Subject: [PATCH 020/316] =?UTF-8?q?=E8=AE=A4=E9=A2=86=E6=96=87=E7=AB=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ... How to Monitor Docker Containers using Grafana on Ubuntu.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/tech/20160809 How to Monitor Docker Containers using Grafana on Ubuntu.md b/sources/tech/20160809 How to Monitor Docker Containers using Grafana on Ubuntu.md index acdfff0b4f..1921705d03 100644 --- a/sources/tech/20160809 How to Monitor Docker Containers using Grafana on Ubuntu.md +++ b/sources/tech/20160809 How to Monitor Docker Containers using Grafana on Ubuntu.md @@ -1,4 +1,4 @@ -Being translated by ChrisLeeGit +Being translated by Bestony How to Monitor Docker Containers using Grafana on Ubuntu ================================================================================ From a97f79894302a17ed2604cbf8ab48d1ae422f312 Mon Sep 17 00:00:00 2001 From: wxy Date: Fri, 7 Oct 2016 11:20:25 +0800 Subject: [PATCH 021/316] =?UTF-8?q?=E6=A0=A1=E5=AF=B9=2020160823=20The=20i?= =?UTF-8?q?nfrastructure=20behind=20Twitter=20-=20=20efficiency=20and=20op?= =?UTF-8?q?timization?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @eriwoon 请确认 --- ... Twitter - efficiency and optimization.md | 71 +++++++++---------- 1 file changed, 32 insertions(+), 39 deletions(-) diff --git a/translated/tech/20160823 The infrastructure behind Twitter - efficiency and optimization.md b/translated/tech/20160823 The infrastructure behind Twitter - efficiency and optimization.md index 11d8040a4b..f47d262379 100644 --- a/translated/tech/20160823 The infrastructure behind Twitter - efficiency and optimization.md +++ b/translated/tech/20160823 The infrastructure behind Twitter - efficiency and optimization.md @@ -1,26 +1,26 @@ -Twitter背后的基础设施:效率与优化 +揭秘 Twitter 背后的基础设施:效率与优化篇 =========== -过去我们曾经发布过一些关于 [Finagle](https://twitter.github.io/finagle/) , [Manhattan](https://blog.twitter.com/2014/manhattan-our-real-time-multi-tenant-distributed-database-for-twitter-scale) 这些项目的文章,还写过一些针对大型事件活动的架构优化的文章,例如天空之城,超级碗, 2014 世界杯,全球新年夜庆祝活动等。在这篇基础设施系列文章中,我主要聚焦于 Twitter 的一些关键设施和组件。我也会写一些我们在系统的扩展性,可靠性,效率性方面的做过的改进,例如我们基础设施的历史,遇到过的挑战,学到的教训,做过的升级,以及我们现在前进的方向等等。 +过去我们曾经发布过一些关于 [Finagle](https://twitter.github.io/finagle/) 、[Manhattan](https://blog.twitter.com/2014/manhattan-our-real-time-multi-tenant-distributed-database-for-twitter-scale) 这些项目的文章,还写过一些针对大型事件活动的[架构优化](https://blog.twitter.com/2013/new-tweets-per-second-record-and-how)的文章,例如天空之城、超级碗、2014 世界杯、全球新年夜庆祝活动等。在这篇基础设施系列文章中,我主要聚焦于 Twitter 的一些关键设施和组件。我也会写一些我们在系统的扩展性、可靠性、效率方面的做过的改进,例如我们基础设施的历史,遇到过的挑战,学到的教训,做过的升级,以及我们现在前进的方向等等。 -> 天空之城:2013年8月2日,宫崎骏的《天空之城》在NTV迎来其第14次电视重播,剧情发展到高潮之时,Twitter的TPS(Tweets Per Second)也被推上了新的高度——143,199 TPS,是平均值的25倍,这个记录保持至今 -- 译者注。 +> 天空之城:2013 年 8 月 2 日,宫崎骏的《天空之城(Castle in the Sky)》在 NTV 迎来其第 14 次电视重播,剧情发展到高潮之时,Twitter 的 TPS(Tweets Per Second)也被推上了新的高度——143,199 TPS,是平均值的 25 倍,这个记录保持至今。-- LCTT 译注 ### 数据中心的效率优化 #### 历史 -当前Twitter硬件和数据中心的规模已经超过大多数公司。但达到这样的规模不是一蹴而就的,系统是随着软硬件的升级优化一步步成熟起来的,过程中我们也曾经犯过很多错误。 +当前 Twitter 硬件和数据中心的规模已经超过大多数公司。但达到这样的规模不是一蹴而就的,系统是随着软硬件的升级优化一步步成熟起来的,过程中我们也曾经犯过很多错误。 -有个一时期我们的系统故障不断。软件问题,硬件问题,甚至底层设备问题不断爆发,常常导致系统运营中断。随着 Twitter 在客户、服务、媒体上的影响力不断扩大,构建一个高效、可靠的系统来提供服务成为我们的战略诉求。 +有个一时期我们的系统故障不断。软件问题、硬件问题,甚至底层设备问题不断爆发,常常导致系统运营中断。出现故障的地方存在于各个方面,必须综合考虑才能确定其风险和受到影响的服务。随着 Twitter 在客户、服务、媒体上的影响力不断扩大,构建一个高效、可靠的系统来提供服务成为我们的战略诉求。 -> Twitter系统故障的界面被称为失败鲸(Fail Whale),如下图 -- 译者注 -![Fail Whale](https://upload.wikimedia.org/wikipedia/en/d/de/Failwhale.png) +> Twitter系统故障的界面被称为失败鲸(Fail Whale),如下图 -- LCTT 译注 +> ![Fail Whale](https://upload.wikimedia.org/wikipedia/en/d/de/Failwhale.png) #### 挑战 -一开始,我们的软件是直接安装在服务器,这意味着软件可靠性依赖硬件,电源、网络以及其他的环境因素都是威胁。这种情况下,如果要增加容错能力,就需要统筹考虑物理设备和在上面运行的服务。 +一开始,我们的软件是直接安装在服务器,这意味着软件可靠性依赖硬件,电源、网络以及其他的环境因素都是威胁。这种情况下,如果要增加容错能力,就需要统筹考虑这些互不关联的物理设备因素及在上面运行的服务。 -最早采购数据中心方案的时候,我们都还是菜鸟,对于站点选择、运营和设计都非常不专业。我们先直接租用主机,业务增长后我们改用主机托管。早期遇到的问题主要是因为设备故障、数据中心设计问题、维护问题以及人为操作失误。我们也在持续迭代我们的硬件设计,从而增强硬件和数据中心的容错性。 +最早采购数据中心方案的时候,我们都还是菜鸟,对于站点选择、运营和设计都非常不专业。我们先直接托管主机,业务增长后我们改用租赁机房。早期遇到的问题主要是因为设备故障、数据中心设计问题、维护问题以及人为操作失误。我们也在持续迭代我们的硬件设计,从而增强硬件和数据中心的容错性。 服务中断的原因有很多,其中硬件故障常发生在服务器、机架交换机、核心交换机这地方。举一个我们曾经犯过的错误,硬件团队最初在设计服务器的时候,认为双路电源对减少供电问题的意义不大 -- 他们真的就移除了一块电源。然而数据中心一般给机架提供两路供电来提高冗余性,防止电网故障传导到服务器,而这需要两块电源。最终我们不得不在机架上增加了一个 ATS 单元(AC transfer switch 交流切换开关)来接入第二路供电。 @@ -28,9 +28,9 @@ Twitter背后的基础设施:效率与优化 #### 我们学到的教训以及技术的升级、迁移和选型 -我们学到的第一个教训就是要先建模,将可能出故障的地方(例如建筑的供电和冷却系统、硬件、光线网络等)和运行在上面的服务之间的依赖关系弄清楚,这样才能更好地分析,从而优化设计提升容错能力。 +我们学到的第一个教训就是要先建模,将可能出故障的地方(例如建筑的供电和冷却系统、硬件、光纤网络等)和运行在上面的服务之间的依赖关系弄清楚,这样才能更好地分析,从而优化设计提升容错能力。 -我们增加了更多的数据中心提升地理容灾能力,减少自然灾害的影响。而且这种站点隔离也降低了软件的风险,减少了例如软件部署升级和系统故障的风险。这种多活的数据中心架构提供了代码灰度发布的能力,减少代码首次上线时候的影响。 +我们增加了更多的数据中心提升地理容灾能力,减少自然灾害的影响。而且这种站点隔离也降低了软件的风险,减少了例如软件部署升级和系统故障的风险。这种多活的数据中心架构提供了代码灰度发布(staged code deployment)的能力,减少代码首次上线时候的影响。 我们设计新硬件使之能够在更高温度下正常运行,数据中心的能源效率因此有所提升。 @@ -46,9 +46,9 @@ Twitter背后的基础设施:效率与优化 Twitter 是一个很大的公司,它对硬件的要求对任何团队来说都是一个不小的挑战。为了满足整个公司的需求,我们的首要工作是能检测并保证购买的硬件的品质。团队重点关注的是性能和可靠性这两部分。对于硬件我们会做系统性的测试来保证其性能可预测,保证尽量不引入新的问题。 -随着我们一些关键组件的负荷越来越大(如 Mesos , Hadoop , Manhattan , MySQL 等),市面上的产品已经无法满足我们的需求。同时供应商提供的一些高级服务器功能,例如 Raid 管理或者电源热切换等,可靠性提升很小,反而会拖累系统性能而且价格高昂,例如一些 Raid 控制器价格高达系统总报价的三分之一,还拖累了 SSD 的性能。 +随着我们一些关键组件的负荷越来越大(如 Mesos、Hadoop、Manhattan、MySQL 等),市面上的产品已经无法满足我们的需求。同时供应商提供的一些高级服务器功能,例如 Raid 管理或者电源热切换等,可靠性提升很小,反而会拖累系统性能而且价格高昂,例如一些 Raid 控制器价格高达系统总报价的三分之一,还拖累了 SSD 的性能。 -那时,我们也是 MySQL 数据库的一个大型用户。SAS(Serial Attached SCSI,串行连接 SCSI )设备的供应和性能都有很大的问题。我们大量使用 1 u 的服务器,它的驱动器和回写缓存一起也只能支撑每秒 2000 次顺序 IO。为了获得更好的效果,我们只得不断增加 CPU 核心数并加强磁盘能力。我们那时候找不到更节省成本的方案。 +那时,我们也是 MySQL 数据库的一个大型用户。SAS(Serial Attached SCSI,串行连接 SCSI )设备的供应和性能都有很大的问题。我们大量使用 1U 规格的服务器,它的磁盘和回写缓存一起也只能支撑每秒 2000 次的顺序 IO。为了获得更好的效果,我们只得不断增加 CPU 核心数并加强磁盘能力。我们那时候找不到更节省成本的方案。 后来随着我们对硬件需求越来越大,我们可以成立了一个硬件团队,从而自己来设计更便宜更高效的硬件。 @@ -58,62 +58,59 @@ Twitter 是一个很大的公司,它对硬件的要求对任何团队来说都 - 2012 - 采用 SSD 作为我们 MySQL 和 Key-Value 数据库的主要存储。 - 2013 - 我们开发了第一个定制版 Hadoop 工作站,它现在是我们主要的大容量存储方案。 -- 2013 - 我们定制的解决方案应用在 Mesos 、 TFE( Twitter Front-End )以及缓存设备上。 +- 2013 - 我们定制的解决方案应用在 Mesos、TFE( Twitter Front-End )以及缓存设备上。 - 2014 - 我们定制的 SSD Key-Value 服务器完成开发。 - 2015 - 我们定制的数据库解决方案完成开发。 - 2016 - 我们开发了一个 GPU 系统来做模糊推理和训练机器学习。 #### 学到的教训 -硬件团队的工作本质是通过做取舍来优化TCO(总体拥有成本),最终达到达到降低 CAPEX(资本支出)和 OPEX(运营支出)的目的。概括来说,服务器降成本就是: +硬件团队的工作本质是通过做取舍来优化 TCO(总体拥有成本),最终达到达到降低 CAPEX(资本支出)和 OPEX(运营支出)的目的。概括来说,服务器降成本就是: 1. 删除无用的功能和组件 2. 提升利用率 -Twitter 的设备总体来说有这四大类:存储设备、计算设备、数据库和 GPU 。 Twitter 对每一类都定义了详细的需求,让硬件工程师更针对性地设计产品,从而优化掉那些用不到或者极少用的冗余部分。例如,我们的存储设备就专门为 Hadoop 优化,设备的购买和运营成本相比于 OEM 产品降低了 20% 。同时,这样做减法还提高了设备的性能和可靠性。同样的,对于计算设备,硬件工程师们也通过移除无用的特性获得了效率提升。 +Twitter 的设备总体来说有这四大类:存储设备、计算设备、数据库和 GPU 。 Twitter 对每一类都定义了详细的需求,让硬件工程师更针对性地设计产品,从而优化掉那些用不到或者极少用的冗余部分。例如,我们的存储设备就专门为 Hadoop 优化过,设备的购买和运营成本相比于 OEM 产品降低了 20% 。同时,这样做减法还提高了设备的性能和可靠性。同样的,对于计算设备,硬件工程师们也通过移除无用的特性获得了效率提升。 一个服务器可以移除的组件总是有限的,我们很快就把能移除的都扔掉了。于是我们想出了其他办法,例如在存储设备里,我们认为降低成本最好的办法是用一个节点替换多个节点,并通过 Aurora/Mesos 来管理任务负载。这就是我们现在正在做的东西。 -对于这个我们自己新设计的服务器,首先要通过一系列的标准测试,然后会再做一系列负载测试,我们的目标是一台新设备至少能替换两台旧设备。大多数的提升都比较简单,例如增加 CPU 的进程数,同时我们的测试也比较出新 CPU 的 单线程能力提高了 20~50% ,对应能耗降低了 25% ,这都是我们测试环节需要做的工作。 +对于这个我们自己新设计的服务器,首先要通过一系列的标准测试,然后会再做一系列负载测试,我们的目标是一台新设备至少能替换两台旧设备。最大的性能提升来自增加 CPU 的线程数,我们的测试结果表示新 CPU 的 单线程能力提高了 20~50% 。同时由于整个服务器的线程数增加,我们看到单线程能效提升了 25%。 -这个新设备首次部署的时候,监控发现新设备只能替换 1.5 台旧设备,这比我们的目标低了很多。对性能数据检查后发现,我们之前新硬件的部分指标是错的,而这正是我们在做性能测试需要发现的问题。 +这个新设备首次部署的时候,监控发现新设备只能替换 1.5 台旧设备,这比我们的目标低了很多。对性能数据检查后发现,我们之前对负载特性的一些假定是有问题的,而这正是我们在做性能测试需要发现的问题。 -对此我们硬件团队开发了一个模型,用来预测在不同的硬件配置下当前 Aurora 任务的打包效率。这个模型正确的预测了新旧硬件的性能比例。模型还指出了我们一开始没有考虑到的存储需求,并因此建议我们增加 CPU 核心数。另外,它还预测,如果我们修改内存的配置,那系统的性能还会有较大提高。 +对此我们硬件团队开发了一个模型,用来预测在不同的硬件配置下当前 Aurora 任务的填充效率。这个模型正确的预测了新旧硬件的性能比例。模型还指出了我们一开始没有考虑到的存储需求,并因此建议我们增加 CPU 核心数。另外,它还预测,如果我们修改内存的配置,那系统的性能还会有较大提高。 -硬件配置的改变都需要花时间去操作,所以我们的硬件工程师们就首先找出几个关键痛点。例如我们和站点工程团队一起调整任务顺序来降低存储需求,这种修改很简单也很有效,新设备可以代替 1.85 个旧设备了。 +硬件配置的改变都需要花时间去操作,所以我们的硬件工程师们就首先找出几个关键痛点。例如我们和 SRE(Site Reliability Engineer,网站可靠性工程师)团队一起调整任务顺序来降低存储需求,这种修改很简单也很有效,新设备可以代替 1.85 个旧设备了。 -为了更好的优化效率,我们对新硬件的配置做了修改,扩大了内存和磁盘容量就将 CPU 利用率提高了20% ,而这只增加了非常小的成本。同时我们的硬件工程师也和生产的伙伴一起优化发货顺序来降低货运成本。后续的观察发现我们的自己的新设备实际上可以代替 2.4 台旧设备,这个超出了预定的目标。 +为了更好的优化效率,我们对新硬件的配置做了修改,只是扩大了内存和磁盘容量就将 CPU 利用率提高了20% ,而这只增加了非常小的成本。同时我们的硬件工程师也和合作生产厂商一起为那些服务器的最初出货调整了物料清单。后续的观察发现我们的自己的新设备实际上可以代替 2.4 台旧设备,这个超出了预定的目标。 ### 从裸设备迁移到 mesos 集群 -直到2012年为止,软件团队在 Twitter 开通一个新服务还需要自己操心硬件:配置硬件的规格需求,研究机架尺寸,开发部署脚本以及处理硬件故障。同时,系统中没有所谓的“服务发现”机制,当一个服务需要调用一个另一个服务时候,需要读取一个 YAML 配置文件,这个配置文件中有目标服务对应的主机 IP 和端口信息(端口信息是由一个公共 wiki 页面维护的)。随着硬件的替换和更新,YAML 配置文件里的内容也会不断的编辑更新。每次更新都需要花几个小时甚至几天来重启在各个服务,从而将新配置刷新到所有服务的缓存里,所以我们只能尽量一次增加多个配置并且按次序分别重启。我们经常遇到重启过程中 cache 不一致导致的问题,因为有的主机在使用旧的配置有的主机在用新的。有时候一台主机的异常(例如它正在重启)会导致整个站点都无法正常工作。 +直到 2012 年为止,软件团队在 Twitter 开通一个新服务还需要自己操心硬件:配置硬件的规格需求,研究机架尺寸,开发部署脚本以及处理硬件故障。同时,系统中没有所谓的“服务发现”机制,当一个服务需要调用一个另一个服务时候,需要读取一个 YAML 配置文件,这个配置文件中有目标服务对应的主机 IP 和端口信息(预留的端口信息是由一个公共 wiki 页面维护的)。随着硬件的替换和更新,YAML 配置文件里的内容也会不断的编辑更新。在缓存层做修改意味着我们可以按小时或按天做很多次部署,每次添加少量主机并按阶段部署。我们经常遇到在部署过程中 cache 不一致导致的问题,因为有的主机在使用旧的配置有的主机在用新的。有时候一台主机的异常(例如在部署过程中它临时宕机了)会导致整个站点都无法正常工作。 -在 2012/2013 年的时候,Twitter 开始尝试两个新事物:服务发现(来自 ZooKeeper 集群和 Finagle 核心模块中的一个库)和 Mesos(包括基于 Mesos 的一个自研的计划任务框架 Aurora ,它现在也是 Apache 基金会的一个项目)。 +在 2012/2013 年的时候,Twitter 开始尝试两个新事物:服务发现(来自 ZooKeeper 集群和 [Finagle](https://twitter.github.io/finagle/) 核心模块中的一个库)和 [Mesos](http://mesos.apache.org/)(包括基于 Mesos 的一个自研的计划任务框架 Aurora ,它现在也是 Apache 基金会的一个项目)。 服务发现功能意味着不需要再维护一个静态 YAML 主机列表了。服务或者在启动后主动注册,或者自动被 mesos 接入到一个“服务集”(就是一个 ZooKeeper 中的 znode 列表,包含角色、环境和服务名信息)中。任何想要访问这个服务的组件都只需要监控这个路径就可以实时获取到一个正在工作的服务列表。 -现在我们通过 Mesos/Aurora ,而不是使用脚本(我们曾经是 Capistrano 的重度用户)来获取一个主机列表、分发代码并规划重启任务。现在软件团队如果想部署一个新服务,只需要将软件包上传到一个叫 Packer 的工具上(它是一个基于 HDFS 的服务),再在 Aurora 配置上描述文件(需要多少 CPU ,多少内存,多少个实例,启动的命令行代码),然后 Aurora 就会自动完成整个部署过程。 Aurora 先找到可用的主机,从 Packer 下载代码,注册到“服务发现”,最后启动这个服务。如果整个过程中遇到失败(硬件故障、网络中断等等), Mesos/Aurora 会自动重选一个新主机并将服务部署上去。 +现在我们通过 Mesos/Aurora ,而不是使用脚本(我们曾经是 [Capistrano](https://github.com/capistrano/capistrano) 的重度用户)来获取一个主机列表、分发代码并规划重启任务。现在软件团队如果想部署一个新服务,只需要将软件包上传到一个叫 Packer 的工具上(它是一个基于 HDFS 的服务),再在 Aurora 配置上描述文件(需要多少 CPU ,多少内存,多少个实例,启动的命令行代码),然后 Aurora 就会自动完成整个部署过程。 Aurora 先找到可用的主机,从 Packer 下载代码,注册到“服务发现”,最后启动这个服务。如果整个过程中遇到失败(硬件故障、网络中断等等), Mesos/Aurora 会自动重选一个新主机并将服务部署上去。 #### Twitter 的私有 PaaS 云平台 -Mesos/Aurora 和服务发现这两个功能给我们带了革命性的变化。虽然在接下来几年里,我们碰到了无数 bug ,伤透了无数脑筋,学到了分布式系统里的无数教训,但是这套架还是非常赞的。以前大家一直忙于处理硬件搭配和管理,而现在,大家只需要考虑如何优化业务以及需要多少系统能力就可以了。同时,我们也从根本上解决了 CPU 利用率低的问题,以前服务直接安装在服务器上,这种方式无法充分利用服务器资源,任务协调能力也很差。现在 Mesos 允许我们把多个服务打包成一个服务包,增加一个新服务只需要修改硬件配额,再改一行配置就可以了。 +Mesos/Aurora 和服务发现这两个功能给我们带了革命性的变化。虽然在接下来几年里,我们碰到了无数 bug ,伤透了无数脑筋,学到了分布式系统里的无数教训,但是这套架还是非常赞的。以前大家一直忙于处理硬件搭配和管理,而现在,大家只需要考虑如何优化业务以及需要多少系统能力就可以了。同时,我们也从根本上解决了 Twitter 之前经历过的 CPU 利用率低的问题,以前服务直接安装在服务器上,这种方式无法充分利用服务器资源,任务协调能力也很差。现在 Mesos 允许我们把多个服务打包成一个服务包,增加一个新服务只需要修改配额,再改一行配置就可以了。 -在两年时间里,多数“无状态”服务迁移到了 Mesos 平台。一些大型且重要的服务(包括我们的用户服务和广告服务)是最先迁移上去的。因为它们的体量巨大,所以他们从这些服务里获得的好处也最多。 +在两年时间里,多数“无状态”服务迁移到了 Mesos 平台。一些大型且重要的服务(包括我们的用户服务和广告服务系统)是最先迁移上去的。因为它们的体量巨大,所以它们从这些服务里获得的好处也最多,这也降低了它们的服务压力。 我们一直在不断追求效率提升和架构优化的最佳实践。我们会定期去测试公有云的产品,和我们自己产品的 TCO 以及性能做对比。我们也拥抱公有云的服务,事实上我们现在正在使用公有云产品。最后,这个系列的下一篇将会主要聚焦于我们基础设施的体量方面。 -特别感谢 Jennifer Fraser, David Barr, Geoff Papilion, Matt Singer, Lam Dong 对这篇文章的贡献。 - - - +特别感谢 [Jennifer Fraser][1]、[David Barr][2]、[Geoff Papilion][3]、 [Matt Singer][4]、[Lam Dong][5] 对这篇文章的贡献。 -------------------------------------------------------------------------------- -via: https://blog.twitter.com/2016/the-infrastructure-behind-twitter-efficiency-and-optimization?utm_source=webopsweekly&utm_medium=email +via: https://blog.twitter.com/2016/the-infrastructure-behind-twitter-efficiency-and-optimization 作者:[mazdakh][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) +译者:[eriwoon](https://github.com/eriwoon) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 @@ -121,9 +118,5 @@ via: https://blog.twitter.com/2016/the-infrastructure-behind-twitter-efficiency- [1]: https://twitter.com/jenniferfraser [2]: https://twitter.com/davebarr [3]: https://twitter.com/gpapilion -[4]: https://twitter.com/lamdong - - - - - +[4]: https://twitter.com/mattbytes +[5]: https://twitter.com/lamdong \ No newline at end of file From 10f786169897ee17f8f6bfb768ed090197791681 Mon Sep 17 00:00:00 2001 From: firstadream Date: Fri, 7 Oct 2016 23:17:57 +0800 Subject: [PATCH 022/316] Update 20160913 Ryver - Why You Should Be Using It instead of Slack.md --- ...You Should Be Using It instead of Slack.md | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/sources/tech/20160913 Ryver - Why You Should Be Using It instead of Slack.md b/sources/tech/20160913 Ryver - Why You Should Be Using It instead of Slack.md index a576f65b1b..b8c95935a9 100644 --- a/sources/tech/20160913 Ryver - Why You Should Be Using It instead of Slack.md +++ b/sources/tech/20160913 Ryver - Why You Should Be Using It instead of Slack.md @@ -1,62 +1,62 @@ -firstadream is translating -Ryver: Why You Should Be Using It instead of Slack +为什么你应该使用Ryver弃用Slack? ===== +貌似每个人都听说过Slack,它是一款跨平台的,可以使你时刻保持与他人同步的团队沟通应用。它革新了用户讨论和计划项目的方式,显而易见,它升级了email的沟通功能。 -It seems like everyone has heard of Slack, a team communication tool that can be used across multiple platforms to stay in the loop. It has revolutionised the way users discuss and plan projects, and it’s a clear upgrade to emails. +我在一个非常小的写作团队工作,不管是通过手机还是电脑,我从未在使用Slack过程中遇到过沟通问题。若想与任何规模的团队保持同步,继续使用Slack仍然不失为不错的方式。 -I work in small writing teams, and I’ve never had a problem with communicating with others on my phone or computer while using it. If you want to keep up to date with team of any size, it’s a great way to stay in the loop. +既然如此,为什么我们还要讨论今天的话题?相比Slack,Ryver提供升级版的服务,这被认为是下一个大事件。Ryver完全免费,它的团队正在奋力争取更大的市场份额。 -So, why are we here? Ryver is supposed to be the next big thing, offering an upgraded service in comparison to Slack. It’s completely free, and they’re pushing for a larger share of the market. +是否Ryver已经强大到可以扮演Slack杀手的角色?这两种旗鼓相当的消息应用究竟有何不同? -Is it good enough to be a Slack-Killer? What are the differences between two similar sounding services? +想了解更多,请阅读下文。 -Read on to find out more. -### Why Ryver? +###为什么是Ryver ? ![](https://maketecheasier-2d0f.kxcdn.com/assets/uploads/2016/04/Ryver.jpg) -Why mess with something that works? The developers at Ryver are well aware of Slack, and they’re hoping their improved service will be enough to make you switch over. They promise a completely free team-communication service with no hidden charges along the way. +为什么运行正常的功能仍然会引起混乱?Ryver的开发者对Slack的功能滚瓜烂熟,他们希望Ryver改进的服务足以让你移情别恋。他们承诺Ryver提供完全免费的团队沟通服务,并且不会在任何一个环节隐形收费。 -Thankfully, they deliver on their main aim with a high quality product. +谢天谢地,他们用高质量产品兑现了自己的承诺。 -Extra content is the name of the game, and they promise to remove some of the limits you’ll find on a free account with Slack. Unlimited data storage is a major plus point, and it’s also more open in a number of ways. If storage limits are an issue for you, you have to check out Ryver. +额外的内容是关键所在,他们承诺删除一些你在Slack免费账号上面的限制。无限的存储空间是一个加分点,除此之外,在许多其他方面Ryver也更加开放。如果存储空间限制对你来说是个痛点,不防试试Ryver。 -It’s a simple system to use, as it was built so that all functions are always one click away. It’s a mantra used to great success by Apple, and there aren’t many growing pains when you first get started. +这是一个简单易用的系统,所有的功能都可以一键搞定。这种设计哲学使Apple大获成功,当你开始使用后,也不会遭遇成长的烦恼。 ![](https://maketecheasier-2d0f.kxcdn.com/assets/uploads/2016/09/ryver-web-interface.png) -Conversations are split between personal chats and public posts, and it means there’s a clear line between team platforms and personal use. It should help to avoid broadcasting any embarrassing announcements to your colleagues, and I’ve seen a few during my time as a Slack user. +会话区分私聊和公示,这意味着团队平台和私人应用有明确的界限。它应该有助于避免广播任何尴尬的公告给你的同事,这些我在使用Slack期间都遇到过。 -Integration with a number of existing apps is supported, and there are native applications for most platforms. +Ryver支持与大量已有App的集成,并有大多数平台的原生应用程序 。 -You can add guests when needed at no additional cost, and it’s useful if you deal with external clients regularly. Guests can add more guests, so there’s an element of fluidity that isn’t seen with the more popular option. +在需要时你可以添加额外客户而无需增加费用,如果你经常和外部客户打交道,这将是一个非常有用的功能。客户可以增加更多客户,这种流动性的元素是无法从其他更流行的消息应用中看到的。 -Think of Ryver as a completely different service that will cater to different needs. If you need to deal with numerous clients on the same account, it’s worth trying out. +考虑到Ryver是一个为迎合不同需求而产生的完全不同的服务。如果你需要一个账户来处理多种客户,Ryver值得一试。 -The question is how is it free? The quick answer is premium users will be paying your way. Like Spotify and other services, there’s a minority paying for the rest of us. Here’s a direct link to their download page if you’re interested in giving it a go. +问题是它是如何做到免费的? 快速的答案是高级用户将为你付费。 像Spotify和其他应用一样,有一小部分人为我们其他人支付费用。 这里有一个直接链接到他们的下载页面的地址,如果有兴趣就去试一试吧。 -### Should You Switch to Ryver? +###你应该切换到Ryver吗? ![](https://maketecheasier-2d0f.kxcdn.com/assets/uploads/2016/04/Slack-homepage.jpg) -Slack is great as long as you stick to smaller teams like I do, but Ryver has a lot to offer. The idea of a completely free team messaging program is noble, and it works perfectly. +像我一样在小团队使用Slack的体验还是非常棒,但是Ryver可以给予更多。一个完全免费的消息应用程序的想法不可谓不宏伟,更何况它工作的十分完美。 -There’s nothing wrong with using both, so make sure to try out the competition if you’re not willing to pay for a premium Slack account. You might find that both are better in different situations, depending on what you need. +同时使用两种消息应用也无可厚非,但是如果你不愿意支付一个溢价的Slack账户,一定要尝试一下竞争对手的服务。你可能会发现,在不同的情况下,两者都更好,这取决于你需要什么。 -Above all, Ryver is a great free alternative, and it’s more than just a Slack clone. They have a clear idea of what they’re trying to achieve, and they have a decent product that offers something different in a crowded marketplace. +最重要的是,Ryver是一个伟大的免费替代品,它不仅仅是一个Slack克隆。 他们清楚地知道他们想要实现什么,他们有一个体面的产品,在一个拥挤不堪的市场提供不同的东西。 -However, there’s a chance that it will disappear if there’s a sustained lack of funding in the future. It could leave your teams and discussions in disarray. Everything is fine for now, but be careful if you plan to export a larger business over to the new upstart. +但是,如果将来持续缺乏资金,Ryver有可能消失。 它可能会让你的团队和讨论陷入混乱。 目前一切还好,但是如果你计划把更大的业务委托给这个新贵还是需要三思而行。 -If you’re tired of Slack’s limitations on a free account, you’ll be impressed by what Ryver has to offer. To learn more, check out their website for information about the service. + +如果你厌倦了Slack对一个免费帐户的限制,你会对Ryver印象深刻。 要了解更多,请访问其网站以获取有关服务的信息。 -------------------------------------------------------------------------------- via: https://www.maketecheasier.com/why-use-ryver-instead-of-slack/?utm_medium=feed&utm_source=feedpress.me&utm_campaign=Feed%3A+maketecheasier 作者:[James Milin-Ashmore][a] -译者:[译者ID](https://github.com/译者ID) +译者:[firstadream](https://github.com/firstadream) 校对:[校对者ID](https://github.com/校对者ID) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From e3da72cbbe80e608199b67016c11d44f55ae5d59 Mon Sep 17 00:00:00 2001 From: FrankXinqi Date: Fri, 7 Oct 2016 23:20:11 +0800 Subject: [PATCH 023/316] =?UTF-8?q?=E3=80=90=E6=AD=A3=E5=9C=A8=E7=BF=BB?= =?UTF-8?q?=E8=AF=91=E3=80=9120160531=20Linux=20vs.=20Windows=20device=20d?= =?UTF-8?q?river=20model.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sources/talk/20160531 Linux vs. Windows device driver model.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/talk/20160531 Linux vs. Windows device driver model.md b/sources/talk/20160531 Linux vs. Windows device driver model.md index 2eda1e6927..706c18dd09 100644 --- a/sources/talk/20160531 Linux vs. Windows device driver model.md +++ b/sources/talk/20160531 Linux vs. Windows device driver model.md @@ -1,3 +1,5 @@ +Editing by FrankXinqi + Linux vs. Windows device driver model : architecture, APIs and build environment comparison ============================================================================================ From 91402ac92e5cd270c7b258ed95ac2d861a6d22e3 Mon Sep 17 00:00:00 2001 From: firstadream Date: Fri, 7 Oct 2016 23:35:29 +0800 Subject: [PATCH 024/316] Create 20160913 Ryver - Why You Should Be Using It instead of Slack.md --- ...You Should Be Using It instead of Slack.md | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 translated/tech/20160913 Ryver - Why You Should Be Using It instead of Slack.md diff --git a/translated/tech/20160913 Ryver - Why You Should Be Using It instead of Slack.md b/translated/tech/20160913 Ryver - Why You Should Be Using It instead of Slack.md new file mode 100644 index 0000000000..b8c95935a9 --- /dev/null +++ b/translated/tech/20160913 Ryver - Why You Should Be Using It instead of Slack.md @@ -0,0 +1,64 @@ + +为什么你应该使用Ryver弃用Slack? +===== +貌似每个人都听说过Slack,它是一款跨平台的,可以使你时刻保持与他人同步的团队沟通应用。它革新了用户讨论和计划项目的方式,显而易见,它升级了email的沟通功能。 + +我在一个非常小的写作团队工作,不管是通过手机还是电脑,我从未在使用Slack过程中遇到过沟通问题。若想与任何规模的团队保持同步,继续使用Slack仍然不失为不错的方式。 + +既然如此,为什么我们还要讨论今天的话题?相比Slack,Ryver提供升级版的服务,这被认为是下一个大事件。Ryver完全免费,它的团队正在奋力争取更大的市场份额。 + +是否Ryver已经强大到可以扮演Slack杀手的角色?这两种旗鼓相当的消息应用究竟有何不同? + +想了解更多,请阅读下文。 + + +###为什么是Ryver ? + +![](https://maketecheasier-2d0f.kxcdn.com/assets/uploads/2016/04/Ryver.jpg) + +为什么运行正常的功能仍然会引起混乱?Ryver的开发者对Slack的功能滚瓜烂熟,他们希望Ryver改进的服务足以让你移情别恋。他们承诺Ryver提供完全免费的团队沟通服务,并且不会在任何一个环节隐形收费。 + +谢天谢地,他们用高质量产品兑现了自己的承诺。 + +额外的内容是关键所在,他们承诺删除一些你在Slack免费账号上面的限制。无限的存储空间是一个加分点,除此之外,在许多其他方面Ryver也更加开放。如果存储空间限制对你来说是个痛点,不防试试Ryver。 + +这是一个简单易用的系统,所有的功能都可以一键搞定。这种设计哲学使Apple大获成功,当你开始使用后,也不会遭遇成长的烦恼。 + +![](https://maketecheasier-2d0f.kxcdn.com/assets/uploads/2016/09/ryver-web-interface.png) + +会话区分私聊和公示,这意味着团队平台和私人应用有明确的界限。它应该有助于避免广播任何尴尬的公告给你的同事,这些我在使用Slack期间都遇到过。 + +Ryver支持与大量已有App的集成,并有大多数平台的原生应用程序 。 + +在需要时你可以添加额外客户而无需增加费用,如果你经常和外部客户打交道,这将是一个非常有用的功能。客户可以增加更多客户,这种流动性的元素是无法从其他更流行的消息应用中看到的。 + +考虑到Ryver是一个为迎合不同需求而产生的完全不同的服务。如果你需要一个账户来处理多种客户,Ryver值得一试。 + +问题是它是如何做到免费的? 快速的答案是高级用户将为你付费。 像Spotify和其他应用一样,有一小部分人为我们其他人支付费用。 这里有一个直接链接到他们的下载页面的地址,如果有兴趣就去试一试吧。 + +###你应该切换到Ryver吗? + +![](https://maketecheasier-2d0f.kxcdn.com/assets/uploads/2016/04/Slack-homepage.jpg) + +像我一样在小团队使用Slack的体验还是非常棒,但是Ryver可以给予更多。一个完全免费的消息应用程序的想法不可谓不宏伟,更何况它工作的十分完美。 + +同时使用两种消息应用也无可厚非,但是如果你不愿意支付一个溢价的Slack账户,一定要尝试一下竞争对手的服务。你可能会发现,在不同的情况下,两者都更好,这取决于你需要什么。 + +最重要的是,Ryver是一个伟大的免费替代品,它不仅仅是一个Slack克隆。 他们清楚地知道他们想要实现什么,他们有一个体面的产品,在一个拥挤不堪的市场提供不同的东西。 + +但是,如果将来持续缺乏资金,Ryver有可能消失。 它可能会让你的团队和讨论陷入混乱。 目前一切还好,但是如果你计划把更大的业务委托给这个新贵还是需要三思而行。 + + +如果你厌倦了Slack对一个免费帐户的限制,你会对Ryver印象深刻。 要了解更多,请访问其网站以获取有关服务的信息。 + +-------------------------------------------------------------------------------- + +via: https://www.maketecheasier.com/why-use-ryver-instead-of-slack/?utm_medium=feed&utm_source=feedpress.me&utm_campaign=Feed%3A+maketecheasier + +作者:[James Milin-Ashmore][a] +译者:[firstadream](https://github.com/firstadream) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://www.maketecheasier.com/author/james-ashmore/ From c7c8f4afd92494e2c4da2559f3c85a1b91822cd9 Mon Sep 17 00:00:00 2001 From: firstadream Date: Fri, 7 Oct 2016 23:36:23 +0800 Subject: [PATCH 025/316] Delete 20160913 Ryver - Why You Should Be Using It instead of Slack.md --- ...You Should Be Using It instead of Slack.md | 64 ------------------- 1 file changed, 64 deletions(-) delete mode 100644 sources/tech/20160913 Ryver - Why You Should Be Using It instead of Slack.md diff --git a/sources/tech/20160913 Ryver - Why You Should Be Using It instead of Slack.md b/sources/tech/20160913 Ryver - Why You Should Be Using It instead of Slack.md deleted file mode 100644 index b8c95935a9..0000000000 --- a/sources/tech/20160913 Ryver - Why You Should Be Using It instead of Slack.md +++ /dev/null @@ -1,64 +0,0 @@ - -为什么你应该使用Ryver弃用Slack? -===== -貌似每个人都听说过Slack,它是一款跨平台的,可以使你时刻保持与他人同步的团队沟通应用。它革新了用户讨论和计划项目的方式,显而易见,它升级了email的沟通功能。 - -我在一个非常小的写作团队工作,不管是通过手机还是电脑,我从未在使用Slack过程中遇到过沟通问题。若想与任何规模的团队保持同步,继续使用Slack仍然不失为不错的方式。 - -既然如此,为什么我们还要讨论今天的话题?相比Slack,Ryver提供升级版的服务,这被认为是下一个大事件。Ryver完全免费,它的团队正在奋力争取更大的市场份额。 - -是否Ryver已经强大到可以扮演Slack杀手的角色?这两种旗鼓相当的消息应用究竟有何不同? - -想了解更多,请阅读下文。 - - -###为什么是Ryver ? - -![](https://maketecheasier-2d0f.kxcdn.com/assets/uploads/2016/04/Ryver.jpg) - -为什么运行正常的功能仍然会引起混乱?Ryver的开发者对Slack的功能滚瓜烂熟,他们希望Ryver改进的服务足以让你移情别恋。他们承诺Ryver提供完全免费的团队沟通服务,并且不会在任何一个环节隐形收费。 - -谢天谢地,他们用高质量产品兑现了自己的承诺。 - -额外的内容是关键所在,他们承诺删除一些你在Slack免费账号上面的限制。无限的存储空间是一个加分点,除此之外,在许多其他方面Ryver也更加开放。如果存储空间限制对你来说是个痛点,不防试试Ryver。 - -这是一个简单易用的系统,所有的功能都可以一键搞定。这种设计哲学使Apple大获成功,当你开始使用后,也不会遭遇成长的烦恼。 - -![](https://maketecheasier-2d0f.kxcdn.com/assets/uploads/2016/09/ryver-web-interface.png) - -会话区分私聊和公示,这意味着团队平台和私人应用有明确的界限。它应该有助于避免广播任何尴尬的公告给你的同事,这些我在使用Slack期间都遇到过。 - -Ryver支持与大量已有App的集成,并有大多数平台的原生应用程序 。 - -在需要时你可以添加额外客户而无需增加费用,如果你经常和外部客户打交道,这将是一个非常有用的功能。客户可以增加更多客户,这种流动性的元素是无法从其他更流行的消息应用中看到的。 - -考虑到Ryver是一个为迎合不同需求而产生的完全不同的服务。如果你需要一个账户来处理多种客户,Ryver值得一试。 - -问题是它是如何做到免费的? 快速的答案是高级用户将为你付费。 像Spotify和其他应用一样,有一小部分人为我们其他人支付费用。 这里有一个直接链接到他们的下载页面的地址,如果有兴趣就去试一试吧。 - -###你应该切换到Ryver吗? - -![](https://maketecheasier-2d0f.kxcdn.com/assets/uploads/2016/04/Slack-homepage.jpg) - -像我一样在小团队使用Slack的体验还是非常棒,但是Ryver可以给予更多。一个完全免费的消息应用程序的想法不可谓不宏伟,更何况它工作的十分完美。 - -同时使用两种消息应用也无可厚非,但是如果你不愿意支付一个溢价的Slack账户,一定要尝试一下竞争对手的服务。你可能会发现,在不同的情况下,两者都更好,这取决于你需要什么。 - -最重要的是,Ryver是一个伟大的免费替代品,它不仅仅是一个Slack克隆。 他们清楚地知道他们想要实现什么,他们有一个体面的产品,在一个拥挤不堪的市场提供不同的东西。 - -但是,如果将来持续缺乏资金,Ryver有可能消失。 它可能会让你的团队和讨论陷入混乱。 目前一切还好,但是如果你计划把更大的业务委托给这个新贵还是需要三思而行。 - - -如果你厌倦了Slack对一个免费帐户的限制,你会对Ryver印象深刻。 要了解更多,请访问其网站以获取有关服务的信息。 - --------------------------------------------------------------------------------- - -via: https://www.maketecheasier.com/why-use-ryver-instead-of-slack/?utm_medium=feed&utm_source=feedpress.me&utm_campaign=Feed%3A+maketecheasier - -作者:[James Milin-Ashmore][a] -译者:[firstadream](https://github.com/firstadream) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]: https://www.maketecheasier.com/author/james-ashmore/ From 6b8ce69c337badc03e1b446b274e32b44a9d5206 Mon Sep 17 00:00:00 2001 From: Bestony Date: Sat, 8 Oct 2016 07:10:15 +0800 Subject: [PATCH 026/316] =?UTF-8?q?=E7=BF=BB=E8=AF=91=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...cker Containers using Grafana on Ubuntu.md | 150 +++++++++--------- 1 file changed, 75 insertions(+), 75 deletions(-) diff --git a/sources/tech/20160809 How to Monitor Docker Containers using Grafana on Ubuntu.md b/sources/tech/20160809 How to Monitor Docker Containers using Grafana on Ubuntu.md index 1921705d03..271045617a 100644 --- a/sources/tech/20160809 How to Monitor Docker Containers using Grafana on Ubuntu.md +++ b/sources/tech/20160809 How to Monitor Docker Containers using Grafana on Ubuntu.md @@ -1,22 +1,20 @@ -Being translated by Bestony -How to Monitor Docker Containers using Grafana on Ubuntu -================================================================================ +# 如何在 Ubuntu 上使用 Grafana 监控 Docker -Grafana is an open source feature rich metrics dashboard. It is very useful for visualizing large-scale measurement data. It provides a powerful and elegant way to create, share, and explore data and dashboards from your disparate metric databases. +Grafana 是一个有着丰富指标的开源控制面板。在进行大型的测量数据的可视化时是非常有用的。根据不同的丰富指标,它提供了一个强大、优雅的方式来创建、浏览数据的方式。 -It supports a wide variety of graphing options for ultimate flexibility. Furthermore, it supports many different storage backends for your Data Source. Each Data Source has a specific Query Editor that is customized for the features and capabilities that the particular Data Source exposes. The following datasources are officially supported by Grafana: Graphite, InfluxDB, OpenTSDB, Prometheus, Elasticsearch and Cloudwatch +它提供了丰富多样、灵活的图形选项。此外,针对数据源,它支持许多不同的存储后端。每个数据源都有针对特定数据源公开的特性和功能定制的查询编辑器。下述数据源 Grafana 提供了正式的支持:Graphite, InfluxDB, OpenTSDB, Prometheus, Elasticsearch 和 Cloudwatch。 -The query language and capabilities of each Data Source are obviously very different. You can combine data from multiple Data Sources onto a single Dashboard, but each Panel is tied to a specific Data Source that belongs to a particular Organization. It supports authenticated login and a basic role based access control implementation. It is deployed as a single software installation which is written in Go and Javascript. +查询语言和每个数据源的能力显然是不同的,你可以将来自多个数据源的数据混合到一个单一的仪表盘上,但每个小组被绑定到属于一个特定组织的特点数据源。它支持验证登陆和基于角色的访问控制的实现。它是作为一个独立软件部署的,使用 Go 和 JavaScript 编写的。 -In this article, I'll explain on how to install Grafana on a docker container in Ubuntu 16.04 and configure docker monitoring using this software. +在这篇文章,我将讲解如何在 Ubuntu 16.04 上安装 Grafana 并使用这个软件配置 Docker 监控 -### Pre-requisites ### +### 先决条件 -- Docker installed server +- 安装好 Docker 的服务器 -### Installing Grafana ### +### 安装 Grafana -We can build our Grafana in a docker container. There is an official docker image available for building Grafana. Please run this command to build a Grafana container. +我们可以在 Docker 中构建我们的 Grafana。 这里有一个官方的 Grafana Docker 镜像.请运行下述命令来构建Grafana 容器。 ``` root@ubuntu:~# docker run -i -p 3000:3000 grafana/grafana @@ -50,117 +48,119 @@ t=2016-07-27T15:20:20+0000 lvl=info msg="Starting plugin search" logger=plugins t=2016-07-27T15:20:20+0000 lvl=info msg="Server Listening" logger=server address=0.0.0.0:3000 protocol=http subUrl= ``` -We can confirm the working of the Grafana container by running this command `docker ps -a` or by accessing it by URL `http://Docker IP:3000` +我们可以通过运行此命令确认 Grafana 容器的工作状态 `docker ps -a` 或通过这个URL访问 `http://Docker IP:3000` -All Grafana configuration settings are defined using environment variables, this is much useful when using container technology. The Grafana configuration file is located at /etc/grafana/grafana.ini. +所有的 Grafana 配置设置都使用环境变量定义,在使用容器技术时这个是非常有用的。Grafana 配置文件路径为 /etc/grafana/grafana.ini. -### Understanding the Configuration ### +### 理解配置项 -The Grafana has number of configuration options that can be specified in its configuration file as .ini file or can be specified using environment variables as mentioned before. +Grafana 有多个 ini 文件作为被指定的配置文件,或可以指定使用前面提到的环境变量。 -#### Config file locations #### +#### 配置文件位置 -Normal config file locations. +通常配置文件路径: -- Default configuration from : $WORKING_DIR/conf/defaults.ini -- Custom configuration from : $WORKING_DIR/conf/custom.ini +- 默认配置文件路径 : $WORKING_DIR/conf/defaults.ini +- 自定义配置文件路径 : $WORKING_DIR/conf/custom.ini -PS : When you install Grafana using the deb or rpm packages or docker images, then your configuration file is located at /etc/grafana/grafana.ini +PS:当你使用 deb、rpm 或 docker 镜像安装 Grafana ,你的配置文件在 /etc/grafana/grafana.ini -#### Understanding the config variables #### +#### 理解配置变量 -Let's see some of the variables in the configuration file below: +现在我们看一些配置文件中的变量: -`instance_name` : It's the name of the grafana server instance. It default value is fetched from ${HOSTNAME}, which will be replaced with environment variable HOSTNAME, if that is empty or does not exist Grafana will try to use system calls to get the machine name. +`instance_name` : 这是 Grafana 服务器实例的名字。默认值从 ${HOSTNAME} 获取,将会被环境变量 HOSTNAME替换,如果为空或不存在,Grafana 将会尝试使用系统调用来获取机器名。 `[paths]` -`data` : It's the path where Grafana stores the sqlite3 database (when used), file based sessions (when used), and other data. +`data` : 这个是 Grafana 存储 sqlite3 数据库(如果使用),基于文件的 Sessions(如果使用),和其他数据的路径 -`logs` : It's where Grafana stores the logs. +`logs` : 这个是 Grafana 存储日志的路径 -Both these paths are usually specified via command line in the init.d scripts or the systemd service file. +这些路径通常都是在 init.d 脚本或 systemd service文件通过命令行指定。 `[server]` -`http_addr` : The IP address to bind the application. If it's left empty it will bind to all interfaces. +`http_addr` : 应用监听的 IP 地址,如果为空,则监听所有的IP。 -`http_port` : The port to which the application is bind to, defaults is 3000. You can redirect your 80 port to 3000 using the below command. +`http_port` : 应用监听的端口,默认是 3000,你可以使用下面的命令在 80 端口重定向到 3000 端口。 ``` $iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 3000 ``` -`root_url` : This is the URL used to access Grafana from a web browser. +`root_url` : 这个 URL 用于从浏览器访问 Grafana 。 -`cert_file` : Path to the certificate file (if protocol is set to https). +`cert_file` : 证书文件的路径(如果协议是 HTTPS) -`cert_key` : Path to the certificate key file (if protocol is set to https). +`cert_key` : 证书密钥文件的路径(如果协议是 HTTPS) `[database]` -Grafana uses a database to store its users and dashboards and other informations. By default it is configured to use sqlite3 which is an embedded database included in the main Grafana binary. +Grafana 使用数据库来存储用户和仪表盘以及其他信息,默认配置为使用嵌入在 Grafana 主要的二进制文件中传的 SQLite3 `type` -You can choose mysql, postgres or sqlite3 as per our requirement. +你可以根据你的需求选择 MySQL、Postgres、SQLite3。 `path` -It's applicable only for sqlite3 database. The file path where the database will be stored. + +它只在选择 SQLite3 数据库时被应用,这个是数据库将要被存储的路径。 `host` -It's applicable only to MySQL or Postgres. it includes IP or hostname and port. For example, for MySQL running on the same host as Grafana: host = 127.0.0.1:3306 +仅适用 MySQL 或者 Postgres。它包括 IP 地址或主机名以及端口。例如,Grafana 和 MySQL 运行在同一台主机上设置如: host = 127.0.0.1:3306 `name` -The name of the Grafana database. Leave it set to grafana or some other name. +Grafana 数据库的名称,把它设置为 Grafana 或其它名称。 `user` -The database user (not applicable for sqlite3). +数据库用户(不适用于 SQLite3) `password` -The database user's password (not applicable for sqlite3). +数据库用户密码(不适用于 SQLite3) -`ssl_mode` -For Postgres, use either disable, require or verify-full. For MySQL, use either true, false, or skip-verify. +`ssl_mode` +对于Postgres,使用 disable,require,或 verify-full.对于 MySQL,使用 true,false,或 skip-verify `ca_cert_path` -(MySQL only) The path to the CA certificate to use. On many linux systems, certs can be found in /etc/ssl/certs. + +(只适用于MySQL)CA 证书文件路径,在多数 Linux 系统中,证书可以在 /etc/ssl/certs 找到 `client_key_path` -(MySQL only) The path to the client key. Only if server requires client authentication. +(只适用于MySQL)客户端密钥的路径,只在服务端需要用户端验证时使用。 `client_cert_path` -(MySQL only) The path to the client cert. Only if server requires client authentication. +(只适用于MySQL)客户端证书的路径,只在服务端需要用户端验证时使用。 `server_cert_name` -(MySQL only) The common name field of the certificate used by the mysql server. Not necessary if ssl_mode is set to skip-verify. +(只适用于MySQL) MySQL 服务端使用的证书的通用名称字段。如果 ssl_mode 设置为 skip-verify 时可以不设置 `[security]` -`admin_user` : It is the name of the default Grafana admin user. The default name set is admin. +`admin_user` : 这个是 Grafana 默认的管理员用户的用户名,默认设置为 admin. -`admin_password` : It is the password of the default Grafana admin. It is set on first-run. The default password is admin. +`admin_password` : 这个是 Grafana 默认的管理员用户的密码,在第一次运行时设置,默认为 admin -`login_remember_days` : The number of days the keep me logged in / remember me cookie lasts. +`login_remember_days` : 保持登陆/记住我 的持续天数 -`secret_key` : It is used for signing keep me logged in / remember me cookies. +`secret_key` : 用于保持登陆/记住我的 cookies 的签名 -### Essentials components for setting up Monitoring ### +### 设置监控的重要组件 -We use the below components to create our Docker Monitoring system. +我们可以使用下面的组件来创建我们的 Docker 监控系统 -`cAdvisor` : It is otherwise called Container Advisor. It provides its users an understanding of the resource usage and performance characteristics. It collects, aggregates, processes and exports information about the running containers. You can go through this documentation for more information about this. +`cAdvisor` : 他被称为 Container Advisor。它提供了对用户的资源利用和性能特征的解读。它收集、合并、处理、导出运行中的容器的信息。你可以通过文档了解更多关于这个。 -`InfluxDB` : It is a time series, metrics, and analytic database. We use this datasource for setting up our monitoring. cAdvisor displays only real time information and doesn’t store the metrics. Influx Db helps to store the monitoring information which cAdvisor provides in order to display a time range other than real time. +`InfluxDB` : 这是一个时间排序、度量和分析数据库。我们使用这个数据源来设置我们的监控。cAdvisor 只展示时间信息,不保存度量信息。Influx Db帮助保存 cAdvisor 提供的监控数据,以展示非实时数据。 -`Grafana Dashboard` : It allows us to combine all the pieces of information together visually. This powerful Dashboard allows us to run queries against the data store InfluxDB and chart them accordingly in beautiful layout. +`Grafana Dashboard` : 它可以帮助我们在视觉上整合所有的信息。这个强大的仪表盘使我们能够针对数据存储 InfluxDB 进行查询并将他们放在一个布局合理好看的图表中。 -### Installation of Docker Monitoring ### +### Docker监控的安装 -We need to install each of these components one by one in our docker system. +我们需要一步一步的安装每一个下面的组件在我们的 Docker 系统中。 -#### Installing InfluxDB #### +#### 安装 InfluxDB -We can use this command to pull InfluxDB image and setuup a influxDB container. +我们可以使用这个命令来拉取 InfluxDB 镜像,并部署了 influxDB 容器。 ``` root@ubuntu:~# docker run -d -p 8083:8083 -p 8086:8086 --expose 8090 --expose 8099 -e PRE_CREATE_DB=cadvisor --name influxsrv tutum/influxdb:0.8.8 @@ -185,17 +185,17 @@ d3b6f7789e0d1d01fa4e0aacdb636c221421107d1df96808ecbe8e241ceb1823 --name influxsrv : container have name influxsrv, use to cAdvisor link it. ``` -You can test your InfluxDB installation by calling this URL >>http://45.79.148.234:8083 and login with user/password as "root". +你可以测试 InfluxDB 是否安装好,通过访问这个 URL>>http://45.79.148.234:8083 (译者注,应当访问你自己的服务器的IP:8083),并且使用 root 用户的帐号和密码登陆 ![InfluxDB Administration 2016-08-01 14-10-08](http://blog.linoxide.com/wp-content/uploads/2016/07/InfluxDB-Administration-2016-08-01-14-10-08-1-1024x530.png) -We can create our required databases from this tab. +我们可以在这个界面上创建我们需要的数据库. ![createDB influx](http://blog.linoxide.com/wp-content/uploads/2016/07/createDB-influx-1024x504.png) -#### Installing cAdvisor #### +#### 安装 cAdvisor -Our next step is to install cAdvisor container and link it to the InfluxDB container. You can use this command to create it. +我们的下一个步骤是安装 cAdvisor 容器,并将其链接到 InfluxDB 容器。你可以使用此命令来创建它。 ``` root@ubuntu:~# docker run --volume=/:/rootfs:ro --volume=/var/run:/var/run:rw --volume=/sys:/sys:ro --volume=/var/lib/docker/:/var/lib/docker:ro --publish=8080:8080 --detach=true --link influxsrv:influxsrv --name=cadvisor google/cadvisor:latest -storage_driver_db=cadvisor -storage_driver_host=influxsrv:8086 @@ -217,49 +217,49 @@ root@ubuntu:~# -storage_driver_db=cadvisor: database name. Uses db ‘cadvisor’ by default ``` -You can test our cAdvisor installation by calling this URL >>http://45.79.148.234:8080. This will provide you the statistics of your Docker host and containers. +你可以通过访问这个地址来测试安装 cAdvisor 是否正常 >>http://45.79.148.234:8080. 这将为你的 Docker 主机和容器提供统计信息。 ![cAdvisor - Docker Containers 2016-08-01 14-24-18](http://blog.linoxide.com/wp-content/uploads/2016/07/cAdvisor-Docker-Containers-2016-08-01-14-24-18-776x1024.png) -#### Installing the Grafana Dashboard #### +#### 安装 Grafana 控制面板 -Finally, we need to install the Grafana Dashboard and link to the InfluxDB. You can run this command to setup that. +首先我们需要安装 Grafana 仪表板并链接到 InfluxDB,你可以执行下面的命令来设置他 ``` root@ubuntu:~# docker run -d -p 3000:3000 -e INFLUXDB_HOST=localhost -e INFLUXDB_PORT=8086 -e INFLUXDB_NAME=cadvisor -e INFLUXDB_USER=root -e INFLUXDB_PASS=root --link influxsrv:influxsrv --name grafana grafana/grafana f3b7598529202b110e4e6b998dca6b6e60e8608d75dcfe0d2b09ae408f43684a ``` -Now we can login to Grafana and configure the Data Sources. Navigate to http://45.79.148.234:3000 or just http://45.79.148.234: +现在我们可以登陆 Grafana 来配置数据源. 访问 http://45.79.148.234:3000 或 http://45.79.148.234: -Username - admin -Password - admin +用户名- admin +密码- admin -Once we've installed Grafana, we can connect the InfluxDB. Login on the Dashboard and click on the Grafana icon(Fireball) in the upper left hand corner of the panel. Click on Data Sources to configure. +一旦我们安装好了 Grafana,我们可以链接 InfluxDB。登陆到控制台并且点击面板左上方角落的 Grafana 图标(火球)。点击数据源(Data Sources)来配置。 ![addingdatabsource](http://blog.linoxide.com/wp-content/uploads/2016/08/addingdatabsource-1-1024x804.png) -Now you can add our new Graph to our default Datasource InfluxDB. +现在你可以添加我们新的图像到我们默认的数据源 InfluxDB. ![panelgraph](http://blog.linoxide.com/wp-content/uploads/2016/08/panelgraph-1024x576.png) -We can edit and modify our query by adjusting our graph at Metric tab. +我们可以通过在测量页面调整我们的图像可以编辑和调整我们的查询 ![Grafana - Grafana Dashboard 2016-08-01 14-53-40](http://blog.linoxide.com/wp-content/uploads/2016/08/Grafana-Grafana-Dashboard-2016-08-01-14-53-40-1024x504.png) ![Grafana - Grafana Dashboard](http://blog.linoxide.com/wp-content/uploads/2016/08/Grafana-Grafana-Dashboard-1024x509.png) -You can get [more information][1] on docker monitoring here. Thank you for reading this. I would suggest your valuable comments and suggestions on this. Hope you'd a wonderful day! +你可以在 [更多信息][1]看到更多关于Docker监控的小心。 感谢你的阅读。我希望你可以留下有价值的建议和评论。希望你有个美好的一天 --------------------------------------------------------------------------------- +------ via: http://linoxide.com/linux-how-to/monitor-docker-containers-grafana-ubuntu/ 作者:[Saheetha Shameer][a] -译者:[ChrisLeeGit](https://github.com/chrisleegit) +译者:[Bestony](https://github.com/bestony) 校对:[校对者ID](https://github.com/校对者ID) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 -[a]:http://linoxide.com/author/saheethas/ -[1]:https://github.com/vegasbrianc/docker-monitoring +[a]: http://linoxide.com/author/saheethas/ +[1]: https://github.com/vegasbrianc/docker-monitoring From 14b785d48fcfa65f0ca6dc8802288693c6cabbf3 Mon Sep 17 00:00:00 2001 From: Bestony Date: Sat, 8 Oct 2016 07:10:47 +0800 Subject: [PATCH 027/316] =?UTF-8?q?=E7=A7=BB=E5=8A=A8=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 移动文件 --- ...09 How to Monitor Docker Containers using Grafana on Ubuntu.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {sources => translated}/tech/20160809 How to Monitor Docker Containers using Grafana on Ubuntu.md (100%) diff --git a/sources/tech/20160809 How to Monitor Docker Containers using Grafana on Ubuntu.md b/translated/tech/20160809 How to Monitor Docker Containers using Grafana on Ubuntu.md similarity index 100% rename from sources/tech/20160809 How to Monitor Docker Containers using Grafana on Ubuntu.md rename to translated/tech/20160809 How to Monitor Docker Containers using Grafana on Ubuntu.md From 9a30e2f2106afd562cd406e5388c732f4c33f222 Mon Sep 17 00:00:00 2001 From: Bestony Date: Sat, 8 Oct 2016 10:39:30 +0800 Subject: [PATCH 028/316] =?UTF-8?q?=E8=AE=A4=E9=A2=86=E6=96=87=E7=AB=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sources/tech/20160511 4 Container Networking Tools to Know.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/tech/20160511 4 Container Networking Tools to Know.md b/sources/tech/20160511 4 Container Networking Tools to Know.md index 220d41644d..151ac3a30d 100644 --- a/sources/tech/20160511 4 Container Networking Tools to Know.md +++ b/sources/tech/20160511 4 Container Networking Tools to Know.md @@ -1,4 +1,4 @@ -[Translating by itsang] +[Translating by bestony] 4 Container Networking Tools to Know ======================================= From e58e6344932ca1b594f7352466243f8c42c79de2 Mon Sep 17 00:00:00 2001 From: wxy Date: Sat, 8 Oct 2016 12:30:14 +0800 Subject: [PATCH 029/316] PUB:20160823 The infrastructure behind Twitter - efficiency and optimization @eriwoon --- ...nfrastructure behind Twitter - efficiency and optimization.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/tech => published}/20160823 The infrastructure behind Twitter - efficiency and optimization.md (100%) diff --git a/translated/tech/20160823 The infrastructure behind Twitter - efficiency and optimization.md b/published/20160823 The infrastructure behind Twitter - efficiency and optimization.md similarity index 100% rename from translated/tech/20160823 The infrastructure behind Twitter - efficiency and optimization.md rename to published/20160823 The infrastructure behind Twitter - efficiency and optimization.md From cddd1208bc0af324051acf4425572c60ae3c3840 Mon Sep 17 00:00:00 2001 From: wxy Date: Sat, 8 Oct 2016 14:44:34 +0800 Subject: [PATCH 030/316] PUB:20160913 Ryver - Why You Should Be Using It instead of Slack @firstadream --- ...You Should Be Using It instead of Slack.md | 66 +++++++++++++++++++ ...You Should Be Using It instead of Slack.md | 64 ------------------ 2 files changed, 66 insertions(+), 64 deletions(-) create mode 100644 published/20160913 Ryver - Why You Should Be Using It instead of Slack.md delete mode 100644 translated/tech/20160913 Ryver - Why You Should Be Using It instead of Slack.md diff --git a/published/20160913 Ryver - Why You Should Be Using It instead of Slack.md b/published/20160913 Ryver - Why You Should Be Using It instead of Slack.md new file mode 100644 index 0000000000..99e0c7ec25 --- /dev/null +++ b/published/20160913 Ryver - Why You Should Be Using It instead of Slack.md @@ -0,0 +1,66 @@ +Ryver:你应该使用它替代 Slack +=============== + +![](https://maketecheasier-2d0f.kxcdn.com/assets/uploads/2016/09/Ryver-Slack-Feature.jpg) + +貌似每个人都听说过 [Slack][1],它是一款跨平台的,可以使你时刻保持与他人同步的团队沟通应用。它革新了用户讨论和规划项目的方式,显而易见,它升级了 email 的沟通功能。 + +我在一个非常小的写作团队工作,不管是通过手机还是电脑,我从未在使用 Slack 过程中遇到过沟通问题。若想与任何规模的团队保持同步,继续使用 Slack 仍然不失为不错的方式。 + +既然如此,为什么我们还要讨论今天的话题?Ryver 被人们认为是下一个热点,相比 Slack,Ryver 提供了升级版的服务。Ryver 完全免费,它的团队正在奋力争取更大的市场份额。 + +是否 Ryver 已经强大到可以扮演 Slack 杀手的角色?这两种旗鼓相当的消息应用究竟有何不同? + +欲知详情,请阅读下文。 + +### 为什么用 Ryver ? + +![](https://maketecheasier-2d0f.kxcdn.com/assets/uploads/2016/04/Ryver.jpg) + +既然 Slack 能用为什么还要折腾呢?Ryver 的开发者对 Slack 的功能滚瓜烂熟,他们希望 Ryver 改进的服务足以让你移情别恋。他们承诺 Ryver 提供完全免费的团队沟通服务,并且不会在任何一个环节隐形收费。 + +谢天谢地,他们用高质量产品兑现了自己的承诺。 + +额外的内容是关键所在,他们承诺去掉一些你在 Slack 免费账号上面遇到的限制。无限的存储空间是一个加分点,除此之外,在许多其他方面 Ryver 也更加开放。如果存储空间限制对你来说是个痛点,不防试试 Ryver。 + +这是一个简单易用的系统,所有的功能都可以一键搞定。这种设计哲学使 Apple 大获成功。当你开始使用它之后,也不会遭遇成长的烦恼。 + +![](https://maketecheasier-2d0f.kxcdn.com/assets/uploads/2016/09/ryver-web-interface.png) + +会话分为私聊和公示,这意味着团队平台和私人用途有明确的界限。它应该有助于避免将任何尴尬的广而告之给你的同事,这些问题我在使用 Slack 期间都遇到过。 + +Ryver 支持与大量现成的 App 的集成,并在大多数平台上有原生应用程序。 + +在需要时,你可以添加访客而无需增加费用,如果你经常和外部客户打交道,这将是一个非常有用的功能。访客可以增加更多的访客,这种流动性的元素是无法从其他更流行的消息应用中看到的。 + +考虑到 Ryver 是一个为迎合不同需求而产生的完全不同的服务。如果你需要一个账户来处理几个客户,Ryver 值得一试。 + +问题是它是如何做到免费的呢? 简单的答案是高级用户将为你的使用付了费。 就像 Spotify 和其他应用一样,有一小部分人为我们其他人支付了费用。 这里有一个[直接链接][2]到他们的下载页面的地址,如果有兴趣就去试一试吧。 + +### 你应该切换到 Ryver 吗? + +![](https://maketecheasier-2d0f.kxcdn.com/assets/uploads/2016/04/Slack-homepage.jpg) + +像我一样在小团队使用 Slack 的体验还是非常棒,但是 Ryver 可以给予的更多。一个完全免费的团队沟通应用的想法不可谓不宏伟,更何况它工作的十分完美。 + +同时使用这两种消息应用也无可厚非,但是如果你不愿意为一个白金 Slack 账户付费,一定要尝试一下竞争对手的服务。你可能会发现,两者各擅胜场,这取决于你需要什么。 + +最重要的是,Ryver 是一个极棒的免费替代品,它不仅仅是一个 Slack 克隆。他们清楚地知道他们想要实现什么,他们有一个可以在拥挤不堪的市场提供不同的东西的不错的产品。 + +但是,如果将来持续缺乏资金,Ryver 有可能消失。 它可能会让你的团队和讨论陷入混乱。 目前一切还好,但是如果你计划把更大的业务委托给这个新贵还是需要三思而行。 + +如果你厌倦了 Slack 对免费帐户的限制,你会对 Ryver 印象深刻。 要了解更多,请访问其网站以获取有关服务的信息。 + +-------------------------------------------------------------------------------- + +via: https://www.maketecheasier.com/why-use-ryver-instead-of-slack/ + +作者:[James Milin-Ashmore][a] +译者:[firstadream](https://github.com/firstadream) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://www.maketecheasier.com/author/james-ashmore/ +[1]: https://www.maketecheasier.com/new-slack-features/ +[2]: http://www.ryver.com/downloads/ diff --git a/translated/tech/20160913 Ryver - Why You Should Be Using It instead of Slack.md b/translated/tech/20160913 Ryver - Why You Should Be Using It instead of Slack.md deleted file mode 100644 index b8c95935a9..0000000000 --- a/translated/tech/20160913 Ryver - Why You Should Be Using It instead of Slack.md +++ /dev/null @@ -1,64 +0,0 @@ - -为什么你应该使用Ryver弃用Slack? -===== -貌似每个人都听说过Slack,它是一款跨平台的,可以使你时刻保持与他人同步的团队沟通应用。它革新了用户讨论和计划项目的方式,显而易见,它升级了email的沟通功能。 - -我在一个非常小的写作团队工作,不管是通过手机还是电脑,我从未在使用Slack过程中遇到过沟通问题。若想与任何规模的团队保持同步,继续使用Slack仍然不失为不错的方式。 - -既然如此,为什么我们还要讨论今天的话题?相比Slack,Ryver提供升级版的服务,这被认为是下一个大事件。Ryver完全免费,它的团队正在奋力争取更大的市场份额。 - -是否Ryver已经强大到可以扮演Slack杀手的角色?这两种旗鼓相当的消息应用究竟有何不同? - -想了解更多,请阅读下文。 - - -###为什么是Ryver ? - -![](https://maketecheasier-2d0f.kxcdn.com/assets/uploads/2016/04/Ryver.jpg) - -为什么运行正常的功能仍然会引起混乱?Ryver的开发者对Slack的功能滚瓜烂熟,他们希望Ryver改进的服务足以让你移情别恋。他们承诺Ryver提供完全免费的团队沟通服务,并且不会在任何一个环节隐形收费。 - -谢天谢地,他们用高质量产品兑现了自己的承诺。 - -额外的内容是关键所在,他们承诺删除一些你在Slack免费账号上面的限制。无限的存储空间是一个加分点,除此之外,在许多其他方面Ryver也更加开放。如果存储空间限制对你来说是个痛点,不防试试Ryver。 - -这是一个简单易用的系统,所有的功能都可以一键搞定。这种设计哲学使Apple大获成功,当你开始使用后,也不会遭遇成长的烦恼。 - -![](https://maketecheasier-2d0f.kxcdn.com/assets/uploads/2016/09/ryver-web-interface.png) - -会话区分私聊和公示,这意味着团队平台和私人应用有明确的界限。它应该有助于避免广播任何尴尬的公告给你的同事,这些我在使用Slack期间都遇到过。 - -Ryver支持与大量已有App的集成,并有大多数平台的原生应用程序 。 - -在需要时你可以添加额外客户而无需增加费用,如果你经常和外部客户打交道,这将是一个非常有用的功能。客户可以增加更多客户,这种流动性的元素是无法从其他更流行的消息应用中看到的。 - -考虑到Ryver是一个为迎合不同需求而产生的完全不同的服务。如果你需要一个账户来处理多种客户,Ryver值得一试。 - -问题是它是如何做到免费的? 快速的答案是高级用户将为你付费。 像Spotify和其他应用一样,有一小部分人为我们其他人支付费用。 这里有一个直接链接到他们的下载页面的地址,如果有兴趣就去试一试吧。 - -###你应该切换到Ryver吗? - -![](https://maketecheasier-2d0f.kxcdn.com/assets/uploads/2016/04/Slack-homepage.jpg) - -像我一样在小团队使用Slack的体验还是非常棒,但是Ryver可以给予更多。一个完全免费的消息应用程序的想法不可谓不宏伟,更何况它工作的十分完美。 - -同时使用两种消息应用也无可厚非,但是如果你不愿意支付一个溢价的Slack账户,一定要尝试一下竞争对手的服务。你可能会发现,在不同的情况下,两者都更好,这取决于你需要什么。 - -最重要的是,Ryver是一个伟大的免费替代品,它不仅仅是一个Slack克隆。 他们清楚地知道他们想要实现什么,他们有一个体面的产品,在一个拥挤不堪的市场提供不同的东西。 - -但是,如果将来持续缺乏资金,Ryver有可能消失。 它可能会让你的团队和讨论陷入混乱。 目前一切还好,但是如果你计划把更大的业务委托给这个新贵还是需要三思而行。 - - -如果你厌倦了Slack对一个免费帐户的限制,你会对Ryver印象深刻。 要了解更多,请访问其网站以获取有关服务的信息。 - --------------------------------------------------------------------------------- - -via: https://www.maketecheasier.com/why-use-ryver-instead-of-slack/?utm_medium=feed&utm_source=feedpress.me&utm_campaign=Feed%3A+maketecheasier - -作者:[James Milin-Ashmore][a] -译者:[firstadream](https://github.com/firstadream) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]: https://www.maketecheasier.com/author/james-ashmore/ From a32c026f849c01b26118066f652ce56d573bdaa2 Mon Sep 17 00:00:00 2001 From: bazz2 Date: Sat, 8 Oct 2016 18:42:43 +0800 Subject: [PATCH 031/316] [jiajia9linuxer] finish 2 blogs --- ... Principles of Monitoring Microservices.md | 82 +++++++++---------- ...sing Ansible to Provision Vagrant Boxes.md | 79 +++++++++--------- 2 files changed, 80 insertions(+), 81 deletions(-) diff --git a/sources/tech/20160913 The Five Principles of Monitoring Microservices.md b/sources/tech/20160913 The Five Principles of Monitoring Microservices.md index ff459c8dc7..9cc71e897e 100644 --- a/sources/tech/20160913 The Five Principles of Monitoring Microservices.md +++ b/sources/tech/20160913 The Five Principles of Monitoring Microservices.md @@ -1,93 +1,93 @@ -jiajia9linuxer -The Five Principles of Monitoring Microservices +监控微服务的5条原则 ==== ![](http://thenewstack.io/wp-content/uploads/2016/09/toppicsysdig.jpg) -The need for microservices can be summed up in just one word: speed. The need to deliver more functionality and reliability faster has revolutionized the way developers create software. Not surprisingly, this change has caused ripple effects within software management, including monitoring systems. In this post, we’ll focus on the radical changes required to monitor your microservices in production efficiently. We’ll lay out five guiding principles for adapting your monitoring approach for this new software architecture. +我们对微服务的需求可以归纳为一个词:速度,提供更多更可靠更快捷的功能的需求,彻底改变了软件开发模式,毫无疑问,这同样改变了软件管理和系统监控的方式。这里,我们着重于有效的监控生产过程中的微服务,我们将为这一新的软件开发模式制定5条原则来调整你的监控方法。 -Monitoring is a critical piece of the control systems of microservices, as the more complex your software gets, the harder it is to understand its performance and troubleshoot problems. Given the dramatic changes to software delivery, however, monitoring needs an overhaul to perform well in a microservice environment. The rest of this article presents the five principles of monitoring microservices, as follows: +监控是微服务控制系统的关键部分,你的软件越复杂,那么你就越难了解其性能并解决问题。鉴于微服务给软件部署带来的巨大改变,监控系统同样需要进行彻底的改造。文章接下来介绍监控微服务的5条原则,如下: -1. Monitor containers and what’s inside them. -2. Alert on service performance, not container performance. -3. Monitor services that are elastic and multi-location. -4. Monitor APIs. -5. Map your monitoring to your organizational structure. +1. 监控容器和里面的东西 +2. 在服务性能上做监控,而不是容器 +3. 监控弹性和多变的服务 +4. 监控开发接口 +5. 将您的监控映射到您的组织结构 -Leveraging these five principles will allow you to establish more effective monitoring as you make your way towards microservices. These principles will allow you to address both the technological changes associated with microservices, in addition to the organizational changes related to them. +利用这5条原则,你可以建立更有效的对微服务的监控。这些原则,可以让你定位微服务的技术变化和组织变化。 -### The Principles of Microservice Monitoring +### 微服务监控的原则 -#### 1. Monitor Containers and What’s Running Inside Them +#### 1.监控容器和里面的东西 -Containers gained prominence as the building blocks of microservices. The speed, portability, and isolation of containers made it easy for developers to embrace a microservice model. There’s been a lot written on the benefits of containers so we won’t recount it all here. +容器是微服务重要的积木,容器的速度、可移植性和隔离特性让开发者很方便的建立微服务的模型。容器的好处已经写的够多了,在这里我们不再重复。 -Containers are black boxes to most systems that live around them. That’s incredibly useful for development, enabling a high level of portability from development through production, from developer laptop to cloud. But when it comes to operating, monitoring and troubleshooting a service, black boxes make common activities harder, leading us to wonder: what’s running in the container? How is the application/code performing? Is it spitting out important custom metrics? From the DevOps perspective, you need deep visibility inside containers rather than just knowing that some containers exist. +容器对于其他的系统来说就像是黑盒子,它的高度的可移植性,对于开发来说简直大有裨益,从开发到生产,甚至从一台笔记本开发直到云端。但是运行起来后,监控和解决服务问题,这个黑盒子让常规的方法失效了,我们会想:容器里到底在运行着什么?这些程序和代码是怎么运行的?它有什么重要的输出指标吗?在开发者的视角,你需要对容器有更深的了解而不是知道一些容器的存在。 ![](http://thenewstack.io/wp-content/uploads/2016/09/greatfordev.jpg) -The typical process for instrumentation in a non-containerized environment — an agent that lives in the user space of a host or VM — doesn’t work particularly well for containers. That’s because containers benefit from being small, isolated processes with as few dependencies as possible. +非容器环境的典型特征,一个代理程序运行在一台主机或者虚机的用户空间,但是容器里不一样。容器的有点是小,讲各种进程分离开来,尽可能的减少依赖关系。 -And, at scale, running thousands of monitoring agents for even a modestly-sized deployment is an expensive use of resources and an orchestration nightmare. Two potential solutions arise for containers: 1) ask your developers to instrument their code directly, or 2) leverage a universal kernel-level instrumentation approach to see all application and container activity on your hosts. We won’t go into depth here, but each method has pros and cons. +在规模上看,成千上万的监测代理,对即使是一个中等大小的部署都是一个昂贵的资源浪费和业务流程的噩梦。对于容器有两个潜在的解决方案:1)要求你的开发人员直接提交他们的代码,或者2)利用一个通用的内核级的检测方法来查看主机上的所有应用程序和容器活动。我们不会在这里深入,但每一种方法都有优点和缺点。 -#### 2. Leverage Orchestration Systems to Alert on Service Performance +#### 2. 利用业务流程系统提醒服务性能 -Making sense of operational data in a containerized environment is a new challenge. The metrics of a single container have a much lower marginal value than the aggregate information from all the containers that make up a function or a service. +理解容器中数据的运行方式并不容易,一个容器的度量值比组成函数或服务的所有容器的聚合信息都要低得多。 -This particularly applies to application-level information, like which queries have the slowest response times or which URLs are seeing the most errors, but also applies to infrastructure-level monitoring, like which services’ containers are using the most resources beyond their allocated CPU shares. +这特别适用于应用程序级别的信息,就像哪个请求拥有最短响应时间或者哪个URLs有最多的错误,同样也适用于基础设施水平监测,比如哪个服务的容器使用CPU资源超过了事先分配的资源数。 -Increasingly, software deployment requires an orchestration system to “translate” a logical application blueprint into physical containers. Common orchestration systems include Kubernetes, Mesosphere DC/OS and Docker Swarm. Teams use an orchestration system to (1) define your microservices and (2) understand the current state of each service in deployment. You could argue that the orchestration system is even more important than the containers. The actual containers are ephemeral — they matter only for the short time that they exist — while your services matter for the life of their usefulness. +越来越多的软件部署需要一个业务流程系统,将逻辑化的应用程序转化到一个物理的容器中。 +常见的转化系统包括Kubernetes、Mesosphere DC/OS和Docker Swarm。团队用一个业务流程系统来定义微服务和理解部署每个服务的当前状态。容器是短暂的,只有满足你的服务需求才会存在。 -DevOps teams should redefine alerts to focus on characteristics that get as close to monitoring the experience of the service as possible. These alerts are the first line of defense in assessing if something is impacting the application. But getting to these alerts is challenging, if not impossible unless your monitoring system is container-native. +DevOps团队应该尽可能将重点放到如何更好的监控服务的运行特点上,如果应用受到了影响,这些告警点要放在第一道评估线上。但是能观察到这些告警点也并不容易,除非你的监控系统是容器本地的。 -Container-native solutions leverage orchestration metadata to dynamically aggregate container and application data and calculate monitoring metrics on a per-service basis. Depending on your orchestration tool, you might have different layers of a hierarchy that you’d like to drill into. For example, in Kubernetes, you typically have a Namespace, ReplicaSets, Pods and some containers. Aggregating at these various layers is essential for logical troubleshooting, regardless of the physical deployment of the containers that make up the service. +容器原生解决方案利用业务流程元数据来动态聚合容器和应用程序数据,并计算每个服务基础上的监控度量。根据您的业务流程工具,您可能有不同层次的层次结构想检测。比如,在Kubernetes里,你通常有Namespace、ReplicaSets、Pods和一些其他容器。聚集在这些不同的层有助于故障排除,这与构成服务的容器的物理部署无关。 ![](http://thenewstack.io/wp-content/uploads/2016/09/servicemonitoring.jpg) -#### 3. Be Prepared for Services that are Elastic and Multi-Location +#### 3. 监控弹性和多变的服务 -Elastic services are certainly not a new concept, but the velocity of change is much faster in container-native environments than virtualized environments. Rapidly changing environments can wreak havoc on brittle monitoring systems. +弹性服务不是一个新概念,但是它在本地容器中的变化速度比在虚拟环境中快的多。迅速的变化会严重影响检测系统的正常运行。 -Frequently monitoring legacy systems required manual tuning of metrics and checks based on individual deployments of software. This tuning can be as specific as defining the individual metrics to be captured, or configuring collection based on what application is operating in a particular container. While that may be acceptable on a small scale (think tens of containers), it would be unbearable in anything larger. Microservice focused monitoring must be able to comfortably grow and shrink in step with elastic services, without human intervention. +经常监测系统所需的手动调整指标和单独部署的软件,这种调整可以是具体的,如定义要捕获的单个指标,或收集应用程序在一个特定的容器中操作的配置数据。小规模上我们可以接受,但是数以万计规模的容器就不行了。微服务的集中监控必须能够自由的监控弹性服务的增长和缩减,而且无人工干预。 -For example, if the DevOps team must manually define what service a container is included in for monitoring purposes, they no doubt drop the ball as Kubernetes or Mesos spins up new containers regularly throughout the day. Similarly, if Ops were required to install a custom stats endpoint when new code is built and pushed into production, challenges may arise as developers pull base images from a Docker registry. +比如,开发团队必须手动定义容器包含那个服务做监控使用,他们毫无疑问会把球抛给Kubernetes或者Mesos定期的创建新的容器。同样,如果开发团队需要配置一个自定义的状态点从新代码的产生到付诸生产,那么基础镜像从容器中注册会给开发者带来更多的挑战。 -In production, build monitoring toward a sophisticated deployment that spans multiple data centers or multiple clouds. Leveraging, for example, AWS CloudWatch will only get you so far if your services span your private data center as well as AWS. That leads back to implementing a monitoring system that can span these different locations as well as operate in dynamic, container-native environments. +在生产中,建立一个复杂的跨越多个数据中心或多个云部署的监控,会使你的服务跨越你的死人数据中心,具体的应用,比如亚马逊的AWS CloudWatch。通过动态的本地容器环境,这个实时监控系统,会监控不同区域的数据中心。 -#### 4. Monitor APIs +#### 4.监控开发接口 -In microservice environments, APIs are the lingua franca. They are essentially the only elements of a service that are exposed to other teams. In fact, response and consistency of the API may be the “internal SLA” even if there isn’t a formal SLA defined. +在微服务环境中,API接口是通用的。它们是一个服务的必备组件,实际上,API的响应和一致性是服务的内部语言,虽然暂时还没人定义它们。 -As a result, API monitoring is essential. API monitoring can take many forms but clearly, must go beyond binary up/down checks. For instance, it’s valuable to understand the most frequently used endpoints as a function of time. This allows teams to see if anything noticeable has changed in the usage of services, whether it be due to a design change or a user change. +因此,API接口的监控也是必需的。API监控可以有不同的形式,但是它绝对不是简单的上下检查。例如,了解最常使用的点作为时间函数是有价值的。这使得团队可以看到,服务使用的变化,无论是由于设计变更或用户的改变。 -You can also consider the slowest endpoints of your service, as these can reveal significant problems, or, at the very least, point to areas that need the most optimization in your system. +你也可以记录服务最缓慢的点,这些可以揭示重大的问题,至少,指向需要在系统中做优化的区域。 -Finally, the ability to trace service calls through your system represents another critical capability. While typically used by developers, this type of profiling will help you understand the overall user experience while breaking information down into infrastructure and application-based views of your environment. +最终,跟踪系统服务响应会成为一个很重要的能力,它会帮助开发者了解最终用户体验,同时将信息分成基础设施和应用程序环境两大部分。 -#### 5. Map Monitoring to Your Organizational Structure +#### 5. 将您的监控映射到您的组织结构 -While most of this post has been focused on the technological shift in microservices and monitoring, like any technology story, this is as much about people as it is about software bits. +这篇文章着重在微服务和监控上,像其他科技文章一样,这是因为很多人都关注软件层面。 -For those of you familiar with Conway’s law, he reminds us that the design of systems is defined by the organizational structure of the teams building them. The allure of creating faster, more agile software has pushed teams to think about restructuring their development organization and the rules that govern it. +对于那些熟悉康威定律的人来说,系统的设计是基于开发团队的组织结构。创造更快,更敏捷的软件的迫力,推动团队思考重新调整他们的组织结构和管理它的规则。 ![](http://thenewstack.io/wp-content/uploads/2016/09/mapmonitoring.jpg) -So if an organization wants to benefit from this new software architecture approach, their teams must, therefore, mirror microservices themselves. That means smaller teams, loosely coupled; that can choose their direction as long as it still meets the needs of the whole. Within each team, there is more control than ever over languages used, how bugs are handled, or even operational responsibilities. +如果他们想从新的软件架构比如微服务上获益,那么他们需要更小的更松散更耦合的团队,可以选择自己的方向只要能够满足整个需求即可。在一个团队中,对于什么开发语言的使用,bug的提交甚至工作职责都会有更大的控制能力。 -DevOps teams can enable a monitoring platform that does exactly this: allows each microservice team to isolate their alerts, metrics, and dashboards, while still giving operations a view into the global system. +开发团队可以启用一个监控平台:让每一个微服务团队可以定位自己的警报,指标,和控制面板,同时也要给全局系统的操作一个图表。 -### Conclusion +### 总结 -There’s one, clear trigger event that precipitated the move to microservices: speed. Organizations wanted to deliver more capabilities to their customers in less time. Once this happened, technology stepped in, the architectural move to micro-services and the underlying shift to containers make speed happen. Anything that gets in the way of this progress train is going to get run over on the tracks. +快捷让微服务流行起来。开发组织要想为客户提供更快的更多的功能,然后微服务技术就来了,架构转向微服务并且容器的流行让快捷开发成为可能,所有相关的进程理所当然的搭上了这辆火车。 -As a result, the fundamental principles of monitoring need to adapt to the underlying technology and organizational changes that accompany microservices. Operations teams that recognize this shift can adapt to microservices earlier and easier. +最后,基本的监控原则需要适应加入到微服务的技术和结构。越早认识到这种转变的开发团队,能更早更容易的适应微服务这一新的架构。 -------------------------------------------------------------------------------- via: http://linoxide.com/firewall/pfsense-setup-basic-configuration/ 作者:[Apurva Dave][a] [Loris Degioanni][b] -译者:[译者ID](https://github.com/译者ID) +译者:[jiajia9linuxer](https://github.com/jiajia9linuxer) 校对:[校对者ID](https://github.com/校对者ID) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/sources/tech/20160915 Using Ansible to Provision Vagrant Boxes.md b/sources/tech/20160915 Using Ansible to Provision Vagrant Boxes.md index 43ca998742..3a10014d55 100644 --- a/sources/tech/20160915 Using Ansible to Provision Vagrant Boxes.md +++ b/sources/tech/20160915 Using Ansible to Provision Vagrant Boxes.md @@ -1,72 +1,71 @@ -jiajia9linuxer -Using Ansible to Provision Vagrant Boxes +用Ansible来配置Vagrant Boxes ==== ![](https://i1.wp.com/cdn.fedoramagazine.org/wp-content/uploads/2016/08/vagrant-plus-ansible.jpg?w=1352&ssl=1) -Ansible is a great tool for system administrators who want to automate system administration tasks. From configuration management to provisioning and managing containers for application deployments, Ansible [makes it easy][1]. The lightweight module based architecture is ideal for system administration. One advantage is that when the node is not being managed by Ansible, no resources are used. +Ansible 是一款系统管理员进行自动化运维的强大工具。Ansible 让配置、交付、管理各种容器,软件部署变得非常简单[1]。基于轻量级模块的架构非常适合系统管理,一个优点就是如果某个节点没有被 Ansible 管理的话,它的资源是没有被使用的。 -This article covers how to use Ansible to provision Vagrant boxes. A [Vagrant box][2] in simple terms is a virtual machine prepackaged with tools required to run the development environment. You can use these boxes to distribute the development environment used by other team members for project work. Using Ansible, you can automate provisioning the Vagrant boxes with your development packages. +这篇文章介绍用 Ansible 来配置 Vagrant boxes,它是一个配置好的基础虚拟机映像,包含在开发环境中需要用到的工具。你可以用它来部署开发环境,然后和其他成员协同工作。用 Ansible,你可以用你的开发包自动化配置 Vagrant boxes。 -This tutorial uses Fedora 24 as the host system and [CentOS][3] 7 as the Vagrant box. +我们用 Fedora 24 做主机,用 CentOS 7 来作 Vagrant box -### Setting up prerequisites +### 设置工作环境 -To configure Vagrant boxes using Ansible, you’ll need a few things setup. This tutorial requires you to install Ansible and Vagrant on the host machine. On your host machine, execute the following command to install the tools: +在用 Ansible 配置 Vagrant boxes 时,你需要做几件准备的事情。首先在主机上安装 Ansible 和 Vagrant,在主机上运行下面的命令来安装: ``` sudo dnf install ansible vagrant vagrant-libvirt ``` -The above command installs both Ansible and Vagrant on your host system, along with Vagrant’s libvirt provider. Vagrant doesn’t provide functionality to host your virtual machine guests (VMs). Rather, it depends on third party providers such as libvirt, VirtualBox, VMWare, etc. to host the VMs. This provider works directly with libvirt and KVM on your Fedora system. +上面的命令将 Ansible 和 Vagrant 在你的主机上,也包括 Vagrant 的自动部署工具。Vagrant 不能自己管理虚拟主机,需要第三方工具比如:libirt,VirtualBox,VMWare等等。工具直接在你的 Fedora 系统上运行。 -Next, make sure your user is in the wheel group. This special group allows you to run system administration commands. If you created your user as an administrator, such as during installation, you’ll have this group membership. Run the following command: +接着确认你的账户在正确的用户组 wheel 当中,确保你可以运行系统管理员命令。如果你的账号在安装过程中就创建为管理员,那么你就肯定在这个用户组里。运行下面的命令: ``` id | grep wheel ``` -If you see output, your user is in the group, and you can move on to the next section. If not, run the following command. You’ll need to provide the password for the root account. Substitute your user name for the text : +如果你能看到输出,那么你的账户就在这个组里,可以进行下一步。如果没有的话,你需要运行下面的命令,这一步需要你提供 root 账户的密码,在里加上你的用户名: ``` su -c 'usermod -a -G wheel ' ``` -Then you will need to logout, and log back in, to inherit the group membership properly. +然后,你需要注销然后重新登录,确保在用户组里。 -Now it’s time to create your first Vagrant box, which you’ll then configure using Ansible. +现在要建立你的第一个 Vagrant box 了,你需要用 Ansible 来配置它。 -### Setting up the Vagrant box +### 设置 Vagrant box -Before you use Ansible to provision a box, you must create the box. To start, create a new directory which will store files related to the Vagrant box. To create this directory and make it the current working directory, issue the following command: +配置一个镜像 box 之前,你需要先创建它。创建一个目录,存放 Vagrant box 相关的文件,并且将它设置为工作目录,用下面这条命令: ``` mkdir -p ~/lampbox && cd ~/lampbox ``` -Before you create the box, you should understand the goal. This box is a simple example that runs CentOS 7 as its base system, along with the Apache web server, MariaDB (the popular open source database server from the original developers of MySQL) and PHP. +在创建镜像 box 之前,你需要搞清楚目的,这个镜像 box 是一个运行 CentOS 7 基础系统的模板包括 Apache 的 web 服务,MariaDB(MySQL 原始开发者创建的一个流行的开源数据库)数据库和 PHP 服务。 -To initialize the Vagrant box, use the vagrant init command: +初始化 Vagrant box,用 vagrant 开发工具初始化命令: ``` vagrant init centos/7 ``` -This command initializes the Vagrant box and creates a file named Vagrantfile, with some pre-configured variables. Open this file so you can modify it. The following line lists the base box used by this configuration. +这个命令初始化 Vagrant box 创建一些 Vagrantfile 名字的文件,也包含一些预先配置的文件。你可以打开和编辑它们,下面的命令显示基本的镜像box和配置。 ``` config.vm.box = "centos/7" ``` -Now setup port forwarding, so after you finish setup and the Vagrant box is running, you can test the server. To setup port forwarding, add the following line just before the end statement in Vagrantfile: +设置端口转发,这样在你设置玩 Vagrant box 之后可以测试它。用下面的命令实现: ``` config.vm.network "forwarded_port", guest: 80, host: 8080 ``` -This option maps port 80 of the Vagrant Box to port 8080 of the host machine. +这个命令将 Vagrant Box 的 80 端口映射为主机的 8080 端口。 -The next step is to set Ansible as our provisioning provider for the Vagrant Box. Add the following lines before the end statement in your Vagrantfile to set Ansible as the provisioning provider: +下一步是设置 Ansible 作为配置 Vagrant Box 的工具,下面的命令将 Ansible 作为配置工具在 end 之前加入到 Vagrantfile 中: ``` config.vm.provision :ansible do |ansible| @@ -74,13 +73,13 @@ config.vm.provision :ansible do |ansible| end ``` -(You must add all three lines before the final end statement.) Notice the statement ansible.playbook = “lamp.yml”. This statement defines the name of the playbook used to provision the box. +(必须将这三行在最后的语句之前加入)ansible.playbook = "lamp.yml"这一句定义了配置镜像box的手册的名字。 -### Creating the Ansible playbook +### 创建Ansible详细手册 -In Ansible, playbooks describe a policy to be enforced on your remote nodes. Put another way, playbooks manage configurations and deployments on remote nodes. Technically speaking, a playbook is a YAML file in which you write tasks to perform on remote nodes. In this tutorial, you’ll create a playbook named lamp.yml to provision the box. +Ansible 的手册描述的是执行在你的远端节点的策略,换句话说,它管理远端节点的配置和部署。详细的说,手册是一个 Yaml 文件,在里面你写入在远端节点上将要执行的任务。所以,你需要创建一个名为 lamp.yml 的手册来配置镜像 box。 -To make the playbook, create a file named lamp.yml in the same directory where your Vagrantfile is located and add the following lines to it: +在 Vagrantfile 的目录里创建一个 lamp.yml 文件,将下面的内容粘贴到文件当中: ``` --- @@ -104,43 +103,43 @@ To make the playbook, create a file named lamp.yml in the same directory where y command: firewall-cmd --add-service=http --permanent ``` -An explanation of each line of lamp.yml follows. +每一行代表的意思: -- hosts: all specifies the playbook should run over every host defined in the Ansible configuration. Since no hosts are configured hosts yet, the playbook will run on localhost. -- sudo: true states the tasks should be performed with root privileges. -- tasks: specifies the tasks to perform when the playbook runs. Under the tasks section: -- - name: … provides a descriptive name to the task -- - yum: … specifies the task should be executed by the yum module. The options name and state are key=value pairs for use by the yum module. +- hosts: 定义 Ansible 配置文件需要在所有的主机上运行,因为还没定义主机,暂时只在本地运行。 +- sudo: 需要用 root 权限运行的任务 +- tasks: 确定的任务 +- - name: 描述任务的名字 +- - yum: 描述任务需要调用 yum 模块,需要 key=value 成对被 yum 模块调用。 -When this playbook executes, it installs the latest versions of the Apache (httpd) web server, MariaDB, and PHP. Then it installs and starts firewalld, and opens a port for the Apache server. You’re now done writing the playbook for the box. Now it’s time to provision it. +当手册运行时,它会安装最新的 Apache 的 web 服务,MariaDB 和 PHP。当安装完毕开始工作,会给 Apache 打开一个端口。你可以给镜像 box 写手册,并且可以配置它了。 -### Provisioning the box +### 配置镜像 box -A few final steps remain before using the Vagrant Box provisioned using Ansible. To run this provisioning, execute the following command: +用 Ansible 配置 Vagrant Box 只需要以下几部了: ``` vagrant up --provider libvirt ``` -The above command starts the Vagrant box, downloads the base box image to the host system if not already present, and then runs the playbook lamp.yml to provision. +上面的命令运行 Vagrant box,将基本的镜像 box 下载到主机当中,然后运行 lamp.yml 手册来进行配置。 -If everything works fine, the output looks somewhat similar to this example: +如果一切正常,输出应该和下面的例子类似: ![](https://i1.wp.com/cdn.fedoramagazine.org/wp-content/uploads/2016/08/vagrant-ansible-playbook-run.png?w=574&ssl=1) -This output shows that the box has been provisioned. Now check whether the server is accessible. To confirm, open your web browser on the host machine and point it to the address http://localhost:8080. Remember, port 8080 of the local host is forwarded to port 80 of the Vagrant box. You should be greeted with the Apache welcome page like the one shown below: +这个输出显示镜像 box 已经被配置好了,现在检查服务是否可用,打开浏览器,输入 http://localhost:8080,记住主机的 8080 端口是 Vagrant box 映射过来的 80 端口。你应该可以看到如下的 Apache 的欢迎界面。 ![](https://i0.wp.com/cdn.fedoramagazine.org/wp-content/uploads/2016/08/vagrant-ansible-apache-up.png?w=1004&ssl=1) -To make changes to your Vagrant box, first edit the Ansible playbook lamp.yml. You can find plentiful documentation on Ansible at [its official website][4]. Then run the following command to re-provision the box: +改变 Vagrantbox,你可以修改 lamp.yml 手册,你能从 Ansible 的官网上找到很多文章。然后运行下面的命令: ``` vagrant provision ``` -### Conclusion +### 总结 -You’ve now seen how to use Ansible to provision Vagrant boxes. This was a basic example, but you can use these tools for many other use cases. For example, you can deploy complete applications along with up-to-date version of required tools. Be creative as you use Ansible to provision your remote nodes or containers. +现在我们知道怎么用 Ansible 来配置 Vagrant boxes 了。这只是一个基本的例子,但是你可以用这些工具来实现不同的例子。比如你可以部署最新的工具,现在你可以用 Ansible 来配置你自己的远端服务器和容器了。 -------------------------------------------------------------------------------- @@ -148,7 +147,7 @@ You’ve now seen how to use Ansible to provision Vagrant boxes. This was a basi via: https://fedoramagazine.org/using-ansible-provision-vagrant-boxes/ 作者:[Saurabh Badhwar][a] -译者:[译者ID](https://github.com/译者ID) +译者:[jiajia9linuxer](https://github.com/jiajia9linuxer) 校对:[校对者ID](https://github.com/校对者ID) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From ac3a402fb09b96b38fb3371ca14f67ff6875851d Mon Sep 17 00:00:00 2001 From: firstadream Date: Sat, 8 Oct 2016 22:37:39 +0800 Subject: [PATCH 032/316] Update 20160621 Docker Datacenter in AWS and Azure in Few Clicks.md --- ...20160621 Docker Datacenter in AWS and Azure in Few Clicks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/tech/20160621 Docker Datacenter in AWS and Azure in Few Clicks.md b/sources/tech/20160621 Docker Datacenter in AWS and Azure in Few Clicks.md index d9431155ff..a77c07561f 100644 --- a/sources/tech/20160621 Docker Datacenter in AWS and Azure in Few Clicks.md +++ b/sources/tech/20160621 Docker Datacenter in AWS and Azure in Few Clicks.md @@ -1,4 +1,4 @@ -translated by pspkforever +translated by pspkforever,now Firstadream DOCKER DATACENTER IN AWS AND AZURE IN A FEW CLICKS =================================================== From e85a5956bae8ad11b17be7524476e32f1b9c0f47 Mon Sep 17 00:00:00 2001 From: messon007 Date: Sat, 8 Oct 2016 21:57:58 +0100 Subject: [PATCH 033/316] =?UTF-8?q?=E3=80=90=E7=BF=BB=E8=AF=91=E4=B8=AD?= =?UTF-8?q?=E3=80=91Going=20Serverless=20with=20AWS=20Lambda=20and=20API?= =?UTF-8?q?=20Gateway?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit messon007翻译 --- ...0160807 Going Serverless with AWS Lambda and API Gateway.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sources/tech/20160807 Going Serverless with AWS Lambda and API Gateway.md b/sources/tech/20160807 Going Serverless with AWS Lambda and API Gateway.md index fa9ff7e5f9..5339933366 100644 --- a/sources/tech/20160807 Going Serverless with AWS Lambda and API Gateway.md +++ b/sources/tech/20160807 Going Serverless with AWS Lambda and API Gateway.md @@ -1,3 +1,6 @@ + +###################Translating by messon007################### + Going Serverless with AWS Lambda and API Gateway ============================ From 4b278643609d576fdd855f3132199c9d78d1d671 Mon Sep 17 00:00:00 2001 From: wxy Date: Sun, 9 Oct 2016 14:47:51 +0800 Subject: [PATCH 034/316] =?UTF-8?q?PUB:20160809=20Part=203=20-=20Let?= =?UTF-8?q?=E2=80=99s=20Build=20A=20Web=20Server?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @StdioA 哈哈哈,终于校对发布了!~ --- ...60809 Part 3 - Let’s Build A Web Server.md | 253 +++++++++--------- 1 file changed, 131 insertions(+), 122 deletions(-) rename {translated/tech => published}/20160809 Part 3 - Let’s Build A Web Server.md (70%) diff --git a/translated/tech/20160809 Part 3 - Let’s Build A Web Server.md b/published/20160809 Part 3 - Let’s Build A Web Server.md similarity index 70% rename from translated/tech/20160809 Part 3 - Let’s Build A Web Server.md rename to published/20160809 Part 3 - Let’s Build A Web Server.md index 41a128a8a7..9162ce1d3b 100644 --- a/translated/tech/20160809 Part 3 - Let’s Build A Web Server.md +++ b/published/20160809 Part 3 - Let’s Build A Web Server.md @@ -1,13 +1,13 @@ -translating by StdioA - 搭个 Web 服务器(三) ===================================== ->“当我们必须创造时,才能够学到更多。” ——伯爵 +>“当我们必须创造时,才能够学到更多。” ——皮亚杰 -在本系列的第二部分中,你创造了一个可以处理基本 HTTP GET 请求的、朴素的 WSGI 服务器。当时我问了一个问题:“你该如何让你的服务器在同一时间处理多个请求呢?”在这篇文章中,你会找到答案。系好安全带,我们要认真起来,全速前进了!你将会体验到一段非常快速的旅程。准备好你的 Linux,Mac OS X(或者其他 *nix 系统),还有你的 Python. 本文中所有源代码均可在 [GitHub][1] 上找到。 +在本系列的[第二部分](https://linux.cn/article-7685-1.html)中,你创造了一个可以处理基本 HTTP GET 请求的、朴素的 WSGI 服务器。当时我问了一个问题:“你该如何让你的服务器在同一时间处理多个请求呢?”在这篇文章中,你会找到答案。系好安全带,我们要认真起来,全速前进了!你将会体验到一段非常快速的旅程。准备好你的 Linux、Mac OS X(或者其他 *nix 系统),还有你的 Python。本文中所有源代码均可在 [GitHub][1] 上找到。 -首先,我们来回顾一下 Web 服务器的基本结构,以及服务器处理来自客户端的请求时,所需的必要步骤。你在第一及第二部分中创建的轮询服务器只能够在同一时间内处理一个请求。在处理完当前请求之前,它不能够打开一个新的客户端连接。所有请求为了等待服务都需要排队,在服务繁忙时,这个队伍可能会排的很长,一些客户端可能会感到不开心。 +### 服务器的基本结构及如何处理请求 + +首先,我们来回顾一下 Web 服务器的基本结构,以及服务器处理来自客户端的请求时,所需的必要步骤。你在[第一部分](https://linux.cn/article-7662-1.html)及[第二部分](https://linux.cn/article-7685-1.html)中创建的轮询服务器只能够一次处理一个请求。在处理完当前请求之前,它不能够接受新的客户端连接。所有请求为了等待服务都需要排队,在服务繁忙时,这个队伍可能会排的很长,一些客户端可能会感到不开心。 ![](https://ruslanspivak.com/lsbaws-part3/lsbaws_part3_it1.png) @@ -53,7 +53,7 @@ if __name__ == '__main__': serve_forever() ``` -为了观察到你的服务器在同一时间只能处理一个请求,我们对服务器的代码做一点点修改:在将响应发送至客户端之后,将程序阻塞 60 秒。这个修改只需要一行代码,来告诉服务器进程暂停 60 秒钟。 +为了观察到你的服务器在同一时间只能处理一个请求的行为,我们对服务器的代码做一点点修改:在将响应发送至客户端之后,将程序阻塞 60 秒。这个修改只需要一行代码,来告诉服务器进程暂停 60 秒钟。 ![](https://ruslanspivak.com/lsbaws-part3/lsbaws_part3_it2.png) @@ -84,7 +84,7 @@ HTTP/1.1 200 OK Hello, World! """ client_connection.sendall(http_response) - time.sleep(60) # 睡眠语句,阻塞该进程 60 秒 + time.sleep(60) ### 睡眠语句,阻塞该进程 60 秒 def serve_forever(): @@ -126,88 +126,85 @@ $ curl http://localhost:8888/hello ![](https://ruslanspivak.com/lsbaws-part3/lsbaws_part3_it3.png) -当你等待足够长的时间(60 秒以上)后,你会看到第一个 `curl` 程序完成,而第二个 `curl` 在屏幕上输出了“Hello, World!”,然后休眠 60 秒,进而停止运行。 +当你等待足够长的时间(60 秒以上)后,你会看到第一个 `curl` 程序完成,而第二个 `curl` 在屏幕上输出了“Hello, World!”,然后休眠 60 秒,进而终止。 ![](https://ruslanspivak.com/lsbaws-part3/lsbaws_part3_it4.png) -这两个程序这样运行,是因为在服务器在处理完第一个来自 `curl` 的请求之后,只有等待 60 秒才能开始处理第二个请求。这个处理请求的过程按顺序进行(也可以说,迭代进行),一步一步进行,在我们刚刚给出的例子中,在同一时间内只能处理一个请求。 +这样运行的原因是因为在服务器在处理完第一个来自 `curl` 的请求之后,只有等待 60 秒才能开始处理第二个请求。这个处理请求的过程按顺序进行(也可以说,迭代进行),一步一步进行,在我们刚刚给出的例子中,在同一时间内只能处理一个请求。 现在,我们来简单讨论一下客户端与服务器的交流过程。为了让两个程序在网络中互相交流,它们必须使用套接字。你应当在本系列的前两部分中见过它几次了。但是,套接字是什么? ![](https://ruslanspivak.com/lsbaws-part3/lsbaws_part3_it_socket.png) -套接字是一个交互通道的端点的抽象形式,它可以让你的程序通过文件描述符来与其它程序进行交流。在这篇文章中,我只会单独讨论 Linux 或 Mac OS X 中的 TCP/IP 套接字。这里有一个重点概念需要你去理解:TCP 套接字对。 +套接字(socket)是一个通讯通道端点(endpoint)的抽象描述,它可以让你的程序通过文件描述符来与其它程序进行交流。在这篇文章中,我只会单独讨论 Linux 或 Mac OS X 中的 TCP/IP 套接字。这里有一个重点概念需要你去理解:TCP 套接字对(socket pair)。 -> TCP 连接使用的套接字对是一个由 4 个元素组成的元组,它确定了 TCP 连接的两端:本地 IP 地址、本地端口、远端 IP 地址及远端端口。一个套接字对独一无二地确定了网络中的每一个 TCP 连接。在连接一端的两个值:一个 IP 地址和一个端口,通常被称作一个套接字。[1][4] +> TCP 连接使用的套接字对是一个由 4 个元素组成的元组,它确定了 TCP 连接的两端:本地 IP 地址、本地端口、远端 IP 地址及远端端口。一个套接字对唯一地确定了网络中的每一个 TCP 连接。在连接一端的两个值:一个 IP 地址和一个端口,通常被称作一个套接字。(引自[《UNIX 网络编程 卷1:套接字联网 API (第3版)》][4]) ![](https://ruslanspivak.com/lsbaws-part3/lsbaws_part3_it_socketpair.png) -所以,元组 {10.10.10.2:49152, 12.12.12.3:8888} 就是一个能够在客户端确定 TCP 连接两端的套接字对,而元组 {12.12.12.3:8888, 10.10.10.2:49152} 则是在服务端确定 TCP 连接两端的套接字对。在这个例子中,确定 TCP 服务端的两个值(IP 地址 `12.12.12.3` 及端口 `8888`),代表一个套接字;另外两个值则代表客户端的套接字。 +所以,元组 `{10.10.10.2:49152, 12.12.12.3:8888}` 就是一个能够在客户端确定 TCP 连接两端的套接字对,而元组 `{12.12.12.3:8888, 10.10.10.2:49152}` 则是在服务端确定 TCP 连接两端的套接字对。在这个例子中,确定 TCP 服务端的两个值(IP 地址 `12.12.12.3` 及端口 `8888`),代表一个套接字;另外两个值则代表客户端的套接字。 一个服务器创建一个套接字并开始建立连接的基本工作流程如下: ![](https://ruslanspivak.com/lsbaws-part3/lsbaws_part3_it_server_socket_sequence.png) -1. 服务器创建一个 TCP/IP 套接字。我们可以用下面那条 Python 语句来创建: +1. 服务器创建一个 TCP/IP 套接字。我们可以用这条 Python 语句来创建: -``` -listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) -``` + ``` + listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + ``` +2. 服务器可能会设定一些套接字选项(这个步骤是可选的,但是你可以看到上面的服务器代码做了设定,这样才能够在重启服务器时多次复用同一地址): -2. 服务器可能会设定一些套接字选项(这个步骤是可选的,但是你可以看到上面的服务器代码做了设定,这样才能够在重启服务器时多次复用同一地址)。 - -``` -listen_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) -``` - -3. 然后,服务器绑定一个地址。绑定函数可以将一个本地协议地址赋给套接字。若使用 TCP 协议,调用绑定函数时,需要指定一个端口号,一个 IP 地址,或两者兼有,或两者兼无。[1][4] - -``` -listen_socket.bind(SERVER_ADDRESS) -``` + ``` + listen_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + ``` +3. 然后,服务器绑定一个地址。绑定函数 `bind` 可以将一个本地协议地址赋给套接字。若使用 TCP 协议,调用绑定函数 `bind` 时,需要指定一个端口号,一个 IP 地址,或两者兼有,或两者全无。(引自[《UNIX网络编程 卷1:套接字联网 API (第3版)》][4]) + ``` + listen_socket.bind(SERVER_ADDRESS) + ``` 4. 然后,服务器开启套接字的监听模式。 -``` -listen_socket.listen(REQUEST_QUEUE_SIZE) -``` + ``` + listen_socket.listen(REQUEST_QUEUE_SIZE) + ``` -监听函数只应在服务端调用。它会通知操作系统内核,标明它会接受所有向该套接字发送请求的链接。 +监听函数 `listen` 只应在服务端调用。它会通知操作系统内核,表明它会接受所有向该套接字发送的入站连接请求。 -以上四步完成后,服务器将循环接收来自客户端的连接,一次循环处理一条。当有连接可用时,`accept` 函数将会返回一个已连接的客户端套接字。然后,服务器从客户端套接字中读取请求数据,将它在标准输出流中打印出来,并向客户端回送一条消息。然后,服务器会关闭这个客户端连接,并准备接收一个新的客户端连接。 +以上四步完成后,服务器将循环接收来自客户端的连接,一次循环处理一条。当有连接可用时,接受请求函数 `accept` 将会返回一个已连接的客户端套接字。然后,服务器从这个已连接的客户端套接字中读取请求数据,将数据在其标准输出流中输出出来,并向客户端回送一条消息。然后,服务器会关闭这个客户端连接,并准备接收一个新的客户端连接。 这是客户端使用 TCP/IP 协议与服务器通信的必要步骤: ![](https://ruslanspivak.com/lsbaws-part3/lsbaws_part3_it_client_socket_sequence.png) -下面是一段示例代码,使用这段代码,客户端可以连接你的服务器,发送一个请求,并打印响应内容: +下面是一段示例代码,使用这段代码,客户端可以连接你的服务器,发送一个请求,并输出响应内容: ``` import socket -# 创建一个套接字,并连接值服务器 +### 创建一个套接字,并连接值服务器 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(('localhost', 8888)) -# 发送一段数据,并接收响应数据 +### 发送一段数据,并接收响应数据 sock.sendall(b'test') data = sock.recv(1024) print(data.decode()) ``` -在创建套接字后,客户端需要连接至服务器。我们可以调用 `connect` 函数来完成这个操作: +在创建套接字后,客户端需要连接至服务器。我们可以调用连接函数 `connect` 来完成这个操作: ``` sock.connect(('localhost', 8888)) ``` -客户端只需提供待连接服务器的 IP 地址(或主机名),及端口号,即可连接至远端服务器。 +客户端只需提供待连接的远程服务器的 IP 地址(或主机名),及端口号,即可连接至远端服务器。 -你可能已经注意到了,客户端不需要调用 `bind` 及 `accept` 函数,就可以与服务器建立连接。客户端不需要调用 `bind` 函数是因为客户端不需要关注本地 IP 地址及端口号。操作系统内核中的 TCP/IP 协议栈会在客户端调用 `connect` 函数时,自动为套接字分配本地 IP 地址及本地端口号。这个本地端口被称为临时端口,也就是一个短暂开放的端口。 +你可能已经注意到了,客户端不需要调用 `bind` 及 `accept` 函数,就可以与服务器建立连接。客户端不需要调用 `bind` 函数是因为客户端不需要关注本地 IP 地址及端口号。操作系统内核中的 TCP/IP 协议栈会在客户端调用 `connect` 函数时,自动为套接字分配本地 IP 地址及本地端口号。这个本地端口被称为临时端口(ephemeral port),即一个短暂开放的端口。 ![](https://ruslanspivak.com/lsbaws-part3/lsbaws_part3_it_ephemeral_port.png) -服务器中有一些端口被用于承载一些众所周知的服务,它们被称作通用端口:如 80 端口用于 HTTP 服务,22 端口用于 SSH 服务。打开你的 Python shell,与你在本地运行的服务器建立一个连接,来看看内核给你的客户端套接字分配了哪个临时端口(在尝试这个例子之前,你需要运行服务器程序 `webserver3a.py` 或 `webserver3b.py`): +服务器中有一些端口被用于承载一些众所周知的服务,它们被称作通用(well-known)端口:如 80 端口用于 HTTP 服务,22 端口用于 SSH 服务。打开你的 Python shell,与你在本地运行的服务器建立一个连接,来看看内核给你的客户端套接字分配了哪个临时端口(在尝试这个例子之前,你需要运行服务器程序 `webserver3a.py` 或 `webserver3b.py`): ``` >>> import socket @@ -222,12 +219,11 @@ sock.connect(('localhost', 8888)) 在我开始回答我在第二部分中提出的问题之前,我还需要快速讲解一些概念。你很快就会明白这些概念为什么非常重要。这两个概念,一个是进程,另外一个是文件描述符。 -什么是进程?进程就是一个程序执行的实体。举个例子:当你的服务器代码被执行时,它会被载入内存,而内存中表现此次程序运行的实体就叫做进程。内核记录了进程的一系列有关信息——比如进程 ID——来追踪它的运行情况。当你在执行轮询服务器 `webserver3a.py` 或 `webserver3b.py` 时,你只启动了一个进程。 +什么是进程?进程就是一个程序执行的实体。举个例子:当你的服务器代码被执行时,它会被载入内存,而内存中表现此次程序运行的实体就叫做进程。内核记录了进程的一系列有关信息——比如进程 ID——来追踪它的运行情况。当你在执行轮询服务器 `webserver3a.py` 或 `webserver3b.py` 时,你其实只是启动了一个进程。 ![](https://ruslanspivak.com/lsbaws-part3/lsbaws_part3_it_server_process.png) 我们在终端窗口中运行 `webserver3b.py`: -Start the server webserver3b.py in a terminal window: ``` $ python webserver3b.py @@ -240,7 +236,7 @@ $ ps | grep webserver3b | grep -v grep 7182 ttys003 0:00.04 python webserver3b.py ``` -`ps` 命令显示,我们刚刚只运行了一个 Python 进程 `webserver3b`。当一个进程被创建时,内核会为其分配一个进程 ID,也就是 PID。在 UNIX 中,所有用户进程都有一个父进程;当然,这个父进程也有进程 ID,叫做父进程 ID,缩写为 PPID。假设你默认使用 BASH shell,那当你启动服务器时,一个新的进程会被启动,同时被赋予一个 PID,而它的父进程 PID 会被设为 BASH shell 的 PID。 +`ps` 命令显示,我们刚刚只运行了一个 Python 进程 `webserver3b.py`。当一个进程被创建时,内核会为其分配一个进程 ID,也就是 PID。在 UNIX 中,所有用户进程都有一个父进程;当然,这个父进程也有进程 ID,叫做父进程 ID,缩写为 PPID。假设你默认使用 BASH shell,那当你启动服务器时,就会启动一个新的进程,同时被赋予一个 PID,而它的父进程 PID 会被设为 BASH shell 的 PID。 ![](https://ruslanspivak.com/lsbaws-part3/lsbaws_part3_it_ppid_pid.png) @@ -248,11 +244,11 @@ $ ps | grep webserver3b | grep -v grep ![](https://ruslanspivak.com/lsbaws-part3/lsbaws_part3_it_pid_ppid_screenshot.png) -另外一个需要了解的概念,就是文件描述符。什么是文件描述符?文件描述符是一个非负整数,当进程打开一个现有文件、创建新文件或创建一个新的套接字时,内核会将这个数返回给进程。你以前可能听说过,在 UNIX 中,一切皆是文件。内核会根据一个文件描述符来为一个进程打开一个文件。当你需要读取文件或向文件写入时,我们同样通过文件描述符来定位这个文件。Python 提供了高层次的文件(或套接字)对象,所以你不需要直接通过文件描述符来定位文件。但是,在高层对象之下,我们就是用它来在 UNIX 中定位文件及套接字:整形的文件描述符。 +另外一个需要了解的概念,就是文件描述符。什么是文件描述符?文件描述符是一个非负整数,当进程打开一个现有文件、创建新文件或创建一个新的套接字时,内核会将这个数返回给进程。你以前可能听说过,在 UNIX 中,一切皆是文件。内核会按文件描述符来找到一个进程所打开的文件。当你需要读取文件或向文件写入时,我们同样通过文件描述符来定位这个文件。Python 提供了高层次的操作文件(或套接字)的对象,所以你不需要直接通过文件描述符来定位文件。但是,在高层对象之下,我们就是用它来在 UNIX 中定位文件及套接字,通过这个整数的文件描述符。 ![](https://ruslanspivak.com/lsbaws-part3/lsbaws_part3_it_process_descriptors.png) -一般情况下,UNIX shell 会将一个进程的标准输入流的文件描述符设为 0,标准输出流设为 1,而标准错误打印的文件描述符会被设为 2。 +一般情况下,UNIX shell 会将一个进程的标准输入流(STDIN)的文件描述符设为 0,标准输出流(STDOUT)设为 1,而标准错误打印(STDERR)的文件描述符会被设为 2。 ![](https://ruslanspivak.com/lsbaws-part3/lsbaws_part3_it_default_descriptors.png) @@ -289,7 +285,7 @@ hello 3 ``` -我还想再提一件事:不知道你有没有注意到,在我们的第二个轮询服务器 `webserver3b.py` 中,当你的服务器休眠 60 秒的过程中,你仍然可以通过第二个 `curl` 命令连接至服务器。当然 `curl` 命令并没有立刻输出任何内容而是挂在哪里,但是既然服务器没有接受连接,那它为什么不立即拒绝掉连接,而让它还能够继续与服务器建立连接呢?这个问题的答案是:当我在调用套接字对象的 `listen` 方法时,我为该方法提供了一个 `BACKLOG` 参数,在代码中用 `REQUEST_QUEUE_SIZE` 变量来表示。`BACKLOG` 参数决定了在内核中为存放即将到来的连接请求所创建的队列的大小。当服务器 `webserver3b.py` 被挂起的时候,你运行的第二个 `curl` 命令依然能够连接至服务器,因为内核中用来存放即将接收的连接请求的队列依然拥有足够大的可用空间。 +我还想再提一件事:不知道你有没有注意到,在我们的第二个轮询服务器 `webserver3b.py` 中,当你的服务器休眠 60 秒的过程中,你仍然可以通过第二个 `curl` 命令连接至服务器。当然 `curl` 命令并没有立刻输出任何内容而是挂在哪里,但是既然服务器没有接受连接,那它为什么不立即拒绝掉连接,而让它还能够继续与服务器建立连接呢?这个问题的答案是:当我在调用套接字对象的 `listen` 方法时,我为该方法提供了一个 `BACKLOG` 参数,在代码中用 `REQUEST_QUEUE_SIZE` 常量来表示。`BACKLOG` 参数决定了在内核中为存放即将到来的连接请求所创建的队列的大小。当服务器 `webserver3b.py` 在睡眠的时候,你运行的第二个 `curl` 命令依然能够连接至服务器,因为内核中用来存放即将接收的连接请求的队列依然拥有足够大的可用空间。 尽管增大 `BACKLOG` 参数并不能神奇地使你的服务器同时处理多个请求,但当你的服务器很繁忙时,将它设置为一个较大的值还是相当重要的。这样,在你的服务器调用 `accept` 方法时,不需要再等待一个新的连接建立,而可以立刻直接抓取队列中的第一个客户端连接,并不加停顿地立刻处理它。 @@ -297,7 +293,7 @@ hello ![](https://ruslanspivak.com/lsbaws-part3/lsbaws_part3_checkpoint.png) -- 迭代服务器 +- 轮询服务器 - 服务端套接字创建流程(创建套接字,绑定,监听及接受) - 客户端连接创建流程(创建套接字,连接) - 套接字对 @@ -308,6 +304,8 @@ hello - 文件描述符 - 套接字的 `listen` 方法中,`BACKLOG` 参数的含义 +### 如何并发处理多个请求 + 现在,我可以开始回答第二部分中的那个问题了:“你该如何让你的服务器在同一时间处理多个请求呢?”或者换一种说法:“如何编写一个并发服务器?” ![](https://ruslanspivak.com/lsbaws-part3/lsbaws_part3_conc2_service_clients.png) @@ -368,13 +366,13 @@ def serve_forever(): while True: client_connection, client_address = listen_socket.accept() pid = os.fork() - if pid == 0: # 子进程 - listen_socket.close() # 关闭子进程中复制的套接字对象 + if pid == 0: ### 子进程 + listen_socket.close() ### 关闭子进程中复制的套接字对象 handle_request(client_connection) client_connection.close() - os._exit(0) # 子进程在这里退出 - else: # 父进程 - client_connection.close() # 关闭父进程中的客户端连接对象,并循环执行 + os._exit(0) ### 子进程在这里退出 + else: ### 父进程 + client_connection.close() ### 关闭父进程中的客户端连接对象,并循环执行 if __name__ == '__main__': serve_forever() @@ -386,13 +384,13 @@ if __name__ == '__main__': $ python webserver3c.py ``` -然后,像我们之前测试轮询服务器那样,运行两个 `curl` 命令,来看看这次的效果。现在你可以看到,即使子进程在处理客户端请求后会休眠 60 秒,但它并不会影响其它客户端连接,因为他们都是由完全独立的进程来处理的。你应该看到你的 `curl` 命令立即输出了“Hello, World!”然后挂起 60 秒。你可以按照你的想法运行尽可能多的 `curl` 命令(好吧,并不能运行特别特别多 ^_^),所有的命令都会立刻输出来自服务器的响应“Hello, World!”,并不会出现任何可被察觉到的延迟行为。试试看吧。 +然后,像我们之前测试轮询服务器那样,运行两个 `curl` 命令,来看看这次的效果。现在你可以看到,即使子进程在处理客户端请求后会休眠 60 秒,但它并不会影响其它客户端连接,因为他们都是由完全独立的进程来处理的。你应该看到你的 `curl` 命令立即输出了“Hello, World!”然后挂起 60 秒。你可以按照你的想法运行尽可能多的 `curl` 命令(好吧,并不能运行特别特别多 `^_^`),所有的命令都会立刻输出来自服务器的响应 “Hello, World!”,并不会出现任何可被察觉到的延迟行为。试试看吧。 -如果你要理解 `fork()`,那最重要的一点是:你调用了它一次,但是它会返回两次:一次在父进程中,另一次是在子进程中。当你创建了一个新进程,那么 `fork()` 在子进程中的返回值是 0。如果是在父进程中,那 `fork()` 函数会返回子进程的 PID。 +如果你要理解 `fork()`,那最重要的一点是:**你调用了它一次,但是它会返回两次** —— 一次在父进程中,另一次是在子进程中。当你创建了一个新进程,那么 `fork()` 在子进程中的返回值是 0。如果是在父进程中,那 `fork()` 函数会返回子进程的 PID。 ![](https://ruslanspivak.com/lsbaws-part3/lsbaws_part3_conc2_how_fork_works.png) -我依然记得在第一次看到它并尝试使用 `fork()` 的时候,我是多么的入迷。它在我眼里就像是魔法一样。这就好像我在读一段顺序执行的代码,然后“砰”地一声,代码变成了两份,然后出现了两个实体,同时并行地运行相同的代码。讲真,那个时候我觉得它真的跟魔法一样神奇。 +我依然记得在第一次看到它并尝试使用 `fork()` 的时候,我是多么的入迷。它在我眼里就像是魔法一样。这就好像我在读一段顺序执行的代码,然后“砰!”地一声,代码变成了两份,然后出现了两个实体,同时并行地运行相同的代码。讲真,那个时候我觉得它真的跟魔法一样神奇。 当父进程创建出一个新的子进程时,子进程会复制从父进程中复制一份文件描述符: @@ -401,38 +399,39 @@ $ python webserver3c.py 你可能注意到,在上面的代码中,父进程关闭了客户端连接: ``` -else: # parent +else: ### parent client_connection.close() # close parent copy and loop over ``` -不过,既然父进程关闭了这个套接字,那为什么子进程仍然能够从来自客户端的套接字中读取数据呢?答案就在上面的图片中。内核会使用描述符引用计数器来决定是否要关闭一个套接字。当你的服务器创建一个子进程时,子进程会复制父进程的所有文件描述符,内核中改描述符的引用计数也会增加。如果只有一个父进程及一个子进程,那客户端套接字的文件描述符引用数应为 2;当父进程关闭客户端连接的套接字时,内核只会减少它的引用计数,将其变为 1,但这仍然不会使内核关闭该套接字。子进程也关闭了父进程中 `listen_socket` 的复制实体,因为子进程不需要关注新的客户端连接,而只需要处理已建立的客户端连接中的请求。 +不过,既然父进程关闭了这个套接字,那为什么子进程仍然能够从来自客户端的套接字中读取数据呢?答案就在上面的图片中。内核会使用描述符引用计数器来决定是否要关闭一个套接字。当你的服务器创建一个子进程时,子进程会复制父进程的所有文件描述符,内核中该描述符的引用计数也会增加。如果只有一个父进程及一个子进程,那客户端套接字的文件描述符引用数应为 2;当父进程关闭客户端连接的套接字时,内核只会减少它的引用计数,将其变为 1,但这仍然不会使内核关闭该套接字。子进程也关闭了父进程中 `listen_socket` 的复制实体,因为子进程不需要关注新的客户端连接,而只需要处理已建立的客户端连接中的请求。 ``` -listen_socket.close() # 关闭子进程中的复制实体 +listen_socket.close() ### 关闭子进程中的复制实体 ``` 我们将会在后文中讨论,如果你不关闭那些重复的描述符,会发生什么。 -你可以从你的并发服务器源码看到,父进程的主要职责为:接受一个新的客户端连接,复制出一个子进程来处理这个连接,然后继续循环来接受另外的客户端连接,仅此而已。服务器父进程并不会处理客户端连接——子进程才会做这件事。 +你可以从你的并发服务器源码中看到,父进程的主要职责为:接受一个新的客户端连接,复制出一个子进程来处理这个连接,然后继续循环来接受另外的客户端连接,仅此而已。服务器父进程并不会处理客户端连接——子进程才会做这件事。 -打个岔:当我们说两个事件并发执行时,我们在说什么? -A little aside. What does it mean when we say that two events are concurrent? +打个岔:当我们说两个事件并发执行时,我们所要表达的意思是什么? ![](https://ruslanspivak.com/lsbaws-part3/lsbaws_part3_conc2_concurrent_events.png) 当我们说“两个事件并发执行”时,它通常意味着这两个事件同时发生。简单来讲,这个定义没问题,但你应该记住它的严格定义: -> 如果你阅读代码时,无法判断两个事件的发生顺序,那这两个事件就是并发执行的。[2][5] +> 如果你不能在代码中判断两个事件的发生顺序,那这两个事件就是并发执行的。(引自[《信号系统简明手册 (第二版): 并发控制深入浅出及常见错误》][5]) 好的,现在你又该回顾一下你刚刚学过的知识点了。 ![](https://ruslanspivak.com/lsbaws-part3/lsbaws_part3_checkpoint.png) - 在 Unix 中,编写一个并发服务器的最简单的方式——使用 `fork()` 系统调用; -- 当一个进程复制出另一个进程时,它会变成刚刚复制出的进程的父进程; +- 当一个进程分叉(`fork`)出另一个进程时,它会变成刚刚分叉出的进程的父进程; - 在进行 `fork` 调用后,父进程和子进程共享相同的文件描述符; -- 系统内核通过描述符引用计数来决定是否要关闭该描述符对应的文件或套接字; -- 服务器父进程的主要职责:现在它做的只是从客户端接受一个新的连接,复制出子进程来处理这个客户端连接,然后开始下一轮循环,去接收新的客户端连接。 +- 系统内核通过描述符的引用计数来决定是否要关闭该描述符对应的文件或套接字; +- 服务器父进程的主要职责:现在它做的只是从客户端接受一个新的连接,分叉出子进程来处理这个客户端连接,然后开始下一轮循环,去接收新的客户端连接。 + +### 进程分叉后不关闭重复的套接字会发生什么? 我们来看看,如果我们不在父进程与子进程中关闭重复的套接字描述符会发生什么。下面是刚才的并发服务器代码的修改版本,这段代码(`webserver3d.py` 中,服务器不会关闭重复的描述符): @@ -470,15 +469,15 @@ def serve_forever(): clients = [] while True: client_connection, client_address = listen_socket.accept() - # 将引用存储起来,否则在下一轮循环时,他们会被垃圾回收机制销毁 + ### 将引用存储起来,否则在下一轮循环时,他们会被垃圾回收机制销毁 clients.append(client_connection) pid = os.fork() - if pid == 0: # 子进程 - listen_socket.close() # 关闭子进程中多余的套接字 + if pid == 0: ### 子进程 + listen_socket.close() ### 关闭子进程中多余的套接字 handle_request(client_connection) client_connection.close() - os._exit(0) # 子进程在这里结束 - else: # 父进程 + os._exit(0) ### 子进程在这里结束 + else: ### 父进程 # client_connection.close() print(len(clients)) @@ -503,7 +502,7 @@ Hello, World! ![](https://ruslanspivak.com/lsbaws-part3/lsbaws_part3_conc3_child_is_active.png) -所以,为什么 `curl` 不终止呢?原因就在于多余的文件描述符。当子进程关闭客户端连接时,系统内核会减少客户端套接字的引用计数,将其变为 1。服务器子进程退出了,但客户端套接字并没有被内核关闭,因为该套接字的描述符引用计数并没有变为 0,所以,这就导致了连接终止包(在 TCP/IP 协议中称作 `FIN`)不会被发送到客户端,所以客户端会一直保持连接。这里就会出现另一个问题:如果你的服务器在长时间运行,并且不关闭重复的文件描述符,那么可用的文件描述符会被消耗殆尽: +所以,为什么 `curl` 不终止呢?原因就在于文件描述符的副本。当子进程关闭客户端连接时,系统内核会减少客户端套接字的引用计数,将其变为 1。服务器子进程退出了,但客户端套接字并没有被内核关闭,因为该套接字的描述符引用计数并没有变为 0,所以,这就导致了连接终止包(在 TCP/IP 协议中称作 `FIN`)不会被发送到客户端,所以客户端会一直保持连接。这里也会出现另一个问题:如果你的服务器长时间运行,并且不关闭文件描述符的副本,那么可用的文件描述符会被消耗殆尽: ![](https://ruslanspivak.com/lsbaws-part3/lsbaws_part3_conc3_out_of_descriptors.png) @@ -529,7 +528,7 @@ virtual memory (kbytes, -v) unlimited file locks (-x) unlimited ``` -你可以从上面的结果看到,在我的 Ubuntu box 中,系统为我的服务器进程分配的最大可用文件描述符(文件打开)数为 1024。 +你可以从上面的结果看到,在我的 Ubuntu 机器中,系统为我的服务器进程分配的最大可用文件描述符(文件打开)数为 1024。 现在我们来看一看,如果你的服务器不关闭重复的描述符,它会如何消耗可用的文件描述符。在一个已有的或新建的终端窗口中,将你的服务器进程的最大可用文件描述符设为 256: @@ -607,15 +606,18 @@ if __name__ == '__main__': $ python client3.py --max-clients=300 ``` -过一会,你的服务器就该爆炸了。这是我的环境中出现的异常截图: +过一会,你的服务器进程就该爆了。这是我的环境中出现的异常截图: ![](https://ruslanspivak.com/lsbaws-part3/lsbaws_part3_conc3_too_many_fds_exc.png) -这个例子很明显——你的服务器应该关闭重复的描述符。但是,即使你关闭了多余的描述符,你依然没有摆脱险境,因为你的服务器还有一个问题,这个问题在于“僵尸”! +这个例子很明显——你的服务器应该关闭描述符副本。 + +#### 僵尸进程 + +但是,即使你关闭了描述符副本,你依然没有摆脱险境,因为你的服务器还有一个问题,这个问题在于“僵尸(zombies)”! ![](https://ruslanspivak.com/lsbaws-part3/lsbaws_part3_conc3_zombies.png) - 没错,这个服务器代码确实在制造僵尸进程。我们来看看怎么回事。重新运行你的服务器: ``` @@ -636,13 +638,13 @@ vagrant 9099 0.0 1.2 31804 6256 pts/0 S+ 16:33 0:00 python webserve vagrant 9102 0.0 0.0 0 0 pts/0 Z+ 16:33 0:00 [python] ``` -你看到第二行中,pid 为 9102,状态为 Z+,名字里面有个 `` 的进程了吗?那就是我们的僵尸进程。这个僵尸进程的问题在于:你无法将它杀掉。 +你看到第二行中,pid 为 9102,状态为 `Z+`,名字里面有个 `` 的进程了吗?那就是我们的僵尸进程。这个僵尸进程的问题在于:你无法将它杀掉! ![](https://ruslanspivak.com/lsbaws-part3/lsbaws_part3_conc3_kill_zombie.png) 就算你尝试使用 `kill -9` 来杀死僵尸进程,它们仍旧会存活。自己试试看,看看结果。 -这个僵尸到底是什么,为什么我们的服务器会造出它们呢?一个僵尸进程是一个已经结束的进程,但它的父进程并没有等待它结束,并且也没有收到它的终结状态。如果一个进程在父进程退出之前退出,系统内核会把它变为一个僵尸进程,存储它的部分信息,以便父进程读取。内核保存的进程信息通常包括进程 ID,进程终止状态,以及进程的资源占用情况。OK,所以僵尸进程确实有存在的意义,但如果服务器不管这些僵尸进程,你的系统调用将会被阻塞。我们来看看这个要如何发生。首先,关闭你的服务器;然后,在一个新的终端窗口中,使用 `ulimit` 命令将最大用户进程数设为 400(同时,要确保你的最大可用描述符数大于这个数字,我们在这里设为 500): +这个僵尸到底是什么,为什么我们的服务器会造出它们呢?一个僵尸进程(zombie)是一个已经结束的进程,但它的父进程并没有等待(`waited`)它结束,并且也没有收到它的终结状态。如果一个进程在父进程退出之前退出,系统内核会把它变为一个僵尸进程,存储它的部分信息,以便父进程读取。内核保存的进程信息通常包括进程 ID、进程终止状态,以及进程的资源占用情况。OK,所以僵尸进程确实有存在的意义,但如果服务器不管这些僵尸进程,你的系统将会被壅塞。我们来看看这个会如何发生。首先,关闭你运行的服务器;然后,在一个新的终端窗口中,使用 `ulimit` 命令将最大用户进程数设为 400(同时,要确保你的最大可用描述符数大于这个数字,我们在这里设为 500): ``` $ ulimit -u 400 @@ -661,33 +663,35 @@ $ python webserver3d.py $ python client3.py --max-clients=500 ``` -然后,过一会,你的服务器应该会再次爆炸,它会在创建新进程时抛出一个 `OSError: 资源暂时不可用` 异常。但它并没有达到系统允许的最大进程数。这是我的环境中输出的异常信息截图: +然后,过一会,你的服务器进程应该会再次爆了,它会在创建新进程时抛出一个 `OSError: 资源暂时不可用` 的异常。但它并没有达到系统允许的最大进程数。这是我的环境中输出的异常信息截图: ![](https://ruslanspivak.com/lsbaws-part3/lsbaws_part3_conc3_resource_unavailable.png) -你可以看到,如果服务器不管僵尸进程,它们会引发问题。我会简单探讨一下僵尸进程问题的解决方案。 +你可以看到,如果服务器不管僵尸进程,它们会引发问题。接下来我会简单探讨一下僵尸进程问题的解决方案。 我们来回顾一下你刚刚掌握的知识点: ![](https://ruslanspivak.com/lsbaws-part3/lsbaws_part3_checkpoint.png) -- 如果你不关闭重复的描述符,客户端就不会在请求处理完成后终止,因为客户端连接没有被关闭; -- 如果你不关闭重复的描述符,长久运行的服务器最终会把可用的文件描述符(最大文件打开数)消耗殆尽; -- 当你创建一个新进程,而父进程不等待子进程,也不在子进程结束后收集它的终止状态,它会变为一个僵尸进程; -- 僵尸通常都会吃东西,在我们的例子中,僵尸进程会占用资源。如果你的服务器不管僵尸进程,它最终会消耗掉所有的可用进程(最大用户进程数); -- 你不能杀死僵尸进程,你需要等待它。 +- 如果你不关闭文件描述符副本,客户端就不会在请求处理完成后终止,因为客户端连接没有被关闭; +- 如果你不关闭文件描述符副本,长久运行的服务器最终会把可用的文件描述符(最大文件打开数)消耗殆尽; +- 当你创建一个新进程,而父进程不等待(`wait`)子进程,也不在子进程结束后收集它的终止状态,它会变为一个僵尸进程; +- 僵尸通常都会吃东西,在我们的例子中,僵尸进程会吃掉资源。如果你的服务器不管僵尸进程,它最终会消耗掉所有的可用进程(最大用户进程数); +- 你不能杀死(`kill`)僵尸进程,你需要等待(`wait`)它。 -所以,你需要做什么来处理僵尸进程呢?你需要修改你的服务器代码,来等待僵尸进程,并收集它们的终止信息。你可以在代码中使用系统调用 `wait` 来完成这个任务。不幸的是,这个方法里理想目标还很远,因为在没有终止的子进程存在的情况下调用 `wait` 会导致程序阻塞,这会阻碍你的服务器处理新的客户端连接请求。那么,我们有其他选择吗?嗯,有的,其中一个解决方案需要结合信号处理以及 `wait` 系统调用。 +### 如何处理僵尸进程? + +所以,你需要做什么来处理僵尸进程呢?你需要修改你的服务器代码,来等待(`wait`)僵尸进程,并收集它们的终止信息。你可以在代码中使用系统调用 `wait` 来完成这个任务。不幸的是,这个方法离理想目标还很远,因为在没有终止的子进程存在的情况下调用 `wait` 会导致服务器进程阻塞,这会阻碍你的服务器处理新的客户端连接请求。那么,我们有其他选择吗?嗯,有的,其中一个解决方案需要结合信号处理以及 `wait` 系统调用。 ![](https://ruslanspivak.com/lsbaws-part3/lsbaws_part3_conc4_signaling.png) -这是它的工作流程。当一个子进程退出时,内核会发送 `SIGCHLD` 信号。父进程可以设置一个信号处理器,它可以异步响应 `SIGCHLD` 信号,并在信号响应函数中等待子进程收集终止信息,从而阻止了僵尸进程的存在。 +这是它的工作流程。当一个子进程退出时,内核会发送 `SIGCHLD` 信号。父进程可以设置一个信号处理器,它可以异步响应 `SIGCHLD` 信号,并在信号响应函数中等待(`wait`)子进程收集终止信息,从而阻止了僵尸进程的存在。 ![](https://ruslanspivak.com/lsbaws-part3/lsbaws_part_conc4_sigchld_async.png) -顺便,异步事件意味着父进程无法提前知道事件的发生时间。 +顺便说一下,异步事件意味着父进程无法提前知道事件的发生时间。 -修改你的服务器代码,设置一个 `SIGCHLD` 信号处理器,在信号处理器中等待终止的子进程。修改后的代码如下(webserver3e.py): +修改你的服务器代码,设置一个 `SIGCHLD` 信号处理器,在信号处理器中等待(`wait`)终止的子进程。修改后的代码如下(webserver3e.py): ``` ####################################################### @@ -722,7 +726,7 @@ HTTP/1.1 200 OK Hello, World! """ client_connection.sendall(http_response) - # 挂起进程,来允许父进程完成循环,并在 "accept" 处阻塞 + ### 挂起进程,来允许父进程完成循环,并在 "accept" 处阻塞 time.sleep(3) @@ -738,12 +742,12 @@ def serve_forever(): while True: client_connection, client_address = listen_socket.accept() pid = os.fork() - if pid == 0: # 子进程 - listen_socket.close() # 关闭子进程中多余的套接字 + if pid == 0: ### 子进程 + listen_socket.close() ### 关闭子进程中多余的套接字 handle_request(client_connection) client_connection.close() os._exit(0) - else: # 父进程 + else: ### 父进程 client_connection.close() if __name__ == '__main__': @@ -766,7 +770,7 @@ $ curl http://localhost:8888/hello ![](https://ruslanspivak.com/lsbaws-part3/lsbaws_part3_conc4_eintr.png) -刚刚发生了什么?`accept` 调用失败了,错误信息为 `EINTR` +刚刚发生了什么?`accept` 调用失败了,错误信息为 `EINTR`。 ![](https://ruslanspivak.com/lsbaws-part3/lsbaws_part3_conc4_eintr_error.png) @@ -822,20 +826,20 @@ def serve_forever(): client_connection, client_address = listen_socket.accept() except IOError as e: code, msg = e.args - # 若 'accept' 被打断,那么重启它 + ### 若 'accept' 被打断,那么重启它 if code == errno.EINTR: continue else: raise pid = os.fork() - if pid == 0: # 子进程 - listen_socket.close() # 关闭子进程中多余的描述符 + if pid == 0: ### 子进程 + listen_socket.close() ### 关闭子进程中多余的描述符 handle_request(client_connection) client_connection.close() os._exit(0) - else: # 父进程 - client_connection.close() # 关闭父进程中多余的描述符,继续下一轮循环 + else: ### 父进程 + client_connection.close() ### 关闭父进程中多余的描述符,继续下一轮循环 if __name__ == '__main__': @@ -854,7 +858,7 @@ $ python webserver3f.py $ curl http://localhost:8888/hello ``` -看到了吗?没有 EINTR 异常出现了。现在检查一下,确保没有僵尸进程存活,调用 `wait` 函数的 `SIGCHLD` 信号处理器能够正常处理被终止的子进程。我们只需使用 `ps` 命令,然后看看现在没有处于 Z+ 状态(或名字包含 `` )的 Python 进程就好了。很棒!僵尸进程没有了,我们很安心。 +看到了吗?没有 EINTR 异常出现了。现在检查一下,确保没有僵尸进程存活,调用 `wait` 函数的 `SIGCHLD` 信号处理器能够正常处理被终止的子进程。我们只需使用 `ps` 命令,然后看看现在没有处于 `Z+` 状态(或名字包含 `` )的 Python 进程就好了。很棒!僵尸进程没有了,我们很安心。 ![](https://ruslanspivak.com/lsbaws-part3/lsbaws_part3_checkpoint.png) @@ -862,6 +866,8 @@ $ curl http://localhost:8888/hello - 使用 `SIGCHLD` 信号处理器可以异步地等待子进程终止,并收集其终止状态; - 当使用事件处理器时,你需要牢记,系统调用可能会被打断,所以你需要处理这种情况发生时带来的异常。 +#### 正确处理 SIGCHLD 信号 + 好的,一切顺利。是不是没问题了?额,几乎是。重新尝试运行 `webserver3f.py` 但我们这次不会只发送一个请求,而是同步创建 128 个连接: ``` @@ -882,7 +888,7 @@ $ ps auxw | grep -i python | grep -v grep ![](https://ruslanspivak.com/lsbaws-part3/lsbaws_part3_conc5_signals_not_queued.png) -这个问题的解决方案依然是设置 `SIGCHLD` 事件处理器。但我们这次将会用 `WNOHANG` 参数循环调用 `waitpid`,来保证所有处于终止状态的子进程都会被处理。下面是修改后的代码,`webserver3g.py`: +这个问题的解决方案依然是设置 `SIGCHLD` 事件处理器。但我们这次将会用 `WNOHANG` 参数循环调用 `waitpid` 来替代 `wait`,以保证所有处于终止状态的子进程都会被处理。下面是修改后的代码,`webserver3g.py`: ``` ####################################################### @@ -904,13 +910,13 @@ def grim_reaper(signum, frame): while True: try: pid, status = os.waitpid( - -1, # 等待所有子进程 - os.WNOHANG # 无终止进程时,不阻塞进程,并抛出 EWOULDBLOCK 错误 + -1, ### 等待所有子进程 + os.WNOHANG ### 无终止进程时,不阻塞进程,并抛出 EWOULDBLOCK 错误 ) except OSError: return - if pid == 0: # 没有僵尸进程存在了 + if pid == 0: ### 没有僵尸进程存在了 return @@ -939,20 +945,20 @@ def serve_forever(): client_connection, client_address = listen_socket.accept() except IOError as e: code, msg = e.args - # 若 'accept' 被打断,那么重启它 + ### 若 'accept' 被打断,那么重启它 if code == errno.EINTR: continue else: raise pid = os.fork() - if pid == 0: # 子进程 - listen_socket.close() # 关闭子进程中多余的描述符 + if pid == 0: ### 子进程 + listen_socket.close() ### 关闭子进程中多余的描述符 handle_request(client_connection) client_connection.close() os._exit(0) - else: # 父进程 - client_connection.close() # 关闭父进程中多余的描述符,继续下一轮循环 + else: ### 父进程 + client_connection.close() ### 关闭父进程中多余的描述符,继续下一轮循环 if __name__ == '__main__': serve_forever() @@ -974,13 +980,15 @@ $ python client3.py --max-clients 128 ![](https://ruslanspivak.com/lsbaws-part3/lsbaws_part3_conc5_no_zombies.png) -恭喜!你刚刚经历了一段很长的旅程,我希望你能够喜欢它。现在你拥有了自己的建议并发服务器,并且这段代码能够为你在继续研究生产级 Web 服务器的路上奠定基础。 +### 大功告成 + +恭喜!你刚刚经历了一段很长的旅程,我希望你能够喜欢它。现在你拥有了自己的简易并发服务器,并且这段代码能够为你在继续研究生产级 Web 服务器的路上奠定基础。 我将会留一个作业:你需要将第二部分中的 WSGI 服务器升级,将它改造为一个并发服务器。你可以在[这里][12]找到更改后的代码。但是,当你实现了自己的版本之后,你才应该来看我的代码。你已经拥有了实现这个服务器所需的所有信息。所以,快去实现它吧 ^_^ 然后要做什么呢?乔希·比林斯说过: -> “我们应该做一枚邮票——专注于一件事,不达目的不罢休。” +> “就像一枚邮票一样——专注于一件事,不达目的不罢休。” 开始学习基本知识。回顾你已经学过的知识。然后一步一步深入。 @@ -990,13 +998,13 @@ $ python client3.py --max-clients 128 下面是一份书单,我从这些书中提炼出了这篇文章所需的素材。他们能助你在我刚刚所述的几个方面中发掘出兼具深度和广度的知识。我极力推荐你们去搞到这几本书看看:从你的朋友那里借,在当地的图书馆中阅读,或者直接在亚马逊上把它买回来。下面是我的典藏秘籍: -1. [UNIX网络编程 (卷1):套接字联网API (第3版)][6] -2. [UNIX环境高级编程 (第3版)][7] -3. [Linux/UNIX系统编程手册][8] -4. [TCP/IP详解 (卷1):协议 (第2版) (爱迪生-韦斯莱专业编程系列)][9] -5. [信号系统简明手册 (第二版): 并发控制深入浅出及常见错误][10]. 这本书也可以从[作者的个人网站][11]中买到。 +1. [《UNIX 网络编程 卷1:套接字联网 API (第3版)》][6] +2. [《UNIX 环境高级编程(第3版)》][7] +3. [《Linux/UNIX 系统编程手册》][8] +4. [《TCP/IP 详解 卷1:协议(第2版)][9] +5. [《信号系统简明手册 (第二版): 并发控制深入浅出及常见错误》][10],这本书也可以从[作者的个人网站][11]中免费下载到。 -顺便,我在撰写一本名为《搭个 Web 服务器:从头开始》的书。这本书讲解了如何从头开始编写一个基本的 Web 服务器,里面包含本文中没有的更多细节。订阅邮件列表,你就可以获取到这本书的最新进展,以及发布日期。 +顺便,我在撰写一本名为《搭个 Web 服务器:从头开始》的书。这本书讲解了如何从头开始编写一个基本的 Web 服务器,里面包含本文中没有的更多细节。订阅[原文下方的邮件列表][13],你就可以获取到这本书的最新进展,以及发布日期。 -------------------------------------------------------------------------------- @@ -1004,7 +1012,7 @@ via: https://ruslanspivak.com/lsbaws-part3/ 作者:[Ruslan][a] 译者:[StdioA](https://github.com/StdioA) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 @@ -1013,12 +1021,13 @@ via: https://ruslanspivak.com/lsbaws-part3/ [1]: https://github.com/rspivak/lsbaws/blob/master/part3/ [2]: https://github.com/rspivak/lsbaws/blob/master/part3/webserver3a.py [3]: https://github.com/rspivak/lsbaws/blob/master/part3/webserver3b.py -[4]: https://ruslanspivak.com/lsbaws-part3/#fn:1 -[5]: https://ruslanspivak.com/lsbaws-part3/#fn:2 -[6]: http://www.amazon.com/gp/product/0131411551/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0131411551&linkCode=as2&tag=russblo0b-20&linkId=2F4NYRBND566JJQL -[7]: http://www.amazon.com/gp/product/0321637739/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321637739&linkCode=as2&tag=russblo0b-20&linkId=3ZYAKB537G6TM22J -[8]: http://www.amazon.com/gp/product/1593272200/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1593272200&linkCode=as2&tag=russblo0b-20&linkId=CHFOMNYXN35I2MON -[9]: http://www.amazon.com/gp/product/0321336313/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321336313&linkCode=as2&tag=russblo0b-20&linkId=K467DRFYMXJ5RWAY +[4]: http://www.epubit.com.cn/book/details/1692 +[5]: http://www.amazon.com/gp/product/1441418687/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441418687&linkCode=as2&tag=russblo0b-20&linkId=QFOAWARN62OWTWUG +[6]: http://www.epubit.com.cn/book/details/1692 +[7]: http://www.epubit.com.cn/book/details/1625 +[8]: http://www.epubit.com.cn/book/details/1432 +[9]: http://www.epubit.com.cn/book/details/4232 [10]: http://www.amazon.com/gp/product/1441418687/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441418687&linkCode=as2&tag=russblo0b-20&linkId=QFOAWARN62OWTWUG [11]: http://greenteapress.com/semaphores/ [12]: https://github.com/rspivak/lsbaws/blob/master/part3/webserver3h.py +[13]: https://ruslanspivak.com/lsbaws-part1/ \ No newline at end of file From 2f1c7de89bd2add95e2bb190e2e8f41dffa5cd31 Mon Sep 17 00:00:00 2001 From: Jinwen Zhang Date: Mon, 10 Oct 2016 00:10:01 +0800 Subject: [PATCH 035/316] translated 20160912 Content Security Policy, Your Future Best Friend.md --- ...ecurity Policy, Your Future Best Friend.md | 258 ------------------ ...ecurity Policy, Your Future Best Friend.md | 258 ++++++++++++++++++ 2 files changed, 258 insertions(+), 258 deletions(-) delete mode 100644 sources/tech/20160912 Content Security Policy, Your Future Best Friend.md create mode 100644 translated/tech/20160912 Content Security Policy, Your Future Best Friend.md diff --git a/sources/tech/20160912 Content Security Policy, Your Future Best Friend.md b/sources/tech/20160912 Content Security Policy, Your Future Best Friend.md deleted file mode 100644 index caf9ac6743..0000000000 --- a/sources/tech/20160912 Content Security Policy, Your Future Best Friend.md +++ /dev/null @@ -1,258 +0,0 @@ -wcnnbdk1 Translating -Content Security Policy, Your Future Best Friend -===== - -A long time ago, my personal website was attacked. I do not know how it happened, but it happened. Fortunately, the damage from the attack was quite minor: A piece of JavaScript was inserted at the bottom of some pages. I updated the FTP and other credentials, cleaned up some files, and that was that. - -One point made me mad: At the time, there was no simple solution that could have informed me there was a problem and — more importantly — that could have protected the website’s visitors from this annoying piece of code. - -A solution exists now, and it is a technology that succeeds in both roles. Its name is content security policy (CSP). - -### What Is A CSP? Link - -The idea is quite simple: By sending a CSP header from a website, you are telling the browser what it is authorized to execute and what it is authorized to block. - -Here is an example with PHP: - -``` -"); -?> -``` - -#### SOME DIRECTIVES LINK - -You may define global rules or define rules related to a type of asset: - -``` -default-src 'self' ; - # self = same port, same domain name, same protocol => OK -``` - -The base argument is default-src: If no directive is defined for a type of asset, then the browser will use this value. - -``` -script-src 'self' www.google-analytics.com ; - # JS files on these domains => OK -``` - -In this example, we’ve authorized the domain name www.google-analytics.com as a source of JavaScript files to use on our website. We’ve added the keyword 'self'; if we redefined the directive script-src with another rule, it would override default-src rules. - -If no scheme or port is specified, then it enforces the same scheme or port from the current page. This prevents mixed content. If the page is https://example.com, then you wouldn’t be able to load http://www.google-analytics.com/file.js because it would be blocked (the scheme wouldn’t match). However, there is an exception to allow a scheme upgrade. If http://example.com tries to load https://www.google-analytics.com/file.js, then the scheme or port would be allowed to change to facilitate the scheme upgrade. - -``` -style-src 'self' data: ; - # Data-Uri in a CSS => OK -``` - -In this example, the keyword data: authorizes embedded content in CSS files. - -Under the CSP level 1 specification, you may also define rules for the following: - -- `img-src` - -valid sources of images - -- `connect-src` - -applies to XMLHttpRequest (AJAX), WebSocket or EventSource - -- `font-src` - -valid sources of fonts - -- `object-src` - -valid sources of plugins (for example, `, , `) - -- `media-src` - -valid sources of `