使用Nginx搭建简单的集群
使用Nginx搭建简单的集群
官网地址:https://nginx.org/
集群:是将多个单独存在的服务器,通过集群技术将其集合,构成一个工作组、一台大型的服务器,以单一系统的模式加以管理。
一、Nginx(对nginx了解的可以直接跳过)
1、简介:
Nginx (engine x) 是一款是由俄罗斯的程序设计师 Igor Sysoev 所开发高性能的 Web 和反向代理服务器。第一个公开版本 0.1.0 发布于 2004 年 10 月 4 日。Nginx 是一个很强大的高性能 Web 和反向代理服务器,它具有很多非常优越的特性:在连接高并发的情况下,Nginx 是 Apache 服务不错的替代品。
2、作用:
http 协议代理
搭建虚拟主机
服务的反向代理
在反向代理中配置集群的负载均衡(本次使用)
3、代理:
正向代理
正向代理,意思是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端才能使用正向代理。
反向代理
反向代理服务器位于用户与目标服务器之间,但是对于用户而言,反向代理服务器就相当于目标服务器,即用户直接访问反向代理服务器就可以获得目标服务器的资源。同时,用户不需要知道目标服务器的地址,也无须在用户端作任何设定。反向代理服务器通常可用来
作为 Web 加速,即使用反向代理作为 Web 服务器的前置机来降低网络和服务器的负载,提高访问效率。
相同点
正向代理和反向代理所处的位置都是客户端和真实服务器之间,所做的事情也都是把客户端的请求转发给服务器,再把服务器的响应转发给客户端。
区别
位置不同:
正向代理,架设在客户机和目标主机之间;
反向代理,架设在服务器端;
代理对象不同:
正向代理,代理客户端,服务端不知道实际发起请求的客户端;
反向代理,代理服务端,客户端不知道实际提供服务的服务端;
总结
简单来说就是正向代理代理的是客户端,反向代理是代理的服务端。对于正向代理而言,我们可以通过代理服务器访问目标服务器,使得真实的客户端对于服务端不可见。对于反向代理而言,我们可以通过访问代理服务器而访问目标服务器,使得真实的服务器对于客户端不可见。
4、安装运行:
这里以Windows为例,Linux上怎么操作可以自己找教学:
1、下载:
到官网:https://nginx.org/ 点击右侧的 download 选择一个稳定的windows版本进行下载:
2、运行
将下载好的zip压缩包解压,然后使用双击 这里的exe文件,出现一闪而过的画面后浏览器访问:localhost
出现下面画面说明你成功了:
3、关闭
可以通过右击windows底部任务栏空白区域,通过任务管理器关闭(右击结束该任务):
5、nginx关键目录结构讲解
conf/nginx.conf nginx配置文件
html 存放静态文件(html、css、Js等)
logs 日志目录,存放日志文件
sbin/nginx 二进制文件,用于启动、停止Nginx服务使用的linux版本的就能看见
以下为一个Linux目录参考,使用tree命令查看的目录:
这里Windows版本重点关注,html 和 logs 和 conf/nginx.conf 就行,我这里放了一些东西不是初始nginx的内容哦。
# 安装tree yum install tree # 树形结构查看目录 tree nginx
6、配置文件梳理
这里我不过多赘述,nginx可以做的东西很多,可以了解一下后,再看看对应需要编译扩展的模块和需要修改的配置文件。
配置文件和注释:
# 全局块 # 指定可以运行 nginx 服务的用户和用户组,只能在全局块配置 # user nobody; # nginx 进程,一般数值为 cpu 核数 worker_processes 1; # 错误日志存放目录 # error_log logs/error.log; # error_log logs/error.log notice; # error_log logs/error.log info; # 进程 pid 存放位置 # pid logs/nginx.pid; # event 块 # 工作模式及连接数上限 events { # 单个后台 worker process 进程的最大并发链接数 worker_connections 1024; } # http 块 # http 块是 Nginx 服务器配置中的重要部分,代理、缓存和日志定义等绝大多数的功能 # 和第三方模块的配置都可以放在这个模块中。 http { # 文件扩展名与类型映射表 include mime.types; # 默认文件类型 default_type application/octet-stream; # 设置日志模式 # log_format main '$remote_addr - $remote_user [$time_local] "$request" ' # '$status $body_bytes_sent "$http_referer" ' # '"$http_user_agent" "$http_x_forwarded_for"'; # nginx 访问日志 # access_log logs/access.log main; # 开启高效传输模式 sendfile on; # 激活 tcp_nopush 参数可以允许把 http response header 和文件的开始放在一个文件里发布,积极的作用是减少网络报文段的数量 # tcp_nopush on; # 连接超时时间,单位是秒 keepalive_timeout 65; # 开启 gzip 压缩功能 # gzip on; # server 块 # server 块和“虚拟主机”的概念有密切联系。 server { # 监听端口 listen 80; # 80 端口访问时可以不写 server_name localhost; # 编码识别 # charset koi8-r; # 日志格式及日志存放路径 # access_log logs/host.access.log main; location / { # 站点根目录,即网站程序存放目录 root html; # 首页排序 index index.html index.htm; } # 错误页面 # error_page 404 /404.html; # 将服务器错误页面重定向到静态页面/50x.html error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } # 代理 PHP 脚本到 Apache 上监听 127.0.0.1:80 # location ~ \.php$ { # proxy_pass http://127.0.0.1; # } # 将 PHP 脚本传递到正在监听 127.0.0.1:9000 的 FastCGI 服务器 # location ~ \.php$ { # root html; # fastcgi_pass 127.0.0.1:9000; # fastcgi_index index.php; # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; # include fastcgi_params; # } # 如果 Apache 的文档根目录与 nginx 的根目录一致,则拒绝访问 .htaccess 文件 # location ~ /\.ht { # deny all; # } } # 另一个虚拟主机,混合使用 IP、名称和基于端口的配置 # server { # listen 8000; # listen somename:8080; # server_name somename alias another.alias; # # location / { # root html; # index index.html index.htm; # } # } # HTTPS server # # server { # listen 443 ssl; # server_name localhost; # # # 服务的证书 # # ssl_certificate cert.pem; # # # 服务端 key # # ssl_certificate_key cert.key; # # # 会话缓存 # # ssl_session_cache shared:SSL:1m; # # # 会话超时时间 # # ssl_session_timeout 5m; # # # 加密算法 # # ssl_ciphers HIGH:!aNULL:!MD5; # # # 启动加密算法 # # ssl_prefer_server_ciphers on; # # location / { # root html; # index index.html index.htm; # } # } }
7、解读server块
监听IP和端口
我们可以看到其监听的端口和IP地址
# server 块 # server 块和“虚拟主机”的概念有密切联系。 server { # 监听端口 和 ip[也可以是域名] listen 80; # 80 端口访问时可以不写 server_name localhost; # 编码识别 # charset koi8-r; # 日志格式及日志存放路径 # access_log logs/host.access.log main; location / { # 站点根目录,即网站程序存放目录 root html; # 首页排序 index index.html index.htm; } # 错误页面 # error_page 404 /404.html; # 将服务器错误页面重定向到静态页面/50x.html error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } # 代理 PHP 脚本到 Apache 上监听 127.0.0.1:80 # location ~ \.php$ { # proxy_pass http://127.0.0.1; # } # 将 PHP 脚本传递到正在监听 127.0.0.1:9000 的 FastCGI 服务器 # location ~ \.php$ { # root html; # fastcgi_pass 127.0.0.1:9000; # fastcgi_index index.php; # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; # include fastcgi_params; # } # 如果 Apache 的文档根目录与 nginx 的根目录一致,则拒绝访问 .htaccess 文件 # location ~ /\.ht { # deny all; # } }
访问默认页面
我们也看到了对应 html 目录下的 index.html 文件,这正是我们访问默认地址所看到的初始页面。
提示:可以修改其中内容重启后查看
<!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> html { color-scheme: light dark; } body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>
分析location 匹配规则
是指监听server模块对应ip和端口的访问地址,并映射到其中 "{}" 的处理方式中
location / { # 对于 IP + 端口 ... } location /images/ { # 对于 指定与路径开头的请求如:http://example.com/images/logo.png ... } location = /images/test.png { # 精确匹配如:http://example.com/images/logo.png ... } # 当然还存在一些模糊匹配方式可以查看相关资料
解释一下这里的配置,我们访问 localhost:80时将会访问:html目录下的index.html文件 。
location / { # 站点根目录,即网站程序存放目录 root html; # 首页排序 index index.html index.htm; }
尝试访问我们自己的页面
相信有过vue开发经验的小伙伴知道vue项目打包后的dist目录下有一个index.html,所以其实这里我们只需要改root根路径,就可以通过ip访问一个基于vue开发的打包好的前端项目了。
放入一个打包好的dist目录:
修改配置文件
location / { root html/dist; index index.html; }
重启查看
我们可以看到这里已经可以访问我们基于vue写的简单页面了,因为后端代码已经部署线上所以这里可以直接使用
8、nginx补充
最后我想说nginx还有很多功能,如果想要了解更多可以去B站和找一些优质博客去学习。这里可以提一些,比如有Java SpringBoot项目开发经验的人应该知道我们可以通过Spring的静态资源映射获取对应的图片或者页面资源,那么这里我们使用nginx既然可以代理页面,那么映射图片资源当然也是可以的,而且更快。
# 注意:这里的alias 后面跟的是图片的实际根路径: linux上是 /.../images/xxx.png windows上是 盘符:\...\images\xxx.png location /images/ { alias /中间路径/images/; # 参考存放路径,可以是其他目录 try_files $uri $uri/ =404; } # 这样配置后,你根据对应server的 IP+端口访问如: localhost:80/images/test.png # 就会在下面这个实际存放图片的地址中找到对应图片 /中间路径/images/test.png
二、配置集群
1、准备一个简单的SpringBoot项目
这里就给一个Controller就行了:
@RestController @RequestMapping("/test") public class TestController { @Value("${server.port}") private String port; @GetMapping("/getIPAndPort") public String getIPAndPort() throws UnknownHostException { String hostAddress = InetAddress.getLocalHost().getHostAddress(); System.out.println(hostAddress + ":" + port + "被调用"); return hostAddress + ":" + port + "被调用"; } }
2、通过IDEA启动多个服务
开启services窗口
添加SpringBoot项目
点击下方后找到Spring Boot项并点击
就会出现
启动多个服务
点击下方复制服务
给新服务取名和配置启动端口,然后
像这样准备几个就行了
3、配置nginx
# 在http块中添加 集群和一个server块即可 http { # 定义一个集群 upstream cluster { server 127.0.0.1:8888; server 127.0.0.1:8899; server 127.0.0.1:9999; server 127.0.0.1:8080; } # 监听80端口 如果访问的路径带有test 如:http://localhost/test/getIPAndPort # 就会根据对应负载均衡规则匹配:http://127.0.0.1:[对应端口号]/test/getIPAndPort server { listen 80; server_name localhost; location /test/ { proxy_pass http://cluster; } } }
4、查看
重复访问:
输出结果:
当你看到上述结果的时候说明一个基本的集群配置就成功了。
5、负载均衡策略
名称 | 说明 |
---|---|
轮询 | 默认方式 |
weight | 权重方式 |
ip_hash | 依据ip分配方式 |
least_conn | 依据最少连接方式 |
url_hash | 依据url分配方式 |
fair | 依据响应时间方式 |
写法:
# 在http块中添加 集群和一个server块即可 http { # 定义一个集群 upstream cluster { least_conn; # 策略写在此处 server 127.0.0.1:8888; server 127.0.0.1:8899; server 127.0.0.1:9999; server 127.0.0.1:8080; } # 监听80端口 如果访问的路径带有test 如:http://localhost/test/getIPAndPort # 就会根据对应负载均衡规则匹配:http://127.0.0.1:[对应端口号]/test/getIPAndPort server { listen 80; server_name localhost; location /test/ { proxy_pass http://cluster; } } }
三、总结:
为什么要集群?毫无疑问比起单台服务在性能上,集群服务的效率要高的多。而且有时候比起直接买一个性能更好的服务器,我们使用多个性能较差的服务器的成本可能更低,且相较于一台服务器的多台服务使得服务可以更加可靠,只有一台如果挂了 --__--,多台服务器运行其中一个挂了还有其他的在。当然优点不止于此。
但是没有问题吗?类似多线程或者说进程并发。同理上述的例子只是查询操作,而且获取的还是进程内部的值,类似于JVM中的线程私有区,此时多个服务之间没有冲突。但是如果我们访问的数据的作用域在这几个服务之间共享呢?且提供添加等操作。那么会就出现并发问题,同时如果这里不是业务集群而是数据库集群,那么是否还需要考虑数据之间的共享同步?而且多个集群之间我们又怎么感知对方是否存活?
当然这是学习了一些东西之后的思考,且确实是需要考虑和处理的,当然不是很全。
本文作者:如此而已~~~
本文链接:https://www.cnblogs.com/fragmentary/p/18279012
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步