×
关于Socket 编程发展OpenResty 简介Lua 入门Lua 简介Lua 环境搭建基础数据类型表达式控制结构if/elsewhilerepeatforbreak,returnLua函数函数的定义函数的参数函数返回值全动态函数调用模块String 库Table 库日期时间函数数学库函数文件操作

Lua 高阶

元表面向对象编程局部变量判断数组大小非空判断正则表达式不用标准库虚变量抵制使用 module() 定义模块调用代码前先定义函数点号与冒号操作符的区别module 是邪恶的FFI什么是 JITNginxNginx 新手起步location 匹配规则if 是邪恶的静态文件服务日志反向代理负载均衡陷阱和常见错误

OpenResty

环境搭建Windows 平台CentOS 平台Ubuntu 平台Mac OS X 平台Hello World与其他 location 配合获取 uri 参数获取请求 body输出响应体日志输出简单API Server框架使用 Nginx 内置绑定变量子查询不同阶段共享变量防止 SQL 注入如何发起新 HTTP 请求

LuaRestyRedisLibrary

访问有授权验证的 Redisselect+set_keepalive 组合操作引起的数据读写错误redis 接口的二次封装(简化建连、拆连等细节)redis 接口的二次封装(发布订阅)pipeline 压缩请求数量script 压缩复杂请求动态生成的 lua-resty-redis 模块方法LuaCjsonLibraryjson解析的异常捕获稀疏数组空table编码为array还是objectPostgresNginxModule调用方式简介不支持事务超时健康监测SQL注入LuaNginxModule执行阶段概念正确的记录日志热装载代码阻塞操作缓存sleep定时任务禁止某些终端访问请求返回后继续执行调试请求中断后的处理我的 lua 代码需要调优么变量的共享范围动态限速shared.dict 非队列性质正确使用长链接如何引用第三方 resty 库body 在 location 中的传递典型应用场景怎样理解 cosocket如何安全启动唯一实例的 timer如何正确的解析域名使用动态 DNS 来完成 HTTP 请求LuaRestyLock缓存失效风暴

stream_lua_module

balancer_by_lua

OpenResty 与 SSL

HTTPS 时代动态加载证书和 OCSP staplingTLS session resumption测试代码静态分析单元测试代码覆盖率API 测试性能测试持续集成灰度发布Web 服务API的设计数据合法性检测协议无痛升级代码规范连接池C10K 编程TIME_WAIT 问题与 Docker 使用的网络瓶颈火焰图什么时候使用如何定位问题

OpenResty 周边

如何添加自己的lua api

零碎知识点记录

2016-7 月汇总如何在后台开启轻量级线程来定时更新共享内存一个 openresty 内存“泄漏”问题用 do-end 整理你的代码lua 中如何 continue调用 FFI 出现 "table overflow"如何定位 openresty 崩溃 bug

与 Docker 使用的网络瓶颈


Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app)。几乎没有性能开销,可以很容易地在机器和数据中心中运行。最重要的是,他们不依赖于任何语言、框架包括系统。

Docker 自 2013 年以来非常火热,无论是从 GitHub 上的代码活跃度,还是 Redhat 在 RHEL6.5 中集成对 Docker 的支持, 就连 Google 的 Compute Engine 也支持 Docker 在其之上运行。

笔者使用 Docker 的原因和目的,可能与其他公司不太一样。我们一直存在"分发"需求,Docker 主要是用来屏蔽企业用户平台的不一致性。我们的企业用户使用的系统比较杂,仅仅主流系统就有 Ubuntu, Centos,RedHat,AIX 还有一些定制裁减系统等,可谓百花齐放。

虽然 OpenResty 具有良好的跨平台特性,无奈我们的安全项目比较重,组件比较多,是不可能逐一适配不同平台的,工作量、稳定性等,难度和后期维护复杂度是难以想象的。如果您的应用和我们一样需要二次分发,非常建议考虑使用 Docker。这个年代是云的时代,二次分发其实成本很高,后期维护成本也很高,所以尽量做到云端。

说说 Docker 与 OpenResty 之间的"坑"吧,你们肯定对这个更感兴趣。

我们刚开始使用的时候,是这样启动的:

docker run -d -p 80:80 openresty

首次压测过程中发现 Docker 进程 CPU 占用率 100%,单机接口 4-5 万的 QPS 就上不去了。经过我们多方探讨交流,终于明白原来是网络瓶颈所致(OpenResty 太彪悍,Docker 默认的虚拟网卡受不了了 ^_^)。

最终我们绕过这个默认的桥接网卡,使用 --net 参数即可完成。

docker run -d --net=host openresty

多么简单,就这么一个参数,居然困扰了我们好几天。一度怀疑我们是否要忍受引入 Docker 带来的低效率网络。所以有时候多出来交流、学习,真的可以让我们学到好多。虽然这个点是我们自己挖出来的,但是在交流过程中还学到了很多好东西。

Docker Network settings,引自:http://www.lupaworld.com/article-250439-1.html

默认情况下,所有的容器都开启了网络接口,同时可以接受任何外部的数据请求。
--dns=[]         : Set custom dns servers for the container
--net="bridge"   : Set the Network mode for the container
                          'bridge': creates a new network stack for the container on the docker bridge
                          'none': no networking for this container
                          'container:<name|id>': reuses another container network stack
                          'host': use the host network stack inside the container
--add-host=""    : Add a line to /etc/hosts (host:IP)
--mac-address="" : Sets the container's Ethernet device's MAC address

你可以通过 docker run --net none 来关闭网络接口,此时将关闭所有网络数据的输入输出,你只能通过 STDIN、STDOUT 或者 files 来完成 I/O 操作。默认情况下,容器使用主机的 DNS 设置,你也可以通过 --dns 来覆盖容器内的 DNS 设置。同时 Docker 为容器默认生成一个 MAC 地址,你可以通过 --mac-address 12:34:56:78:9a:bc 来设置你自己的 MAC 地址。

Docker 支持的网络模式有:

  • none。关闭容器内的网络连接
  • bridge。通过 veth 接口来连接容器,默认配置。
  • host。允许容器使用 host 的网络堆栈信息。注意:这种方式将允许容器访问 host 中类似 D-BUS 之类的系统服务,所以认为是不安全的。
  • container。使用另外一个容器的网络堆栈信息。  

None 模式

将网络模式设置为 none 时,这个容器将不允许访问任何外部 router。这个容器内部只会有一个 loopback 接口,而且不存在任何可以访问外部网络的 router。

Bridge 模式

Docker 默认会将容器设置为 bridge 模式。此时在主机上面将会存在一个 docker0 的网络接口,同时会针对容器创建一对 veth 接口。其中一个 veth 接口是在主机充当网卡桥接作用,另外一个 veth 接口存在于容器的命名空间中,并且指向容器的 loopback。Docker 会自动给这个容器分配一个 IP ,并且将容器内的数据通过桥接转发到外部。

Host 模式

当网络模式设置为 host 时,这个容器将完全共享 host 的网络堆栈。host 所有的网络接口将完全对容器开放。容器的主机名也会存在于主机的 hostname 中。这时,容器所有对外暴露的端口和对其它容器的连接,将完全失效。

Container 模式

当网络模式设置为Container时,这个容器将完全复用另外一个容器的网络堆栈。同时使用时这个容器的名称必须要符合下面的格式:--net container:<name|id>.

比如当前有一个绑定了本地地址 localhost 的 Redis 容器。如果另外一个容器需要复用这个网络堆栈,则需要如下操作:

$ sudo docker run -d --name redis example/redis --bind 127.0.0.1
$ # use the redis container's network stack to access localhost
$ sudo docker run --rm -ti --net container:redis example/redis-cli -h 127.0.0.1

分类导航

关注微信下载离线手册

bootwiki移动版 bootwiki
(群号:472910771)