Nginx是目前使用量最大的web服务器和负载均衡服务器

实现的方案有:

  • nginx+consul
  • nginx+etcd

这里主要介绍nginx+etcd,具体方法都差不多

下面介绍一下怎么实现的

安装并运行etcd

安装etcd

目前最新版本为3.4.7

1wget https://github.com/etcd-io/etcd/releases/download/v3.4.7/etcd-v3.4.7-linux-amd64.tar.gz
2tar xf etcd-v3.4.7-linux-amd64.tar.gz -C /usr/bin \
3 --strip-components 1 etcd-v3.4.7-linux-amd64/etcd{,ctl}

创建etcd用户和工作目录

1groupadd -g 379 etcd
2useradd -u 379 -g 379 etcd -s /sbin/nologin -d /etc/etcd

创建unit文件

 1cat > /usr/lib/systemd/system/etcd.service <<EOF
 2[Unit]
 3Description=etcd key value storage
 4Documentation=https://etcd.io
 5After=network.target
 6
 7[Service]
 8User=etcd
 9Group=etcd
10ExecStart=/usr/bin/etcd --logger=zap --data-dir=/etc/etcd --enable-v2=true
11ExecReload=/bin/kill -HUP \$MAINPID
12KillMode=process
13Restart=always
14RestartSec=30s
15
16[Install]
17WantedBy=multi-user.target
18EOF

备注upsync模块只支持v2版本的API,一定要加上--enable-v2=true,默认为禁用

运行etcd

1systemctl enable --now etcd

编译安装nginx

安装依赖包

 1dnf -y install gcc \
 2  make \
 3  pcre-devel \
 4  openssl-devel \
 5  zlib-devel \
 6  libxml2-devel \
 7  libxslt-devel \
 8  gd-devel \
 9  perl-ExtUtils-Embed \
10  gperftools

创建nginx用户

1groupadd -g 800 nginx
2useradd -u 800 -g 800 -d /var/lib/nginx -c 'Nginx web server' -s /sbin/nologin nginx

下载nginx最新稳定版本

1wget http://nginx.org/download/nginx-1.16.1.tar.gz

下载upsync模块

1wget https://github.com/weibocom/nginx-upsync-module/archive/v2.1.2.tar.gz

解压

1tar xf nginx-1.16.1.tar.gz
2tar xf nginx-upsync-module-2.1.2.tar.gz

编译nginx

 1cd nginx-1.16.1
 2./configure --prefix=/usr/share/nginx \
 3  --sbin-path=/usr/sbin/nginx \
 4  --modules-path=/usr/lib64/nginx/modules \
 5  --conf-path=/etc/nginx/nginx.conf \
 6  --error-log-path=/var/log/nginx/error.log \
 7  --http-log-path=/var/log/nginx/access.log \
 8  --http-client-body-temp-path=/var/lib/nginx/tmp/client_body \
 9  --http-proxy-temp-path=/var/lib/nginx/tmp/proxy \
10  --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi \
11  --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi \
12  --http-scgi-temp-path=/var/lib/nginx/tmp/scgi \
13  --pid-path=/run/nginx.pid \
14  --lock-path=/run/lock/subsys/nginx \
15  --user=nginx \
16  --group=nginx \
17  --with-file-aio \
18  --with-http_ssl_module \
19  --with-http_v2_module \
20  --with-http_realip_module \
21  --with-stream_ssl_preread_module \
22  --with-http_addition_module \
23  --with-http_xslt_module=dynamic \
24  --with-http_image_filter_module=dynamic \
25  --with-http_sub_module \
26  --with-http_dav_module \
27  --with-http_flv_module \
28  --with-http_mp4_module \
29  --with-http_gunzip_module \
30  --with-http_gzip_static_module \
31  --with-http_random_index_module \
32  --with-http_secure_link_module \
33  --with-http_degradation_module \
34  --with-http_slice_module \
35  --with-http_stub_status_module \
36  --with-http_perl_module=dynamic \
37  --with-http_auth_request_module \
38  --with-mail=dynamic \
39  --with-mail_ssl_module \
40  --with-pcre-jit \
41  --with-stream=dynamic \
42  --with-stream_ssl_module \
43  --with-google_perftools_module \
44  --with-debug \
45  --add-module=../nginx-upsync-module-2.1.2

修改配置文件

 1mkdir /etc/nginx/conf.d
 2vim /etc/nginx/nginx.conf
 3# 在http模块内添加upstream,假设你的etcd是127.0.0.1:2379或者改成自己的
 4    upstream test {
 5        upsync 127.0.0.1:2379/v2/keys/upstreams/test upsync_timeout=6m upsync_interval=500ms upsync_type=etcd strong_dependency=off;
 6        upsync_dump_path /etc/nginx/conf.d/servers_test.conf;
 7        include /etc/nginx/conf.d/servers_test.conf;
 8    }
 9
10# 在server中添加location,进行反向代理
11        location /test {
12             proxy_pass http://test;
13        }

创建servers_test.conf文件

假设要代理的服务是127.0.0.1:8081

1vim /etc/nginx/conf.d/servers_test.conf
2server 127.0.0.1:8081 weight=1 max_fails=2 fail_timeout=10s;

创建unit文件

 1cat > /usr/lib/systemd/system/nginx.service <<EOF
 2[Unit]
 3Description=The nginx HTTP and reverse proxy server
 4After=network.target remote-fs.target nss-lookup.target
 5
 6[Service]
 7Type=forking
 8PIDFile=/run/nginx.pid
 9# Nginx will fail to start if /run/nginx.pid already exists but has the wrong
10# SELinux context. This might happen when running `nginx -t` from the cmdline.
11# https://bugzilla.redhat.com/show_bug.cgi?id=1268621
12ExecStartPre=/usr/bin/rm -f /run/nginx.pid
13ExecStartPre=/usr/sbin/nginx -t
14ExecStart=/usr/sbin/nginx
15ExecReload=/bin/kill -s HUP \$MAINPID
16KillSignal=SIGQUIT
17TimeoutStopSec=5
18KillMode=process
19PrivateTmp=true
20
21[Install]
22WantedBy=multi-user.target
23EOF

运行nginx

1mkdir /var/lib/nginx/tmp
2
3nginx -t
4nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
5nginx: configuration file /etc/nginx/nginx.conf test is successful
6
7systemctl enable --now nginx

尝试往etcd中添加数据,数据添加格式

1 curl -X PUT http://$etcd_ip:$port/v2/keys/upstreams/$upstream_name/$backend_ip:$backend_port

先尝试启动3个web服务,监听在8081,8082,8083端口上

尝试给test添加3条记录

1curl -X PUT http://127.0.0.1:2379/v2/keys/upstreams/test/127.0.0.1:8081 -d value="{\"weight\":1, \"max_fails\":2, \"fail_timeout\":10}"
2{"action":"set","node":{"key":"/upstreams/test/127.0.0.1:8081","value":"{\"weight\":1, \"max_fails\":2, \"fail_timeout\":10}","modifiedIndex":6,"createdIndex":6}}
3
4curl -X PUT http://127.0.0.1:2379/v2/keys/upstreams/test/127.0.0.1:8082 -d value="{\"weight\":1, \"max_fails\":2, \"fail_timeout\":10}"
5{"action":"set","node":{"key":"/upstreams/test/127.0.0.1:8082","value":"{\"weight\":1, \"max_fails\":2, \"fail_timeout\":10}","modifiedIndex":7,"createdIndex":7}}
6
7curl -X PUT http://127.0.0.1:2379/v2/keys/upstreams/test/127.0.0.1:8083 -d value="{\"weight\":1, \"max_fails\":2, \"fail_timeout\":10}"
8{"action":"set","node":{"key":"/upstreams/test/127.0.0.1:8083","value":"{\"weight\":1, \"max_fails\":2, \"fail_timeout\":10}","modifiedIndex":8,"createdIndex":8}}

查看nginx配置文件

1cat /etc/nginx/conf.d/servers_test.conf
2server 127.0.0.1:8083 weight=1 max_fails=2 fail_timeout=10s;
3server 127.0.0.1:8082 weight=1 max_fails=2 fail_timeout=10s;
4server 127.0.0.1:8081 weight=1 max_fails=2 fail_timeout=10s;

已经自动加载到配置文件中了,后续的服务通过注册到etcd上,使用etcd的服务发现的功能可以实现服务的热加载。