问题描述

nginx reload是有一定损耗的,如果你使用的是长连接的话,那么当reload nginx时长连接所有的worker进程会进行优雅退出,并当该worker进程上的所有连接都释放时,进程才真正退出。

解决办法

对于社区版nginx目前有三个选择方式:

  1. Tengine 的Dyups模块。
  2. 微博的Upsync+Consul 实现动态负载均衡。
  3. OpenResty的balancer_by_lua(又拍云使用其开源的slardar(Consul balancer_by_lua))。

本文使用upsync模块来解决配置文件修改后,reload nginx进程造成性能下降的问题。

它的功能是拉取 consul 的后端 server 的列表,并更新 Nginx 的路由信息。此模块不依赖于任何第三方模块。consul 作为 Nginx 的 db,利用 consul 的 KV 服务,每个 Nginx work 进程独立的去拉取各个 upstream 的配置,并更新各自的路由。

实战

给nginx打补丁包

这步可以不做,如果不做,编译的时候删除这个模块

git clone https://github.com/xiaokai-wang/nginx_upstream_check_module
## 打补丁包
patch -p0 < /usr/local/src/nginx_upstream_check_module-master/check_1.9.2+.patch

下载nginx-upsync-module源码

git clone https://github.com/weibocom/nginx-upsync-module.git

下载nginx源码
wget 'http://nginx.org/download/nginx-1.10.1.tar.gz'
tar -xzvf nginx-1.10.1.tar.gz
cd nginx-1.10.1/
开始编译
./configure --prefix=/data/app/nginx-1.10.1 --user=nginx --group=nginx --with-http_ssl_module --with-http_stub_status_module --add-module=/usr/local/src/nginx-upsync-module-master/ --add-module=/usr/local/src/nginx_upstream_check_module-master/
make
make install

启动consul

wget https://releases.hashicorp.com/consul/0.6.4/consul_0.6.4_linux_amd64.zip
unzip consul_0.6.4_linux_amd64.zip
./consul agent -advertise=x.x.x.x -client=0.0.0.0 -dev

创建nginx配置文件

mkdir -p /usr/local/nginx/conf/servers
/usr/local/nginx/conf/nginx.conf
events {
worker_connections 4096; ## Default: 1024
} http {
upstream test {
# fake server otherwise ngx_http_upstream will report error when startup
server 127.0.0.1:11111; # all backend server will pull from consul when startup and will delete fake server
upsync 127.0.0.1:8500/v1/kv/upstreams/test upsync_timeout=6m upsync_interval=500ms upsync_type=consul strong_dependency=off;
upsync_dump_path /usr/local/nginx/conf/servers/servers_test.conf;
} upstream bar {
server 127.0.0.1:8090 weight=1 fail_timeout=10 max_fails=3;
} server {
listen 8080; location = /proxy_test {
proxy_pass http://test;
} location = /bar {
proxy_pass http://bar;
} location = /upstream_show {
upstream_show;
} }
}

测试

for i in `seq 3`;do mkdir html$i/test -p && echo $i >html$i/test/test.html; done;  

docker run -d -p 8001:80 -v /root/html1/:/usr/share/nginx/html nginx
docker run -d -p 8002:80 -v /root/html2/:/usr/share/nginx/html nginx
docker run -d -p 8003:80 -v /root/html3/:/usr/share/nginx/html nginx

添加服务

curl -X PUT -d '{"weight":1, "max_fails":2, "fail_timeout":10}' http://127.0.0.1:8500/v1/kv/upstreams/test/192.168.56.12:8001
curl -X PUT -d '{"weight":1, "max_fails":2, "fail_timeout":10}' http://127.0.0.1:8500/v1/kv/upstreams/test/192.168.56.12:8002
curl -X PUT -d '{"weight":1, "max_fails":2, "fail_timeout":10}' http://127.0.0.1:8500/v1/kv/upstreams/test/192.168.56.12:8003

查看conf/servers/servers_test.conf 文件中是否有内容

cat conf/servers/servers_test.conf
server 192.168.56.12:8003 weight=1 max_fails=2 fail_timeout=10s;
server 192.168.56.12:8002 weight=1 max_fails=2 fail_timeout=10s;
server 192.168.56.12:8001 weight=1 max_fails=2 fail_timeout=10s;

或者浏览器打开http://192.168.56.11:8080/upstream_show?test

显示内容如下:

Upstream name: test; Backend server count: 3
server 192.168.56.12:8003 weight=1 max_fails=2 fail_timeout=10s;
server 192.168.56.12:8002 weight=1 max_fails=2 fail_timeout=10s;
server 192.168.56.12:8001 weight=1 max_fails=2 fail_timeout=10s;

总结

此模块只修改upstream 中的缓存信息,不能修改或添加其他配置

测试中遇到的问题

在添加服务时出现如下错误,导致服务添加不能实时进行,大约需要3分钟左右时间。

consul日志:

2016/03/22 05:34:42 [DEBUG] http: Request GET /v1/kv/upstreams/test?recurse&index=169 (149.023µs) from=127.0.0.1:38853
2016/03/22 05:34:43 [DEBUG] http: Request GET /v1/kv/upstreams/test?recurse&index=169 (146.759µs) from=127.0.0.1:38854
2016/03/22 05:34:45 [DEBUG] http: Request GET /v1/kv/upstreams/test?recurse&index=169 (149.853µs) from=127.0.0.1:38855
2016/03/22 05:34:46 [DEBUG] http: Request GET /v1/kv/upstreams/test?recurse&index=169 (111.46µs) from=127.0.0.1:38856
2016/03/22 05:34:48 [DEBUG] http: Request GET /v1/kv/upstreams/test?recurse&index=169 (142.696µs) from=127.0.0.1:38857
2016/03/22 05:34:48 [DEBUG] http: Request GET /v1/kv/upstreams/test?recurse&index=169 (112.089µs) from=127.0.0.1:38858
2016/03/22 05:34:49 [DEBUG] http: Request GET /v1/kv/upstreams/test?recurse&index=169 (114.29µs) from=127.0.0.1:38859
2016/03/22 05:34:50 [DEBUG] http: Request GET /v1/kv/upstreams/test?recurse&index=169 (148.245µs) from=127.0.0.1:38860

nginx日志

2016/03/22 05:35:09 [error] 18879#0: recv() failed (104: Connection reset by peer)
2016/03/22 05:35:09 [error] 18879#0: upsync_recv: recv error with upsync_server: 127.0.0.1:8500
2016/03/22 05:35:10 [error] 18879#0: recv() failed (104: Connection reset by peer)
2016/03/22 05:35:10 [error] 18879#0: upsync_recv: recv error with upsync_server: 127.0.0.1:8500
2016/03/22 05:35:11 [error] 18879#0: recv() failed (104: Connection reset by peer)
2016/03/22 05:35:11 [error] 18879#0: upsync_recv: recv error with upsync_server: 127.0.0.1:8500
2016/03/22 05:35:13 [error] 18879#0: recv() failed (104: Connection reset by peer)
2016/03/22 05:35:13 [error] 18879#0: upsync_recv: recv error with upsync_server: 127.0.0.1:8500
2016/03/22 05:35:13 [error] 18879#0: recv() failed (104: Connection reset by peer)
2016/03/22 05:35:13 [error] 18879#0: upsync_recv: recv error with upsync_server: 127.0.0.1:8500
2016/03/22 05:35:14 [error] 18879#0: recv() failed (104: Connection reset by peer)

问题现象

当添加一个服务时,出现此问题,新增服务不能及时添加到负载中,不影响运行正常的服务。 此时再往consul继续添加一个服务时,可能会导致此错误终止,并能成功添加当前两条服务记录。

帮助文档

官方github地址

nginx_upstream_check_module

死磕nginx系列--使用upsync模块实现负载均衡的更多相关文章

  1. 死磕nginx系列--nginx 目录

    死磕nginx系列--nginx入门 死磕nginx系列--nginx配置文件 死磕nginx系统-nginx日志配置 死磕nginx系列--nginx服务器做web服务器 死磕nginx系列--使用 ...

  2. 死磕nginx系列

    死磕nginx系列 死磕nginx系列--nginx入门 死磕nginx系列--nginx配置文件 死磕nginx系统--nginx日志配置 死磕nginx系列--nginx服务器做web服务器 死磕 ...

  3. 死磕nginx系列--配置文档解读

    nginx配置文件主要分为四个部分: main(全局设置) http ( ) upstream(负载均衡服务器设置) server(主机设置) location(URL匹配特点位置的设置) serve ...

  4. 死磕nginx系列--nginx入门

    nginx 功能介绍 Nginx因为它的稳定性.丰富的模块库.灵活的配置和低系统资源的消耗而闻名.业界一致认为它是Apache2.2+mod_proxy_balancer的轻量级代替者,不仅是因为响应 ...

  5. 死磕nginx系列--使用nginx做负载均衡

    使用nginx做负载均衡的两大模块: upstream 定义负载节点池. location 模块 进行URL匹配. proxy模块 发送请求给upstream定义的节点池. upstream模块解读 ...

  6. 死磕nginx系列--nginx 限流配置

    限流算法 令牌桶算法 算法思想是: 令牌以固定速率产生,并缓存到令牌桶中: 令牌桶放满时,多余的令牌被丢弃: 请求要消耗等比例的令牌才能被处理: 令牌不够时,请求被缓存. 漏桶算法 算法思想是: 水( ...

  7. 死磕nginx系列-nginx日志配置

    nginx access日志配置 access_log日志配置 access_log用来定义日志级别,日志位置.语法如下: 日志级别: debug > info > notice > ...

  8. 死磕nginx系列--nginx服务器做web服务器

    nginx 做静态服务器 HTML页面如下 <!DOCTYPE html> <html lang="en"> <head> <meta c ...

  9. 死磕nginx系列--使用nginx做cache服务

    配置文件 nginx.conf 主配置文件 worker_processes 1; events { worker_connections 1024; } http { include mime.ty ...

随机推荐

  1. 乐字节-Java8新特性-Lambda表达式

    上一篇文章我们了解了Java8新特性-接口默认方法,接下来我们聊一聊Java8新特性之Lambda表达式. Lambda表达式(也称为闭包),它允许我们将函数当成参数传递给某个方法,或者把代码本身当作 ...

  2. Magic Number (zoj3622)

    Magic Number (zoj3622) Time Limit : 4000/2000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Oth ...

  3. Java - Map总结

    Java提高篇(三三)-----Map总结 一.Map概述 首先先看Map的结构示意图 Map:“键值”对映射的抽象接口.该映射不包括重复的键,一个键对应一个值. SortedMap:有序的键值对接口 ...

  4. ThinkPHP中create()方法自动验证表单信息

    自动验证是ThinkPHP模型层提供的一种数据验证方法,可以在使用create创建数据对象的时候自动进行数据验证. 原理: create()方法收集表单($_POST)信息并返回,同时触发表单自动验证 ...

  5. BZOJ3351: [ioi2009]Regions(根号分治)

    题意 题目链接 Sol 很神仙的题 我们考虑询问(a, b)(a是b的祖先),直接对b根号分治 如果b的出现次数\(< \sqrt{n}\),我们可以直接对每个b记录下与它有关的询问,这样每个询 ...

  6. Origin绘制双Y轴图的方法

    1.已有数据绘图如下,其中网络流量的单位是M Bytes/s,与另外两组数据的单位(时间)不同,现在要为其添加右侧Y轴. 2.首先选中该图像,找到工具条,点击第三个按钮“Add Right-Y Lay ...

  7. css实现3D立方体旋转特效

    先来看运行后出来的效果 它是在不停运行的一个立方体 先来看html部分的代码 <div class="rect-wrap"> <!--舞台元素,设置perspec ...

  8. python学习笔记之——操作mysql数据库

    Python 标准数据库接口为 Python DB-API,Python DB-API为开发人员提供了数据库应用编程接口. Python 数据库接口支持非常多的数据库,你可以选择适合你项目的数据库: ...

  9. 语义SLAM的数据关联和语义定位(三)

    与现有方法的异同 特征点SLAM中的数据关联 先回忆一下特征点SLAM中,我们是如何处理数据关联的.下面以ORBSLAM为例. 在初始化部分,我们通过特征描述子的相似性,建立两帧之间的特征点关联,然后 ...

  10. onlyoffice文档协作的权限开发,利用casbin和golang语言

    登录用户,对于已经进行了权限设置的文档,将根据权限数据库,比对用户名,当与用户有关时,就显示相对应的权限,当都与登录用户无关时,则显示拒绝访问: 对于未登录用户,已经设置了权限的文档,都将显示拒绝访问 ...