EDITORIAL言葉
私たちの毎日の仕事では、実際には、我々はより多くの場所のためか、当社のウェブサイトへの入り口としてそれを使用する、すべてのサービスは、単純な静的なHTMLページであることを軽量WEBサーバとしてnginxのは不可能です。あなたはバックエンドインターフェイス、またはフロントページであるかどうか、我々はサービスへのユーザー要求をしましょう。いくつかの理由があります:
1.集中管理より管理しやすいです。
特別パブリックIPおよび帯域幅を設定した各マシンは、それはあまりにも無駄である場合2.外部サービスがパブリックIPを必要としている、あなたは、帯域幅を必要とする、あなたは、帯域幅の料金は私が最近仕上げ少数のクラウド・サービス・プロバイダーで見ることができます。
帯域幅が大きいほど、コストが高く、これは高い幾何学的な成長ではありません。
3.当社のサービスは、一般的にサービスの一点ではなく、その後、前方及び後方端部は、アドレスを設定する方法を、各構成を伝えることができないのですか?それはあまりにも面倒スポットではありません。
私たちの世代サーバ4.同様のRedis /サーバ・データベースなどのネットワークは、一般的に、セキュリティのために許可されていませんが、我々は常にその上にデータを確認するためにサーバにログインする必要はありませんか?
これは、我々は彼らのアプリケーションシナリオは、当然のことながら、この設計は、中小企業のために十分である方法によって、いくつかのエージェントに話をする必要があり、単純な理由で、結局、メーカーがされていない、彼らの特定のアーキテクチャを知りませんそして、実装。
TCPプロキシ
我々は確かにまだ最初のエージェントは次であるかを理解しなければならないと言って前にTCPプロキシ?
プロキシ(プロキシ)、我々は表現するための図を使用して、実際のネットワーク情報の中継点です。
クラスタのクラウド・プロバイダーのサーバーがパブリックIPを持っている経由でこのようなシナリオは、外部のユーザーは、それがパブリックネットワークにアクセスすることが可能であるが、他のサーバーがクラスタ内にあるパブリックIPアドレス、パブリックネットワークを持っていません、我々はアクセスできませんでしたが、そこだけで、パブリックIPサーバーは、そのネットワークカードは、クラスタ内にあり、これらは公共のIPネットワークは、マシンがユーザと通信することができないだけで、そして彼らができることを意味し、マシンと通信することはできませんバックエンドクラスタ通信。その後、我々は、ユーザーとバックエンドのクラスタ間の相互メッセンジャー、そのパブリックIPネットワークを実現するために、仲介として、そして、サーバは外観を伝えるのに役立つ、パブリックIPアドレスを持つように、クラスタの後ろにユーザーにアクセスする方法を考えなければなりませんマシンは、プロキシサーバーになります。
それはどのようなTCPプロキシですか?
私たちの日常の訪問のWebアプリケーションでは、HTTPを使用している://、httpsのを://。しかし、MySQLのようHTTP以外のいくつかのサービス、この接続は、これは明らかにWEBサービスではないので、そのままでは、我々は、Webプロキシサービスエージェントようにすることはできません。そして、このようなサービスがTCPのサービスで、我々は、TCPプロキシを排他的に使用しています。
我々はまた、例えばTCPプロキシMySQLは、具体的な構成を使用する方法について話をします。
私たちは、参加するために、時間にコンパイルした --with-ストリーム我々は欠かせないプロキシを使用することである引数を、。
同様に、nginx.confにより、メインの設定ファイルでは、含まれ 、設定ファイルが置かれているTCPの設定用に別のディレクトリを設定します:
TCP、HTTPプロキシサービスではない、ということは注目に値する、と私たちの前の位置が同じではありませんすべてが、我々はHTTPの外側の層を配置する必要があり、次のとおりです。
ユーザーroot; ... HTTP { ... } ストリーム{ TCPを含む /*.confと、 }
私たちの新しいTCPの ディレクトリ:私は直接のnginxを使用してrootユーザーを使用しての利便性のためにここにいます
ます。mkdir /データ/サービス/ nginxの/ confに/ TCP
ディレクトリにMySQLのプロキシ設定ファイルを増やし:MySQLのプロキシ-demo.confを
上流MYSQL-PROXY- DEMO { 一貫したハッシュの$ REMOTE_ADDR。 サーバー 192.168.10.204:3306 ; } サーバー{ 聞く 5000 。 proxy_connect_timeout 10秒; proxy_timeout 300S; proxy_pass MYSQL -PROXY- DEMO。 }
簡単な説明:
エージェントは、後端に複数の機械を必要とする場合nginxのにおいては、上流使用する必要があるため、MYSQLベースのPROXY-DEMOは唯一の要件、名前の上流に取り込まれます。
2.ハッシュxxxはスケジューリングモデルで、当然のことながら、ちょうどここのサーバレコードを書き、スケジューリング問題内の他のすべてのノードが存在しません。
3.サーバーxxxはプロキシレコードの必要性、各サーバーです。
同様4.サーバーセグメントおよびHTTP Webサービスが、サーバー名を必要としません。
5.接続タイムアウト、proxy_timeoutエージェントのタイムアウトをproxy_connect_timeout。
6. proxy_pass、最も重要な1つのプロキシ、我々はポートの名前プロキシするサービスまたは上流います。それは、後に使用されます。
nginxの私たちは、データベース接続をテストし、この時間をリロードします。
可以看到,我们成功的使用代理服务器的 IP + 端口通过 Navict 连接到了其它主机的 MySQL 数据库。
正向代理
正向代理不是我们使用的重点,因为在日常的使用中用的并不多,但是在某些特殊的场景下很有用。
比如有个局域网用户,无法访问互联网,但是局域网中另外一台机器却能够访问到互联网,所有我们可以通过那台机器作为代理去访问互联网。
正向代理的好处在于能够对需要访问的网站隐藏用户的真实信息。
这是系统为我提供的解决方案,但是并不是很好用,如果你想直接使用,请直接跳到后面第三方模块搭建正向代理。
我们在 vhosts 目录下新建配置:forward-proxy-demo.conf
server { resolver 8.8.8.8; access_log off; listen 6080; location / { proxy_pass $scheme://$http_host$request_uri; proxy_set_header HOST $http_host; # 配置缓存大小,关闭磁盘缓存读写减少I/O,以及代理连接超时时间 proxy_buffers 256 4k; proxy_max_temp_file_size 0; proxy_connect_timeout 30; # 配置代理服务器 Http 状态缓存时间 proxy_cache_valid 200 302 10m; proxy_cache_valid 301 1h; proxy_cache_valid any 1m; proxy_next_upstream error timeout invalid_header http_502; } }
简单说明:
红色部分为核心配置,这里我们直到了,在 nginx 中我们是可以通过 proxy_set_header 来处理请求头的。
我们在另外一台不能上网的机器上增加配置:
重载 nginx 后我们在不能上网的机器上执行 curl 百度:
curl -I --proxy 192.168.100.111:6080 http://www.baidu.com
结果如下:
当然我们也可以将代理配置定义成环境变量:
export http_proxy=http://192.168.100.111:6080
这样就能直接执行:
第三方模块搭建正向代理
当然,上面的配置都是针对 HTTP 的,对于 HTTPS 代理或者说整个正向代理,我们推荐使用第三方模块:ngx_http_proxy_connect_module
GITHUB 地址:
将下载的 zip 包上传到服务器,重新编译 nginx,具体方法参考前面的动态添加模块:
1. 安装依赖:
yum install -y patch
2. 解压打补丁,编译:
从 GITHUB 上面,我们可以看到各个版本的 nginx 对应的补丁版本:
cd /data/packages/nginx unzip ngx_http_proxy_connect_module-master.zip cd nginx-1.16.0/ patch -p1 < /data/packages/nginx/ngx_http_proxy_connect_module-master/patch/proxy_connect_rewrite_101504.patch
编译不安装:
./configure --prefix=/data/services/nginx \ --user=nginx \ --group=nginx \--with-http_stub_status_module \ --with-http_gzip_static_module \ --with-http_secure_link_module \ --with-http_flv_module \ --with-http_ssl_module \ --with-http_mp4_module \ --with-stream \ --with-http_realip_module \ --with-http_v2_module \ --with-http_sub_module \ --with-http_image_filter_module \ --with-pcre=/data/packages/nginx/pcre-8.43 \ --with-openssl=/data/packages/nginx/openssl-1.1.1c \ --with-zlib=/data/packages/nginx/zlib-1.2.11 \ --add-module=/data/packages/nginx/nginx-upload-module-master \ --add-module=/data/packages/nginx/nginx-upstream-fair-master \ --add-module=/data/packages/nginx/ngx_cache_purge-master \ --add-module=/data/packages/nginx/ngx-fancyindex-master \ --add-module=/data/packages/nginx/echo-nginx-module-master \ --add-module=/data/packages/nginx/ngx_http_proxy_connect_module-master # 编译 make
3. 备份替换旧版:
# 备份 mv /data/services/nginx/sbin/nginx /data/backup/nginx/nginx_$(date +%F) # 更新 cp /data/packages/nginx/nginx-1.16.0/objs/nginx /data/services/nginx/sbin/ # 查看 /data/services/nginx/sbin/nginx -V
如图:
4. 添加 nginx 正向代理配置:
server { listen 6080; resolver 202.96.128.166; resolver_timeout 30s; # 代理配置 proxy_connect; proxy_connect_allow 443 563; proxy_connect_connect_timeout 10s; proxy_connect_read_timeout 10s; proxy_connect_send_timeout 10s; location / { proxy_pass http://$host; proxy_set_header Host $host; } }
重载配置访问测试:
curl -I --proxy 192.168.100.111:6080 http://www.baidu.com
curl -I --proxy 192.168.100.111:6080 https://www.alipay.com
HTTP 访问结果:
HTTPS 访问结果:
当然,我们也可以设置环境变量:
export http_proxy=http://192.168.100.111:6080 export https_proxy=http://192.168.100.111:6080 no_proxy="localhost,127.0.0.1,localaddress,.localdomain.com"
最后,小结一下:正向代理配置虽然能够满足我们的一定需求,但是有些时候不是很稳定,包括在配置过程中,有时候并不能一次就能访问成功,需要多测试几次。
反向代理 / 负载均衡
反向代理一直是我们 nginx 服务配置的重中之重,我们工作的项目中大部分其实都是围绕着反向代理展开的。如果你用 nginx,你说你没有配置过静态资源 WEB 我相信,但是你没有用过反向代理,那你一定不是做运维的。
那什么是反向代理?
这需要我们和正向代理结合起来理解,我们之前正向代理的时候是我们代理别人的服务让我们能够访问到。
那么反向代理就是代理我们的服务让别人能够访问到,是不是一下子就清晰了。
我们本次测试环境用到了三台机器,一台是我们的 nginx,另外两台是安装了 tomcat 服务的服务器。我们要实现以下图示:
用户访问 nginx 的 8090 端口调度到后端的 TOMCAT 8080 上面去。
至于 TOMCAT 怎么安装部署这里就不做过多说明,这里做了个小处理,在 TOMCAT webapps 下面默认 ROOT 项目的 index.jsp 文件增加了本机 IP 用于区分:
此时我们启动两个 TOMCAT 访问测试:
节点1结果:
节点2结果:
在 nginx 的 vhosts 目录下增加如下配置:reverse-proxy-demo.conf
upstream REVERSE-PROXY-DEMO { ip_hash; server 192.168.100.112:8080 weight=1 max_fails=3 fail_timeout=10s; server 192.168.100.113:8080 weight=1 max_fails=3 fail_timeout=10s; } server { listen 8090; server_name localhost; location / { proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 30; proxy_send_timeout 30; proxy_read_timeout 30; proxy_pass http://REVERSE-PROXY-DEMO; } }
如 TCP 代理一般,TCP 代理其实也是反向代理的一种,我们定义的 upstream 的名称要求唯一。
重载 nginx 访问测试:
可以看到请求被分配到了 100.113 这台机器上面去了!
我们之前就在使用 upstream,但是 upstream 到底是啥我们一直没说,其实 upstream 就是负载均衡。
从字面上的意思就可以理解,负载均衡就是均衡的,按照特定的调度算法,将请求调度到指定的节点(upstream server)。
upstream 配置说明:
1. nginx 负载均衡调度算法加上我们安装的 fair 模块,大致有以下 4 种:
调度算法 | 说明 |
---|---|
权重轮询(默认) | 按照顺序逐一分配到不同的后端。自动剔除失败的机器,使访问不受影响。 |
ip_hash | 每个请求按照 IP 的 Hash 结果分配,使来自同一 IP 的固定访问到同一后端。能解决部分程序 session 没共享的问题 |
fair | 更智能的算法,可以根据页面大小和加载速度进行智能负载,响应快的优先分配。 |
url_hash | 需要按照 nginx hash 模块,按照访问的 URL 定向到某个机器上,能提升后端缓存服务器的效率。 |
日常用到比较多的就是前三个。
2. server 后面的参数:
参数 | 说明 |
---|---|
weight | 分配到请求权重,权重比例多高分配到请求的机会越大。 |
max_fails | 最大的失败连接次数。 |
fail_timeout | 等待请求的目标服务器响应的时长。 |
backup | 当所有机器都 down 掉才会调度到这台机器。 |
down | 手动停用某台机器。 |
这其实就是一些健康检查参数,但是这些参数存在不足,在实际应用中,可以结合 keepalived 来完成,后面会单独说明。
server 段关于反向代理的一些配置:
参数 | 说明 |
---|---|
proxy_redirect | 重写应答头部的报文 |
proxy_connect_timeout | nginx 将一个请求发送至 upstream server 之前等待的最大时长 |
proxy_set_header | 将发送至 upsream server 的报文的某首部进行重写 |
proxy_cookie_domain | 将 upstream server 通过 Set-Cookie 首部设定的 domain 修改为指定的值,可以为字符串、正则或变量 |
proxy_cookie_path | 将 upstream server 通过 Set-Cookie 首部设定的 path 修改为指定的值,可以为字符串、正则或变量 |
proxy_hide_header | 设定发送给客户端的报文中需要隐藏的首部 |
proxy_send_timeout | 发送至 upstream server 的写操作的超时时长 |
proxy_read_timeout | 发送至 upstream server 的读操作的超时时长 |
proxy_pass | 指定将请求代理至 upstream server 的 URL 路径 |
其实上面的配置我们可以简单的做个调整就能变成我们反向代理的配置模板。
小结
简单的 TCP / 正向 / 反向代理负载均衡就这些内容,当然还要优化的空间,后面会专门针对 nginx 配置优化再度进行说明。