使用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中的线程私有区,此时多个服务之间没有冲突。但是如果我们访问的数据的作用域在这几个服务之间共享呢?且提供添加等操作。那么会就出现并发问题,同时如果这里不是业务集群而是数据库集群,那么是否还需要考虑数据之间的共享同步?而且多个集群之间我们又怎么感知对方是否存活?

​ 当然这是学习了一些东西之后的思考,且确实是需要考虑和处理的,当然不是很全。

posted @ 2024-07-01 23:07  如此而已~~~  阅读(1164)  评论(0)    收藏  举报
//雪花飘落效果