作者:admin
服务网格-Envoy学习笔记:Envoy架构总览(1)
#术语
在我们深入了解架构文档之前,我们需要了解一些术语。有些定义在行业内部可能有争议,不过在Envoy的文档和代码中就是这么定义的,所以c’est la vie(这就是生活)。
**主机(Host)**:能够进行网络通信的实体 (手机、服务器等上的应用程序)。在本文档中,主机是一个逻辑网络应用程序。一个物理硬件可能有多个主机在上面运行,只要每个主机都可以独立寻址。
**下游(Downstream)**:一个下游主机连接Envoy,向Envoy发送请求,并收到响应。
**上游(Upstream)**:一个上游主机收到来自Envoy的连接和请求,并给出响应给Envoy。
**监听器(Listener)**:一个监听器是可由下游客户端连接的命名网络位置 (例如,端口、unix 域套接字等)。Envoy可以同时开放一个或多个供下游主机连接的监听器。
**集群(Cluster)**:群集是Envoy连接的逻辑上相似的上游主机组。Envoy通过服务发现发现集群的成员。它可以选择通过健康检查来确定群集成员的运行状况。Envoy根据负载平衡策略将请求路由到确定的群集成员。
**网格(Mesh)**:一组互相协调以提供一致的网络拓扑的主机。在本文档中, “Envoy 网格” 是一组Envoy 代理, 它为由许多不同服务和应用程序平台组成的分布式系统提供消息传递网络。
**运行时配置(Runtime configuration):与 Envoy 一起部署的额外的实时配置系统。可以更改配置设置影响操作,而无需重新启动 Envoy 或更改主配置。
#线程模型
Envoy 使用具有多个线程体系结构的单个进程。单个主线程控制各种零星的协调任务,而一些工作线程执行监听、筛选和转发。一旦监听器接受了连接,连接就会将其生存期的剩余时间绑定到单个工作线程。这使得 Envoy 拥有大量的工作线程(令人尴尬的并行),在工作线程之间进行少量更复杂的代码协调处理。通常 Envoy 是100% 非阻塞的,对于大多数工作负载,我们建议将工作线程的数量配置为计算机上的硬件线程数。
服务网格-Envoy学习笔记:什么是Envoy
随着服务网格的概念爆火,Istio+Envoy的组合受到了热捧。于是开始着手研究Envoy,并在此记入笔记。
本文我在简书上也发表过(https://www.jianshu.com/u/6421d3fed5e4)。
#什么是Envoy
Envoy 是一个基于七层的代理和通讯总线,专为大型面向服务的体系结构而设计。该项目的诞生主要出于如下的想法:
>网络对应用程序应该是透明的。当网络和应用程序确实出现问题时,应该很容易确定问题的根源。
实际上,实现前面的想法是极其困难的。Envoy试图通过提供以下高级别特征来做到这一点:
**独立于进程的架构** :Envoy是一个独立的进程,旨在与每个应用程序服务器一起运行。所有Envoy组成了一个透明的通信网格,其中每个应用程序发送和接收来自本地主机的消息,并且不用知道网络拓扑。与传统的服务通信服务的库方法相比,进程外架构有两个实质性好处:
– Envoy支持任何编程语言写的服务。只用部署一个Envoy就可以在Java、C++、Go、PHP、Python等服务间形成网格。面向服务的体系结构使用多个应用程序框架和语言的情况越来越普遍。Envoy以透明的方式弥合了这些差距。
– 任何使用过大型面向服务的体系结构的人都知道,部署库升级可能会非常痛苦。Envoy可以在整个基础设施中迅速部署和升级。
**基于最新的C++11开发**:Envoy是基于C++11编写的。选择本机代码是因为我们认为像Envoy这样的体系结构组件应该尽可能给应用程序让路。现代应用程序开发人员习惯于在共享云环境中的部署,以及使用非常高效但性能不是特别好的语言 (如 PHP、Python、Ruby、Scala 等), 在这种环境下,找到尾延迟的原因变得非常的困难。本机代码通常提供出色的延迟属性,不会给已经令人困惑的情况增加额外的混乱。与用 C 编写的其他本机代码代理解决方案不同,C++11 提供了出色的开发人员工作效率和性能。
**基于 L3/L4 网络Filter的架构**:Envoy的核心使用的是基于 L3/L4 的网络代理。可插拔的Filter链机制允许编写Filter以执行不同的 tcp 代理任务并插入主服务器。当然Envoy也提供现成的Filter以支持各种任务,如原始 TCP代理、HTTP 代理、TLS客户端证书身份验证等。
**基于 L7 网络的HTTP Filter架构**:HTTP是现代应用程序体系结构的重要组成部分,Envoy支持额外的 HTTP L7 Filter层。HTTP Filter可以插入到 HTTP 连接管理子系统中,该子系统支持执行不同的任务,如缓冲、速率限制、路由、嗅探亚马逊的 Dynamodb 等。
**对HTTP/2 的极佳支持**:在 HTTP 模式下运行时,Envoy同时支持 HTTP/1.1 和 HTTP/2。Envoy可以做到让 HTTP/1.1 和 HTTP/2 之间的通讯保持透明。这意味着对于任意的 HTTP/1.1 和 HTTP/2 的客户端和目标服务器的组合,Envoy都可以将他们桥接起来。当然建议在配置Envoy服务时使用 HTTP/2 在所有组件之间创建一个长链的网格,这样请求和响应可以多路复用。Envoy 不支持 SPDY,因为这个协议正在逐渐被淘汰。
>SPDY(读作“SPeeDY”)是 Google 开发的基于 TCP 的应用层协议,用以最小化网络延迟,提升网络速度,优化用户的网络使用体验。互联网工程任务组(IETF)对谷歌提出的 SPDY 协议进行了标准化,于2015年5推出了类似于 SPDY 协议的 HTTP 2.0 协议标准(简称HTTP/2)。谷歌因此宣布放弃对SPDY协议的支持,转而支持HTTP/2。
**HTTP L7 路由**:在 HTTP 模式下运行时,Envoy 的路由子系统能够根据路径、权限、内容类型、运行时值等来路由和重定向请求。在使用 Envoy 作为前端代理时,此功能非常有用。同时在构建服务网格时也会利用此功能。
**对 gRPC 的支持**:gRPC 是一个来自谷歌的 RPC框架, 使用 HTTP/2 作为底层的多路复用传输。Envoy支持所有需要用作 gPRC请求和响应的路由和负载均衡基础的 HTTP/2 功能。这两个系统是非常互补的。
**对MongoDB的 L7 网络协议的支持**:对于当今的 Web 应用,MongoDB数据库非常流行。因为Envoy支持基于 L7 的网络协议,所以Envoy 支持 MongoDB 连接的嗅探、数据统计和日志记录。
**对DynamoDB的 L7 网络协议的支持**:DynamoDB是由Amazion提供的基于键值对的NoSQL数据库。因为Envoy支持基于 L7 的网络协议,所以Envoy 支持 DynamoDB 连接的嗅探和数据统计。
**服务的动态注册和发现**:Envoy 可以选择使用一组分层的动态配置 API 来进行集中管理。这些层为Envoy提供了以下方面的动态更新: 后端群集的主机、后端群集本身、HTTP 路由、侦听套接字和通信加密。为了实现更简单的部署, 后端主机发现可以通过 DNS 解析 (甚至完全跳过) 完成, 层也可以替换为静态配置文件。
**健康检查**:构建 Envoy 网格的建议方法是将服务发现视为最终一致的过程。 Envoy 包括一个运行状况检查子系统,该子系统可以选择对上游服务集群执行主动运行状况检查。然后,Envoy 使用服务发现和运行状况检查信息的联合来确定健康的负载均衡服务器。Envoy 还支持通过异常检测子系统进行被动运行状况检查。
**高级负载均衡**:分布式系统中不同组件之间的负载平衡是一个复杂的问题。由于 Envoy 是一个独立的代理而不是库,因此它能够在一个位置实现高级负载平衡技术,并使任何应用程序都可以访问。目前Envoy 包括支持自动重试、断路、通过外部速率限制服务限制全局速率、请求隐藏和异常值检测。未来计划为Request Racing提供支持。
**前端/边缘系统代理支持**: 虽然 Envoy 主要是为服务通信系统而设计的,但对前端/边缘系统也是很有用的(可观测性、管理、相同的服务发现和负载平衡算法等)。Envoy包含足够的功能,使其可用作大多数 Web 应用服务用例的边缘代理。这包括作为 TLS 的终点、HTTP/1.1 和 HTTP/2 支持, 以及 HTTP L7 路由。
**最好的观察统计能力**:如上所述,Envoy 的首要目标是使网络透明。但是在网络级别和应用程序级都无法避免的容易出现问题。Envoy 包含了对所有子系统的强有力的统计支持。 [statsd](https://github.com/etsy/statsd) (和其他兼容的数据提供程序) 是当前支持的统计接收器,插入不同的统计接收器也并不困难。Envoy 可以通过管理端口查看统计信息,还支持通过第三方供应商进行分布式追踪。
大溪地游记
经过几个月的准备,2017年3月18日,我们终于开启期盼许久的大溪地蜜月之旅。早上10点左右于上海浦东机场飞往东京成田,转机大溪地航班(Tahiti Air)。海水般湛蓝的机身以及身着彩衣手捧栀子花的乘务人员,浓浓的海岛风情铺面而来,心情也随之起舞。
十几个小时的飞行后,飞机终于落地大溪地首都帕皮提。与国内18个小时的时差,一觉睡醒的我们又回到了3月18号上午10点左右。正值雨季和旱季之交(大溪地11月到3月是雨季,4月到10月是旱季,全年平均气温27°),一下飞机虽是滂沱大雨,然而体感非常舒适,机场大厅门口有热情的大溪地歌舞欢迎仪式。取了行李找到地接,顺利搭乘当地的小飞机前往波拉波拉岛。大溪地当地来往几个主要岛屿之间的主要交通工具就是这种小飞机,大概可以承载20几个人,一边喝着乘务人员提供的清凉可口的菠萝汁,一边俯瞰窗外美丽的景色,疲劳尽消,深深地被眼前的景色折服。大大小小的岛屿如珍珠般散落在这片蔚蓝的海域,美丽的泻湖仿若镶嵌在珍珠周围的钻石,熠熠生辉。
45分钟左右的飞行后,到达拥有大溪地最漂亮泻湖的岛屿—波拉波拉,同时也是大溪地商业开发得最佳的岛。出发前网上一番比较之后,在波拉波拉我们选择了洲际泰拉索度假村。大溪地每个度假村在码头都设有自家的接驳人员和快艇,小飞机落地后我们很快乘上快艇,驶向度假村。一望无垠的大海,飞驰的快艇,清凉的海风,溅起的浪花,飞扬的心情……首先出现在眼前的便是海岛度假村独具特色的水屋,一栋连着一栋,与海天相连,仿若在欢迎远道而来的游客。整个度假村其实就是一个独立的小岛,礼宾员开着敞篷电动车带着我们将整个度假村介绍了一遍。不仅有露天游泳池、私家沙滩,还有环境幽雅的餐厅、设施齐全的健身房、深水SPA会馆等各种场所。
礼宾部确认好次日的婚礼安排,正式入住我们的水上钻石屋。近百平的水屋,内部设施相当完善齐全,客厅的透明茶几可看到水下的鱼儿在畅游,偶有魔鬼鱼一闪而过。面朝美丽的Otemanu山,喝着酒店准备的香槟,有兴致的话,可从露台直接跳入海水里游泳……一切都美得恍若梦境。
晚餐在珊瑚餐厅,纯正的法式套餐,非常可口。
散步回水屋,经过礼宾部,把第三天游玩的项目预定好,露台躺椅上数了会星星,伴着海水的声音,一夜好眠。
波拉波拉的第二天,美味的早餐过后,借来双桨划起皮筏,经过水屋,与来自各国的友人闲聊几句,之后是悠闲的浮潜,追逐五彩缤纷的鱼儿。午餐过后,开始婚礼前的准备。温柔的日本化妆师美眉帮忙化了好看的妆,穿上Tahiti传统纱笼,坐着花船从水屋划到沙滩,迎接我们的是热情的号角音乐和歌舞,同时用英文和大溪地语举行的婚礼仪式,赐予我们大溪地名字和结婚证书,喝着椰汁鸡尾酒,观看草裙舞后,花船送我们回水屋,一路是各国友人的欢呼祝福,露台已摆上鲜花香槟蛋糕,今天我们是其他游人眼中的风景。晚上6点50waiter准时来接我们到沙滩,浪漫的篝火,鲜花装饰的餐桌,香脆的羊角小面包之后是两道前菜,之后是主菜,最后是甜点。轻柔的海风,悠扬的音乐,非常惬意。
波拉波拉第三天,早餐后来到预定的水上摩托艇,颂载着我跟在教练后面,飞驰在蔚蓝的海面上,如履平地。第一次骑摩托艇的颂意外地很快上手,惹得教练一直竖拇指夸赞。先是到另外一个度假村,接了一对美国夫妇,然后围着波拉波拉本岛转了一圈,远远地看到码头的Robert Wan,接着在一片浅滩稍作停留,翠绿色的海水,柔软细腻的白沙;然后又骑到一个小野岛,上面长满椰树和不知名的热带水果,教练摘来几只椰子,教我们如何剥,颂和同行American友人聊完川普后开始比赛剥椰子。沙滩上有还多呆萌的海参,返程时遇到好多骑摩托艇的朋友,隔着湛蓝的海水和浪花,相互打招呼欢呼。两个多小时的水上摩托艇非常开心,心情好到飞起。下午体验了洲际波拉波拉最具特色的深海SPA,check-out之后乘坐小飞机来到下一站—塔哈岛(Taha)。
入住乐塔哈水上度假村,我们的水屋面朝美丽的塔哈岛,不同于波拉波拉的另一种风景。相比于波拉波拉,塔哈更加原生态,更适合深度游,岛上植被丰富,沙子里好多螃蟹洞,经常看到一只只大小螃蟹从眼前飞快地横行而过,整个度假村就像一个热带雨林。昨天一场大雨过后,岛上蚊子奇多,工作人员给了我们一瓶驱蚊剂,效果非常好,据说夜晚整个度假村会进行一次驱蚊。晚餐在香草餐厅,不再是法式套餐,点了沙拉和意面,味道非常好。饭后接待大厅定好后面几天的游玩项目,散步回水屋,平静的海面灯光点点,天空繁星闪烁,露台躺椅上吹了会风,相当惬意。
塔哈第二天,美味的早餐过后,开始今天的深潜活动,只有我们俩和两位教练。坐着快艇来到一片深水区域,第一次深潜的俩人在教练的指导下穿戴好装备,抓着绳索下海。海底巨大的水压让我的耳朵疼痛难忍,几经尝试还是放弃了,乖乖地待在艇上,与助教闲聊等待颂他们。颂倒是很快掌握诀窍顺利地随教练潜入海底,幸运地在大概七八米深的海底与各种海洋生物零距离接触。45分钟后来到塔哈本岛的一个小商店,教练买了些食物,整座岛的人数屈指可数。之后便驱船回到度假村。下午度假村里玩了会皮筏艇和浮潜,之后颂在房间里休息,塔哈水屋里没有wifi,只有餐厅和接待大厅有,百无聊赖的自己在露台玩起自拍,雨滴嗒嗒,一阵急雨过后,远处的塔哈岛上空架起美丽的彩虹……晚餐仍然是香草餐厅,今晚有特色的波利尼西亚音乐和歌舞表演,以及自助晚餐,能歌善舞,热情淳朴的Tahiti朋友。
塔哈第三天,大溪地之旅最丰富多彩的一天—泻湖一日游。早上9点出发,教练开着快艇载着我们一行7个人,先是来到珍珠工作坊参观珍珠养殖培育的全过程。接着到塔哈著名的浮潜圣地,珊瑚花园。与度假村的浮潜不同,此处深达4米多,珊瑚礁鱼类贝类非常丰富,弥补了昨天未能深潜的遗憾。然后是去香草工作坊参观了香草从养殖到制作的整个过程。接着又去了另一片水域浮潜,追逐小鲨鱼。2米多长的小鲨鱼成群在水下嬉戏,相当可爱。中午来到教练的office,一个私人小岛野餐。岛上到处是掉落的椰子,还有一只可爱的猫咪。下午离开快艇,教练开着Jeep车带我们绕塔哈本岛环游,穿梭在热带植被中。最后参观了用椰汁酿造朗姆酒的工作坊,舔了点75度的朗姆酒,入口烈而不烧,异常香醇。回来后晚餐仍然是香草餐厅。
塔哈第四天,早餐过后,阳光明媚的天空飘起一阵急雨,波光滟滟,水波潋潋。度假村的珍珠商店里,欣赏了会光泽美丽的黑珍珠,然后泳池里游了会,收拾行李乘着快艇离开塔哈,来到Tahiti的教育与文化中心—若依雅提岛,等候飞往首都帕皮提的小飞机。
乘坐小飞机离开若依雅提岛,到达Tahiti首都帕皮提。值得一提的是从飞机上欣赏美丽的Tahiti,真的别有一番景致。巨大的云朵仿佛北极冰山,又像成群的图腾野兽,浩浩荡荡,气势恢宏。每一个岛屿都像是上帝随手洒落的珍珠,点缀着这片蓝。由于我们主动要求提前了一班机,导致酒店没办法协调接机,于是俩人决定拉着行李箱走到酒店,顺便欣赏下沿途风景。路上偶遇一法国帅哥爸比,热情地邀请我俩搭顺风车,副驾坐了位超级cute的小baby。
首都帕皮提更加商业气息,房屋多傍山而建,层层叠叠,错落有致,洲际花园小洋房住了一晚。
第二天凌晨早早起来,行李收拾妥当,吃好早餐,酒店泊车将我们送至机场,仍然是飞往东京的Tahiti Air,仍然是充满异域风情的乘务人员,仍然是清香的栀子花相送,一切都是如此美好,再见,Tahiti,人生中永恒的记忆~
apache反向代理session错乱问题
最近生产上碰到棘手的问题。通过apache反向代理tomcat,session会错乱丢失。
apache配置如下:
ProxyPass /webtest/ http://192.168.1.1/web/
ProxyPassReverse /webtest/ http://192.168.1.1/web/
ProxyPassReverseCookiePath /web /webtest
ProxyPass /webhaha/ http://192.168.1.1/webhaha/
ProxyPassReverse /webhaha/ http://192.168.1.1/webhaha/
出问题的就是webhaha应用。
原因是ProxyPassReverseCookiePath 中/web是会自动匹配所有/web*的链接,并把cookie代理到webtest上。导致session错乱。
解决方法,修改ProxyPassReverseCookiePath为
ProxyPassReverseCookiePath /web/ /webtest/
问题解决
Tomcat莫名自动退出
今天生产上遇到问题,tomcat进程莫名其妙退出了。查询应用日志和tomcat日志没有任何结果。
上网查询以后,说程序crash的话可以查看内核日志,目录在/var/log/message文件下查找。网上文件说出现Out of memory: Kill process 31201 (java) score 783 or sacrifice child那么可以推测为内存溢出,被linux的保护程序OOM Killer干掉了。更多可以参考这个网页( http://backdrift.org/oom-killer-how-to-create-oom-exclusions-in-linux )。
但是我没有这句话,有可能是程序crash掉。日志有如下内容:
May 8 09:54:44 test abrt[4029]: Saved core dump of pid 3715 (/usr/java/bin/java) to /var/spool/abrt/ccpp-2017-05-08-09:54:44-3715 (2001559552 bytes) May 8 09:54:44 test abrtd: Directory 'ccpp-2017-05-08-09:54:44-3715' creation detected May 8 09:54:44 test abrtd: Package 'jdk' isn't signed with proper key May 8 09:54:44 test abrtd: 'post-create' on '/var/spool/abrt/ccpp-2017-05-08-09:54:44-3715' exited with 1 May 8 09:54:44 srdsdevapp69 abrtd: Corrupted or bad directory /var/spool/abrt/ccpp-2017-05-08-09:54:44-3715, deleting
中途临时产生了core文件,但最后又被删掉了。
abrtd默认只保留软件包里的程序产生的core文件,修改下面的参数可以让其记录所有程序的core文件。
$vi /etc/abrt/abrt-action-save-package-data.conf
…
ProcessUnpackaged = yes
Ruby安装的那些坑
安装参考http://guides.rubyonrails.org/getting_started.html
安装Ruby
sudo apt-get install ruby2.0
ruby -v 显示1.9.3
修改软链接切换到2.0
Ubuntu从14.04开始在主软件库中提供Ruby 2.0,同时提供的还有1.9.3(软件包名称是ruby1.9.1)。不过由于Ruby 2.0在垃圾回收方面的显著改进,大量程序推荐使用Ruby 2.0,这时问题出现了。通过运行“ruby -v”可知:
~$ ruby -v
ruby 1.9.3p484 (2013-11-22 revision 43786) [x86_64-linux]
Ubuntu 14.04中默认的Ruby版本是1.9.3,而Ruby 2.0则需要用命令“ruby2.0”运行,程序运行前必须设定好运行版本否则可能造成错误。
Kaijia一直使用GitLab管理代码,以前GitLab还支持Ruby 1.9.3,不过从GitLab 7.0开始,Ruby 1.9.3的支持就被移除了(毕竟运行Ruby 1.9.3的GitLab简直是内存杀手)。现在Kaijia需要使用Ruby 2.0运行GitLab,但是GitLab只支持系统默认的Ruby(即1.9.3)无法选择运行的版本,也无法通过指定运行命令“ruby2.0”设置 Ruby版本;安装指南中也一直是编译安装Ruby 2.1,没有提到如何使用系统提供的Ruby 2.0,因此只能在系统层面上设置Ruby的全局默认版本。
Ubuntu 12.10及以后的版本提供一个ruby-switch小脚本实现全局Ruby版本的切换,同时也可以用update-alternatives命令来切 换版本,但自从ruby1.9.1包直接写死默认路径后update-alternatives就无法使用了,ruby-switch的原作者也申请从 Debian unstable源中移除了脚本,Ubuntu也同样将此包移除。因此可以说之前可用的方式全都失效了。
既然软性方法没有了,那就只能使用(不可复原的)硬方法了。硬方法即是强制替换/usr/bin/目录下与Ruby相关的符号链接到Ruby 2.0对应的版本,这样即可实现默认版本的切换:
cd /usr/bin/
ln -sf ruby2.0 ruby
ln -sf gem2.0 gem
ln -sf erb2.0 erb
ln -sf irb2.0 irb
ln -sf rake2.0 rake
ln -sf rdoc2.0 rdoc
ln -sf testrb2.0 testrb
替换完成之后还可以更新一下gem:
gem update –system
gem pristine –all
这时Ruby的默认版本就已经切换到2.0了。当然虽然这样做比较暴力,但也是可以还原的,如果想切换会Ruby 1.9.3,只需要运行(请注意在Ubuntu 14.04中,Ruby 1.9.3的名称为ruby1.9.1):
cd /usr/bin/
ln -sf ruby1.9.1 ruby
ln -sf gem1.9.1 gem
ln -sf erb1.9.1 erb
ln -sf irb1.9.1 irb
ln -sf rake1.9.1 rake
ln -sf rdoc1.9.1 rdoc
ln -sf testrb1.9.1 testrb
同样的,再更新一下gem之后Ruby就又切换回1.9.3了。
sudo gem install rails
报错 不用怀疑这是被墙了,解决办法换镜像
ERROR: Could not find a valid gem ‘rails’ (>= 0), here is why:
Unable to download data from https://rubygems.org/ – Errno::ECONNRESET: Connection reset by peer – SSL_connect (https://rubygems.org/latest_specs.4.8.gz)
更新gem的软件源
sudo gem sources –r https://rubygems.org
sudo gem sources -a http://rubygems.org
重新执行报错:
mkmf.rb can’t find header files for ruby at /usr/lib/ruby/include/ruby.h
搜了一下Stackoverflow得到提示:
mkmf is part of the ruby1.9.1-dev package. This package contains the header files needed for extension libraries for Ruby 1.9.1. You need to install the ruby1.9.1-dev package by doing:
sudo apt-get install ruby1.9.1-dev
sudo apt – get install ruby1 . 9.1 – dev |
Then you can install Rails as per normal
我们相应的装2.0-dev就行了
sudo apt-get install ruby2.0-dev
sudo apt – get install ruby2 . 0 – dev |
重新执行报错:
Building native extensions. This could take a while…
ERROR: Error installing rails:
ERROR: Failed to build gem native extension.
/usr/bin/ruby2.0 extconf.rb
checking if the C compiler accepts … yes
Building nokogiri using packaged libraries.
Using mini_portile version 2.0.0
checking for gzdopen() in -lz… no
zlib is missing; necessary for building libxml2
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers. Check the mkmf.log file for more details. You may
need configuration options.
Provided configuration options:
–with-opt-dir
–without-opt-dir
–with-opt-include
–without-opt-include=${opt-dir}/include
–with-opt-lib
–without-opt-lib=${opt-dir}/lib
–with-make-prog
–without-make-prog
–srcdir=.
–curdir
–ruby=/usr/bin/ruby2.0
–help
–clean
–use-system-libraries
–enable-static
–disable-static
–with-zlib-dir
–without-zlib-dir
–with-zlib-include
–without-zlib-include=${zlib-dir}/include
–with-zlib-lib
–without-zlib-lib=${zlib-dir}/lib
–enable-cross-build
–disable-cross-build
Gem files will remain installed in /var/lib/gems/2.0.0/gems/nokogiri-1.6.7.2 for inspection.
Results logged to /var/lib/gems/2.0.0/gems/nokogiri-1.6.7.2/ext/nokogiri/gem_make.out
执行如下命令
sudo apt-get install zlib1g zlib1g-dev
sudo apt-get install libxslt1-dev libxml2-dev
最后还是资源被墙,果断翻墙解决
gem install nokogiri 报错checking if the C compiler accepts问题
用sudo apt-get install libgmp-dev 解决