博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
nginScript系列:通过TCP负载均衡和Galera集群来扩展MySQL
阅读量:6095 次
发布时间:2019-06-20

本文共 4500 字,大约阅读时间需要 15 分钟。

这是nginScript系列文章的第三篇,将介绍如何使用nginScript将客户端循序渐进地重定向到新的服务器。查看第一篇“”,第二篇“”。

\\

NGINX Plus在版本里就引入了TCP的负载均衡,在随后的版本里不断地添加新特性,包括支持。在这篇文章里,我们将探讨NGINX Plus是如何实现TCP负载均衡的。

\\

为了了解NGINX Plus的特性,我们使用了一个简单的测试环境,这个环境包含了应用程序所必需的组件,包括一个可伸缩的数据库。

\\

(点击放大图像)

\\

\\

MySQL负载均衡测试环境

\\

在这个环境里,NGINX Plus作为数据库服务器的反向代理,监听MySQL的3306端口。反向代理为客户端提供了一个简单的接口,后端的MySQL节点可以自由伸缩(甚至离线),不会对客户端有任何影响。我们使用作为客户端,在测试环境里充当前端应用。

\\

本文所描述的很多特性在开源的NGINX和NGINX Plus里都有提供。不过,为了简单起见,我们通篇使用NGINX Plus,有些在NGINX里没有的特性我们会明确指明。

\\

我们将探讨如下几个应用场景。

\\
  • TCP负载均衡\\t
  • 高可用和健康检查\\t
  • 日志和诊断\\t
  • 并发写入\

TCP负载均衡

\\

在为应用程序配置负载均衡之前,需要了解应用程序是如何连接到数据库的。我们使用MySQL命令行工具mysql连接到Galera集群,运行查询,然后关闭连接。不过,在实际当中,很多应用框架使用来减小延迟,有效利用数据库的资源。

\\

TCP的负载均衡是在stream context里配置的,所以我们在nginx.conf文件里增加了一个stream配置块来配置我们的MySQL负载均衡。

\\
\stream { include stream.conf; }
\\

我们的TCP负载均衡配置与主配置文件是分开的。我们在相同的目录创建stream.conf文件。要注意,在默认情况下,conf.d目录被保留用于http context配置,如果在这里添加stream配置是不会生效的。

\\
\upstream galera_cluster {\    server 127.0.0.1:33061; # node1\    server 127.0.0.1:33062; # node2\    server 127.0.0.1:33063; # node3\    zone tcp_mem 64k;\}\\server {\    listen 3306; # MySQL默认端口\    proxy_pass galera_cluster;\}
\\

首先,我们定义了一个upstream组,名字叫作galera_cluster,包含了Galera集群里的三个MySQL节点。在我们的测试环境里,可以分别通过本地的不同端口访问它们。

\\

zone指令指定了一些内存,NGINX Plus的工作线程用它来维护负载均衡的状态。server{}配置块定义了NGINX Plus是如何处理客户端的。NGINX Plus监听MySQL的默认端口3306,并将流量转向到Galera集群。

\\

为了验证配置的正确性,我们可以使用MySQL客户端来获取它所连接的MySQL节点的机器名。

\\
\$ echo \"SHOW VARIABLES WHERE Variable_name = 'hostname'\" | mysql --protocol=tcp --user=nginx --password=plus -N 2\u0026gt; /dev/null\hostname    node1
\\

我们可以重复同样的命令,来验证负载均衡是否正常。

\\
\$ !!;!!;!!\hostname    node2\hostname    node3\hostname    node1
\\

这足以说明轮询负载均衡算法是正常的。不过,如果我们的应用程序使用连接池来访问数据库,那么就有可能导致每个节点的连接数不均衡。另外,我们无法保证每一个连接的负载是均等的,因为处理查询的连接有可能很空闲也有可能很忙。另一种负载均衡算法叫作最少连接数(Least Connections),可以使用least_conn指令来配置。

\\
\upstream galera_cluster {\    server 127.0.0.1:33061; # node1\    server 127.0.0.1:33062; # node2\    server 127.0.0.1:33063; # node3\    zone tcp_mem 64k;\    least_conn;\}
\\

现在,如果有客户端连接到数据库,NGINX Plus会选择集群里具有最少连接数的节点。

\\

高可用和健康检查

\\

在集群里进行负载均衡的最大好处是它可以提供高可用性。基于上述的配置,如果一个新的TCP连接建立失败,NGINX Plus就把这台服务器标记为“down”,并停止向它发送TCP数据包。

\\

除了能够探测到宕机的服务器,NGINX Plus还能自动进行自发的健康检查。因此,在客户端发送请求到那些不可用的服务器之前,NGINX Plus能够提前检测到它们(这个特性只在NGINX Plus里提供)。另外,我们可以通过应用程序级别的健康检测来测试服务器的可用性。我们向每一台服务器发送请求,如果服务器返回响应,说明它运行正常。我们在配置里添加了一些内容。

\\
\upstream galera_cluster {\    server 127.0.0.1:33061; # node1\    server 127.0.0.1:33062; # node2\    server 127.0.0.1:33063; # node3\    zone tcp_mem 64k;\    least_conn;\}\\match mysql_handshake {\    send \\x00;\    expect ~* \\x00\\x00; # 用于过滤握手响应数据包中的空值\}\\server {\    listen 3306; # MySQL默认端口\    proxy_pass galera_cluster;\    proxy_timeout 2s;\    health_check match=mysql_handshake interval=20 fails=1 passes=2;\}
\\

在这个例子里,match配置块定义了初始化一个MySQL握手协议需要的请求和响应数据。server配置块里的health_check指令使用了由match配置块定义的模式,并确保NGINX Plus只会向可用的服务器发起MySQL连接。我们每20秒执行一次健康检查,如果连接服务器失败一次,就把这个服务器从TCP负载均衡池里移除,如果连续两次健康检查成功,那么就重新把服务器放回负载均衡池。

\\

日志和诊断

\\

NGINX Plus提供了灵活的日志,所有的TCP和UDP处理过程都可以被记录下来,用于调试和离线分析。对于使用了TCP协议的系统,比如MySQL,NGINX Plus会在每次连接关闭之后记录一条日志。log_format指令指定哪些值可以出现在日志里。我们可以选择出现在Stream模块里的任意可用变量值。我们在stream.conf文件最上面的stream context里定义日志格式。

\\
\log_format mysql '$remote_addr [$time_local] $protocol $status $bytes_received '\                 '$bytes_sent $upstream_addr $upstream_connect_time '\                 '$upstream_first_byte_time $upstream_session_time $session_time';
\\

在server配置块里使用access_log指令来启用日志,并指定日志文件的路径和之前配置过的日志格式的名字。

\\
\server {\    ...\    access_log /var/log/nginx/galera_access.log mysql;\}
\\

这样的配置将生成如下格式的日志。

\\
\$ tail -3 /var/log/nginx/galera_access.log\192.168.91.1 [16/Nov/2016:17:42:18 +0100] TCP 200 369 1611 127.0.0.1:33063 0.000 0.003 12.614 12.614\192.168.91.1 [16/Nov/2016:17:42:18 +0100] TCP 200 369 8337 127.0.0.1:33061 0.001 0.001 11.181 11.181\192.168.91.1 [16/Nov/2016:17:42:19 +0100] TCP 200 369 1611 127.0.0.1:33062 0.001 0.001 10.460 10.460
\\

通过nginScript使用高级日志

\\

nginScript是NGINX的\"原生\"可编程配置语言。它是为NGINX和NGINX Plus专门实现的JavaScript,也是专门为服务器端的使用场景而设计的。

\\

在Stream模块里,可以通过nginScript访问请求和响应消息里的数据包。也就是说,我们可以查看从客户端发出的SQL查询请求,并从中抽取有用的元素,比如SQL的SELECT或UPDATE方法。nginScript可以把这些值变成普通的NGINX变量。在这个例子里,我们的JavaScript代码被放在/etc/nginx/sql_method.js文件里。

\\
\var method = \"-\"; // 全局变量\var client_messages = 0;\\function getSqlMethod(s) {\    if ( !s.fromUpstream ) {\        client_messages++;\        if ( client_messages == 3 ) { // SQL语句出现在第3个数据包里\            var query_text = s.buffer.substr(1,10).toUpperCase();\            var methods = [\"SELECT\

转载地址:http://gnwza.baihongyu.com/

你可能感兴趣的文章
【算法笔记】多线程斐波那契数列
查看>>
Ajax使用进阶
查看>>
Jquery元素选取、常用方法
查看>>
C语言下的错误处理的问题
查看>>
Java中解析XML的方法
查看>>
条目六《当心C++编译器中最烦人的分析机制》
查看>>
servlet的简单定义
查看>>
laravel sql复杂语句,原生写法----连表分组
查看>>
webstorm中github的配置
查看>>
老妈-养生
查看>>
backbone实例todos分析(三)总结 (转)
查看>>
Eclipse add external jars导致运行出现java.lang.NoClassDefFoundError的解决方法
查看>>
如何察看SQL Server 数据库中各个表的空间占用情况
查看>>
现代软件工程 第一章 概论 第2题——韩婧
查看>>
MSSQL孤立用户的解决办法
查看>>
Threads in Spring
查看>>
【HDOJ】1073 Online Judge
查看>>
TCHAR2char、CString2TCHAR*、TCHAR*2CString
查看>>
Hystrix是个什么玩意儿
查看>>
Storm入门(四)WordCount示例
查看>>