Nginx学习:Stream四层负载均衡浅尝及总结
学习了这么久,也该有个结束了,在最后一篇中,我们先来看一下 Nginx 做四层代理并实现负载均衡的模块。这个和 HTTP 模块中的七层代理没啥差别,就简单演示一下。最后,再稍稍总结一下,主要就是讲讲我们还有哪些东西没讲到。毕竟整个 Nginx 体系就是一个应用服务器体系的学习,牵涉到的东西还有很多。那么出于什么原因咱们不再继续了呢?别急,下面会说出原因。
Stream四层负载
先来看看四层负载代理。什么是四层,什么是七层,不用多解释了吧。物数网传会表应 在 信管师 的系列中还没背好?七层就是指的表现层,在 Nginx 中就是 http 协议的代理和负载均衡。而在老版本的 Nginx 中,只有 Http 这个模块,因此,也就只有七层代理。
不过,其实很早 Nginx 就有了 Stream 模块,这个模块就是做四层代理的,也就是 TCP、UDP 的代理与负载均衡。这个模块需要单独编译,直接加上 --with-stream 就好了。
我们的测试直接使用 Redis 来进行,因为 Redis 比较方便地就在单机上开多个服务器,而且安装速度也快。我们先准备好 6379、6380、6381 三个 Redis 实例。然后直接使用 Stream 模块配置就好了。
go
stream{
upstream redis {
server 127.0.0.1:6379;
server 127.0.0.1:6380;
server 127.0.0.1:6381;
}
server {
listen 8041;
proxy_pass redis;
}
}
是不是和 HTTP 中的没啥差别吧,确实是,就这样就可以啦。然后我们使用 Redis 客户端直接连接。
go
➜ ~ redis-cli -h 192.168.56.88 -p 8041
192.168.56.88:8041> set aa 1
OK
一切正常。这时你可以去 88 上的 Redis ,看看这个 aa 到底是落在哪一个端口实例上了。然后我们多次连接,进行获取测试,会发现,有时候连接上可以获取 aa 的值,有时候不行。这就是服务器组轮询在起作用了。每次连接,都会在服务器组中获取一个 server ,默认是轮询的。这里也可以使用 hash、random 之类的轮询策略。
然后看一下 Nginx 的错误日志,如果错误等级是 info 及以下,就可以看到这样的连接信息。
go
2022/09/26 10:11:29 [info] 2531#0: *48 client 192.168.56.1:51861 connected to 0.0.0.0:8041
2022/09/26 10:11:29 [info] 2531#0: *48 proxy 127.0.0.1:50182 connected to 127.0.0.1:6379
2022/09/26 10:11:31 [info] 2531#0: *48 client disconnected, bytes from/to client:101/11488, bytes from/to upstream:11488/101
2022/09/26 10:11:32 [info] 2531#0: *50 client 192.168.56.1:51862 connected to 0.0.0.0:8041
2022/09/26 10:11:32 [info] 2531#0: *50 proxy 127.0.0.1:40886 connected to 127.0.0.1:6380
2022/09/26 10:11:33 [info] 2531#0: *50 client disconnected, bytes from/to client:80/11483, bytes from/to upstream:11483/80
2022/09/26 10:11:34 [info] 2531#0: *52 client 192.168.56.1:51863 connected to 0.0.0.0:8041
2022/09/26 10:11:34 [info] 2531#0: *52 proxy 127.0.0.1:58272 connected to 127.0.0.1:6381
2022/09/26 10:11:38 [info] 2531#0: *52 client disconnected, bytes from/to client:185/11524, bytes from/to upstream:11524/185
可以看到,当我们的客户端建立连接时,Nginx 也直接代理到某一个 server 端口实例上。注意,在连接时,这个代理的实例是不会变的,当我们关闭客户端连接后,再次进入连接,就会连接到另外一台上了,所以 aa 就获取不到了。
如果想你多从读取配置,那么这三台 Redis 实例需要做数据同步。这样才能保证读取到的数据是一致的,但请求流量却分开了。
其实呀,对于 Redis 来说,咱们直接上 Cluster 就可以了,完全不需要 Nginx 嘛。不过 MySQL 的 Cluster 听说就没有 Redis 的那么简单好用了,所以很多时候,如果要做 MySQL 的从库负载均衡,经常还是会使用第三方工具。
Nginx 做四层,说实话,实际使用的公司并不多。这个功能出来的时间并不长,和 LVS 或者 HAProxy 相比优势也不大,资料也不多,实际应用的效果也更无从得知。毕竟那两货一直深耕代理负载均衡这一块,也都是头部王者了。Nginx 要使用的话,一是小项目可以做端口转发,比如我们不暴露 3306 或 6379 端口,而使用 Nginx 代理一个让人摸不着头脑的端口给外部使用;二是小项目,随便整,试试效果也不是不行,哪天抗不住了再换上 LVS 或者 HAProxy 呗。
Nginx 学习告一段落
好了,我们的 Nginx 这一阶段的内容就落幕了。不对呀,OpenResty 不讲讲?Keepalived 不玩玩?
不玩了,玩不动。为什么呢?最主要的原因是用不到啊。各位 PHPer 大佬,本身就是身兼数职的,PHP是基本功,前端得会一点吧,数据库不能说不会设计吧,Linux 至少服务能搭起来吧,来来回回其实要掌握的东西不少。而且在大部分情况下,就像我一样,经历的全是小公司,用过 Swoole 的都没几个,大部分性能瓶颈其实都在数据库上。这种情况下,别跟我提 OpenResty ,也别提什么 Keepalived ,我还 IP 漂移呢,能有两台做负载均衡的都不错了。
因此,这两块内容,将来如果有需要,咱们就单独说,如果到我退休了也踫不到,那也算是意料之中。各位大佬如果有时间、有精力,可以继续深耕下去,甚至是翻翻 Nginx 的源码也没问题。不过我在这一块的学习确实是要告一段落了。
其它还有很多东西没讲,比如 Mail 模块,我没搞明白干嘛用的,资料也不多。还有一些可能用不太上的,比如 ngx_http_geo_module、ngx_http_geoip_module、ngx_http_grpc_module、ngx_http_memcached_module、ngx_http_perl_module、ngx_http_spdy_module、ngx_http_memcached_module、ngx_http_scgi_module、ngx_http_uwsgi_module、ngx_http_v2_module、ngx_http_xslt_module、njs 。有些过时了、有些看不懂、有些真的没啥资料。一样的留给各位大佬自行研究吧,将来如果踫到了用到的时候,咱也单独再写。
最后就是一堆商业模块,包括:ngx_http_auth_jwt_module、ngx_http_f4f_module、ngx_http_hls_module、ngx_http_keyval_module、ngx_http_session_log_module、ngx_http_status_module、ngx_http_upstream_conf_module、ngx_http_upstream_hc_module 。这些只能随缘了。
下一阶段
好了,Redis、Nginx 这两大块暂时告一段落。接下来探索的是 XunSearch (迅搜)这个大系列文章,消息队列可能只会通过几篇小文章简单写写,划重点了,XunSearch 可能是全网唯一的一个关于迅搜这个搜索引擎的教程,目前来说真的仅此一份,而且你不光会学习到这个工具,更多的是能够了解到许多搜索引擎相关的知识,而这些知识才是财富。不管是 XS 还是 ES ,或者是 Solr、Sphinex 等等等,通用的基础知识都是一样的。
微服务、CI/CD、ElasticSearch、Kafka 等等这些都只做了解,随便找点视频学习了解,大家也可以都随便看看或者跟着练练哈,这些都不会写文章了,但是如果在文章中出现一些概念名词的话也不要惊讶,说明我可能正好就学完这些概念了。
再之后呢?核心不变,PHP+数据存储,都和 PHP小课堂 一样,写各种探索、测试和应用文章啦。
好吧,这一阶段任务也不轻吧,不过大体方向就是这些了。这是我近一两年的简要学习路线,学习总要有个规划,别太大,也别太小,一个月拿下大数据?一年学完 Redis ?前一个有点难,后一个估计前俩月看时间充足不想学,过俩月忘了这件事了。
要不,你也定定你的学习规划,在评论区写写吧~